Skip to Content
View as Markdown

エラー

すべての 4xx/5xx レスポンスは同じ JSON エンベロープを持ちます:

{ "code": 400, "message": "invalid_input", "details": [ { "field": "items[0].unit_price", "message": "must be a positive decimal string" } ] }
  • code — 数値の HTTP ステータス (400、401、404、…)。汎用的な HTTP レイヤの処理には有用ですが、分岐ロジックには message のほうを switch してください — code だけでは、例えば invalid_input と payment_method_not_supported (どちらも 400) を区別できません。
  • message — lower-snake-case のセンチネル名 (センチネル名を小文字のスネークケースにしたもの。例: INVALID_INPUT は "invalid_input" になります)。リリース間で安定しています — こちらで switch してください。
  • details — バリデーションエラー時に設定されます。{ field, message } の配列で、クライアントが入力にエラーをひも付けられるようになっています。それ以外では省略されます。

エラーボディにはトレース ID もタイムスタンプも含まれません。問題を報告する際は、レスポンスの Date ヘッダー、X-RateLimit-* ヘッダー、マーチャント ID、エンドポイント、おおよそのリクエスト時刻をサポートにお送りください。

認証失敗は別の形をしています。 上記のエンベロープは、ほとんどのエラーで API が返すものです。処理される前に拒否されたリクエスト (/b2b/v1/* 呼び出しでの欠落 / 不正な X-Signature、未知の X-Client-ID、期限切れの X-Timestamp) は { "error": "...", "message": "..." } の形で返ります。ここで error は粗いスラグ (unauthorized / bad_request / service_unavailable)、message が詳細を運びます。数値の code も details もありません。まず HTTP ステータスで分岐し、次に message を読んでください。例 (401):

{ "error": "unauthorized", "message": "invalid signature" }

HTTP ステータス → 典型的なコード

HTTP典型的な code 値意味
400INVALID_INPUT、MISSING_REQUIRED、INVALID_FORMAT、INVALID_LENGTH、INVALID_VALUE、PAYMENT_METHOD_NOT_SUPPORTED、AMOUNT_BELOW_MINIMUM不正なリクエスト — details を確認
401INVALID_CREDENTIALS、INVALID_TOKEN、TOKEN_EXPIRED、INVALID_SIGNATURE (B2B); SESSION_EXPIRED (ダッシュボードのみ)認証失敗 — 不正なキー、期限切れタイムスタンプ、署名誤り。ダッシュボードのサインイン関連コードは B2B 統合には関係ありません。
402INSUFFICIENT_CREDITマーチャントのプリペイド残高が尽きました — リトライ前にチャージしてください
403FORBIDDEN、IP_BLOCKEDキーは有効ですが、この呼び出しに必要なスコープ / IP 許可がありません
404NOT_FOUND、RECORD_NOT_FOUNDリソースが存在しない (またはこのマーチャントには存在しない)
409ALREADY_EXISTS異なるボディでの冪等性リプレイ、またはステートマシンが遷移を拒否
429TOO_MANY_REQUESTS、TOO_MANY_ATTEMPTSレート制限到達; バックオフしてリトライ
500INTERNAL_SERVER_ERROR、EXTERNAL_SERVICE_ERROR当方の問題; バックオフ付きでリトライ可能。
503SERVICE_UNAVAILABLE下流の依存が停止中。バックオフ付きでリトライ

全コードリファレンス

目にする可能性のある code 値:

認証 (401)

  • INVALID_CREDENTIALS — API キーの組み合わせが拒否された
  • INVALID_TOKEN — トークンがパース不能または改ざんされている
  • TOKEN_EXPIRED — トークンが期限切れ
  • SESSION_EXPIRED — ダッシュボードセッションが期限切れ
  • INVALID_SIGNATURE — B2B / Webhook 呼び出しの HMAC 署名不一致

認可 (403)

  • FORBIDDEN — 認証は通ったが、このアクションを実行する権限がない
  • IP_BLOCKED — この IP アドレスからのリクエストはブロックされている

未検出 (404)

  • NOT_FOUND — 汎用
  • RECORD_NOT_FOUND — 指定された ID の行が存在しない

競合 (409)

  • ALREADY_EXISTS — 汎用

バリデーション (400)

  • INVALID_INPUT — 汎用; details を確認
  • MISSING_REQUIRED — 必須フィールドが欠落
  • INVALID_FORMAT — 値が期待形式と一致しない (例: UUID、URL、メール)
  • INVALID_LENGTH — 値が短すぎる、または長すぎる
  • INVALID_VALUE — 値が許容される enum / 範囲外
  • PAYMENT_METHOD_NOT_SUPPORTED — プロバイダ / アセットの組み合わせがマーチャントに対して有効化されていない
  • AMOUNT_BELOW_MINIMUM — 注文額がネットワーク別または環境レベルの下限を下回っている。レスポンスの details.floor_usd に設定された下限 (USD) が入っているので、そのまま表示できます; message テキストにも同じ内容が記載されています。
  • INSUFFICIENT_BALANCE — バイヤーのウォレットが送金分の支払いアセットを十分に保有していない。
  • INSUFFICIENT_GAS — バイヤーのウォレットが送金をブロードキャストするためのネイティブトークン(ネットワーク手数料用)を保有していない。

決済 / 課金 (402)

  • INSUFFICIENT_CREDIT — マーチャントのプリペイド残高がネットワーク手数料(ガス)とプラットフォーム手数料を賄えない。ダッシュボードからチャージしてリトライしてください

レート制限 (429)

  • TOO_MANY_REQUESTS — IP のレート制限を超過
  • TOO_MANY_ATTEMPTS — 同じリソースに対する繰り返し失敗 (例: OTP) がスロットルを発動

サーバーエラー (500)

  • EXTERNAL_SERVICE_ERROR — サードパーティプロバイダが失敗した
  • INTERNAL_SERVER_ERROR — 予期しないエラー; レスポンスの Date ヘッダーと X-RateLimit-* ヘッダーを添えてサポートにご連絡ください

可用性 (503)

  • SERVICE_UNAVAILABLE — サービスが一時的に利用できません; バックオフ付きでリトライ

バリデーションエラー (400)

リクエストボディの形式不正が原因の場合、details は配列なので、 エラーをフィールドに紐付けてマッピングできます:

{ "code": 400, "message": "invalid_input", "details": [ { "field": "items[0].unit_price", "message": "must be a positive decimal string" }, { "field": "success_url", "message": "must be a valid https URL" } ] }

認証エラー (401)

INVALID_SIGNATURE の一般的な原因は 3 つあります:

  • 不正なシークレットキー (環境変数を再確認)
  • タイムスタンプのずれが 5 分超 (NTP で同期)
  • 不正な canonical 文字列 (最も多いのは: \n セパレータ漏れ、または、送信したものと異なるパース後に再シリアライズしたボディに署名している)

正確な署名アルゴリズムは 認証 を参照してください。

レート制限 (429)

サーフェス制限
全 API ルート (/b2b/v1/* 含む)IP アドレス単位 — 500 req/min、共通バケット。マーチャント単位ではありません。
公開チェックアウト (/checkout/*)より厳しいサブバケット — IP あたり 20 req/min

X-RateLimit-Limit と X-RateLimit-Remaining は、レート制限がかかった すべてのレスポンスに含まれます (成功時のみではありません)。 あなたの IP に対する現在のバジェットとして扱ってください。

レート制限のレスポンスには Retry-After ヘッダー (ウィンドウがリセットされる までの秒数) が含まれます — これに従ってください。フォールバックとして、 ジッタ付きでバックオフ — ベース 1s から指数的に 30s まで。

レート制限は変更される可能性があります。正当なトラフィックで制限に 達する場合 (例: 大規模な過去範囲の整合性チェック) は、サポートにご連絡ください。

残高不足 (402)

INSUFFICIENT_CREDIT (HTTP 402 Payment Required) は、プリペイド残高が、 実行しようとしていた操作 (典型的には暗号資産決済の精算、またはネットワーク 手数料がスポンサーされるオンチェーン処理) のネットワーク手数料(ガス)と プラットフォーム手数料をカバーできないことを意味します。 マーチャントダッシュボードからチャージし (Billing → Add credit)、 操作をリトライしてください。すでに進行中の操作は、チャージ後に自動的に継続されます。

サーバーエラー (5xx)

500 はリクエストを処理できなかったことを意味します。バックオフ付きで リトライ — idempotency_key があれば、元のリクエストが部分的に成功 していても二重課金になりません。

リトライが 1 分以内に回復しない場合、バイヤーには「一時的に決済が 利用できません」と一般的なメッセージを表示し、失敗したエンドポイント、 マーチャント ID、レスポンスの Date ヘッダーと X-RateLimit-* の値、 おおよそのリクエスト時刻を添えてサポートにご連絡ください — それで 該当リクエストを特定できます。

Webhook 配信エラー

Webhook 配信は別の失敗チャネルです — あなたのサーバーが呼び出し側 ではないため、API エラーとしては表面化しません。配信が non-2xx を 返す (またはタイムアウトする) と、0s、1min、5min、15min、1h、6h の 指数バックオフでリトライされます (合計 6 回 — Webhook → 概要 と同じスケジュール)。配信単位の完全な 履歴は、ダッシュボードの Developers → Webhooks → [endpoint] → Delivery log に表示されます。6 回目の試行後、配信はダッシュボードで 「Failed」と表示され、サーバーが正常化した後に手動で再生できます。