メインコンテンツへスキップ
x402 は HTTP 402 Payment Required 標準に基づくオンチェーン支払いプロトコルで、呼び出し元が API リクエストを開始する際にオンチェーン決済を完了できるようにします。自動化プログラム、AI エージェント、マイクロサービス間の呼び出し課金シナリオに非常に適しています。このガイドを通じて、AceDataCloud の注文支払いをプログラム的に自分のシステムで実現し、「リクエスト即支払い」の体験を実現できます。 公式資料参照: この文書は、AceDataCloud プラットフォームの x402 支払い機能をビジネスに統合する必要がある開発者を対象としており、環境の準備から支払い呼び出しの完了までの完全なプロセスを紹介し、Axios、Fetch、Python requests および httpx のサンプルコードを提供します。核心要点:
  • 支払いリンクは Base メインネット で完了し、資産は USDC を使用;
  • 保有するウォレットの EVM 秘密鍵 を使用して X-PAYMENT 署名ヘッダーを生成する必要があります;
  • すべての API は https://platform.acedata.cloud ドメインにあり、Authorization ヘッダーには Platform Token を含める必要があります。

一、準備作業

1. 注文を確認し、受取情報を記録

コンソールにログイン https://platform.acedata.cloud、注文リストまたは注文詳細ページで支払いが必要な注文を確認できます。注文詳細には以下が表示されます:
  • 注文 ID(例: 7744945e-5e77-4dcc-a9c4-528692d17b34);
  • 受取アドレス pay_to(402 応答でも返されますが、ページ情報を基準にすることをお勧めします)。
注文 ID を記録し、pay_to アドレスを確認してください。後の署名時に資金がこのアドレスに送信されることを保証する必要があります。

2. 支払いウォレットと資金の準備

  • Base メインネットをサポートする EVM ウォレットを準備し、使用する秘密鍵をエクスポート;
  • Base メインネットに十分な USDC をチャージ(支払い金額の単位は 6 桁の小数の最小単位);
  • x402 Facilitator がネットワーク手数料を代わりに支払うため、支払いウォレットには十分な USDC を保持する必要があります;
  • 秘密鍵はローカル署名のみに使用し、適切に保管し、ブラウザや信頼できない環境での露出を避けてください。

3. Platform Token の作成

Platform Token はプラットフォーム API を呼び出すために使用され、ログイン後のブラウザで使用されるユーザー Token と同様の機能を持ちますが、期限切れにはなりません。以下の手順に従って作成してください:
  1. コンソールページ https://platform.acedata.cloud/console/platform-tokens を開く;
  2. 「Token を作成」をクリックし、指示に従ってメモ情報を入力して生成;
  3. 生成された Token(例: platform-v1-xxxx)をコピーし、platform_token として適切に保存。
platform-token 以降のすべての API 呼び出しヘッダーには以下を含める必要があります:
Authorization: Bearer {platform_token}

4. 基本情報のリクエスト

  • API 基本ドメイン:https://platform.acedata.cloud
  • 支払いリクエストパス:/api/v1/orders/{order_id}/pay/
  • リクエストとレスポンスはすべて JSON 形式で、UTF-8 でエンコードされています。

二、支払いプロセスの概要

  1. 支払いリクエストの発行X-PAYMENT ヘッダーなしの最初の POST リクエストを発行し、プラットフォームが 402 Payment Required を返すトリガーを引きます;
  2. 支払い要件の読み取り:402 応答の accepts 配列を解析し、networkbaseasset が USDC、payTo が注文ページと一致することを確認;
  3. X-PAYMENT の生成:支払いウォレットの秘密鍵、応答ボディ内の要件、Facilitator が返す EIP-712 ドメインなどの情報を使用して署名を生成(通常は公式 SDK を利用して完了);
  4. 署名を持って再試行X-PAYMENT ヘッダーを同じパスのリクエストに追加し、プラットフォームが検証に成功した後、200 を返す;
  5. 結果の解析:レスポンスヘッダー X-PAYMENT-RESPONSE を読み取り、オンチェーン取引ハッシュ、実際の引き落とし金額などの情報を取得して照合に使用。

三、接**###**続の例

1. 最初のリクエスト(402 をトリガー)

POST https://platform.acedata.cloud/api/v1/orders/{order_id}/pay/
Authorization: Bearer {platform_token}
Content-Type: application/json

{
  "pay_way": "X402"
}
典型的な 402 応答(フィールドの順序は若干異なる場合があります):
{
  "error": "この注文には支払いが必要です。",
  "accepts": [
    {
      "scheme": "exact",
      "network": "base",
      "asset": "0x833589fcd6edb6e08f4c7c32d4f71b54b268aa0e",
      "maxAmountRequired": "1250000",
      "payTo": "0x302afdd980aaefca3afa8df7222a6002774f6724",
      "extra": {
        "eip712": { "...": "..." }
      }
    }
  ],
  "paywall": { ... }
}
重要なフィールドの説明:
  • network:必ず base(Base メインネット)である必要があります;
  • asset:Base USDC コントラクトアドレス(例は公式メインネットコントラクト);
  • maxAmountRequired:今回の支払いに必要な USDC 原子単位(1 USDC = 1,000,000 atomic units);
  • payTo:プラットフォームの受取アドレスで、注文詳細ページと一致する必要があります;
  • extra:署名に必要な EIP-712 ドメイン情報など。

2. X-PAYMENT の生成

一般的な方法は公式 SDK(例: x402-jsx402-fetchx402.clients など)を使用することです:
  1. 支払いウォレットの秘密鍵をアカウントオブジェクトに変換;
  2. 402 応答の accepts データを記録し、network == "base" の支払いオプションを選択;
  3. SDK が提供する署名関数を呼び出して Base64 エンコードされた X-PAYMENT 文字列を生成(クライアントが直接 facilitator に接続する必要はありません;プラットフォームのバックエンドが facilitator を呼び出して verify/settle を完了します);
  4. maxAmountRequired が受け入れ可能な範囲内であることを確認することをお勧めします。超過した場合はユーザーにチャージを促します。
手動で実装する必要がある場合は、x402 公式ドキュメントを参照し、extra.eip712 が提供するドメイン情報に従って EIP-712 構造体を構築し、署名を行ってください。

3. 署名を持って再試行

POST https://platform.acedata.cloud/api/v1/orders/{order_id}/pay/
Authorization: Bearer {platform_token}
Content-Type: application/json
X-PAYMENT: {base64_signed_payload}

{
  "pay_way": "X402"
}
支払いが成功した場合、レスポンスステータスは 200 となり、レスポンスボディには更新された注文情報が返され、以下が付随します:
X-PAYMENT-RESPONSE: eyJ0cmFuc2FjdGlvbiI6IjB4...==
X-PAYMENT-RESPONSE は SDK のデコード関数を使用してオンチェーン取引ハッシュ、支払いネットワーク、支払者アドレスなどのデータを取得し、ビジネスの入金や表示に使用します。

四、多言語サンプルコード

以下のサンプルはすべて、環境変数または設定ファイルから注入されることを前提としています:
  • ACE_PLATFORM_TOKEN:プラットフォームトークン;
  • ACE_X402_ORDER_ID:注文ID;
  • ACE_X402_PRIVATE_KEY:支払いウォレットの秘密鍵(0x プレフィックス付き)。

1. Axios(TypeScript)

import axios from "axios";
import { Hex } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { buildPaymentHeader, decodePaymentResponse } from "x402-js";

const baseURL = "https://platform.acedata.cloud";
const orderId = process.env.ACE_X402_ORDER_ID!;
const platformToken = process.env.ACE_PLATFORM_TOKEN!;
const privateKey = process.env.ACE_X402_PRIVATE_KEY as Hex;

const account = privateKeyToAccount(privateKey);
const api = axios.create({
  baseURL,
  headers: {
    Authorization: `Bearer ${platformToken}`,
    "Content-Type": "application/json",
  },
});

async function payOrder() {
  const payPath = `/api/v1/orders/${orderId}/pay/`;

  const initial = await api.post(
    payPath,
    { pay_way: "X402" },
    { validateStatus: () => true }
  );
  if (initial.status !== 402) {
    throw new Error(`予期しないステータス ${initial.status}`);
  }

  const requirement = initial.data.accepts.find(
    (item: any) => item.network === "base"
  );
  if (!requirement) {
    throw new Error("ベース要件が返されていません");
  }

  const paymentHeader = await buildPaymentHeader({
    account,
    requirement,
  });

  const final = await api.post(
    payPath,
    { pay_way: "X402" },
    { headers: { "X-PAYMENT": paymentHeader } }
  );

  if (final.status >= 400) {
    throw new Error(`x402 支払い失敗: ${final.status} ${final.statusText}`);
  }
  const receipt = decodePaymentResponse(final.headers["x-payment-response"]);
  console.log("x402 レシート", receipt);
}

payOrder().catch(console.error);

2. Fetch(JavaScript)

import { wrapFetchWithPayment, decodePaymentResponse } from "x402-fetch";
import { privateKeyToAccount } from "viem/accounts";

const account = privateKeyToAccount(process.env.ACE_X402_PRIVATE_KEY!);
const platformToken = process.env.ACE_PLATFORM_TOKEN!;
const orderId = process.env.ACE_X402_ORDER_ID!;
const fetchWithPayment = wrapFetchWithPayment(fetch, account);

async function payOrder() {
  const url = `https://platform.acedata.cloud/api/v1/orders/${orderId}/pay/`;

  const response = await fetchWithPayment(url, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${platformToken}`,
    },
    body: JSON.stringify({ pay_way: "X402" }),
  });

  if (!response.ok) {
    const errorBody = await response.text();
    throw new Error(`x402 支払い失敗: ${response.status} ${errorBody}`);
  }

  const receipt = decodePaymentResponse(
    response.headers.get("x-payment-response")!
  );
  console.log("x402 レシート", receipt);
}

payOrder().catch(console.error);

3. Python requests

import os
from eth_account import Account
from x402.clients.requests import x402_requests
from x402.clients.base import decode_x_payment_response

order_id = os.environ["ACE_X402_ORDER_ID"]
platform_token = os.environ["ACE_PLATFORM_TOKEN"]
account = Account.from_key(os.environ["ACE_X402_PRIVATE_KEY"])

session = x402_requests(
    account,
    payment_requirements_selector=lambda accepts, **_: next(
        req for req in accepts if req.network == "base" and req.scheme == "exact"
    ),
)

response = session.post(
    f"https://platform.acedata.cloud/api/v1/orders/{order_id}/pay/",
    json={"pay_way": "X402"},
    headers={"Authorization": f"Bearer {platform_token}"},
)

response.raise_for_status()
receipt_header = response.headers.get("X-PAYMENT-RESPONSE")
if receipt_header:
    print("x402 レシート:", decode_x_payment_response(receipt_header))

4. Python httpx(非同期)

import asyncio
import os
from eth_account import Account
from x402.clients.httpx import x402HttpxClient
from x402.clients.base import decode_x_payment_response

async def pay_order() -> None:
    order_id = os.environ["ACE_X402_ORDER_ID"]
    platform_token = os.environ["ACE_PLATFORM_TOKEN"]
    account = Account.from_key(os.environ["ACE_X402_PRIVATE_KEY"])

    async with x402HttpxClient(
        account=account,
        base_url="https://platform.acedata.cloud",
        headers={"Authorization": f"Bearer {platform_token}"},
        payment_requirements_selector=lambda accepts, **_: next(
            req for req in accepts if req.network == "base"
        ),
    ) as client:
        response = await client.post(
            f"/api/v1/orders/{order_id}/pay/",
            json={"pay_way": "X402"},
        )
        response.raise_for_status()
        receipt_header = response.headers.get("X-PAYMENT-RESPONSE")
        if receipt_header:
            print("x402 レシート:", decode_x_payment_response(receipt_header))

asyncio.run(pay_order())
サンプルは重要な呼び出しのみを示しており、実運用環境では例外処理、リトライ戦略、ログおよびセキュリティ制御を追加してください。

五、支払い成功後の検証

  • コンソール検証:注文詳細ページ https://platform.acedata.cloud/console/orders/{order_id} にアクセスし、ページに「支払い成功」と表示されるか、注文の状態が支払い済み/完了に変わっている場合、チェーン上の決済が完了したことを示します。
  • API 検証GET https://platform.acedata.cloud/api/v1/orders/{order_id}/ を呼び出し、Authorization: Bearer {platform_token} を持参し、レスポンスの state フィールドを確認します(PAID または FINISHED は支払い成功を示します)。
  • 回伝ヘッダー:支払い成功のレスポンスから X-PAYMENT-RESPONSE を読み取り、チェーン上の取引ハッシュを最終証明書として解析できます;この情報はシステムログに保存することをお勧めします。

六、よくある問題のトラブルシューティング

  • まだ 402 が返される:支払いアドレスが Base メインネットに十分な USDC を持っていることを確認し、maxAmountRequired がウォレットの残高やカスタム制限を超えていないか確認してください。
  • 署名失敗:秘密鍵に 0x プレフィックスが付いていることを確認してください;署名時にはレスポンスの extra(EIP-712 ドメイン)と payTo を厳密に使用し、フィールドの順序を変更しないでください。
  • ネットワーク不一致accepts に複数の要件が存在する可能性があるため、network === "base" のオプションを選択してください。
  • X-PAYMENT-RESPONSE が欠落:支払いが実際に引き落とされていないことを示します;レスポンスボディ内のエラーに基づいて再度発起してください;チェーン上の混雑が発生した場合は、後で再試行してください。
  • プラットフォームトークンが無効:トークンが削除されていないことを確認し、platform-v1- プレフィックスで始まっていることを確認してください;インターフェースが 401 を返す場合は、コンソールで再生成してください。

七、さらなる支援

  • オンラインドキュメントとよくある質問:プラットフォームコンソールの上部ナビゲーション「ドキュメント」。
  • チケットの提出とカスタマーサポート:https://platform.acedata.cloud/support
  • コミュニティ交流:Discord https://discord.gg/f9GRuKCmRc、X(Twitter)https://x.com/acedatacloud
  • その他の連絡先:メール office@acedata.cloudoffice@germey.tech;会社住所 651 N Broad St, Suite 201, Middletown, Delaware, USA;WeChat カスタマーサポートはサポートページで最新のQRコードを確認してください。
  • フィードバックと提案:上記のいずれかの方法で改善要求をお知らせください。