Refunds, returns and disputes
Send refunds from your wallet, return funds you don't accept, and keep disputes rare.
There's no refund endpoint and no refunded status. Payments go straight to your wallet, and money never moves on an API key, so a refund is a send from your wallet that you make yourself. This guide covers where to send it, how much, and how to keep a record.
Where to send it
| The customer paid | Send the refund to |
|---|---|
| Crypto from their own wallet | method.from_address, the address the transfer came from, on the same network. Confirm it with the customer first. |
| Crypto from an exchange | An address the customer gives you. The address the transfer came from often belongs to the exchange, not to them. |
| Card, Apple Pay or Google Pay | An address the customer gives you. Card payments arrive as crypto on the selected network, so the refund goes out in crypto, not back to the card. |
How much to send
- A whole crypto payment:
method.amountofmethod.assetis what arrived. For a card payment,amount_receivedis what the customer paid, in the payment's currency. - An overpayment's excess:
method.overpaid_amount, inmethod.asset. - A late or wrong-network transfer you don't want to accept: everything that arrived, from the payment that
needs_review. - Coin prices move after a payment. Decide whether you refund the same coin amount or the same value in your currency, and say which in your terms.
Send the refund
From a wallet created or imported in 402pay, open Wallet in the dashboard, choose the coin and network, and send. Each payment landed at its own address, so the send draws on the addresses holding the coin, signed in your browser with your encryption password. From an external wallet, send in your own wallet app, then record the send in the dashboard with its transaction hash, so your history matches. API keys can't send, so refunds go out from the dashboard, which checks each one as send from the wallet describes.
Every send pays a network fee. A token send, such as USDC on Polygon, pays it in the network's own coin, POL on Polygon, so keep a little of it in the wallet; without enough, the send fails with insufficient_fee_funds. Estimate the fee first.
curl "https://dash.402pay.co/api/v1/wallet/fee-estimates?network=polygon" \ -H "Authorization: Bearer $PAY402_SECRET_KEY"Keep a record
The payment stays succeeded after a refund, so your own records are the source of truth. Add the refund to the payment's metadata, which merges by key, so you can filter refunded payments later.
curl -X PATCH "https://dash.402pay.co/api/v1/payments/pmt_QI02vLdJGd48hBbg" \ -H "Authorization: Bearer $PAY402_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{ "metadata": { "refund_status": "refunded", "refund_tx_hash": "0x5a1f9c3e8b7d6a2f4c0e9b8a7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c" } }'Give the send itself a note, up to 280 characters, when you make it in the dashboard, or later with PATCH /wallet/transactions/{id}.
curl -X PATCH "https://dash.402pay.co/api/v1/wallet/transactions/wtx_Q7vXk2Lp9RmT4sYb" \ -H "Authorization: Bearer $PAY402_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{ "note": "Refund for order_1042" }'Late and wrong-network transfers
A payment that needs_review already has its funds in your wallet. If you don't want to accept it, send the funds back the same way as a refund. The payment stays needs_review, so record what you did in its metadata, such as review set to returned, and filter those out of your review queue.
Disputes
A crypto transfer can't be reversed by the sender, so crypto payments have no chargebacks. Cardholders can still dispute a card payment with their bank, and you'll be asked for evidence. A clear description of what customers are buying, and your refund policy shown before they pay, keep disputes rare.