What are the exception cases, and does the order still succeed?
Waffo classifies an off-spec transfer into one of these cases — the label is what support uses when you raise a ticket.
Two rules run through the table: settlement is always based on the order
amount, never on what was transferred; and a return of funds to the shopper is
not a refund on your account — no refund order, nothing in your refund reports.
The shopper overpaid — do I get the extra?
No, the order completes at the order amount and the surplus is not yours. A small excess — within a tolerance of the order amount, or smaller than the cost of sending it back — is not returned and is not credited to you either; a larger excess goes back to the paying address, less that transfer cost. So never reconcile a stablecoin order against the on-chain amount.The shopper underpaid or paid too late — can I still fulfil?
No, neither case pays the order, so do not release goods on the strength of an on-chain transfer you observed yourself. Waffo sends the received amount back to the paying address less the transfer cost; if it does not cover that cost, nothing is sent back. Guide shoppers to pay the full order amount in one transfer, inside the payment window on the payment page.Wrong chain, wrong token, or an old address — will it auto-resolve?
No.WRONG_TOKEN, WRONG_CHAIN and NO_MATCH_ORDER are never handled
automatically: the order does not succeed and the funds do not go back on their
own. Raise a support ticket with the transaction hash, chain, token and order id.
The usual cause of NO_MATCH_ORDER is a reused receiving address — addresses are
issued per order, so if you cache one or let a shopper pay in twice, the second
transfer matches no order.
Why is a return slow when the shopper paid from an exchange?
Automatic returns only go to a self-custody wallet (an EOA). Funds sent from an exchange withdrawal address or a contract address cannot safely be returned there — the address is not the shopper’s own — so the case goes to manual handling and takes considerably longer. Where you can, tell shoppers to pay from their own wallet rather than straight from an exchange account.Where can I see these exception cases myself?
Nowhere in the Portal, and this is the honest answer rather than a missing screen: no merchant-facing view carries on-chain detail. The transaction list and the transaction detail have no chain column, no transaction hash, no confirmation count and no received-amount-versus-order-amount comparison, so an overpay, an underpay or a wrong-chain transfer is not something you can look up. What you can see is the order: it either reached a final success state or it did not. Everything above is a statement about where the funds went, not about the order, and none of these cases creates a refund order on your account — so they never appear in your refund list or refund reports either. That leaves one route when a shopper insists they paid: raise the order id with support, together with the transaction hash, chain and token the shopper can give you. Those four facts are what the case is identified by. The one exception is the x402 signature path, where a successful order returns an on-chain settlement receipt on the API, transaction hash included — see x402 stablecoin acquiring.What must I send when I refund a stablecoin order?
A refund destination address is mandatory for every USDC and USDT refund. Send it inextendInfo on /api/v1/order/refund. The outer extendInfo value is a string
containing JSON, not a nested JSON object.
Here is a complete request body. Replace each placeholder with the value for your
order and customer:
refundAmount to the full refundable order amount. The refund address must be
valid for the original payment chain. Omit it and the request fails parameter
validation up front with A0003 and the message
Parameter validation failed ( missing refund optional field ).
msgParams.missingFields contains extendInfo.refundAddress. No refund order is
created, so there is nothing to inquire about afterwards; on fiat orders it is
unnecessary and ignored if sent. Treat this as an integration change:
if you already call the refund API and then add stablecoin acceptance, update your
refund path first. Collect the address from the shopper yourself — Waffo cannot
contact your shopper to ask for one.
Can I refund to a different chain, or to any wallet?
No to both. The chain is read from the original payment and locked; there is no chain parameter on the refund request and any attempt to supply one is ignored. The chain determines which address format is accepted, and the address is validated against that chain’s format when the refund is processed:
Two format details worth building into your own input validation, because they
are checked and they surprise people:
- Mixed-case EVM addresses are checksum-verified (EIP-55). An address that is entirely lower-case or entirely upper-case is accepted as-is; one with mixed case must have a valid EIP-55 checksum. So an address that has been “tidied up” by hand — one letter re-cased — fails, while the same address all in lower case passes.
- Tron addresses are Base58Check-decoded, not just pattern-matched. A single mistyped character fails the checksum rather than being accepted and failing later on-chain.
INVALID_REFUND_ADDRESS_FORMAT, followed by the specific reason. Unlike a
missing address, a malformed one is caught one step later — after the refund
order has already been created — so the outcome is a refund order in
ORDER_REFUND_FAILED, visible on refund inquiry and in the Portal’s Refunds
list with that reason. Nothing moved on-chain. Because the failed record already
exists, retrying with a corrected address is a fresh request with a new
refundRequestId: resending the old id returns the failed record, not a new
attempt. Check remainingRefundAmount before you resend.
Use a self-custody (EOA) wallet address. A contract-based wallet, including a
multi-signature wallet, is not supported as a refund destination, and the Portal
states the same rule in the refund drawer.
The Portal applies the same constraints: in the refund drawer the chain is a
read-only label for the original payment chain, noted as “Refund must use the
same chain as the original payment,” the address field is validated against that
chain’s format as you type, and the detail page then shows the address used. No
Portal view surfaces on-chain detail — no transaction hash, confirmation count or
network fee.
Can I issue a partial refund on a stablecoin order?
No. The published payment method catalogue listsUSDC and
USDT as full refund only, and the refund-shape check enforces it: a refund
for less than the full amount is refused, and so is a second refund after a full
one. Confirm the shape that applies to your own agreement on the Refundable
column of Service → Payin, or refundAllowed on your configuration response
— the four shapes and their codes are explained in
Reading Your Payment Method Configuration.
So plan a stablecoin refund as one all-or-nothing action per order. If your
business needs partial value returned, that is a commercial arrangement outside
the refund API, not a partial refund.