Skip to Content
View as Markdown

認証

InfraIO Pay には認証モデルの異なる 2 つの API サーフェス があります。 呼び出し主体に合わせて選択してください:

サーフェスパスプレフィックス想定対象認証方式
マーチャント B2B/b2b/v1/*あなたのサーバーHMAC-SHA256 リクエスト署名
ダッシュボードマーチャントダッシュボードが使用マーチャントダッシュボードのブラウザセッションBearer JWT

本ページは API キーペアを使ってサーバーから呼び出す B2B サーフェスを 扱います。ダッシュボードサーフェスは InfraIO Pay マーチャントダッシュボードが 使用するもので、公開された連携用サーフェスではありません。

/b2b プレフィックスを含めたフルパスを送信し、同じパスに署名して ください (下記参照)。

エンドポイント

環境ベース URL
Testhttps://api-dev.infraio.xyz
Livehttps://api.infraio.xyz

URL パターンは同じです — 環境は URL ではなく キーのプレフィックス (pk_test_… vs pk_live_…) で制御します。

キーペア

マーチャントダッシュボード (Developers → API keys → + Add key) から 2 つの値を取得します:

  • Publishable key (pk_test_… または pk_live_…) — あなたの アカウントを識別します。X-Client-ID として送信。ブラウザバンドルに 埋め込んでも安全です (SDK は既にそうしています)。
  • Secret key (sk_test_… または sk_live_…) — HMAC 署名鍵。 サーバー限定。データベースパスワードと同じ扱いをしてください。

シークレットキーがブラウザバンドル、Git リポジトリ、ログ行、 共有チャットなどに混入した場合 — 直ちに ダッシュボードから 失効させてください。失効は即時で、オーバーラップウィンドウはありません。 新しいキーを発行して再デプロイしてください。

リクエストの署名

/b2b/v1/* への各呼び出しは 3 つのヘッダーを伴います:

X-Client-ID: pk_live_70d0becbd7a53047b0dfe88a960d10ad X-Timestamp: 1715990400 X-Signature: 9a8b7c6d… (hex HMAC-SHA256)

署名は canonical 文字列に対して計算されます:

METHOD + "\n" + PATH + "\n" + TIMESTAMP + "\n" + BODY
  • METHOD — 大文字の HTTP 動詞 (POST、GET など)。
  • PATH — /b2b プレフィックスを含めた リクエストパス、ホストと クエリ文字列を除く (例: /b2b/v1/checkout-sessions/quick)。 プレフィックスは必須です。クエリパラメータは 署名対象に 含めません — GET …?cursor=…&limit=20 ではパスのみに署名し、?… 部分には署名しません。
  • TIMESTAMP — Unix 秒の 10 進文字列 (例: "1715990400")、 X-Timestamp と完全一致させてください。
  • BODY — 生のリクエストボディバイト。GET/DELETE では空文字。

シークレット キーで HMAC-SHA256 署名し、hex で出力:

import { createHmac } from "node:crypto"; function sign({ method, path, body, secret }: { method: string; path: string; body: string; secret: string; }) { const timestamp = Math.floor(Date.now() / 1000).toString(); const input = [method.toUpperCase(), path, timestamp, body].join("\n"); const signature = createHmac("sha256", secret).update(input).digest("hex"); return { timestamp, signature }; }

なぜ Bearer ではなく HMAC か

素の Bearer トークン API は、リクエストごとにあなたの唯一のシークレットを ネットワーク越しに送信します。TLS 終端プロキシのログを 1 つでも捕捉 されれば、アカウントの鍵がそのまま渡ります。HMAC 署名なら、シークレット 自体は移動せず、そこから導出された署名 (そのリクエストとその分にだけ バインドされた一回限りの値) だけが流れます。

トレードオフ: 呼び出しごとに署名を計算する必要があります。サーバー SDK はまだありませんが、上記のヘルパーは言語あたり 15 行程度です。

タイムスタンプの許容範囲

許容範囲は ±5 分 (300 秒) です。このウィンドウ外のリクエストは 401 invalid_signature で拒否されます。2 つの含意:

  1. サーバー時計を NTP で同期 してください。時計がずれた長時間 稼働の cron は断続的に失敗します。
  2. 署名を事前計算してキューに入れないでください。 リトライキューで

    5 分滞留すると、その署名は期限切れになります。

キーのスコープ

シークレットキーは以下のスコープバンドルを 1 つ以上保持します:

スコープ想定用途
read注文、セッション、返金の一覧 / 読み取り
write_orderチェックアウトセッション、注文の作成
write_refund返金の発行、返金リクエストトークンの発行
webhook_manageWebhook エンドポイントの作成 / 更新 / 削除

ダッシュボードはデフォルトで「フルアクセス」キー (4 つすべて) を 発行します。Developers → API keys → + Add key から、統合に必要な スコープだけにチェックを入れた制限付きスコープキーを発行できます。

スコープはまだ強制されていません。 スコープはキーに記録されダッシュボードに 表示されますが、有効な sk_… キーであれば、あなたのマーチャントのどの /b2b/v1/* エンドポイントでも呼び出せます。スコープをセキュリティ境界として 頼らないでください。アクセスを制限するにはキーをローテーションまたは失効 させてください。

検証に失敗した場合

署名、X-Client-ID、またはタイムスタンプが無効な場合、リクエストは API に 到達する前に 401 INVALID_SIGNATURE で拒否されます。この方式で署名される のは /b2b/v1/* リクエストのみです。Webhook は別のスキームを使用します (下記参照)。

次に

  • エラー — 4xx/5xx 時のレスポンス形式。
  • セキュリティ → API キー — ローテーション、 失効、シークレットが漏れたときの対処。
  • Webhook → 署名検証 — 異なる HMAC スキームを使用 (ヘッダーは X-Signature: sha256=…、 署名対象は X-Timestamp + "." + raw_body、24 時間のローテーション猶予 ウィンドウ中は任意で X-Signature-Prev)。スキームを混同しないで ください — ハッシュアルゴリズムは共通ですが、署名対象バイトと シークレットファミリ (whsec_… vs sk_…) は異なります。