Refund a payment
Create full or partial refunds and understand Gateway underpayments and overpayments
Refund a PaymentIntent
Use a secret key to fully or partially refund a succeeded PaymentIntent.
// Full refund: omit amount.
const fullRefund = await paymentIntentClient.paymentIntents.refund(
paymentIntentId,
);
// Partial refund: use the fiat currency's major unit.
const partialRefund = await paymentIntentClient.paymentIntents.refund(
paymentIntentId,
{ amount: 500, reason: "customer_request" },
);amount uses the same fiat currency and major unit as the PaymentIntent. It means ¥500 for JPY and $500 for USD.
The response contains the updated paymentIntent and the new refund as { id, status }.
status: "requested" means the refund was recorded in the ledger. The actual transfer is completed asynchronously through the TRADOM Payment approval and execution flow.
Constraints
- Only a
succeededPaymentIntent can be refunded - The secret key and PaymentIntent must belong to the same merchant
- A partial refund must be greater than zero and no more than the unrefunded balance (exceeding it fails with
payment_intent_unexpected_state(409); a non-positive or non-numeric amount fails withparameter_invalid(400)) - A server-side row lock prevents concurrent requests from exceeding the balance
- A full refund requests the entire remaining balance
The PaymentIntent remains succeeded after a refund. Check amountRefunded, refunds.data, or the payment_intent.refunded event.
The REST endpoint is POST /api/v1/payment_intents/{id}/refund. There is no legacy top-level /api/v1/refunds endpoint.
Gateway underpayments and overpayments
Gateway compares the received deposit with the expected amount.
- Underpayment: automatically refund received funds or send the case to operations
- Overpayment: continue the payment and request a refund for the difference
Check state.matchStatus, underpaymentRefundStatus, and overpaymentRefundStatus from checkoutStatus. This flow is separate from the PaymentIntent refund API.