Integrate x402 with PolyPay
Create protected resource rules in the dashboard, then use the PolyPay SDK in server-side routes. The SDK handles the 402 challenge, payment verification, and settlement calls.
AI Agent Payments requires an active subscription and is also available on Pay-as-you-go. When the subscription expires or becomes inactive, resource configurations are not deleted, but dashboard management and verify/settle runtime access are frozen; restoring an active subscription brings them back without recreating resources.
The PolyPay SDK uses x402 v2 by default: PAYMENT-REQUIRED advertises the challenge, the agent submits authorization through PAYMENT-SIGNATURE, and PAYMENT-RESPONSE returns the settlement receipt. Set protocolVersion: 1 only during a controlled legacy migration.
The configured resource and method remain the canonical public request identity behind reverse proxies. V2 accepts only PAYMENT-SIGNATURE; legacy X-PAYMENT is enabled only with protocolVersion: 1.
Integration flow
- Create a Resource configuration on the AI Agent Payments page in the dashboard.
- Set the public resource URL, HTTP method, price, network, USDC contract, and settlement wallet.
- Install and initialize the PolyPay SDK in a server-side route. Keep the API Key only in server environment variables.
- Wrap the protected route with the SDK. Unpaid requests return 402; paid requests continue to the business response.
- Review Payment records in the dashboard to track verification, settlement, and on-chain transaction status.
Server-side SDK examples
x402 must run server-side with API Key mode. Never expose API Keys or settlement logic in browser bundles.
import { polypayX402 } from '@polypay/sdk/x402';
const x402 = polypayX402({
apiKey: process.env.POLYPAY_API_KEY!,
resource: {
resource: 'https://merchant.example.com/api/premium-data',
method: 'GET',
price: '$0.01',
amount: '10000',
network: 'eip155:8453',
asset: 'USDC',
payTo: '0xYourMerchantSettlementWallet',
description: 'Premium market data'
}
});
export async function GET(request: Request) {
const result = await x402.verifyAndSettle(request);
if (!result.paid) {
return result.required();
}
return Response.json(
{ data: 'premium payload' },
{ headers: result.responseHeaders }
);
}Supported networks
Current support is limited to the standard EVM exact flow using Circle USDC transferWithAuthorization.
The SDK validates the scheme, network, matching Circle USDC contract, and EIP-3009 metadata during initialization. Unsupported overrides fail before a payment challenge is generated.
| Network | CAIP-2 | USDC Contract |
|---|---|---|
| Base | eip155:8453 | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 |
| Ethereum | eip155:1 | 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 |
| Polygon | eip155:137 | 0x3c499c542cef5e3811e1192ce70d8cc03d5c3359 |
| Arbitrum | eip155:42161 | 0xaf88d065e77c8C2239327C5EDb3A432268e5831 |
| Optimism | eip155:10 | 0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85 |
Platform validation rules
- The scheme must be exact.
- network, asset, assetContract, payTo, and amount must match the resource requirement.
- resource URL and HTTP method are bound to the current request and must match.
- The matching Resource must remain enabled; missing, disabled, or ambiguous resource bindings are rejected.
- validAfter / validBefore must be within the allowed window, and each nonce can settle only once.
- The EIP-712 signature must recover authorization.from.
The raw facilitator settle response returns paymentId/replayed, while the SDK maps them to stable fulfillmentKey/shouldFulfill fields on the verifyAndSettle() result. Only the request that wins the first confirmed state transition receives shouldFulfill=true; concurrent and later replays receive false. This flag does not replace business idempotency: routes that write data or trigger external actions must still atomically persist the result under the unique fulfillmentKey and return it on retries instead of executing again merely because paid=true. Read-only routes may continue returning the same content when paid=true.
Standard facilitator endpoint
When an official or third-party x402 server SDK calls PolyPay directly, configure its facilitator base URL as https://api.polypay.ai/api/v2/x402. This endpoint returns raw standard supported, verify, and settle JSON; existing PolyPay SDKs continue to use the compatible /api/v1/pay/x402 endpoint.
A settle timeout is an indeterminate result. Retry the exact same payment proof; PolyPay rebroadcasts the same persisted signed transaction or reconciles the existing settlement without creating a second charge. Do not generate a replacement authorization solely because of a timeout. Standard requests without method/resource context must also resolve to one unique enabled Resource.
Unsupported chains
BSC, Tron, Solana, TON, and BTC are not part of the current standard EVM exact flow. Supporting them later requires a separate x402 scheme or PolyPay extension.
Rate limits and safe retries
When a request exceeds its current policy, PolyPay returns a real HTTP 429. Application responses use error code 40001; a CDN or WAF may instead return HTML or plain text, so clients must check HTTP status before parsing by Content-Type.
HTTP/1.1 429 Too Many Requests
Retry-After: 10
RateLimit-Limit: 60
RateLimit-Remaining: 0
RateLimit-Reset: 10
{"code":40001,"message":"RateLimitExceeded","data":{"retry_after":10}}Honor Retry-After first; it may be seconds or an HTTP-date. If absent, use jittered exponential backoff. Automatically retry only replay-safe or idempotency-protected requests, with a bounded retry count.
verify and settle have separate limits, and settle also has a per-merchant concurrency guard. HTTP 429 is temporary throttling, not an invalid payment or failed settlement. Reuse the same payment proof and preserve business idempotency when retrying.