x402 Protocol Troubleshooting Guide
Issue: Payment Successful but Claimable Balance is 0
Symptoms
- •User pays successfully (Transaction confirmed on-chain).
- •Tokens are deducted from Payer.
- •Tokens are held by Escrow contract.
- •
GET /api/revenue/walletreturnsclaimableBalance: 0.
Root Cause Analysis
The x402 Protocol uses a PaymentProcessor to atomically handle payments and update the Escrow ledger.
If the Relayer fails to use the PaymentProcessor, it falls back to a Direct Token Transfer (Legacy Mode).
- •Direct Transfer: Moves tokens to Escrow but does NOT call
Escrow.receivePayment. Result: Funds trapped, Ledger not updated. - •PaymentProcessor: Calls
receiveWithAuthorizationANDEscrow.receivePayment. Result: Funds secured, Ledger updated.
Diagnosis Steps
- •Check Market Logs:
- •Look for
[Relayer] Settling directly on token...(BAD). - •Look for
[Relayer] Settling via PaymentProcessor...(GOOD).
- •Look for
- •Check
serviceId:- •If
serviceIdis missing/undefined inrelayer.settle(), it forces fallback.
- •If
- •Check Service Registration:
- •The
PaymentProcessorreverts if the service is not registered inServiceRegistry. - •Verification: Call
ServiceRegistry.getService(serviceIdHash).
- •The
Solution
- •Register Service On-Chain:
- •Ensure every service in DB has a corresponding on-chain registration.
- •ID Format:
keccak256(utf8(serviceUUID)).
- •Update API Logic:
- •Ensure
api/agent/executecomputes the hash and passes it torelayer.settle(sig, serviceIdHash).
- •Ensure
- •Check Environment:
- •Ensure
PAYMENT_PROCESSOR_ADDRESSis set in.env.
- •Ensure
- •Rebuild Application:
- •If running in production (
next start), YOU MUST RUNnpm run buildafter code changes.
- •If running in production (
Issue: Signature Verification Failed
Symptoms
- •
interact-demo.jsfails with "Signature verification failed".
Solution
- •Domain Separator:
- •Ensure
name,version,chainId,verifyingContractmatch the on-chain Token exactly. - •Example:
Mock USD CoinvsMockUSDC.
- •Ensure
- •Spender/To Field:
- •For
PaymentProcessor, thetofield in the signature must match the address expected byreceiveWithAuthorization. - •In
X402PaymentProcessor, it callsreceiveWithAuthorization(..., to=Escrow). Thus, signature must beto: EscrowAddress.
- •For
Issue: "402 Payment Required" from Provider
Symptoms
- •Gateway says payment successful, but Provider rejects request.
Solution
- •HTTP Method: Ensure Provider accepts
POST(Gateway proxies via POST). - •Header Verification:
- •Gateway sends
X-402-TxHash. - •Provider must explicitly trust this header if verifying via Gateway.
- •Gateway sends