Refunds
Issue full or partial refunds on paid intents. Support multiple partial refunds up to the original amount.
Refunds
Refund paid intents fully or partially. You can issue multiple partial refunds on the same intent until the total refunded equals the original payment amount.
Full refund
Omit the amount field to refund the entire payment.
POST /dev/intents/{referenceNumber}/refundcurl -X POST https://api.elebne.ai/api/v1/dev/intents/PI-3XXXXXXXXXXXXXX/refund \
-H "Authorization: Bearer sk_test_YOUR_KEY" \
-H "Content-Type: application/json" \
-H "X-Idempotency-Key: refund-order-5678" \
-d '{
"reason": "customer_request",
"note": "Customer changed their mind"
}'const response = await fetch(
'https://api.elebne.ai/api/v1/dev/intents/PI-3XXXXXXXXXXXXXX/refund',
{
method: 'POST',
headers: {
'Authorization': 'Bearer sk_test_YOUR_KEY',
'Content-Type': 'application/json',
'X-Idempotency-Key': 'refund-order-5678',
},
body: JSON.stringify({
reason: 'customer_request',
note: 'Customer changed their mind',
}),
}
);
const { data } = await response.json();
console.log(data.refunded); // trueresponse = requests.post(
'https://api.elebne.ai/api/v1/dev/intents/PI-3XXXXXXXXXXXXXX/refund',
headers={
'Authorization': 'Bearer sk_test_YOUR_KEY',
'Content-Type': 'application/json',
'X-Idempotency-Key': 'refund-order-5678',
},
json={
'reason': 'customer_request',
'note': 'Customer changed their mind',
},
)
print(response.json())Partial refund
Include an amount field (in centimes) to refund only part of the payment.
curl -X POST https://api.elebne.ai/api/v1/dev/intents/PI-3XXXXXXXXXXXXXX/refund \
-H "Authorization: Bearer sk_test_YOUR_KEY" \
-H "Content-Type: application/json" \
-H "X-Idempotency-Key: partial-refund-1" \
-d '{
"amount": 20000,
"reason": "product_defective",
"note": "1 of 3 items was damaged"
}'const response = await fetch(
'https://api.elebne.ai/api/v1/dev/intents/PI-3XXXXXXXXXXXXXX/refund',
{
method: 'POST',
headers: {
'Authorization': 'Bearer sk_test_YOUR_KEY',
'Content-Type': 'application/json',
'X-Idempotency-Key': 'partial-refund-1',
},
body: JSON.stringify({
amount: 20000,
reason: 'product_defective',
note: '1 of 3 items was damaged',
}),
}
);
const { data } = await response.json();
console.log(data.amountRefunded); // 20000response = requests.post(
'https://api.elebne.ai/api/v1/dev/intents/PI-3XXXXXXXXXXXXXX/refund',
headers={
'Authorization': 'Bearer sk_test_YOUR_KEY',
'Content-Type': 'application/json',
'X-Idempotency-Key': 'partial-refund-1',
},
json={
'amount': 20000,
'reason': 'product_defective',
'note': '1 of 3 items was damaged',
},
)
print(response.json())Multiple partial refunds
You can issue multiple partial refunds on the same intent. Each refund is tracked individually in the refunds array.
Original payment: 50000 centimes (500.00 MRU)
1st partial refund: 20000 centimes (200.00 MRU) -> totalAmountRefunded: 20000
2nd partial refund: 15000 centimes (150.00 MRU) -> totalAmountRefunded: 35000
3rd partial refund: 15000 centimes (150.00 MRU) -> totalAmountRefunded: 50000 (fully refunded)After any refund, the intent status changes to REFUNDED. You can continue issuing partial refunds until totalAmountRefunded equals the original amount.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
amount | integer | No | Partial refund amount in centimes. Omit for full refund. Minimum: 1. |
reason | string | No | Refund reason. Suggested values: customer_request, product_defective, duplicate, fraud. |
note | string | No | Free-text note for your records. Max 500 characters. |
Checking refund status
After refunding, the intent's refunds array contains each individual refund:
{
"success": true,
"data": {
"referenceNumber": "PI-3XXXXXXXXXXXXXX",
"status": "REFUNDED",
"amount": 50000,
"payment": {
"amountPaid": 50000,
"paidAt": "2026-04-04T10:35:00.000Z",
"method": "WALLET"
},
"refunds": [
{
"amountRefunded": 20000,
"reason": "product_defective",
"note": "1 of 3 items was damaged",
"refundedAt": "2026-04-04T14:00:00.000Z"
},
{
"amountRefunded": 15000,
"reason": "customer_request",
"note": null,
"refundedAt": "2026-04-04T15:30:00.000Z"
}
],
"totalAmountRefunded": 35000
}
}Error cases
| Error code | HTTP | Description |
|---|---|---|
IDEMPOTENCY_KEY_REQUIRED | 400 | Missing X-Idempotency-Key header |
INTENT_NOT_FOUND | 404 | Intent does not exist or belongs to another business |
INTENT_REFUND_INVALID_STATUS | 400 | Intent is not in PAID or REFUNDED status |
REFUND_EXCEEDS_REMAINING | 400 | Refund amount exceeds remaining refundable balance |
INSUFFICIENT_BALANCE | 400 | Merchant account has insufficient balance for the refund |
Merchant balance required
Refunds are debited from your merchant account balance. Ensure you have sufficient funds before issuing refunds.
Testing refunds in sandbox
In sandbox mode, use the simulate-payment endpoint to create a paid intent, then test refunds against it.
Create an intent with sk_test_ key
Simulate payment via POST /dev/intents/{ref}/simulate-payment
Issue a refund via POST /dev/intents/{ref}/refund
Next steps
- Webhooks & Events -- receive
payment.refundedevents in real-time - Payment Intents -- full intent lifecycle reference
- Hosted Checkout -- redirect-based payment flow
Was this page helpful?