Four checks, in order, all of them fail-closed. The code below is the shipped source, with its longer comments and the unreachable-RPC branch trimmed.
// pay/backend/src/x402.ts
const verification = await verifyPayment(tx, chain, env)
if (!verification.ok) {
return c.json({ error: 'Payment not verified', chain }, 402)
}
const rates = await getCryptoPrices(env)
const valueUsd = valueUsdOf(verification.amount, verification.currency, chain, rates)
if (valueUsd === null) {
return c.json({ error: 'Payment currency cannot be valued', chain }, 402)
}
// Require at least 99% of target USD to account for price drift.
if (valueUsd < usdTarget * PAYMENT_TOLERANCE) {
return c.json({ error: 'Payment amount too low', requiredUsd: usdTarget,
receivedUsd: valueUsd }, 402)
}
const replayKey = `x402:${new URL(c.req.url).pathname}:${chain}:${tx}`
if (await env.CUSTOMERS.get(replayKey)) {
return c.json({ error: 'Payment already used', chain, tx }, 402)
}
await env.CUSTOMERS.put(replayKey,
JSON.stringify({ at: Date.now(), sender: verification.sender }))
Note what is absent: no callback to a payment processor, no webhook to wait for, no pending state. The chain is the source of truth and it is read directly.