Handling Refunds
This guide explains how to process refunds through the SwiftPay API.
How Refunds Work
When you create a refund:
- The refund is created in
pending status
- We process the refund with our payment processor
- The refund status updates to
completed or failed
- Webhooks notify you of the status change
Refunds can only be created for completed checkout sessions.
Creating a Refund
Full Refund
To refund the full amount of a payment:
curl -X POST https://api.swiftpay.cx/api/refunds \
-H "Authorization: Bearer mp_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"checkoutSessionId": "sess_abc123",
"reason": "Customer requested refund"
}'
const response = await fetch("https://api.swiftpay.cx/api/refunds", {
method: "POST",
headers: {
Authorization: "Bearer mp_live_your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
checkoutSessionId: "sess_abc123",
reason: "Customer requested refund",
}),
});
const refund = await response.json();
import requests
response = requests.post(
'https://api.swiftpay.cx/api/refunds',
headers={
'Authorization': 'Bearer mp_live_your_api_key',
'Content-Type': 'application/json'
},
json={
'checkoutSessionId': 'sess_abc123',
'reason': 'Customer requested refund'
}
)
refund = response.json()
Response
{
"success": true,
"data": {
"id": "ref_xyz789",
"checkoutSessionId": "sess_abc123",
"amountInCents": 2999,
"reason": "Customer requested refund",
"status": "pending",
"requestedAt": "2024-01-15T10:30:00Z"
}
}
Refund Statuses
| Status | Description |
|---|
pending | Refund created, awaiting processing |
processing | Refund is being processed |
completed | Refund successful, funds returned |
failed | Refund failed |
Checking Refund Status
Get a Specific Refund
curl https://api.swiftpay.cx/api/refunds/ref_xyz789 \
-H "Authorization: Bearer mp_live_your_api_key"
List All Refunds
curl "https://api.swiftpay.cx/api/refunds?page=1&limit=20" \
-H "Authorization: Bearer mp_live_your_api_key"
Filter by Transaction
curl "https://api.swiftpay.cx/api/refunds?transactionId=sess_abc123" \
-H "Authorization: Bearer mp_live_your_api_key"
Refund Webhooks
Subscribe to refund events to get real-time updates:
| Event | Description |
|---|
refund.completed | Refund processed successfully |
refund.failed | Refund failed |
Example Webhook Payload
{
"id": "evt_abc123",
"type": "refund.completed",
"created": 1640995200,
"data": {
"refundId": "ref_xyz789",
"sessionId": "sess_abc123",
"amount": 2999,
"status": "completed",
"timestamp": "2024-01-15T10:35:00Z"
}
}
Refunds and Reserves
If a refund exceeds your available balance, funds will be drawn from your
rolling reserves.
When processing a refund:
- We first check your available balance
- If insufficient, we consume from your active reserves (oldest first)
- If still insufficient, the refund will fail
You can view your balance breakdown via the Balance API:
curl https://api.swiftpay.cx/api/balance \
-H "Authorization: Bearer mp_live_your_api_key"
{
"success": true,
"data": {
"availableBalance": 50000,
"reservedBalance": 15000,
"totalBalance": 65000,
"pendingWithdrawals": 0
}
}
Processing Time
| Type | Processing Time |
|---|
| Card Refund | 5-10 business days |
Refund processing time depends on the customer’s bank and card network.
Best Practices
Include a clear reason for every refund. This helps with:
- Internal tracking
- Customer communication
- Dispute resolution
Before creating a refund, check your available balance to ensure sufficient funds:const balance = await getBalance();
if (balance.availableBalance + balance.reservedBalance < refundAmount) {
throw new Error('Insufficient funds for refund');
}
Don’t poll for refund status. Use webhooks to get real-time updates when a refund completes or fails.
Handle Failures Gracefully
If a refund fails, notify your customer and provide alternative resolution options.
Common Issues
Insufficient Balance
{
"success": false,
"error": {
"type": "validation_error",
"message": "Insufficient balance for refund",
"requestId": "req_abc123"
}
}
Solution: Wait for more payments to settle or contact support.
Session Not Completed
{
"success": false,
"error": {
"type": "validation_error",
"message": "Can only refund completed sessions",
"requestId": "req_abc123"
}
}
Solution: Refunds can only be created for sessions with status completed.
Already Refunded
{
"success": false,
"error": {
"type": "conflict_error",
"message": "This session has already been refunded",
"requestId": "req_abc123"
}
}
Solution: Each session can only be refunded once.