Did my x402 payment settle on Base?
Look up the transaction hash from the seller's PAYMENT-RESPONSE header on Base and confirm three things: the transaction succeeded, it moved real Base USDC (contract 0x8335…2913), and the money went to the address and amount you expected. Kertivo Check does all three in one call ($0.01 in USDC on Base), and you can try it free on a real transaction at POST https://kertivo.com/demo.
Who this is for
- Agents and bots that pay x402 endpoints and need to know whether the money actually moved before they retry, pay again, or report a problem.
- Builders debugging a "paid but got nothing back" case.
- Sellers who want to confirm a buyer's payment landed at their
payToaddress.
Why "it returned 200" is not the same as "it settled"
An x402 call has two separate outcomes: the payment (on-chain) and the delivery (the seller's HTTP response). They can disagree. A payment can settle while the seller returns an error, and a client can think it paid when the authorization was never used. On Base you can check the payment side yourself, because USDC transfers are public.
What you can check on-chain:
- Did the transaction succeed? A reverted transaction moved nothing.
- Did it move real USDC? Native Base USDC is
0x833589fcd6edb6e08f4c7c32d4f71b54bda02913. Tokens named like USDC at other addresses, and bridged USDbC (0xd9aa…b6ca), are not what x402 sellers on Base expect. - Did it go to the right address, for the right amount? Compare the transfer's recipient and amount with the
payToandamountfrom the seller's 402 challenge. - Was it a zero-value transfer? A "0 USDC transfer" moves no money. It is the usual address-poisoning pattern, not a payment.
What you cannot check on-chain: whether the seller delivered. If it settled and you got no useful response, keep the transaction hash as proof of payment.
How Kertivo Check answers it (evidence)
Send POST https://kertivo.com/check with a txHash (aliases tx_hash, hash), plus optional expectedPayTo and expectedAmount (or minAmount as a floor). Amounts are decimal USDC ("1" for one dollar), not the 402's atomic integer ("1000000"). If you only have an EIP-3009 authorization, send {from, nonce, validBefore} instead.
The settlement.verdict is settled, not_settled, or (for a spent authorization whose use can't be confirmed) unconfirmed, with a reason:
| Reason | What it means |
|---|---|
confirmed_onchain | Settled and confirmed on Base. |
pending_confirmation | Included but not yet confirmed. |
tx_not_found | No such transaction on Base mainnet. |
tx_reverted | Reverted; no USDC moved. |
no_usdc_transfer | Confirmed, but moved no real Base USDC. |
zero_value_transfer | Only moved 0 USDC; no money changed hands. |
authorization_used | The nonce is spent and its AuthorizationUsed event was found, so the transfer executed (the answer names the tx that used it). |
authorization_canceled | The payer canceled the authorization on-chain (AuthorizationCanceled); no USDC moved and it can never be used. |
authorization_spent_unconfirmed | Verdict unconfirmed: the nonce is spent, but USDC uses one flag for used and canceled and no event was found in the searched window. Send validBefore or the payment tx hash; sellers should not deliver on this alone. |
authorization_unused | Never used; send validBefore too to learn whether it can still settle. |
authorization_unused_pending | Unused, still valid; it could still be settled. |
authorization_unused_or_expired | Never used and past validBefore; it can no longer settle. |
The answer also includes match (recipient and amount checks), warnings (fake_token, bridged_usdbc, no_usdc_transfer, zero_value_transfer, lookalike_address, tx_reverted, and amount_looks_atomic when your amount looks like an atomic integer), and funding (where the payer got the USDC: external, self_funded, or unknown). Every 200 response carries a signed attestation you can verify at /.well-known/attestation.
Real example, from the free demo on 2026-10-15: transaction 0xc37cbdfa…43c1 moved 1 USDC to 0x509e…9ede at block 52409752. Verdict settled, reason confirmed_onchain, payToMatch: true, amountMatch: true, no warnings, payer funding external.
Try it
- Free, no wallet:
curl -s -X POST https://kertivo.com/demoreturns the full answer for a fixed real transaction. Send your real/checkbody to/demoand it reads it the same way (aliases,match, warnings, 400s) against that fixed transaction, so you can test your mapping for free. - Paid, any transaction: call
POST /checkwithout payment to get the 402 with exact requirements, then retry with the payment header (any x402 client does this). - After paying another seller: decode its
PAYMENT-RESPONSEheader (decodePaymentResponseHeaderin@x402/fetch) and pass.transactionastxHash. Copy-paste code is at /examples.
You are only charged when Check answers with HTTP 200. A wrong chain or a token other than USDC returns a 400 (unsupported_chain or unsupported_token) on the paid retry, and a 400 never settles, so it costs nothing.
FAQ
Where do I find the transaction hash?
In the seller's PAYMENT-RESPONSE (or X-PAYMENT-RESPONSE) header. Decoded, it has success, transaction, network, and payer.
The seller returned an error. Was I charged?
Maybe. Check the hash. If the verdict is settled, money moved even though delivery failed. You can file a free, public claim with POST https://kertivo.com/claim and browse existing ones at Kertivo Claims.
I never got a transaction hash, only a signed authorization. Did money move?
Send {from, nonce, validBefore}. USDC tracks whether that nonce was spent, and Check looks for the AuthorizationUsed or AuthorizationCanceled event in the window before validBefore, so the answer is authorization_used, authorization_canceled, authorization_unused_pending, or authorization_unused_or_expired (or authorization_spent_unconfirmed if the nonce is spent but neither event turns up, for example when validBefore is missing).
Is a "settled" verdict proof that the seller is honest?
No. It proves the USDC moved to that address. It says nothing about the quality of what the seller sent back.
Does Kertivo check other chains or tokens?
Not today. Check covers native USDC on Base mainnet only.
Limits
- Base mainnet and native USDC only.
- On-chain data cannot show whether the seller delivered.
- The payer funding scan on regular Check reads a recent block window, so
funding.verdictcan beunknown. Deep scan (/check/deep, $0.05, needs atxHash) reads the payer's funding history from an index instead (latest 500 transfers before the payment plus up to five more pages), andcoverage.historyCompletesays whether that was all of it. - Kertivo holds no funds and does not arbitrate disputes. It reports evidence.
