Skip to main content
x402 は HTTP 402 ステータスコードに基づくオープンな決済プロトコルです。サーバーは未決済のリクエストに対して 402 challenge を返し、支払い側(通常は AI エージェント)はオンチェーンのステーブルコイン承認署名を付けてリクエストを再送し、決済完了後にリソースを取得します。Waffo は x402 を標準的な決済受け入れ機能として提供しており、注文・Webhook・照合は既存の Waffo 統合と完全に同一で、オンチェーンの検証と決済は Waffo が行います。 本ページは 2 種類の読者を対象としています。主対象は加盟店開発者(統合モードの選択、Waffo API の呼び出し、リソース提供の判定)です。AI エージェント開発者は 402 challenge の構造と PAYMENT-SIGNATURE の送信方法を中心にお読みください。エージェント側のやり取りに加盟店の API キーは不要です。

2 つの統合モード

モード 1:加盟店ホスト型 402

加盟店サーバー自身が x402 server として動作します。エージェントに 402 challenge を返し、署名を受け取り、order/create で署名を Waffo に引き渡して決済します。エージェントを自社 API 上に留めたい、x402 プロトコルの詳細を自前で実装できる加盟店に適しています。

モード 2:Waffo ホスト型 402

加盟店は注文を作成し、Waffo が返すホスト型 URL をエージェントに渡すだけです。402 challenge、署名の受け取り、決済はすべて Waffo キャッシャーが行います。x402 プロトコルの詳細に触れず迅速にリリースしたい加盟店に適しています。
両モードは同一の order/create エンドポイントを共用します。区別はただ一つ、リクエストの x402InfopaymentSignatureHeader を含むかどうかです。署名ありはモード 1、署名なしはモード 2 になります。

前提条件

x402 決済の受け入れには、Waffo 導入チームを通じて以下 2 点の開通が必要です。
  1. 加盟店契約で CRYPTO / USDC 決済プロダクトを有効化する
  2. Waffo 側でオンチェーン受取パラメータを設定する
設定が完了していない場合、wallet/inquiryorder/create はエラーコード A0010(加盟店契約で許可されていない操作)を返します。

現在のサポート範囲

以下は現行バージョンの確定した境界です。この前提で開発し、他の機能を想定しないでください。
  • 通貨USDC のみ。orderCurrency は必ず USDC(同一通貨での受け入れ、為替換算なし)
  • ネットワーク:Base のみ(本番は eip155:8453、サンドボックスは Base Sepolia eip155:84532
  • schemeexact のみ(challenge の金額どおりに決済)
  • 承認回数:EIP-3009 の承認はオンチェーンで 1 回のみ消費されます。1 つの署名で決済できるのは 1 回だけで、「1 回の承認で複数回請求」はサポートされません
  • 冪等性paymentRequestId は必須です。同一注文への order/create 再実行は既存注文の実際のステータスを返し、再決済は行われません(冪等性を参照)

オンチェーン受取パラメータの取得

モード 1 で 402 challenge を構築する前に、POST /api/v1/wallet/inquiry で受取パラメータを取得します。このエンドポイントは照会のみで、注文の作成も金額の検証も行いません。
3 つのフィールドはいずれも Waffo の設定値です。challenge の構築にはそのまま使用してください。payTo を自社のウォレットアドレスに置き換えてはいけません。エージェントの署名内の受取アドレスと金額は、決済前にオンチェーンで厳密に検証されます。

モード 1:加盟店ホスト型 402

加盟店側で行うことは 4 つです。
  1. wallet/inquirynetwork / asset / payTo を取得し、価格設定に基づいて 402 challenge を構築(金額はアトミック単位、schemeexact 固定)してエージェントに返す
  2. エージェントの再送リクエストヘッダー PAYMENT-SIGNATURE から署名を取り出し、そのまま order/createx402Info.paymentSignatureHeader に設定する(デコードして再構築しない)
  3. 同期レスポンスの orderStatus で提供可否を判定する:PAY_SUCCESS は提供、PAY_IN_PROGRESSWebhook または order/inquiry の最終ステータスを待つ、ORDER_CLOSE は拒否
  4. 提供時にレスポンスの x402Info.x402ResponsePAYMENT-RESPONSE ヘッダーとしてエージェントに返す。これが x402 準拠の決済レシートです
その他の必須フィールド(goodsInfoorderRequestedAt など)は通常のワンタイム決済の注文作成と同一です。API Reference を参照してください。 paymentSignatureHeader は base64 エンコードされた x402 PaymentPayload です。デコード後の構造は以下のとおりです(エージェント側の x402 SDK が生成するため、加盟店が構築する必要はありません)。
署名内の authorization.towallet/inquiry が返した payTo と一致し、authorization.valueorderAmount のアトミック単位表現と一致しなければなりません(換算ルールは後述の「金額と小数位」を参照)。いずれかが不一致の場合、決済前の検証で失敗し、注文は ORDER_CLOSE になります。したがって 402 challenge でエージェントに提示する価格は order/createorderAmount と一致している必要があります。
x402Response は base64 エンコードされた決済レシート(x402 SettlementResponse)で、orderStatus = PAY_SUCCESS の場合のみ返されます。デコード後:
transaction はオンチェーンのトランザクションハッシュで、照合とオンチェーン検証に使用できます。payer はエージェントの支払いウォレットアドレスです。

モード 2:Waffo ホスト型 402

加盟店側で行うことは 3 つです。
  1. order/createx402Info: { "x402Request": true }(署名なし)と successRedirectUrl / failedRedirectUrl を設定する
  2. レスポンスの orderAction(JSON 文字列)を解析して webUrl を取り出し、エージェントを 302 リダイレクトする。以降の 402 challenge、署名の受け取り、決済はすべて Waffo キャッシャー側で行われます
  3. Webhook または order/inquiry が返す orderStatus に基づいてリソースを提供する
エージェントが webUrl にアクセスすると HTTP 402 を受け取ります。challenge はレスポンスボディにあります(x402 プロトコルでは challenge はボディに置かれ、専用のレスポンスヘッダーはありません)。
署名後、エージェントは初回アクセスと同じ HTTP メソッドで同一 URL に再送し、署名を PAYMENT-SIGNATURE リクエストヘッダー(x402 仕様の X-PAYMENT に相当)に設定します。加盟店の認証情報は一切不要です。
決済完了後、キャッシャーは 302 でエージェントを加盟店の successRedirectUrl または failedRedirectUrl に戻します。ホスト型 URL はブラウザアクセス(チェックアウトページを表示)と x402 クライアントアクセス(プロトコルレスポンスを返す)の両方に対応しています。
302 リダイレクトはフローの接続のためだけのもので、支払いの証明ではありません。「支払い済み」の判定は、Webhook 通知または order/inquiry で確認した orderStatus = PAY_SUCCESS のみに基づいてください。リダイレクトは偽造・消失の可能性があり、リダイレクト時点では決済が確定していないこともあります。
決済成功後、Webhook 通知と order/inquiry レスポンスには x402Info.x402Response(構造はモード 1 と同一)が付加されます。それ以外の通知構造は通常の注文と同じです。Webhook イベントタイプを参照してください。

モード比較

注文ステータスの意味(PAY_IN_PROGRESSAUTHORIZATION_REQUIRED など)は他の決済手段と共通です。決済ライフサイクルを参照してください。

金額と小数位(2 層の単位)

同一の取引に 2 層の金額表現があります。混同しないでください。 換算ルール:アトミック単位 = 金額 × 106通貨と金額における USDC の小数 2 桁は Waffo API 層の orderAmount を指します。402 challenge と EIP-3009 署名内の金額は常にアトミック単位です。モード 1 では両層の金額が同一の値を表す必要があり、不一致の場合は決済検証で失敗します。

エラーコード

x402 は Waffo の既存の外部エラーコードを再利用します。msg に具体的な理由が示されます。 完全な一覧はエラーコードリファレンスを参照してください。

よくある質問

サンドボックスは Base Sepolia テストネット(eip155:84532)で、USDC コントラクトアドレスは 0x036CbD53842c5426634e7929541eC2318f3dCF7e です。本番は Base メインネット(eip155:8453)で、USDC コントラクトアドレスは 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 です。どちらの環境でも network / asset / payTowallet/inquiry の実際の返り値に従ってください。
現在は USDC + Base ネットワークのみです。orderCurrency に他の通貨を指定すると A0007 が返ります。
できません。x402 の exact scheme は EIP-3009 transferWithAuthorization に基づいており、その nonce は USDC コントラクト側で 1 回のみ消費されます。署名は一度決済されると無効になり、再送信はオンチェーンで直接失敗します。サブスクリプション型や従量制の複数回請求は x402 の対象範囲外です。
いけません。PAY_IN_PROGRESS はオンチェーン処理中を意味するだけで、最終的に成功も失敗もあり得ます。リソースを提供できるのは orderStatus = PAY_SUCCESS のみで、最終ステータスは Webhook または order/inquiry で確定します。
レスポンスボディ(JSON)にあります。challenge を運ぶヘッダーはありません。x402 のやり取りにおける唯一のプロトコルリクエストヘッダーは、エージェントが署名を送信する PAYMENT-SIGNATURE(x402 仕様の X-PAYMENT に相当)です。決済レシートは x402Info.x402Response フィールドで返され、仕様の X-PAYMENT-RESPONSE に相当します。
違います。AI 統合ツールは AI コーディングツールで Waffo SDK の統合コードを生成するものです。本ページは AI エージェントが支払い側としてステーブルコインで加盟店のサービスを購入する仕組みです。併用できますが、解決する課題は異なります。

関連ドキュメント