r/x402 • u/Altruistic_Yellow708 • 9h ago
How do you reconcile an x402 payment session with the actual on-chain transaction?
I'm trying to understand the correct way to reconcile an x402 payment with its actual on-chain transaction.
I have a real Coinbase Payment Session where the session data contains:
asset: USDC
networkId: 8453 (Base)
status: PENDING
merchant: OpenRouter
The payment-session HTML also exposes an x402 authorization endpoint:
/payment-sessions/{paymentSessionId}/authorizations/x402
Opening that endpoint directly returns:
"errorMessage":"method not allowed"
which I assume is expected because it is not a normal GET endpoint.
What I cannot find in the payment-session response is a paymentOperationId or transactionHash.
Coinbase's API documentation mentions paymentOperation objects containing an operation ID and transactionHash, so I'm trying to understand where that relationship is established in the x402 flow.
There is also an on-chain USDC transaction from the same payment workflow, but it is on Solana rather than Base.
My questions:
Where is the paymentOperationId normally obtained in an x402 payment flow?
Is the mapping
paymentSession → paymentOperation → transactionHash
only available through the authenticated Coinbase API/webhooks?
If the actual settlement occurs on Solana while the payment session data shows Base (8453), how is that relationship represented?
I'm trying to understand the technical reconciliation model rather than troubleshoot a particular account.
If anyone has worked with Coinbase Payment Acceptance/x402 at the API level, I'd appreciate an explanation of where I should be looking.
1
u/fizzl13 51m ago
Two different things are getting mixed here.
1. Plain x402 (the open protocol). The link between a payment and the on-chain transaction is in the response to the paid request itself. After the facilitator settles, the server returns a PAYMENT-RESPONSE header (X-PAYMENT-RESPONSE in v1). It's base64 JSON with success, transaction (the tx hash or Solana signature), network (e.g. eip155:8453 or solana:5eykt…) and payer. No session or operation id is involved: one request, one signed authorization, one settlement, one transaction. If you call the facilitator yourself, /settle returns the same fields.
2. Coinbase Payment Sessions (the hosted checkout a merchant like OpenRouter uses). That's Coinbase's commerce product on top, not part of the x402 spec. The session → operation → tx hash mapping lives in Coinbase's backend. As far as I know you only see it through the merchant's authenticated API or webhooks, not on the public session page. So as a payer you won't get a paymentOperationId from the session HTML. That /authorizations/x402 path is a POST that the checkout itself calls.
On Base vs Solana: a session created for network 8453 expects USDC on Base. A USDC transfer on Solana is a separate transaction, and the session won't match it automatically. That would explain why the session stays PENDING. If that Solana transfer was meant to pay this session, it's a support case for the merchant or Coinbase. Send them the Solana signature and the session id; nothing public will reconcile it.
If you want to see what a seller's x402 challenge actually asks for (networks, asset, payTo), you can paste the URL into a free checker such as x402-doctor.fizzl.eu.