Home/Blockchain & Web3/okx-agent-payments-protocol
O

okx-agent-payments-protocol

by @okxv
4.5(120)

This skill acts as a unified payment dispatcher, capable of handling various payment protocols including x402 (exact/aggr_deferred), MPP (charge/session), and a2a-pay (a2a_charge). It automatically routes to the matching payment scheme by detecting HTTP response headers or payment IDs, returning ready-to-use authorization headers or transaction hashes and statuses. This skill significantly simplifies the complexity of agent payments, offering developers a convenient and efficient payment integration solution that ensures seamless operations across different payment scenarios.

paymentprotocolweb3agentx402GitHub
Installation
npx skills add https://github.com/okx/onchainos-skills --skill okx-agent-payments-protocol
compare_arrows

Before / After Comparison

1 组
Before

Without a unified dispatcher, developers need to manually understand and integrate multiple complex payment protocols like x402, MPP, and a2a-pay. This involves reading extensive documentation, writing different logic to handle HTTP 402 responses, parsing WWW-Authenticate headers, and managing payment ID flows, which is time-consuming and error-prone.

After

By using the **OKX Agent Payments Protocol** skill, developers can handle all major payment protocols through a single, unified interface. The skill automatically detects the protocol type and dispatches to the correct process, significantly reducing integration effort and potential errors, and accelerating the launch of payment functionalities.

SKILL.md

OKX Agent Payments Protocol (Dispatcher)

Unified entry point for three payment paths, distinguished by HTTP signature: accepts-based 402 (challenge in body for v1 or PAYMENT-REQUIRED header for v2), WWW-Authenticate: Payment 402 (channel-capable, with intent="charge" or "session"), and a2a-pay (paymentId-based agent-to-agent links, no 402 required). This file owns the shared steps — protocol detection, payload decode, user confirmation gate, wallet status check — then dispatches into the right scheme/intent reference.

User-facing terminology — IMPORTANT

Rule 1 — Always call it "OKX Agent Payments Protocol", and always render it bolded. Use the exact English term OKX Agent Payments Protocol in user-visible messages regardless of the user's language, and always wrap it in markdown bold (**OKX Agent Payments Protocol**) so the user sees it emphasized. Keep it as a fixed English noun phrase even inside otherwise-Chinese sentences. Reserve protocol literals and internal identifiers for CLI invocations, HTTP headers, JSON payloads, and code — never speak them to the user.

Rule 2 — Do not narrate internal protocol detection. The dispatch logic (which header was detected, which reference is being loaded, which scheme/intent was selected, TEE vs local-key path) is internal — keep it internal. The user only needs to see: (a) what is being paid, (b) what they need to confirm, (c) the result.

Rule 3 — Externally-defined protocol literals stay byte-for-byte exact. The JSON field x402Version, the HTTP headers X-PAYMENT / PAYMENT-SIGNATURE / PAYMENT-REQUIRED / WWW-Authenticate: Payment, and the reference URL https://x402.org MUST appear verbatim wherever the protocol/server requires them — these are externally defined and changing them breaks interop. CLI subcommand names (onchainos payment pay / pay-local / charge / session ... / a2a-pay ...) are this CLI's own surface and may evolve; refer to them by their current name in CLI invocations and code, but never speak them to the user (Rule 2).

Example

(中) 准备通过 **OKX Agent Payments Protocol** 完成本次支付,下面是扣款明细,请确认…… (EN) Preparing a payment via the **OKX Agent Payments Protocol**. Here are the charge details — please confirm before I proceed…

Progress narration counts as user-visible — Rules 1-3 still apply.

Long-running flows (decode → confirm → wallet check → sign → header assembly → replay) tempt status updates. Every "正在…" / "I'm now…" line is user-facing. Step labels in this SKILL.md (Step A3-Accepts, Step A3-WWW-Authenticate) and reference files (exact / aggr_deferred schemes, charge / session intents) are internal — do NOT echo them in narration.

❌ Don't say✅ Say
"正在处理 accepts-based 流程" / "Processing the accepts-based path""正在通过 OKX Agent Payments Protocol 处理本次支付" / "Processing the payment via the OKX Agent Payments Protocol"
"CLI 自动选择 exact 方案" / "CLI selected the exact scheme" / "走 aggr_deferred 路径""签名完成" / "Signing done"
"组装 PAYMENT-SIGNATURE / X-PAYMENT 头" / "Assembling the PAYMENT-SIGNATURE header""正在重放请求" / "Replaying the request"
"检测到 WWW-Authenticate: Payment / PAYMENT-REQUIRED 协议" / "Detected the channel-based protocol"(silent — go straight to the confirmation prompt)
"加载 references/exact.md" / "Loading the exact playbook"(silent — internal routing)
"进入 session 模式 / charge 模式" / "Entering session intent""支付通道已开" / "Channel opened" — describe the user-visible effect, not the internal mode
"TEE 路径 / 本地 key 路径" / "Using TEE signing path"(silent — signing path is internal)

Read ../okx-agentic-wallet/_shared/preflight.md before any onchainos command. EVM only — CAIP-2 eip155:<chainId> (run onchainos wallet chains for the list).

Reference map

Triggered byLoad
402 with PAYMENT-REQUIRED header (v2) or x402Version body field (v1), CLI returns no sessionCertreferences/exact.md
402 with PAYMENT-REQUIRED header (v2) or x402Version body field (v1), CLI returns sessionCertreferences/aggr_deferred.md
402 with WWW-Authenticate: Payment, intent="charge"references/charge.md
402 with WWW-Authenticate: Payment, intent="session" (also: any mid-session op on a channel_id)references/session.md
User mentions a paymentId / a2a_... link / "create payment link"references/a2a_charge.md

Skill Routing

IntentUse skill
Token prices / charts / wallet PnL / tracker activitiesokx-dex-market
Token search / metadata / holders / cluster analysisokx-dex-token
Smart money / whale / KOL signalsokx-dex-signal
Meme / pump.fun token scanningokx-dex-trenches
Token swaps / trades / buy / sellokx-dex-swap
Authenticated wallet (balance / send / tx history)okx-agentic-wallet
Public address holdingsokx-wallet-portfolio
Tx broadcasting (feePayer=false hash mode)okx-onchain-gateway
Security scanning (token / DApp / tx / signature)okx-security

Channel mid-session ops (close / topup / settle / voucher / refund mentioned with an active channel_id, regardless of fresh 402) → stay here, jump straight into references/session.md at the matching phase. Do NOT search for a separate close-channel / topup-channel / settle-channel tool — they're all onchainos payment session ... subcommands.


Path A: HTTP 402

Step A1: Send the original request

Make the HTTP request the user asked for. If status is not 402, return the body directly — no payment, no wallet check, no other tool calls.

Step A2: Detect the protocol

Priority 1: response.headers['WWW-Authenticate']
  starts with "Payment "        → continue at Step A3-WWW-Authenticate
Priority 2: response.headers['PAYMENT-REQUIRED']
  base64-encoded JSON           → continue at Step A3-Accepts (v2)
Priority 3: response body JSON has "x402Version"
                                → continue at Step A3-Accepts (v1)
Otherwise                       → not a supported payment protocol, stop

Both WWW-Authenticate: Payment and PAYMENT-REQUIRED/x402Version indicators present — STOP and ask the user:

The server offers two payment options via the OKX Agent Payments Protocol:

  1. One-shot purchase, or streaming session (multi-request) (recommended)
  2. One-shot purchase

Which would you like to use?

Internal mapping: option 1 → WWW-Authenticate: Payment path, option 2 → PAYMENT-REQUIRED/x402Version path.

Step A3-Accepts: Decode

v2 — payload is in the PAYMENT-REQUIRED response header (base64-encoded JSON):

headerValue = response.headers['PAYMENT-REQUIRED']
decoded     = JSON.parse(atob(headerValue))

v1 — payload is in the response body (direct JSON, not base64):

decoded = JSON.parse(response.body)

Extract:

accepts = decoded.accepts          // pass full array to the CLI later
option  = decoded.accepts[0]       // for display only

Save decoded for header assembly later — you will need decoded.x402Version and decoded.resource (v2).

Step A3-WWW-Authenticate: Decode

Parse the WWW-Authenticate header:

Payment id="...", realm="...", method="evm", intent="...", request="<base64url>", expires="..."

base64url-decode request to get the JSON body. Save:

intent              charge | session
amount              base units string (e.g. "1000000")
currency            ERC-20 contract address
recipient           merchant payee address
methodDetails:
  chainId           EVM chain ID (e.g. 196 for X Layer)
  escrowContract    REQUIRED for session, ABSENT for charge
  feePayer          true (transaction mode) | false (hash mode)
  splits            optional, charge only, max 10 entries
  minVoucherDelta   optional, session only
  channelId         optional, session topUp/voucher only — pre-existing channel
suggestedDeposit    optional, session only — suggested initial deposit
unitType            optional — "request" | "second" | "byte" etc.

Method check — only method="evm" is supported here. If method is "tempo", "svm", "stripe", etc. → stop and tell the user this dispatcher cannot handle it.

Challenge expiry — if expires=... (ISO-8601) is in the past, the challenge is dead: re-send the original request to get a fresh 402 before signing. Stale challenges fail with 30001 incorrect params.

Convert amount from base units to human-readable using the token's decimals (typically 6 for USDC/USD₮, 18 for native).

Step A4: Display payment details and STOP

⚠️ MANDATORY: Display details and STOP to wait for explicit user confirmation. Do NOT call onchainos wallet status or any other tool until the user confirms.

For accepts-based 402 (PAYMENT-REQUIRED header v2 / x402Version body v1):

This resource requires payment via the OKX Agent Payments Protocol:

  • Network: <chain name> (<option.network>)
  • Token: <token symbol> (<option.asset>)
  • Amount: <human-readable amount> (from option.amount for v2, or option.maxAmountRequired for v1; convert from minimal units using token decimals)
  • Pay to: <option.payTo>

Proceed with payment? (yes / no)

For WWW-Authenticate: Payment 402:

This resource requires payment via the OKX Agent Payments Protocol:

  • Payment type: <one-shot purchase (charge) | streaming session (multi-request)>
  • Network: <chain name> (eip155:<chainId>)
  • Token: <symbol> (<currency address>)
  • Amount per request: <human-readable> (atomic: <amount>)
  • Pay to: <recipient>
  • Who pays gas: <server (transaction mode) | you broadcast it yourself (hash mode)>
  • Split recipients (one-shot only, if present): <N other parties also receive a share>
  • Suggested prepaid balance (session only, if present): <human-readable>

Proceed with payment? (yes / no)

  • User confirms → Step A5.
  • User declines → stop. No payment, no wallet check.

Step A5: Check wallet status (only after the user explicitly confirms)

onchainos wallet status
  • Logged in → Step A6.
  • Not logged in (accepts-based path) → ask the user to choose between (1) wallet login (TEE signing) or (2) local private key (onchainos payment pay-local, exact scheme only). Don't read files or check env vars until the user picks.
  • Not logged in (WWW-Authenticate: Payment path) → ask the user to log in via email OTP or AK. TEE-only — no local-key fallback for this path (only the accepts-based path has one).

Step A6: Hand off to the scheme/intent reference

PathAction
accepts-based (PAYMENT-REQUIRED header v2 / x402Version body v1)Run onchainos payment pay --accepts '<JSON.stringify(decoded.accepts)>'. When the response comes back, look at whether sessionCert is present:• sessionCert present → load references/aggr_deferred.md for header assembly + replay• sessionCert absent → load references/exact.md for header assembly + replayIf the user picked the local-key fallback, run onchainos payment pay-local instead and load references/exact.md (only scheme this fallback supports).
WWW-Authenticate: Payment, intent="charge"Load references/charge.md at "Decide mode".
WWW-Authenticate: Payment, intent="session"Load references/session.md at "Phase S1: Open Channel" (or jump to S2 / S2b / S3 if the user is mid-session with an active channel_id).

After the reference returns the assembled X-PAYMENT / PAYMENT-SIGNATURE header or authorization_header, replay the original request and surface the response to the user. Suggest follow-ups conversationally — never expose internal field names or skill IDs.


Path B: a2a-pay (paymentId-based, no 402)

The user invokes this path explicitly — by mentioning a paymentId / a2a_... link, asking to "create a payment link", or asking to check a2a payment status.

Step B1: Identify the role

User says…LoadRole
"create payment link" / "generate payment" / --amount/--recipientreferences/a2a_charge.md → "Seller — Create"Seller
Provides a paymentId / a2a_... to payreferences/a2a_charge.md → "Buyer — Pay"Buyer
Provides a paymentId and asks for statusreferences/a2a_charge.md → "Status — Query"Either

If the user says only "I want to pay" without a paymentId — STOP and ask the user to provide the seller-issued paymentId. Do not attempt anything else.

Step B2: Wallet status

Both create and pay require a live wallet session. Run onchainos wallet status:

  • Logged in → proceed (load the reference and follow it).
  • Not logged in → ask the user to log in via onchainos wallet login or onchainos wallet login <email>. Do NOT sign without a live session.

Step B3: Hand off to references/a2a_charge.md

The reference contains the full create/pay/status flow including the auto-poll-to-terminal logic and trust-delegation note. Buyer-side trust is delegated to the upstream caller — the buyer signs whatever the on-server challenge declares. Cross-checking the paymentId against the agreed terms is the upstream's responsibility, NOT this dispatcher's.


Cross-cutting

Reading seller errors (WWW-Authenticate: Payment / a2a-pay)

When the seller rejects, do NOT show raw JSON or just the numeric code. Extract the human-readable explanation in priority order, use the first non-empty match:

  1. body.reason (mppx, OKX TS Session)
  2. body.detail (RFC 9457 ProblemDetails)
  3. body.message
  4. body.msg (OKX SA API)
  5. body.error
  6. body.title (RFC 9457 short title — fallback only)
  7. fallthrough — format the whole body and add the HTTP status

Format:

❌ Seller rejected: <reason text> (code <code if present>, HTTP <status>)

Amount display

All user-facing amounts in BOTH human and atomic form: <human> (<atomic>), e.g. 0.0004 USDC (400), 1.5 ETH (1500000000000000000). Compute via amount / 10^decimals from the challenge currency token.

TokenDecimals1 unit in minimalExample
USDC610000001000000 → 1.00 USDC
USDT610000002500000 → 2.50 USDT
USDG61000000500000 → 0.50 USDG
ETH18100000000000000000010000000000000000 → 0.01 ETH

For any symbol not in the table: never assume — query okx-dex-token for the token's decimals first. If you cannot resolve them, render <minimal> <symbol> and append unknown decimals — please double-check the seller-provided amount. Do not block the flow.

Suggest next steps

After a successful payment + response, suggest conversationally:

...

User Reviews (0)

Write a Review

Effect
Usability
Docs
Compatibility

No reviews yet

Statistics

Installs13.5K
Rating4.5 / 5.0
Version
Updated2026年10月21日
Comparisons1

User Rating

4.5(120)
5
37%
4
43%
3
13%
2
5%
1
2%

Rate this Skill

0.0

Compatible Platforms

🤖claude-code

Timeline

Created2026年5月28日
Last Updated2026年10月21日
🎁 Agent Knowledge Cards
Survey