Docs detail
Payment Methods
Card vs crypto payment branches, wallet readiness checks, and payment failure handling.
Owner: genesis-payments
Pizza x402 supports two payment branches at confirm time:
- Card payments (
EUR, Stripe-backed) - Crypto payments (
USDCon Base via x402)
Canonical references:
Payment branch behavior
Card branch
- Create a quote with
POST /v1/orders/quote. - Confirm with
POST /v1/orders/confirmandpaymentMethod: "card". - Confirm response is
200withpaymentIntentIdandclientSecret. - Complete payment on frontend using Stripe Elements/Checkout.
- Order is created by webhook after successful payment.
Crypto branch
- Create a quote with
POST /v1/orders/quote. - First
POST /v1/orders/confirmwithpaymentMethod: "crypto"returns402 PAYMENT_REQUIRED. - Execute x402 payment (dev mock:
PAYMENT-SIGNATURE = paymentRequestId). - Retry
POST /v1/orders/confirmwithPAYMENT-SIGNATURE. - Response
200returnsorderIdand paid status.
Wallet readiness checklist
Before choosing crypto payment, confirm all of the following:
- Customer has a wallet that supports Base.
- Wallet holds enough
USDCon Base (not Ethereum mainnet). - Customer can sign/submit the payment proof before quote expiry.
- Network is
eip155:8453and asset is Base USDC.
If readiness is missing, use wallet setup guidance before retrying payment.
Wallet setup guidance
Use the canonical API endpoint:
curl -sS http://localhost:3000/v1/wallet-setup
The response includes:
- Step-by-step setup instructions.
- Recommended wallet options (Coinbase Wallet for beginners).
- Base network details (
chainId, USDC asset address, explorer, RPC). - Canonical resources (
base docs, wallet download, bridge links).
For docs consistency, prefer the endpoint response over ad-hoc setup text:
GET /v1/wallet-setup(runtime contract)AGENTS.md#get_wallet_setup(agent guidance)
Common payment failures and operator actions
| Error code | When it appears | Action |
|---|---|---|
PAYMENT_REQUIRED | Crypto first confirm call or payment not yet seen | Complete payment then retry confirm with PAYMENT-SIGNATURE |
PAYMENT_INVALID | Signature/proof invalid or expired | Re-run payment step or regenerate quote if expired |
QUOTE_NOT_FOUND | Quote expired or unknown | Recreate quote and restart confirm flow |
ASSERTION_FAILED_METHOD | Confirm method differs from expected | Reconfirm method with user and retry |
ASSERTION_FAILED_CURRENCY | Currency expectation mismatch | Validate card (EUR) vs crypto (USDC) path |
ASSERTION_FAILED_EXPIRY | Expected expiry differs or quote stale | Refresh quote and retry with updated assertions |
Minimal confirm-time safety pattern
Use assertions on confirm calls to lock expected quote state:
expectedQuoteHashexpectedTotalCents/maxTotalCentsexpectedCurrencyexpectedPaymentMethodexpectedExpiresAtexpectedMerchantId/expectedMerchantAddress
This reduces silent divergence in agentic and scripted flows.