Skip to content

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 paidSend the refund to
Crypto from their own walletmethod.from_address, the address the transfer came from, on the same network. Confirm it with the customer first.
Crypto from an exchangeAn address the customer gives you. The address the transfer came from often belongs to the exchange, not to them.
Card, Apple Pay or Google PayAn 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.
A transfer to the wrong address or network can't be undone. Ask the customer to confirm the address, coin and network before you send.

How much to send

  • A whole crypto payment: method.amount of method.asset is what arrived. For a card payment, amount_received is what the customer paid, in the payment's currency.
  • An overpayment's excess: method.overpaid_amount, in method.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.

Estimate the network fee
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.

Note the refund on the payment
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}.

Note the send
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.