diff --git a/internal/escrow/escrow.go b/internal/escrow/escrow.go index 11c357f..aa51ef9 100644 --- a/internal/escrow/escrow.go +++ b/internal/escrow/escrow.go @@ -85,3 +85,49 @@ func DepositEscrowHandler(w http.ResponseWriter, r *http.Request) { "escrow_id": escrowID, }) } + +func ReleaseEscrowHandler(w http.ResponseWriter, r *http.Request) { + claims, ok := r.Context().Value("user").(*middleware.Claims) + if !ok || claims.Role != "buyer" { + log.Printf("[ERROR] Unauthorized access attempt by userID %d with role %s", claims.UserID, claims.Role) + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + + vars := mux.Vars(r) + transactionIDStr := vars["id"] + transactionID, err := strconv.Atoi(transactionIDStr) + if err != nil { + http.Error(w, "Invalid transaction ID", http.StatusBadRequest) + return + } + + var transaction models.Transaction + err = db.DB.Get(&transaction, "SELECT * FROM transactions WHERE transaction_id = $1", transactionID) + if err != nil { + http.Error(w, "Transaction not found", http.StatusNotFound) + return + } + + if transaction.Status != "in_progress" && transaction.Status != "pending" { + http.Error(w, "Cannot release funds for this transaction", http.StatusBadRequest) + return + } + + _, err = db.DB.Exec("UPDATE escrow_accounts SET status = 'released' WHERE transaction_id = $1", transactionID) + if err != nil { + http.Error(w, "Failed to release funds from escrow", http.StatusInternalServerError) + return + } + + _, err = db.DB.Exec("UPDATE transactions SET status = 'completed', updated_at = NOW() WHERE transaction_id = $1", transactionID) + if err != nil { + http.Error(w, "Failed to update transaction status", http.StatusInternalServerError) + return + } + + w.WriteHeader(http.StatusOK) + json.NewEncoder(w).Encode(map[string]string{ + "message": "Funds successfully released to the seller", + }) +} diff --git a/main.go b/main.go index fda7cc7..d12fd35 100644 --- a/main.go +++ b/main.go @@ -42,6 +42,7 @@ func main() { api.HandleFunc("/transactions/{id}/confirm", transactions.ConfirmDeliveryHandler).Methods("PUT") api.HandleFunc("/escrow/{id}/deposit", escrow.DepositEscrowHandler).Methods("POST") + api.HandleFunc("/escrow/{id}/release", escrow.ReleaseEscrowHandler).Methods("PUT") // Setup CORS c := cors.New(cors.Options{ diff --git a/swagger/swagger.yml b/swagger/swagger.yml index f3230fe..20eb839 100644 --- a/swagger/swagger.yml +++ b/swagger/swagger.yml @@ -333,6 +333,62 @@ paths: security: - BearerAuth: [] + /api/escrow/{id}/release: + put: + summary: Release funds from escrow to the seller + description: This endpoint releases the escrowed funds to the seller. Only admin or system can perform this operation. + tags: + - escrow + parameters: + - name: id + in: path + required: true + description: The ID of the transaction to release funds for + schema: + type: integer + responses: + '200': + description: Funds successfully released to the seller + content: + application/json: + schema: + type: object + properties: + message: + type: string + example: "Funds successfully released to the seller" + '400': + description: Bad request - Invalid transaction status or other validation error + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: "Cannot release funds for this transaction" + '404': + description: Not Found - Transaction not found + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: "Transaction not found" + '500': + description: Server error - An error occurred while processing the request + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: "Failed to release funds from escrow" + security: + - BearerAuth: [] /api/upload: post: