x402 v2 Payments 2026: Implementation and Settlement Checks =========================================================== This hands-on Node.js tutorial adds micropayments to an API with x402 v2. Select payment terms, request new signatures, and verify settlement on Base Sepolia, then check retries and requirements for switching to mainnet. - Prepare a receiving address and a test payment wallet, and install the official x402 SDK. - Connect payment middleware for Base Sepolia and check the 402 response to requests without payment. - On the client, select and sign only payment terms that match the allowed chain, token, amount, and recipient. - Use the transaction hash in the settlement response to look up USDC Transfer events. - Test blocking on failure and recovery from duplicate requests, then review the mainnet settings. x402 payments are implemented by including payment requirements in an API's 402 response. Prepare Node.js and a test wallet. First, verify v2 signatures and settlement on Base Sepolia. Configure paid responses to be delivered only after settlement succeeds. Amounts and chain information are based on the official x402, Base, and Circle documentation linked as sources. Setup and installation Prepare a development environment where you can modify the API, along with test wallets. The examples use Node.js 22 and x402 SDK 2.28.0. The installation structure follows the official seller guide. Prepare an EVM wallet address to receive payments. Prepare a separate test wallet for making payments. Obtain Base Sepolia test USDC for the payment wallet. Create the practice project with the commands below. Save the TypeScript files that follow in the same folder. mkdir x402-demo cd x402-demo npm init -y npm pkg set type=module npm install --save-exact express@5.3.0 viem@2.57.12 @x402/core@2.28.0 @x402/express@2.28.0 @x402/evm@2.28.0 @x402/fetch@2.28.0 npm install --save-dev --save-exact typescript tsx @types/node @types/express The receiving server does not need the receiving wallet's private key. Configure the payment private key to be read only by the client process. The wallet signing method follows the official buyer guide. This example has been checked through type checking and a simulated payment flow. It has not been tested through a completed transfer on the actual testnet. Check the on-chain results yourself using the execution steps below. Comparing x402 v1 and v2 When implementing v2, align both the headers and the body fields. Changing only the header names will leave the data structures incompatible. The following table is based on the official migration guide. Category v1 v2 Protocol version x402Version: 1 x402Version: 2 Initial payment requirements JSON body of the 402 response PAYMENT-REQUIRED response header Signed payment data X-PAYMENT request header PAYMENT-SIGNATURE request header Settlement result X-PAYMENT-RESPONSE response header PAYMENT-RESPONSE response header Base mainnet identifier base eip155:8453 Base Sepolia identifier base-sepolia eip155:84532 Amount field in payment requirements maxAmountRequired amount Resource description resource and other fields within payment requirements Top-level resource object Requirements in the payment payload Top-level scheme, network, and other fields accepted object containing the selected requirements Example TypeScript package x402-express @x402/express The location for delivering v1 payment requirements is specified in the HTTP v1 specification. The standard location in v2 is the PAYMENT-REQUIRED header. An implementation may also return a body, but process the requirements using the header. The HTTP v2 specification describes the status code as follows. The server indicates payment is required using the HTTP 402 "Payment Required" status code. Source: x402 HTTP v2 specification v2 payment headers contain Base64-encoded JSON. Base64 is not encryption. Use HTTPS for externally accessible services. HTTP 402 requests and the payment sequence This exercise uses the default authorization flow for the EVM exact scheme. exact is a scheme for paying a specified amount. The sequence follows the x402 v2 core specification. The client requests a paid API without payment information. The server returns HTTP 402 and PAYMENT-REQUIRED. The client selects an allowed set of requirements from accepts. The SDK signs a payment authorization matching the selected requirements. The client retries the request with PAYMENT-SIGNATURE. The server validates the authorization through the facilitator's /verify. If verification passes, the server processes the resource. The server requests settlement through /settle. After settlement succeeds, it delivers the paid body and PAYMENT-RESPONSE. This is not a fixed sequence shared by all payment schemes. v2 also defines flows with different settlement timing. The code below allows only the default authorization flow. Roles of the Resource server and facilitator The Resource server determines prices and conditions for accessing content. The Facilitator handles payment verification and settlement. This division of roles follows the official facilitator documentation. Component Responsibility State that must not be treated as success Client Selects requirements and signs payment authorizations Only the signature has been generated Resource server Declares prices and controls paid responses The client claims success Facilitator /verify Checks the validity of signatures and payment requirements Only isValid: true has been received Facilitator /settle Executes the on-chain payment and returns the result in this exercise Submitted, but the result has not been confirmed /verify is a check that does not change on-chain state. Successful verification therefore does not mean funds have been received. The balance or authorization state may change even after verification. Block the paid body if verification or settlement fails. Blocking access when success cannot be confirmed is called fail-closed behavior. This behavior can also be seen in the official Express implementation. Comparing Base mainnet and testnet Use only Base Sepolia for the first run. Circle states that testnet USDC has no monetary value. The addresses are based on Circle's list of USDC contracts. Item Base mainnet Base Sepolia testnet Purpose Payments with real assets Testing implementation and failure handling Chain ID 8453 84532 x402 v2 network eip155:8453 eip155:84532 USDC contract 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 0x036CbD53842c5426634e7929541eC2318f3dCF7e Public RPC https://mainnet.base.org https://sepolia.base.org Token's monetary value Asset with real monetary value No monetary value Check the Chain ID and RPC in the Base network documentation. Even for the same wallet address, balances are separate on different chains. Do not record testnet success as actual revenue. You can request test USDC from the Circle Testnet Faucet. Select Base Sepolia as the network. Enter the test payment wallet's address as the receiving address. Implementing a paid API in Node.js Attach paymentMiddleware before the paid route. The example below requires 0.001 USDC per call. The amount uses the example price from the official seller guide. (Verified value: 0.001 USDC per call · Source: docs.x402.org · Checked on 2026-10-28) Server file Save the following code as server.ts. The server accepts requests only on the local interface. It reads the receiving address from the PAY_TO environment variable. import express from "express"; import { getAddress, zeroAddress } from "viem"; import { paymentMiddleware } from "@x402/express"; import { HTTPFacilitatorClient, x402ResourceServer } from "@x402/core/server"; import { ExactEvmScheme } from "@x402/evm/exact/server"; const payTo = getAddress(process.env.PAY_TO ?? ""); if (payTo === zeroAddress) throw new Error("Invalid payTo"); const network = "eip155:84532"; const resourceServer = new x402ResourceServer( new HTTPFacilitatorClient({ url: "https://x402.org/facilitator" }), ).register(network, new ExactEvmScheme()); const app = express(); app.use((_req, res, next) => { res.setHeader("Cache-Control", "private, no-store"); next(); }); app.use(paymentMiddleware({ "GET /paid-data": { accepts: [{ scheme: "exact", price: "$0.001", network, payTo }], description: "Sample paid JSON", mimeType: "application/json", }, }, resourceServer)); app.get("/paid-data", (_req, res) => { res.json({ content: "Paid sample content" }); }); app.listen(4021, "127.0.0.1"); https://x402.org/facilitator is the testing address in the official guide. This example uses it for Base Sepolia settlement. For choosing a production facilitator, see the mainnet steps in the seller guide. Price calculation example The example price is 1000 in USDC's smallest units. USDC has 6 decimal places. The SDK's price conversion is based on the EVM server implementation. 0.001 USDC × 10^6 = 1000 smallest units Value to check Expected value in this example price in the server configuration "$0.001" amount in the 402 payment requirements "1000" asset in the payment requirements Base Sepolia USDC contract payTo in the payment requirements Configured receiving address network in the payment requirements eip155:84532 price is an SDK configuration value. The actual v2 payment requirements carry amount. Compare integer amounts as strings or bigint. Running the server and checking the 402 response Run the server in the first Bash terminal. Enter a public receiving address, not a private key. Keep this terminal open while the server is running. read -r -p '수취 지갑 주소: ' PAY_TO export PAY_TO npx tsx server.ts Send a request without payment from a second terminal. The command below does not sign a payment. It prints the HTTP status and decoded payment requirements. node --input-type=module <<'JS' const response = await fetch("http://127.0.0.1:4021/paid-data"); const header = response.headers.get("PAYMENT-REQUIRED"); console.log(response.status); console.log(header && JSON.parse( Buffer.from(header, "base64").toString("utf8") )); JS The expected response without payment is HTTP 402. Compare the printed requirements with the table above. If paid content is returned immediately, fix the route protection configuration first. Selecting payment requirements and implementing the client Restrict the client to signing only approved requirements. This example allows only a fixed price in Base Sepolia USDC. The payment option filter uses registerPolicy from the official x402Client implementation. Save the code below as client.ts. Also save check-transfer.ts from the next section. Once both files are ready, proceed with the execution steps. import { writeFile } from "node:fs/promises"; import { getAddress, zeroAddress, type Hex, type Hash } from "viem"; import { privateKeyToAccount } from "viem/accounts"; import { x402Client, wrapFetchWithPayment } from "@x402/fetch"; import { decodePaymentResponseHeader } from "@x402/core/http"; import { ExactEvmScheme } from "@x402/evm/exact/client"; import { checkTransfer } from "./check-transfer.js"; const key = process.env.EVM_PRIVATE_KEY ?? ""; if (!/^0x[0-9a-fA-F]{64}$/.test(key)) throw new Error("Invalid test key"); const signer = privateKeyToAccount(key as Hex); const payTo = getAddress(process.env.PAY_TO ?? ""); if (payTo === zeroAddress) throw new Error("Invalid payTo"); const network = "eip155:84532"; const token = "0x036CbD53842c5426634e7929541eC2318f3dCF7e"; const client = new x402Client().register(network, new ExactEvmScheme(signer)); client.registerPolicy((version, options) => version === 2 ? options.filter(r => r.scheme === "exact" && r.network === network && r.asset.toLowerCase() === token.toLowerCase() && r.payTo.toLowerCase() === payTo.toLowerCase() && r.amount === "1000" && (!r.extra?.assetTransferMethod || r.extra.assetTransferMethod === "eip3009") && (!r.extra?.paymentFlow || r.extra.paymentFlow === "authorization")) : []); const paidFetch = wrapFetchWithPayment(fetch, client); const response = await paidFetch("http://127.0.0.1:4021/paid-data", { redirect: "error", }); const raw = response.headers.get("PAYMENT-RESPONSE"); if (!raw) throw new Error(`No settlement receipt: HTTP ${response.status}`); const settlement = decodePaymentResponseHeader(raw); await writeFile("settlement.json", JSON.stringify(settlement, null, 2)); if (!response.ok || !settlement.success || settlement.network !== network) { throw new Error("Payment unresolved; inspect settlement.json before retrying"); } const evidence = await checkTransfer( network, settlement.transaction as Hash, signer.address, payTo, 1000n, ); await writeFile("transfer.json", JSON.stringify(evidence, null, 2)); console.log(await response.text()); wrapFetchWithPayment handles the 402 response and retries the request with a signature. Its usage follows the official fetch example. If no payment requirements are allowed, payment creation stops. AI agents can also use this client. However, a per-call price limit is not a cumulative spending limit. Manage the budget for an agent's repeated calls separately. Verifying USDC Transfer events Check the USDC transfer logs using the transaction hash from the settlement result. A successful transaction status alone does not confirm the recipient. The Transfer fields follow the ERC-20 standard. Verification requires the following items. Verification item Compare against RPC's Chain ID Chain allowed by the server Transaction receipt's status Success status Address that emitted the event Official USDC contract on that chain Transfer.from Verified payer Transfer.to Receiving address set by the server Transfer.value Amount required by the server in the smallest units Save the code below as check-transfer.ts. The lookup uses viem's getTransactionReceipt. Event parsing is based on parseEventLogs. import { createPublicClient, http, getAddress, parseEventLogs, erc20Abi, type Address, type Hash, } from "viem"; import { base, baseSepolia } from "viem/chains"; const configs = { "eip155:84532": { chain: baseSepolia, rpc: "https://sepolia.base.org", token: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", }, "eip155:8453": { chain: base, rpc: "https://mainnet.base.org", token: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", }, } as const; export async function checkTransfer( network: keyof typeof configs, hash: Hash, payer: Address, payTo: Address, amount: bigint, ) { const cfg = configs[network]; const rpc = createPublicClient({ chain: cfg.chain, transport: http(cfg.rpc) }); if (await rpc.getChainId() !== cfg.chain.id) throw new Error("Wrong chain"); const receipt = await rpc.getTransactionReceipt({ hash }); if (receipt.status !== "success") throw new Error("Transaction failed"); const logs = parseEventLogs({ abi: erc20Abi, eventName: "Transfer", logs: receipt.logs.filter( log => getAddress(log.address) === getAddress(cfg.token), ), strict: true, }); const transfer = logs.find(log => getAddress(log.args.from) === getAddress(payer) && getAddress(log.args.to) === getAddress(payTo) && log.args.value === amount, ); if (!transfer) throw new Error("Matching USDC Transfer not found"); return { network, transaction: hash, logIndex: transfer.logIndex, blockHash: receipt.blockHash, blockNumber: receipt.blockNumber.toString(), }; } This function confirms that a USDC transfer occurred in the transaction. Whether it belongs to a specific API order must be checked separately. On a production server, use the stored order requirements as the comparison values. Do not trust a client-uploaded transfer.json as proof for granting access. This example's server uses the facilitator's verification and settlement results. If an independent lookup is a condition for granting access, it must run on the server. A failed receipt lookup does not necessarily mean the payment failed. If an RPC error occurs, look up the stored transaction hash again. Set the number of additional confirmations and the response to chain reorganizations through your production policy. Running a test payment and checking the results After saving all the files, run the example with a test wallet. Type checking does not sign anything or transfer funds. The commands below use the TypeScript tools installed earlier. Check the types with the following command. Enter the same receiving address as the server in the second terminal. Enter the test payment wallet's private key with input hidden. Run the client once. Check the saved settlement result and transfer log. npx tsc --noEmit --strict --skipLibCheck --target ES2022 --module NodeNext --moduleResolution NodeNext server.ts client.ts check-transfer.ts read -r -p '같은 수취 지갑 주소: ' PAY_TO read -r -s -p '테스트 결제 지갑 개인키: ' EVM_PRIVATE_KEY export PAY_TO EVM_PRIVATE_KEY npx tsx client.ts unset EVM_PRIVATE_KEY Output Meaning What to check settlement.json Settlement result returned by the server success, network, transaction transfer.json Transfer record found through the RPC lookup Chain, transaction hash, log position, block information Paid body in the console Data printed after this client's verification Confirm that it is the requested content Running the client again may create a new payment. This minimal example has no per-order duplicate prevention store. Add retries only after meeting the requirements in the next section. Handling verification failure conditions In failure tests, check that the paid body is not exposed. Checking only the HTTP status may miss cases where content is not blocked. Refer to the official Express middleware for the baseline behavior. Test condition Expected handling Additional check No payment header Return 402 and payment requirements No paid body Different token or recipient offered Reject through the client policy No signature generated Invalid signature Block due to verification failure Paid handler does not run Insufficient balance Block due to verification or settlement failure Not recorded as successful settlement Failed settlement result Block the paid response Do not send even a prepared body Delayed facilitator response Keep pending because success is unconfirmed Do not automatically generate a new authorization RPC receipt lookup error Keep the transaction hash and query again Do not conclude that payment failed In the default authorization flow, the handler runs before settlement. A settlement failure does not roll back external operations. Start with queries that have no side effects, as in this example. Sending emails or creating external orders requires a separate design. Record payment and task states together. Define which operations should run again after a failure to reduce duplicate work. Lost responses after settlement and recovery through redelivery Store payment completion and content delivery completion as separate states. Payment may finish while the response connection is lost. Handling this situation is covered in the Payment-Identifier extension documentation. The property of not processing the same operation twice when it is requested again is called idempotency. payment-identifier provides a payment identifier for this purpose. Adding the identifier alone does not automatically complete the feature. Comparing duplicate payments and redelivery Preventing reuse of the same signature and preventing duplicate orders must be treated separately. EIP-3009 prevents reuse of an authorization nonce that has already been used. This behavior is defined in the ERC-3009 specification. Situation On-chain authorization perspective API operations perspective Settling the same authorization again Subject to the check for an already-used nonce Existing result must be retrieved Creating a new authorization for the same order May be treated as a separate authorization Duplicate payment prevention is needed Response lost after successful settlement Asset transfer may already be complete Content must be delivered again Timeout after a settlement request Result is still unclear Pending state and settlement confirmation are needed The following procedure is a design proposal for connecting the official extension to a production data store. It is not included in the minimal code above. Add persistent storage and concurrent request controls before using it in production. Declare support for the payment-identifier extension on the server. Keep the identifier for the logical request on the client. Associate the identifier with the payer and request contents on the server. Record the processing state atomically to prevent concurrent execution. Save the transaction evidence and response result when settlement succeeds. Return the stored result if the repeated request has the same authorization and contents. If the settlement result is unclear, check the existing authorization first. A payment identifier is not a password or access token. Do not return cached paid content to a request that merely knows the identifier. Also check whether it is being reused by another user or with a different request body. Keep the chain, transaction hash, and log position together in production records. Link this record to the order to prevent reuse for other orders. A matching Transfer alone does not prove which order it belongs to. Common payment implementation mistakes Confusing version fields and success signals leads to incorrect payment decisions. Use the table below during deployment review. Version differences are based on the x402 migration guide. Common mistake Correct approach Interpreting extra.version: "2" as the x402 version Check the protocol version through x402Version Using maxAmountRequired in v2 Use amount for the amount in payment requirements Creating an X-PAYMENT-REQUIRED header arbitrarily Use the body in v1 and PAYMENT-REQUIRED in v2 Treating isValid: true as completed receipt of funds Check the /settle result separately Treating the transaction's top-level to as the USDC recipient Check USDC Transfer.to Assuming the signer is the transaction sender Compare the authorizing payer with Transfer.from Adding testnet receipts to revenue Keep mainnet and testnet ledgers separate Creating a new payment on every timeout Recover the existing order and authorization state first Treating the SDK package version as the protocol version Manage the package version and x402Version separately USDC signature domain information also contains a version string. That value serves a different purpose from the x402 protocol version. See the ERC-3009 specification for the signing domain structure. Security checks and trust boundaries for external services Control payment success decisions on the server. Responses from an external facilitator are also an explicit trust dependency. The architecture, which also allows self-hosting, is explained in the facilitator documentation. Do not release content based on a client's success message. Compare the chain, token, amount, and recipient declared by the server. Do not log private keys or seed phrases. Exclude full authorization signatures from ordinary access logs as well. Limit payment header size and request processing time. Check that paid responses do not remain in shared caches. Store test keys and production keys in separate locations. Do not create an unpaid bypass when the facilitator fails. Actually test authorization expiration and duplicate requests. The pinned dependencies in this exercise still have security warnings. npm audit reported a zod-related advisory. See the GitHub security advisory for details. npm audit Before deploying to production, check SDK compatibility with the patched version. Forcing a major version replacement may change behavior. Do not use this exercise as a deployment configuration that has passed security review. Comparing a self-hosted server and Cloudflare Gateway Using Cloudflare Gateway changes how the origin server verifies payments. The documentation dated September 30, 2026 specifies the use of x402 v2. The following comparison is based on the Cloudflare x402 documentation. Category Express approach in this article Cloudflare Monetization Gateway Client payment processing Express middleware Gateway Origin server verification point Integration with the selected facilitator PAYMENT-CONTEXT JWT verification Settlement result delivery Middleware's PAYMENT-RESPONSE Gateway generates a settlement receipt Additional checks Facilitator's supported chains and authentication JWT signature verification and origin access protection PAYMENT-CONTEXT is a header between the Gateway and the origin server. It is not a signature header for a regular x402 client. Follow the Cloudflare Payment validation documentation for origin verification. Even when using the Gateway, simply decoding the JWT is not enough. Verify the signature using the keys specified in the documentation. Block paid content if the header is missing or verification fails. Distinguishing actual usage from settlement records The number of on-chain transfers alone cannot prove content consumption. Compile production metrics by linking settlement with response delivery. This is a design recommendation based on the payment flow and redelivery behavior. Record Question it can answer Additional record needed 402 response How often payment requirements were requested Whether payment actually occurred Successful verification Whether the authorization was valid Settlement result USDC transfer Whether assets moved Order association Settlement completed per order Whether a paid request was paid for Response delivery status Redelivery record Whether an already-paid request was recovered Identifier distinguishing it from a new payment Separate test requests from actual usage metrics. Mark retries for the same order separately as well. Do not describe transaction volume itself as API demand or a guarantee of revenue. Steps for switching to Base mainnet Review mainnet use after checking both successful and failed testnet paths. Changing the network string alone does not complete the switch. The baseline procedure follows the official seller guide. Confirm that the selected facilitator supports Base mainnet. Check /supported for v2, exact, and eip155:8453 support. Configure the authentication and terms of use required by the provider. Change the network on both the server and client. Change the client's allowed USDC address to the mainnet address. Recheck the amount in the 402 response against the actual receiving address. Connect the duplicate request store and failure recovery procedures. Complete security checks on production dependencies. Verify the actual transfer and content delivery using the small amount you configured. Multichain support does not mean every combination is supported. Check the support offered by both the SDK and the facilitator. Use the network and token support documentation as the reference. FAQ Q. How does x402 differ from a regular USDC deposit confirmation? A. It sends payment requirements during the HTTP request process and retries the request with a signed payment authorization. Unlike reconciling deposit records later, it links the payment process to requests for paid resources. Q. What are the payment headers in x402 v2? A. Payment requirements are sent via PAYMENT-REQUIRED, and the payment payload via PAYMENT-SIGNATURE. The settlement result is sent via PAYMENT-RESPONSE. Q. Does v1 have an X-PAYMENT-REQUIRED header? A. The official HTTP v1 specification puts the initial payment requirements in the JSON response body. It uses X-PAYMENT for the payment payload and X-PAYMENT-RESPONSE for the settlement result. Q. Is payment complete if /verify succeeds? A. A successful /verify means the payment authorization is valid. In this exercise, you must separately confirm that /settle succeeded. Q. Can Base Sepolia test USDC be considered actual revenue? A. Circle states that testnet USDC has no financial value. Record testnet settlements separately from actual sales. Q. Do I need to put a private key on the receiving server? A. Only a public receiving address is configured on the receiving server in this example. The private key used for payment authorization is read by the payment client. Q. What is the amount value for 0.001 USDC? A. With USDC's 6 decimal places, this is 1000 in the smallest unit. Use the string "1000" in the v2 payment requirements. Q. If the transaction receipt shows success, does that also confirm receipt of USDC? A. A successful transaction status alone is not enough. Check the payer, recipient, and amount against the Transfer event from the official USDC contract. Q. Is it safe to resend the same payment request? A. Preventing reuse of the same authorization nonce and preventing duplicate orders are separate concerns. Check the existing payment status before retrying, and implement idempotency for each order. Q. If PAYMENT-RESPONSE is missing, should I pay again? A. If the response was lost or the request timed out, the settlement result may be unclear. Do not start by creating a new authorization; check the settlement status of the existing request. Q. Does x402 require you to use only a specific company's facilitator? A. The official architecture allows both using an external facilitator and running your own. Check whether your chosen implementation supports the required protocol version, payment method, and chain. Q. Is an AI agent's spending also limited automatically? A. This example only limits payment requirements per request. Manage cumulative spending from repeated calls with a separate budget policy. Q. Is Cloudflare PAYMENT-CONTEXT a standard payment signature header? A. PAYMENT-CONTEXT is a JWT that Gateway passes to the origin server. It serves a different purpose from the client's PAYMENT-SIGNATURE. Q. Can I deploy the example directly to mainnet? A. This code is a minimal setup for testing. Before deploying to production, check dependency security warnings, duplicate request handling, facilitator authentication, and actual settlement. Sources - x402 Protocol Specification v2: https://github.com/x402-foundation/x402/blob/main/specs/x402-specification-v2.md - x402 HTTP Transport v1: https://github.com/x402-foundation/x402/blob/main/specs/transports-v1/http.md - x402 HTTP Transport v2: https://github.com/x402-foundation/x402/blob/main/specs/transports-v2/http.md - x402 Migration Guide: V1 to V2: https://docs.x402.org/guides/migration-v1-to-v2 - x402 Facilitator Roles and Responsibilities: https://github.com/x402-foundation/x402/blob/main/docs/core-concepts/facilitator.md - x402 Quickstart for Sellers: https://docs.x402.org/getting-started/quickstart-for-sellers - x402 Quickstart for Buyers: https://docs.x402.org/getting-started/quickstart-for-buyers - x402 Official TypeScript fetch Client Example: https://github.com/x402-foundation/x402/tree/main/examples/typescript/clients/fetch - x402 Express Middleware Implementation: https://github.com/x402-foundation/x402/blob/main/typescript/packages/http/express/src/index.ts - x402Client Payment Requirements Selection and Policy Implementation: https://github.com/x402-foundation/x402/blob/main/typescript/packages/core/src/client/x402Client.ts - x402 ExactEvmScheme Server Price Conversion Implementation: https://github.com/x402-foundation/x402/blob/main/typescript/packages/mechanisms/evm/src/exact/server/scheme.ts - Circle USDC Contract Addresses: https://developers.circle.com/stablecoins/usdc-contract-addresses - Base Mainnet and Base Sepolia Network Information: https://docs.base.org/get-started/connect-to-base - Circle Testnet Faucet: https://faucet.circle.com/ - viem getTransactionReceipt: https://viem.sh/docs/actions/public/getTransactionReceipt - viem parseEventLogs: https://viem.sh/docs/contract/parseEventLogs - ERC-20 Token Standard: https://eips.ethereum.org/EIPS/eip-20 - ERC-3009 Transfer With Authorization: https://eips.ethereum.org/EIPS/eip-3009 - x402 Payment-Identifier Idempotency Extension: https://docs.x402.org/extensions/payment-identifier - Cloudflare Monetization Gateway x402 protocol: https://developers.cloudflare.com/monetization-gateway/x402/ - Cloudflare Monetization Gateway Payment validation: https://developers.cloudflare.com/monetization-gateway/configuration/payment-validation/ - x402 Networks & Token Support: https://docs.x402.org/core-concepts/network-and-token-support - GitHub Security Advisory: Memory Exhaustion from Zod Validation of Large Collections: https://github.com/advisories/GHSA-mrhx-c7xc-m3w5 Images - A man in a dark gray sweater examines a tablet resting on a server rack shelf.: https://injoys.com/rails/active_storage/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzM4MDcsInB1ciI6ImJsb2JfaWQifX0=--49c502fd8da16158a617c3586dfa81ced4bc95df/ai-f0ae2b5c.webp - A woman types on a laptop opened flat, with a list and two paths converging on one endpoint on its screen.: https://injoys.com/rails/active_storage/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzM4MTMsInB1ciI6ImJsb2JfaWQifX0=--4e70727f132519277c68d1c6279d95585a936549/ai-3dbd1c62.webp --- Category: Tutorial Source: https://injoys.com/en/articles/x402-payments-2026-v2-base-usdc-settlement-guide License: cc_by Translation-Status: reviewed