x402 合规一致性规范 v0.1
给 Agent 支付(x402 / MCP)结算前合规的一套机读契约:每一种合规判决对应一个稳定 reason_code、一个 signal_class、一条 retry 规则。1:1 对齐线上真实的 11 道闸,可对免费端点复现。
端点【今天就返回】 reason_code / signal_class / retry / retry_hint(HTTP 状态码仍是 200/403/409)。 451/-4510 的换码 = 提议中、尚未上线(换 HTTP 状态码是破坏性变更,须版本协商)。
1 · 信号类别与 retry 规则
| signal_class | 含义 | retry |
|---|---|---|
| ok | 已放行 | not_applicable |
| payment | 额度/预算(可补足) | retryable_after_funding |
| regulatory | 确定性合规 FAIL(制裁/混币/吊销/重放) | non_retryable |
| authorization | 归因/授权/白名单/凭证 | retry_after_authorization |
| uncertain | 筛查不可得/不确定 | policy_dependent_backoff |
| client_error | 请求格式错误 | retry_after_fix |
2 · reason_code 分类(对齐真实 11 道闸)
| reason_code | signal_class | retry | 来自 |
|---|---|---|---|
| kya_unattributed | authorization | retry_after_authorization | KYA |
| mandate_revoked | authorization | non_retryable | KYA/Revoked |
| kya_proof_missing | authorization | retry_after_authorization | KYA/Proof |
| kyc_required | authorization | retry_after_authorization | KYA/KYC |
| invalid_input | client_error | retry_after_fix | Input |
| over_per_tx_limit | payment | retryable_after_funding | Firewall/Limit |
| over_daily_limit | payment | retryable_after_funding | Firewall/Velocity |
| payee_not_allowlisted | authorization | retry_after_authorization | Firewall/Allowlist |
| mandate_intent_mismatch | authorization | retry_after_authorization | Mandate |
| sanctioned_or_high_risk_payee | regulatory | non_retryable | Screening/AML |
| behavioral_anomaly | uncertain | policy_dependent_backoff | Behavior/Anomaly |
| replay_detected | authorization | non_retryable | Mandate/Replay |
| clear | ok | not_applicable | allow |
| elevated_risk_payee | uncertain | policy_dependent_backoff | screening: review |
| screening_unavailable | uncertain | policy_dependent_backoff | screening unavailable |
| payee_differs_from_listing | authorization | retry_after_authorization | POST /api/decide: payment_intent.payee differs from the payout wallet listed for resource_ref in the public x402 directory |
| payee_changed_since_previous | authorization | retry_after_authorization | POST /api/decide: payee, network or asset differs from previous_payment_intent |
| payee_is_token_contract | client_error | retry_after_fix | screening: payee is a token contract address, not a recipient |
| idempotency_key_invalid | client_error | retry_after_fix | POST /api/pay: malformed Idempotency-Key (400) |
| idempotency_key_reused | client_error | retry_after_fix | POST /api/pay: Idempotency-Key reused with a different body (422) |
| idempotency_request_in_progress | uncertain | policy_dependent_backoff | POST /api/pay: original request with this Idempotency-Key still running (409) |
| key_scope_denied | authorization | retry_after_authorization | API key restricted to other scopes by its holder (403) |
| key_ip_denied | authorization | retry_after_authorization | API key restricted to an IP allowlist by its holder; this request came from elsewhere (403) |
3 · 可复现测试向量(对免费端点)
curl "https://oceanalt.com/api/risk?addr=0x8589427373D6D84E98730D7795D8f6f8731FDA16" # → verdict:"risky", reason_code:"sanctioned_or_high_risk_payee", signal_class:"regulatory", retry:"non_retryable"
curl "https://oceanalt.com/api/risk?addr=0x742d35Cc6634C0532925a3b844Bc454e4438f44e" # → verdict:"clear", reason_code:"clear", signal_class:"ok", retry:"not_applicable"

