このサイトはコミュニティが運営する非公式の日本語リソースです。公式ドキュメントはdocs.x402.orgをご参照ください。

支払い識別子

冪等性のための支払いID管理とレスポンスキャッシングを提供するエクステンションです。

支払い識別子エクステンションを使用すると、クライアントはリクエストに一意のIDを付与できます。サーバーはこのIDを使ってレスポンスをキャッシュし、同じIDで再試行された場合に重複処理を防ぎます。

主なユースケース

  • ネットワーク障害後の安全な再試行
  • AIエージェントによる重複支払いの防止
  • 決済フローの監査証跡
  • べき等なAPI設計の実現

仕組み

  1. 1クライアントがリクエストの論理的な単位でIDを生成し、X-Payment-Identifierヘッダーに付与して送信
  2. 2サーバーが決済完了後にID・レスポンスをキャッシュ
  3. 3同じIDで再リクエストがきた場合、onProtectedRequestフックでキャッシュを確認して即時返却
  4. 4TTLが切れた後は通常通り再処理

冪等性の動作

シナリオ動作
新しいID通常通り処理し、レスポンスをキャッシュ
TTL内で同じIDキャッシュされたレスポンスを返す(再処理なし)
TTL後に同じID通常通り再処理
IDなし通常通り処理(キャッシュなし)

クライアント実装

generatePaymentId() を使ってIDを生成し、支払いフローにフックします:

import { wrapFetchWithPayment, generatePaymentId } from "x402-fetch";

const paymentClient = wrapFetchWithPayment(fetch, signer, {
  paymentIdentifier: generatePaymentId(),
});

// 同じ論理リクエストには同じIDを使用
const id = generatePaymentId();
const res1 = await paymentClient("https://api.example.com/data", {
  paymentIdentifier: id,
});
// 失敗してもリトライで重複課金されない
const res2 = await paymentClient("https://api.example.com/data", {
  paymentIdentifier: id,
});

サーバー実装

エクステンションを登録し、ルートで有効化します:

import { paymentIdentifierExtension } from "x402/extensions";

server.registerExtension(paymentIdentifierExtension({
  ttl: 3600, // seconds
  store: redisStore, // カスタムストア(省略時はメモリ)
}));

const routes = {
  "GET /data": {
    accepts: [{ scheme: "exact", price: "$0.01", ... }],
    extensions: {
      paymentIdentifier: { enabled: true },
    },
  },
};

本番環境ではstoreにRedisなどの永続ストアを使用することを推奨します。メモリストアはサーバー再起動でキャッシュが消失します。