X402 E2E Verification and Troubleshooting
X402 involves HTTP, SDK, signatures, Facilitator, and on-chain transactions. When troubleshooting signature or settlement issues, it is recommended to verify layer by layer in the order of "public entry -> 402 response -> SDK payment handler -> on-chain settlement". This tutorial explains the inspection methods for each layer and lists common errors.
¶ Check Public Entry
Discovery document:
curl https://x402.acedata.cloud/.well-known/x402
If version and resources are returned, it indicates the platform discovery document is normal. x402.acedata.cloud is the standard entry for X402 API and discovery; the same path on platform.acedata.cloud is retained only as a compatibility entry.
Facilitator supported capabilities:
curl https://facilitator.acedata.cloud/supported
If kinds is returned, it indicates the Facilitator entry is normal.
¶ Check 402 accepts
Send an unauthenticated request that will not incur charges:
curl -sS -X POST https://x402.acedata.cloud/openai/chat/completions \
-H 'Content-Type: application/json' \
-d '{
"model": "gpt-4o-mini",
"messages": [{"role": "user", "content": "hi"}],
"max_tokens": 1
}'
Check whether the returned accepts contains the network you want to use. network is a CAIP-2 identifier:
eip155:8453+exact(Base)eip155:8453+upto(Base, post-metering)eip155:1187947933+exact(SKALE)solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp+exact(Solana)
If the target network is missing, it means the API or current environment is not configured with the corresponding X402 payment method.
¶ Run X402Client Advanced Verification Tool
The X402Client repository provides advanced verification tools that can be used to confirm 402 response selection, signature generation, paid retry, and on-chain settlement. They require a funded wallet, RPC, private key, and development dependencies. For normal business integration, it is recommended to use the TypeScript or Python SDK first; only run these tools when you need to locate signature or on-chain settlement issues.
Repository address: https://github.com/AceDataCloud/X402Client
git clone https://github.com/AceDataCloud/X402Client.git
cd X402Client/typescript
npm install
npm install --no-save ethers @solana/spl-token bs58 tsx
Base:
export X402B_BASE_PAYER_PRIVATE_KEY=0x...
TEST_API_PATH='/openai/chat/completions' \
TEST_BODY='{"model":"gpt-4o-mini","messages":[{"role":"user","content":"hi"}],"max_tokens":10}' \
npx tsx scripts/test-real-e2e.ts
SKALE:
export SKALE_BASE_PRIVATE_KEY=0x...
TEST_API_PATH='/openai/chat/completions' \
TEST_BODY='{"model":"gpt-4o-mini","messages":[{"role":"user","content":"hi"}],"max_tokens":10}' \
npx tsx scripts/test-skale-e2e.ts
Solana:
export X402B_SOLANA_PAYER_PRIVATE_KEY=...
npx tsx scripts/test-solana-e2e.ts
The verification tool usually prints:
- The first request's 402 response.
- The selected payment requirement.
- The signed
PAYMENT-SIGNATUREdigest. - The HTTP status and response body after retry.
- The on-chain settlement transaction, or Facilitator error reason if failed.
Do not send private keys or full PAYMENT-SIGNATURE to log systems or tickets.
Example of public API verification results:
SKALE exact
HTTP 402 -> HTTP 200
content ADC_SKALE_E2E_OK
tx 0x9fd09901e74c763325fe118b2bc64765c3fca785b86b24a78b97964384db084f
block 1969317
explorer https://skale-base-explorer.skalenodes.com/tx/0x9fd09901e74c763325fe118b2bc64765c3fca785b86b24a78b97964384db084f
paid 0.095215 USDC
Base exact
HTTP 402 -> HTTP 200
content ADC_BASE_E2E_OK
tx 0x408430ab3451bc22a51e510cdb4b063d6b9686724fea7a31fc109af20f5cd2f3
block 46726299
explorer https://basescan.org/tx/0x408430ab3451bc22a51e510cdb4b063d6b9686724fea7a31fc109af20f5cd2f3
transfer value 95215 atomic USDC
Solana exact
HTTP 402 -> HTTP 200
content ADC_SOLANA_E2E_OK
chain signature not confirmed in this run because public RPC lookup hit 429
Base upto
HTTP 402 -> HTTP 200
content ADC_BASE_UPTO_OK
tx 0x4b0b836ce1cd1171cdbc37df1637150b024214ec28e7f6f2d09122f15cbfc036
block 46726437
explorer https://basescan.org/tx/0x4b0b836ce1cd1171cdbc37df1637150b024214ec28e7f6f2d09122f15cbfc036
signed ceiling 95215 atomic USDC
transfer value 3 atomic USDC
Explanation:
- SKALE
exact, Baseexact, Solanaexact, and Baseuptoall completed paid retry from HTTP 402 to HTTP 200. - SKALE
exacton-chain transaction can be found on SKALE explorer, settlement amount is0.095215USDC. - Base
exacton-chain transaction can be found on BaseScan, settlement amount is95215atomic USDC. - Base
uptosignature ceiling is95215atomic USDC, but actual on-chain settlement is3atomic USDC, indicating post-metering charges based on actual usage. - Solana path confirmed paid retry and model output. Public RPC may be rate-limited; for strict on-chain reconciliation, please use your own Solana RPC or platform-side settlement records to confirm transaction signatures.
¶ SDK smoke test
Advanced verification tools are used to check signatures and on-chain settlement. The business side should also perform SDK smoke tests to confirm that application code can automatically handle 402 via the payment handler. Below only shows core snippets; complete code requires wallet, provider, and import setup.
TypeScript:
const client = new AceDataCloud({
paymentHandler: createX402PaymentHandler({
network: 'skale',
evmProvider,
evmAddress: wallet.address
})
});
const res = await client.openai.chat.completions.create({
model: 'gpt-4o-mini',
messages: [{ role: 'user', content: 'Reply with exactly ADC_SDK_X402_OK' }],
max_tokens: 8
});
Python:
client = AceDataCloud(
payment_handler=create_x402_payment_handler(
network="skale",
evm_signer=signer,
)
)
res = client.openai.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Reply with exactly ADC_PY_X402_OK"}],
max_tokens=8,
)
If the model returns the fixed string as required, it indicates the SDK, payment handler, Gateway, Facilitator, and upstream API are connected.
The above two segments of the smoke test are using SKALE exact. SKALE currently only provides exact, settling at a fixed amount based on the 402 quote, which will not decrease with the actual token usage. Chat completion belongs to a scenario measured by tokens, and it is recommended to switch to Base and pass preferScheme: 'upto' for settlement based on actual usage when formally integrated.
The results of the SDK smoke test are:
TypeScript SDK
payer 0xd0479FA9FD8C678303d477433d24C15e3723CC1C
elapsed_ms 6782
content ADC_TS_SDK_X402_OK
id chatcmpl-DlcVLO4PQWvmjPDQpy9yQw2QdLGAT
Python SDK
payer 0xd0479FA9FD8C678303d477433d24C15e3723CC1C
elapsed_ms 4786
content ADC_PY_SDK_X402_OK
id chatcmpl-DlcWajqAHOop3iebmO19XRfT5bTPz
Result explanation:
- The TypeScript SDK automatically handles 402, signing, and retries through
createX402PaymentHandler, ultimately obtainingADC_TS_SDK_X402_OK. - The Python SDK completes the same flow through
create_x402_payment_handler, ultimately obtainingADC_PY_SDK_X402_OK. - Both smoke tests use SKALE payer
0xd0479FA9FD8C678303d477433d24C15e3723CC1C. - The returned object from the Python SDK is a
dict, and the content can be read usingres["choices"][0]["message"]["content"]in the example.
¶ Order Payment E2E
Order payment uses the platform API of platform.acedata.cloud, requiring a platform account token. The complete flow is: create a Pending order, POST /api/v1/orders/{order_id}/pay/ triggers 402, and then retry with PAYMENT-SIGNATURE.
Example of small order payment verification results:
created order 78481793-304e-47f7-bc0c-8231aec9cc1e
created state Pending
created price 1.26
http_status=402
x402Version 2
accepts [('eip155:8453', 'exact', '1200000'), ('solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp', 'exact', '1200000')]
status 200
order state Finished
pay_way X402
pay_id 0xfec08cc00a159ea1ec692b32faa9bf3d17595a986301169e689d94f58bc44151
settle_header {'success': True, 'network': 'base', 'transaction': '0xfec08cc00a159ea1ec692b32faa9bf3d17595a986301169e689d94f58bc44151'}
Base tx status 1
block 46726704
explorer https://basescan.org/tx/0xfec08cc00a159ea1ec692b32faa9bf3d17595a986301169e689d94f58bc44151
transfer value 1200000 atomic USDC
Result explanation:
- After creating the order, the order status is
Pending, and the price is1.26. - The first
pay/request returns HTTP 402, withacceptscontaining Baseexactand Solanaexact, both for the amount of1200000atomic USDC. - After retrying with Base
PAYMENT-SIGNATURE, it returns HTTP 200, and the order status changes toFinished, withpay_waybeingX402. - The
PAYMENT-RESPONSEdecoded showssuccess=True,network=base, and provides the same transaction hash. - The transaction status on BaseScan is
1, and the transfer amount is1200000atomic USDC, which is1.2USDC. - The creation price of
1.26enters the X402 payment process, applying the X402 payment discount, resulting in a final signed and settled amount of1.2USDC.
If the order payment does not have Authorization: Bearer {platform_token}, or the order does not belong to the current account, it will fail at the platform permission layer; this is different from directly calling the account-less X402 API of x402.acedata.cloud.
¶ Common Errors
| Phenomenon | Troubleshooting Direction |
|---|---|
| The first request is not 402 | Check if Authorization was mistakenly included, or if this API does not yet have X402 pricing. |
No payment requirement for network |
The target network is not in accepts, switch networks or check Gateway configuration. |
invalid_402 |
The 402 response is not valid JSON, check proxy, gateway, or error page. |
Authorization nonce already processed |
The same PAYMENT-SIGNATURE was reused, re-sign. |
invalid_upto_evm_payload_invalid_signature |
Check if the chainId, Permit2 domain, facilitator address, and signing account of upto are consistent. |
PERMIT2_ALLOWANCE_REQUIRED |
Execute approve-permit2 for USDC on the target chain. |
Payer has insufficient USDC balance |
The payment wallet has insufficient USDC. |
| HTTP 200 but no tx hash | The actual amount for upto may be 0, or the settlement record is still being written asynchronously. |
Solana Missing transaction payload |
The PAYMENT-SIGNATURE envelope does not contain serialized transaction or signature, check wallet adapter. |
¶ Base upto Check List
upto is currently only available on Base (eip155:8453). SKALE only provides exact. Since the upto signature binds more EVM typed data parameters, it is particularly important to confirm that the real-time fields in the 402 response are completely consistent with the client signature during integration.
SKALE exact
HTTP 402 -> HTTP 200
content ADC_SKALE_E2E_OK
tx 0x9fd09901e74c763325fe118b2bc64765c3fca785b86b24a78b97964384db084f
Base upto
HTTP 402 -> HTTP 200
content ADC_BASE_UPTO_OK
tx 0x4b0b836ce1cd1171cdbc37df1637150b024214ec28e7f6f2d09122f15cbfc036
explorer https://basescan.org/tx/0x4b0b836ce1cd1171cdbc37df1637150b024214ec28e7f6f2d09122f15cbfc036
signed ceiling 95215 atomic USDC
transfer value 3 atomic USDC
If Base upto returns invalid_upto_evm_payload_invalid_signature, prioritize checking:
- The
eip155:8453+uptoentry'sextra.chainIdreturned by the API (should be8453). - The
extra.facilitatorAddressreturned by the API. - The Base
uptofacilitator address returned byhttps://facilitator.acedata.cloud/supported. - Permit2 domain, spender, USDC contract, and signing account.
- Whether the wallet has already approved Permit2 for Base USDC.
The signature digest of upto binds the Permit2 domain, chain ID, spender, recipient address, facilitator address, and validAfter. If any of these items are inconsistent, the Facilitator will recover the erroneous signer, thus returning an invalid signature. If all these are consistent but it still returns 402, the next step is to check the Permit2 allowance; if unauthorized, it will return PERMIT2_ALLOWANCE_REQUIRED.
¶ Save Verification Information
At least save the following for a complete verification:
- API path and request body summary;
- Selected network and scheme;
maxAmountRequired;- Payer wallet address;
- Final HTTP status;
- Model output or task ID in the response;
- Settlement transaction link;
- Gateway trace ID or platform usage record ID.
Do not save private keys, complete PAYMENT-SIGNATURE, complete EIP-712 signature, or mnemonic phrases.