Ask for a refund
Create a refund from the server with POST /v1/refunds, a key carrying payments:write and a saved Idempotency-Key. Keep the same payment, amount and reason when replaying that request. A replay with the same key returns the refund you already asked for, never a second one. Save the returned refund ID.
curl -s -X POST https://api.bolrachpay.com/v1/refunds \
-H "Authorization: Bearer $BOLRACH_KEY" \
-H "Idempotency-Key: order-1042-refund-1" \
-H "Content-Type: application/json" \
-d '{
"payment_intent": "pay_36bac68976f34574be70",
"amount": "100000",
"reason": "One item out of stock"
}'
# Leave out "amount" to refund what is left of the payment.Follow it
Read GET /v1/refunds/:id with payments:read. Check its payment_intent, amount, currency and env against the saved payment. An accepted request or a pending status does not mean the buyer has been refunded.
curl -s https://api.bolrachpay.com/v1/refunds/$REFUND_ID \
-H "Authorization: Bearer $BOLRACH_KEY"In the webhook setup, subscribe to refund.pending, refund.completed, refund.failed and refund.review_required. Verify the signature and drop events you have already handled. Read the current refund again when an event arrives. The refund record uses succeeded for confirmed completion, while the event name is refund.completed.
Recover a failed attempt
Retry only a refund that has definitely failed, after you have read why, with POST /v1/refunds/:id/retry and a new saved idempotency key for that retry. Reuse that retry key if its response is lost. Read the original refund's replacement_refund to find the next attempt; never match refunds by amount. Escrow refunds use POST /v1/escrows/:id/refunds/:refundId/retry with escrow:write so the reservation and settlement stay linked. Do not retry pending or unknown outcomes, or create a fresh refund to get round a conflict.
curl -s -X POST https://api.bolrachpay.com/v1/refunds/$REFUND_ID/retry \
-H "Authorization: Bearer $BOLRACH_KEY" \
-H "Idempotency-Key: order-1042-refund-1-retry-1"Refunds that need a person
A refund can change to review_required when late evidence from the processor contradicts an original or replacement refund. This is not successful completion. Read the saved refund and handle the refund.review_required webhook against your own order, then contact support for manual reconciliation. There is no automatic or manual retry endpoint for this state. A checkout that completed earlier does not settle the question or allow another fulfilment.
paid after its payment is refunded. Your order page should read the payment itself, as the hosted checkout guide shows, so a refunded order never ships.