Issue a refund
Refund a successful payment in full or in part. Multiple partial refunds are allowed up to the original amount.
Refunds return money to the customer's card. You can refund a payment in full once, or in several partial refunds that sum up to the original amount. Each refund is its own resource you can look up by ID.
Eligible payments
A payment can be refunded only if it's in succeeded or partially_refunded. Refunds against failed, voided, or already-fully-refunded payments are rejected.
Issuing a refund
Full refund
Send amount: null (or omit it) to refund the entire remaining amount:
await fetch(
`https://sandbox.mintcash.me/payments/${paymentId}/refund`,
{
method: "POST",
headers: { Authorization: ..., "Content-Type": "application/json" },
body: JSON.stringify({
externalId: `refund_${orderId}_full`,
reason: "customer_request",
}),
},
);The payment transitions to refunded (terminal).
Partial refund
Specify an amount less than the remaining refundable balance:
await fetch(
`https://sandbox.mintcash.me/payments/${paymentId}/refund`,
{
method: "POST",
headers: { Authorization: ..., "Content-Type": "application/json" },
body: JSON.stringify({
externalId: `refund_${orderId}_partial_1`,
amount: 1500, // $15.00 of a $49.99 payment
reason: "item_returned",
}),
},
);The payment transitions to partially_refunded. The remaining refundable amount is on the payment response as amountRefundable.
State diagram
What you receive
When a refund processes, you get one of two webhooks:
| Event | When |
|---|---|
payment.partially_refunded | Refund succeeded; more refunds still possible |
payment.refunded | Refund cleared the remaining balance — terminal |
payment.refund_failed | The refund attempt failed; payment is unchanged |
Webhook data includes both the parent payment and the new refund record.
Idempotency
externalId on POST /refund is required and scoped per payment. Two refunds against the same payment can't share an externalId. A retry with the same externalId returns the existing refund record without issuing a duplicate.
Refunds settle on the provider's clock
We tell the provider to refund immediately. The actual money on the customer's card can take 3–10 business days depending on issuer. Set customer expectations accordingly, especially during chargeback disputes.
Listing refunds for a payment
const refunds = await fetch(
`https://sandbox.mintcash.me/payments/${paymentId}/refunds`,
{ headers: { Authorization: ... } },
).then((r) => r.json());
for (const r of refunds) {
console.log(r.id, r.amount, r.status, r.createdAt);
}Or retrieve a single refund by its own ID:
await fetch(`https://sandbox.mintcash.me/refunds/${refundId}`, ...);What to test
- Full refund —
payment.refundedarrives; further refund attempts fail - Two partial refunds totalling less than the payment — payment stays in
partially_refunded - Final partial refund that clears the balance —
payment.refunded - Refund against a failed payment —
400 invalid_argument - Duplicate refund externalId — second call returns the original refund