Skip to main content

Prerequisites

You have attempted a payment via Using the CLI or Build with the SDK.

Quick diagnosis

NO_SETTLER_FOR_CORRIDOR

No settlement provider currently covers the source and destination pair you asked for, so the payment was never offered to anyone.
Retrying the same pair will not help. That is what NOT_RETRYABLE_FIX_REQUEST means: the request has to change, not be repeated. Either pick a different corridor, or check the pair against Supported networks in case an asset ID is pointing at a chain you did not intend. This describes right now. Providers connect and disconnect, so a pair with no provider today may have one later. It is not a statement that the corridor will never be supported. Told apart from NO_QUOTES_RECEIVED by whether anyone was asked. Here nobody was: no provider serves the route. There, providers were offered the payment and none quoted in time, which a retry can fix.

NO_QUOTES_RECEIVED

Submit succeeded — your integration worked — but no settler quoted during the quote window.
Atum-side logs and support tickets call the same condition QUOTE_DEADLINE_EXPIRED. That is the internal name for it, and it never appears in a response. A retry needs a fresh request_id. The code carries retry_classification: RETRY_WITH_NEW_IDENTIFIER, so the original identifier is spent. Reusing it resolves onto the same failed payment instead of starting a new one. The API message sounds like missing liquidity, but settlers may ignore payments they cannot route. A common cause is a wrong destination asset ID — for example, an address from the wrong testnet pasted into the wrong chain field. Check your asset IDs first. Copy verbatim from Supported assets, not from old examples or another chain. Read why nobody quoted. GET /v1/payments/{payment_id}/status carries a decline_summary, counting the settlement providers that declined and the reason each gave. Each entry links to Decline reasons, which says what would have to change for that provider to quote. An empty summary means nobody declined, so the providers never answered at all rather than turning the payment down. A missing one means the breakdown could not be read. In either case, if asset IDs match the catalog, Atum ops can check settler logs for your payment_id (look for unknown destination asset). This is not a spending approval or signing misconfiguration. Wrong asset IDs are a token catalog issue — the gateway accepts the submit, but settlement providers skip it.

Stuck in processing

Poll every 2–5 seconds:
Optional timeline for debugging:
Allow 30–90 seconds on testnet before escalating. Do not resubmit the same payment with a new request_id unless you intend a new payment.

Settlement slower than the confirmation window

Cross-chain settlement can take longer than the gateway’s ~30s synchronous window. When it does, the acceptance side reports the payment as still settling — that is pending, not a confirmed failure. Both x402 and MPP collect the outcome the same way: the payer re-attempts the same purchase until settlement reaches a terminal state. The gateway resolves onto the original payment, so the re-attempt cannot charge twice. What to do:
  1. Treat it as pending, not failed. Re-attempt the same purchase — fresh 402, re-signed credential, same purchase identifier (x402: your paymentIdentifier; MPP: the same /paid/<purchase id> route, whose challenge carries that intentId). The SDK derives the same request_id from it either way.
  2. Do not open a second payment with a new identifier while the first is still settling.
  3. On terminal failure, that identifier is spent — start a new purchase identifier for the same goods.
  4. For out-of-band reconciliation, poll /status (and /timeline) with your payment_id — that’s the authoritative record, and it attributes the settlement transaction to your payment. Use the returned tx hashes to corroborate on-chain if you want.
  5. Some testnet corridors — notably those bridging to slower chains like Tempo — routinely exceed the ~30s synchronous window. Re-attempt the same purchase until it reaches a terminal outcome.

Payment authorization and balance errors

Settlement fails if:
  • Payment authorization was never set for the source USDC/token
  • Depositor has insufficient source token balance
  • Depositor has insufficient network processing fees on the source rail
Fix:
  1. Approve USDC spend on the source rail
  2. Confirm balances on that chain in your wallet explorer
  3. Resubmit with a new request_id if the previous payment failed
For token approval details, see Permit2 and approvals.

Wrong asset ID or chain

The gateway validates that source and destination rails are chains it serves (the ones /v1/defaults lists). It does not validate that a corridor has settlement coverage.
  • Copy asset IDs from Supported networks
  • Match your sandbox profile exactly if you have one

Wrong token variant

Similarly named tokens are not interchangeable. “USDC” on one chain, a bridged “USDC.e,” and a chain-specific tokenized currency like Tempo’s pathUSD are different contracts with different addresses — and often that’s the difference between a payment that settles and one that silently doesn’t. Common mistakes:
  • Using native USDC where the corridor expects a bridged variant (USDC.e), or vice versa.
  • Assuming a chain has native USDC when it doesn’t — Tempo, for example, carries a bridged USDC.e but no native USDC, and pathUSD is its canonical 6-decimal tokenized currency.
  • Copying a token address from the wrong chain (the same symbol, different network).
Fix:
  1. Identify the exact asset for your corridor by chain and contract address — not by symbol alone. Copy from Supported assets, keyed by network.
  2. Confirm you’re watching that same contract in your wallet/explorer on the destination chain — a balance that “didn’t change” is often the right funds landing on a token you weren’t looking at.
  3. If your integration hardcodes addresses, prefer resolving them from the gateway (the examples read corridor addresses from /v1/defaults) so they can’t drift.

Recipient received nothing

If a payment reports success but the receiving wallet shows no change:
  1. Confirm DEST_ADDRESS (or your destination address) is exactly the address you’re checking, on the destination chain.
  2. Confirm you’re watching the correct destination token — see Wrong token variant.
  3. Confirm via the gateway first: poll /status and /timeline by payment_id to get the settlement transaction hash, then verify that hash on the destination-chain explorer. A fresh retry with a new request_id is a second payment — retry only with the same request_id.

Gateway unreachable

A 200 means the gateway is reachable and serving chains. A 404 or 503 means the gateway answered but couldn’t serve defaults — that’s a gateway-side problem, not yours, so retry and contact Atum support rather than changing your code. Only a connection error or a timeout points at network/VPN.

Still stuck?

Ask in the Atum Discord — support is community-based, not on-demand. Include:
  • payment_id
  • request_id (if set)
  • Output of /status and /timeline
  • Source and destination CAIP-19 strings
  • Whether you are on public testnet, sandbox, or production

Next steps