Refunds
Create refund
Return money on a succeeded card payment, in full or in part.
/v1/refundsHeaders
Optional, up to 255 bytes. Send it: a retried refund with the same key returns the original refund and never reaches the processor again, whatever the body says this time — there is no body comparison on refunds, so no 409. Without it every retry is a new refund. See Idempotency.
Example: refund-order-1234
Body parameters
The payreq_* id of a succeeded card payment. Any other method is refused 422 refund_not_supported; any other status 409 not_refundable.
Example: payreq_9b2f...
Whole rupiah, 1 to what is left unrefunded on the payment. Omit it for the whole remaining amount; an explicit 0 is a 422. Partial refunds may be repeated until the amount paid is spent — one rupiah past it is 422 refund_exceeds_amount.
Example: 50000
Free text, max 255 characters, stored and echoed. Not shown to the buyer.
Example: Satu barang dikembalikan
Response fields
The rfd_* id. Read it back with GET /v1/refunds/{id}.
Example: rfd_7c1a...
The payreq_* id the money went back from.
Example: payreq_9b2f...
succeeded, failed or pending. pending is a refund the processor never answered: its amount is held until a human resolves it, so do not retry — see refund_unresolved.
Example: succeeded
Whole rupiah refunded by this refund alone.
Example: 50000
What you sent, echoed. Omitted when empty.
The processor's own words when status is failed. Omitted otherwise.
ISO-8601 with a +07:00 offset.
Example: 2026-08-31T10:12:00+07:00
curl https://pay.kasera.id/v1/refunds \
-H "Authorization: Bearer kp_live_..." \
-H "Idempotency-Key: refund-order-1234" \
-H "Content-Type: application/json" \
-d '{
"transaction_id": "payreq_9b2f...",
"amount": 50000,
"reason": "Satu barang dikembalikan"
}'{
"id": "rfd_7c1a...",
"transaction_id": "payreq_9b2f...",
"status": "succeeded",
"currency": "IDR",
"amount": 50000,
"reason": "Satu barang dikembalikan",
"created_at": "2026-08-31T10:12:00+07:00",
"livemode": true
}