Skip to main content
Refund all or part of a protocol charge or capture before refundExpiry. The refundable limit is maintained onchain, and refunds are always sent to paymentInfo.payer.
This guide’s payment flow is based on the Commerce Payments Protocol.

Demo

The demo above sends real transactions on Base Vibenet, an ephemeral devnet, each time you press a step. It mints Vibenet’s existing USDV test token, not USDC, charges its own payment, and mints fresh USDV as the operator’s refund liquidity before refunding; your browser’s Vibenet demo account acts as both payer and operator. If Vibenet is unavailable, the demo runs as a labeled offline mock and sends nothing.

Fund and Submit the Refund

Captured funds have already left escrow. The deployed OperatorRefundCollector sources replacement liquidity from paymentInfo.operator, so approve it for the refund amount before calling refund.
TypeScript
Every charge or capture increases refundableAmount by its gross amount. Fees do not reduce that limit. Every refund decreases it by the amount returned.
Verify PaymentRefunded(paymentInfoHash, amount, tokenCollector), the transfer to the stored payer, and the updated refundableAmount before completing the return.
Refund accounting is not refund liquidity. The operator or another independently authorized source must provide the tokens. Never reuse residual payer authorization to fund a refund.

See Also

Verify a Payment

Confirm the original protocol settlement and payment hash.

Reconcile Payments

Match refunds to charges and captures.