PayFacto API - v2.0 - POST /refunds
PayFacto API - v2.0 - POST /refunds
Issues a refund for a previously completed charge. Partial refunds are supported — the amount must not exceed the remaining captured amount.
🔑
Authentication — HTTP Basic Auth
All v2.0 endpoints use HTTP Basic Authentication. Set Authorization: Basic base64(username:password). Contact PayFacto for credentials.
📋
Content-Type
All request bodies require Content-Type: application/json.
🔄
Idempotency
Include Idempotency-Key header (max 64 chars) on POST requests. 200 = duplicate; 201 = newly created.
💵
Amounts
All monetary amounts are positive integers in cents. $12.99 = 1299.
POST https://uat.ca.api.payfacto.cloud/payments/v1/refunds
ℹ️
A charge must be captured or succeeded to be refunded. If the batch is settled, use this endpoint rather than a void.
Request body fields
| Field | Constraint | Description |
|---|
| amount | integer · required | Amount to refund in cents. Must be >= 1 and <= remaining captured amount. |
| chargeId | string (UUID) · required | ID of the charge to refund. |
| reason | string · required | DUPLICATE, FRAUDULENT, REQUESTED_BY_CUSTOMER, or REQUESTED_BY_MERCHANT. |
| metadata | object · optional | Key-value pairs stored with the refund. |
| paymentMethod | object · optional | Override payment method. Required for some terminal flows. |
reason values
| reason | Description |
|---|
| DUPLICATE | Duplicate transaction |
| FRAUDULENT | Suspected fraud |
| REQUESTED_BY_CUSTOMER | Customer requested |
| REQUESTED_BY_MERCHANT | Merchant initiated |
⚠️
Use UAT credentials during testing.
JSON — Refund request
{
"amount": 1299,
"chargeId": "a1822999-099d-4fb1-a354-77be553a5b22",
"reason": "REQUESTED_BY_CUSTOMER",
"metadata": { "ticket": "TKT-0042" }
}Response fields (refund object)
| Field | Type | Description |
|---|
| id | string (UUID) | Unique refund identifier. |
| amount | integer | Refund amount in cents. |
| chargeId | string (UUID) | The charge that was refunded. |
| failureReason | string | If failed: LOST_OR_STOLEN_CARD, EXPIRED_OR_CANCELLED_CARD, UNKNOWN. |
| metadata | object | Key-value pairs. |
| originalTransactionTime | string (ISO 8601) | UTC timestamp of original charge. |
| paymentMethod | object | Payment method used for the refund. |
| reason | string | Refund reason from request. |
| result | object | Auth result including authCode. |
| status | string | SUCCEEDED, FAILED, or VOIDED. |
| transactionTime | string (ISO 8601) | UTC timestamp when this refund was created. |
| voidDetail | object | Void details if voided. |
| error | object | Error object on failure. |
5
Response — Code Examples
JSON — 201 Succeeded
{
"id": "3a2049fb-6c9f-433d-9cef-701b6843f0cd",
"amount": 1299,
"chargeId": "a1822999-099d-4fb1-a354-77be553a5b22",
"reason": "REQUESTED_BY_CUSTOMER",
"result": { "authCode": "012345" },
"status": "SUCCEEDED",
"transactionTime": "2024-05-15T17:00:01Z"
}JSON — 402 Failed
{
"id": "3a2049fb-6c9f-433d-9cef-701b6843f0cd",
"amount": 1299,
"failureReason": "LOST_OR_STOLEN_CARD",
"reason": "REQUESTED_BY_CUSTOMER",
"status": "FAILED",
"error": { "code": "ISSUER_DECLINED", "type": "CARD_ERROR", "message": "Declined by the issuer." }
}6
Error / HTTP Status Codes
| HTTP Status | Meaning | Recommended Action |
|---|
| 200 | OK — Previously created (same idempotency key) | Check status field in response body |
| 201 | Created — New resource created | Store the id for future operations |
| 400 | Bad Request — Invalid payload | Check error.details and error.invalidFields |
| 402 | Payment Required — Issuer declined | Check result.declineCode — do not retry automatically |
| 404 | Not Found | Verify the ID in the request path |
| 422 | Unprocessable — Invalid state | Check error.message |
| 500 | Internal Server Error | Retry with backoff; contact PayFacto Support if persistent |