CryptoPayIn
開発者向けドキュメント

決済をオンチェーンで完了させる仕組みを構築。

決済の作成から、顧客をホスト型チェックアウトへ案内し、承認状況を追跡し、本番環境で署名付きWebhookを処理するまで、必要な情報をすべて網羅しています。

APIベースURLバージョン1
https://cryptopayin.com/v1
プロトコルREST / JSON
認証Bearerシークレット
モード本番のみ
イントロダクション

1つのAPI、1つのホスト型フロー

CryptoPayInは、選択された表示通貨で注文の価格を決定し、検証済みの法定通貨/USDおよび暗号資産/USDのスナップショットを確定し、専用の入金アドレスを割り当てたうえで、自社のブロックチェーンノードで入金を監視します。内部会計・手数料・残高は常にUSD建てです。バックエンドにはチェックアウトURLが即座に返され、その後は署名付きのライフサイクルイベントが送信されます。

ベースURL/v1
法定通貨の金額ISO補助単位
暗号資産の値10進数文字列
デフォルトの有効期限30分
!

これは本番APIです。サンドボックス用のプレフィックスはありません。作成に成功するたびに、実際のオンチェーンアドレスが割り当てられます。エンドツーエンドのテストには対応通貨の少額を使用し、シークレットキーは必ずサーバー側で保管してください。

統合の全体像

1キーを作成

ダッシュボード → 開発者向けで一度だけシークレットを生成します。

2決済を作成

注文の通貨・金額・選択したアセットをPOSTします。

3チェックアウトを開く

返されたホスト型URLへお客様を案内します。

4イベントを処理

HMACを検証し、注文を冪等に更新します。

はじめに

最初の決済を作成する

加盟店ダッシュボードでAPIキーを生成し、シークレットを環境変数に保存したうえで、バックエンドから決済を作成します。この例ではETHを使用しているため、トークンのネットワークを選択せずにテストできます。

curl --request POST https://cryptopayin.com/v1/payments \
  --header "Authorization: Bearer $CPI_SECRET_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: order_1042" \
  --data '{
    "amount": 49.99,
    "currency": "USD",
    "asset": "ETH",
    "order_ref": "order_1042",
    "redirect_url": "https://shop.example/orders/1042/paid"
  }'

レスポンスを利用する

決済のidを注文情報とあわせて保存し、その後お客様をcheckout_urlへリダイレクトしてください。暗号資産の金額や入金アドレスを自分で計算しないでください。

{
  "id": "P-9F27C1E4KD",
  "object": "payment",
  "status": "created",
  "amount": 49.99,
  "amount_decimal": "49.99",
  "amount_minor": 4999,
  "currency": "USD",
  "currency_minor_units": 2,
  "amount_usd": 49.99,
  "amount_usd_cents": 4999,
  "fx_rate_usd": "1.000000000000",
  "fx_source": "fixed:USD",
  "fx_observed_at": "2026-07-17T13:00:00+00:00",
  "fx_discrepancy_bps": 0,
  "asset": "ETH",
  "network": "mainnet",
  "crypto_amount": "0.01388612",
  "crypto_received": "0",
  "deposit_address": "0x71b8c3d4700000000000000000000000000084e2",
  "exchange_rate": "3600.00000000",
  "exchange_rate_currency": "USD",
  "exchange_rate_source": "median:cb,cg,cl",
  "exchange_rate_source_count": 3,
  "exchange_rate_observed_at": "2026-07-17T13:00:00+00:00",
  "exchange_rate_discrepancy_bps": 12,
  "confirmations": 0,
  "confirmations_required": 12,
  "order_ref": "order_1042",
  "checkout_url": "https://cryptopayin.com/i/P-9F27C1E4KD",
  "expires_at": "2026-07-17T13:30:00+00:00",
  "created_at": "2026-07-17T13:00:00+00:00",
  "completed_at": null
}
認証情報

認証

すべてのAPIリクエストは、HTTPのBearerヘッダーにシークレットキーを付与して認証します。シークレットキーはcsk_live_で始まります。対になるcpk_live_の値はダッシュボード用の公開識別子であり、Bearer認証情報として使用してはいけません。

AUTHAuthorization: Bearer csk_live_...すべてのエンドポイント
表示は一度きり

生のシークレットが返されるのは、キー作成時の一度だけです。CryptoPayInはパスワードハッシュとインデックス付きSHA-256ルックアップのみを保存し、平文のシークレットは保存しません。

独立したキー

アプリケーションや環境ごとに個別のキーを作成し、それぞれを独立して失効させることができます。1つのアカウントにつき、有効なキーは最大50個まで保持できます。

サーバーサイド限定

csk_live_の値は、ブラウザのJavaScript、モバイルアプリのバイナリ、公開リポジトリ、チェックアウトページのいずれにも絶対に含めないでください。

Webhookのスコープ

Webhookエンドポイントはアカウント全体に紐づけることも、特定のAPIキー1つに紐づけることもでき、統合ごとに分離できます。

i

シークレットが未指定・形式不正・失効済み・不明のいずれかである場合は401 unauthorizedが返されます。停止または解約済みの加盟店アカウントも同様に拒否されます。有効なキーであっても、付与された権限の範囲外で使用された場合は403 insufficient_scopeが返されます。

安全な再試行

冪等性

決済を作成するたびに、一意のIdempotency-Keyを送信してください。送信後に接続が切れた場合は、同一のJSONを同一のキーで再送してください。CryptoPayInは新たなアドレスを割り当てる代わりに、最初の決済をそのまま返します。

ケース結果HTTP
初回利用新しい決済を作成して返します。201
同じキー+同じJSONIdempotent-Replayed: trueとともに、既存の決済を返します。200
同じキー+異なるJSONidempotency_conflictとしてリクエストを拒否します。409

キーはAPI認証情報単位でスコープされ、半角の英字・数字・ピリオド・アンダースコア・コロン・ハイフンを1-128文字含めることができます。永続的な注文UUIDを使うとよいでしょう。同じ仕組みは出金も保護しており、再試行された出金が資金を二重に移動させることはありません。

REST API

APIリファレンス

このAPIは、決済・決済リンク・ショップ・商品・残高・出金をカバーしています。レスポンスはHTTPS上のUTF-8 JSONで返され、作成・更新にはいずれもContent-Type: application/jsonが必要です。更新系の操作は、呼び出し元キーの権限によって制御されます。ブラウザ向けのCORSワークフローは意図的に提供していません。呼び出しはバックエンドから行ってください。

GET/v1/assets利用可能なアセットを確認
GET/v1/currencies表示可能な法定通貨を確認
POST/v1/payments決済を作成
GET/v1/payments決済の一覧・絞り込み
GET/v1/payments/{id}決済を取得
i

バージョン1には、後方互換性のあるフィールドやエンドポイントが追加される場合があります。互換性を破る変更を行う場合は、/v1を黙って変更するのではなく、新しいベースパスを使用します。

APIリファレンス

アセット一覧を取得

GET/v1/assetsBearer認証が必要

チェックアウトで選択肢を決める際は、このエンドポイントを正とみなしてください。有効なカタログ項目、現在の独立検証済みレート、USD換算の最低金額、およびノードと価格フィードの準備状況を返します。ノードが同期中であったり価格を検証できない場合でも、項目はavailable: falseのまま一覧に残ることがあります。

curl https://cryptopayin.com/v1/assets \
  --header "Authorization: Bearer $CPI_SECRET_KEY"
{
  "object": "list",
  "data": [{
    "asset": "USDT",
    "network": "TRC20",
    "type": "token",
    "decimals": 6,
    "minimum_amount": 1,
    "currency": "USD",
    "base_confirmations": 19,
    "available": true,
    "rate_usd": "1.00000000",
    "rate_source": "median:cb,cg,cl",
    "rate_source_count": 3,
    "rate_discrepancy_bps": 4,
    "rate_status": "healthy",
    "rate_updated_at": "2026-07-17T13:00:00+00:00"
  }]
}

カタログとネットワーク識別子

アセットネットワーク値省略形基本承認数
BTCmainnetBTC2
ETHmainnetETH6
USDTTRC20 / ERC20USDT.TRC2019 / 6
USDCERC20USDC.ERC206
DAIERC20DAI6
SHIBERC20SHIB6
PEPEERC20PEPE6
LTCmainnetLTC6
TRXmainnetTRX19
DOGEmainnetDOGE20
XMRmainnetXMR10
SOLmainnetSOL32
!

対応状況は常に変動します。上記の表を、そのまま有効な許可リストとしてハードコードしないでください。USDTのように複数ネットワークにまたがるシンボルについては、networkを明示的に送信するか、ASSET.NETWORKの省略形を使用してください。

APIリファレンス

法定通貨一覧を取得

GET/v1/currenciesBearer認証が必要

有効な表示通貨、そのISO精度、および現在のUSD換算の健全性を返します。available: trueが付いた行のみを提示してください。USDは基軸通貨として内在的に扱われますが、それ以外の通貨はすべて、最新のライブレートと独立した参照チェックが必要です。minimum_amountは、設定済みの有効アセットのうち最も低い下限額をその通貨に換算した値です。選択したアセットによってはより高い金額が必要になる場合があるため、必ずGET /v1/assetsもあわせて確認してください。

curl https://cryptopayin.com/v1/currencies \
  --header "Authorization: Bearer $CPI_SECRET_KEY"
{
  "object": "list",
  "accounting_currency": "USD",
  "data": [{
    "currency": "EUR",
    "name": "Euro",
    "symbol": "€",
    "minor_units": 2,
    "available": true,
    "minimum_amount": "0.86",
    "rate_usd": "1.160000000000",
    "rate_source": "coinbase+ecb",
    "rate_source_count": 2,
    "rate_discrepancy_bps": 18,
    "rate_updated_at": "2026-07-17T13:00:00+00:00",
    "rate_reference_at": "2026-07-16T00:00:00+00:00"
  }]
}
i

後方互換性のため、POST /v1/paymentsでcurrencyを省略した場合もUSDを意味します。JPYのような小数点のない通貨では、端数のある金額は拒否されます。カタログの最低金額やレートは常にライブデータとして扱い、固定値としてハードコードしないでください。

APIリファレンス

決済を作成

POST/v1/payments120リクエスト/分/キー

指定された表示通貨で請求書を作成し、検証済みの最新の法定通貨/USDおよび暗号資産/USDのスナップショットを確定したうえで、正確な暗号資産の金額を計算し、専用のオンチェーン入金アドレスを紐づけます。

リクエストボディ

フィールド必須/任意説明
amount数値または10進数文字列必須currencyでの金額を、その通貨のISO精度で指定します。ロックされたUSD換算額は$1,000,000.00を超えることはできません。アセットごとの最低金額も適用されます。
currency文字列任意GET /v1/currenciesに含まれる、有効な3文字の通貨コード。デフォルトはUSDです。
asset文字列必須ETHのようなシンボル、またはUSDT.TRC20のような省略形を指定します。
network文字列条件付きシンボルが複数のネットワークに存在する場合に必須です。例:ERC20
order_ref文字列任意貴社側の注文識別子(最大128文字)。APIレスポンスおよびイベントに含めて返されます。
customer_email文字列任意有効なメールアドレス(最大190文字)。加盟店の決済レコードとともに保存されます。
redirect_url文字列任意HTTPSのURL(最大255文字)。チェックアウト完了後に提示されます。

レスポンスフィールド

フィールド説明
id文字列P-で始まる、不変の決済識別子。
status文字列現在のライフサイクル状態。
amount / amount_decimal / amount_minor数値 / 文字列 / 整数要求された表示金額を、扱いやすい数値・正確な10進数・ISO補助単位の3形式で表します。
currency / currency_minor_units文字列 / 整数確定した表示通貨とその精度。
amount_usd / amount_usd_cents数値 / 整数内部会計用の、変更不可なUSD建て金額。
fx_rate_usd / fx_source / fx_observed_at10進数文字列 / 文字列 / ISO 8601表示通貨1単位あたりのUSDレートを確定したスナップショットと、その監査用メタデータ。
asset / network文字列解決済みのオンチェーンアセット。
crypto_amount10進数文字列お客様が送金すべき正確な金額。暗号資産の小数値をバイナリの浮動小数点数として扱わないでください。
crypto_received10進数文字列現時点で入金アドレスに着金が確認されている合計額。
deposit_address文字列この決済のために割り当てられた専用アドレス。
exchange_rate10進数文字列crypto_amountの計算に使用された、確定済みの暗号資産/USDレート。このフィールドはv1当初の意味のまま維持されます。
exchange_rate_source / exchange_rate_observed_at文字列 / ISO 8601変更不可な、暗号資産レートの監査用スナップショット。
confirmations整数現在のネットワーク承認数。
confirmations_required整数この決済に必要な承認数のしきい値。USD建て金額が高いほど、追加の承認が必要になる場合があります。
checkout_urlURLお客様に提示する、ホスト型の請求書ページ。
expires_atISO 8601未払いの請求書の期限。
completed_atISO 8601 / null決済完了時の、最終的な決済確定日時。

作成の前に、2つのライブ換算レートについて、鮮度・情報源の数・乖離幅が検証されます。検証に失敗した場合、古いレートを使う代わりにエラーを返して作成を中止します。暗号資産の金額はアセットの実用的な精度で切り上げられるため、端数処理によって加盟店側が不足することはありません。

APIリファレンス

決済一覧を取得

GET/v1/payments240リクエスト/分/キー

認証された加盟店アカウントの決済を、新しい順に返します。突合作業にはカーソルページネーションを使用し、履歴全体を辿ることなく特定の注文を見つけるには、正確な絞り込み条件を使用してください。

クエリパラメータ

パラメータデフォルト説明
limit201〜100の範囲で指定するページサイズ。
starting_after前ページのnext_cursorとして返された決済ID。
statuspendingcompletedexpiredのような、厳密なライフサイクルステータス。
order_ref加盟店側の厳密な注文参照(最大128文字)。
curl "https://cryptopayin.com/v1/payments?status=completed&limit=20" \
  --header "Authorization: Bearer $CPI_SECRET_KEY"
{
  "object": "list",
  "data": [{
    "id": "P-9F27C1E4KD",
    "object": "payment",
    "status": "completed",
    "amount": 49.99,
    "currency": "USD",
    "asset": "ETH",
    "network": "mainnet",
    "crypto_amount": "0.01388612",
    "crypto_received": "0.01388612",
    "order_ref": "order_1042",
    "confirmations": 12,
    "confirmations_required": 12,
    "completed_at": "2026-07-17T13:12:42+00:00"
  }],
  "has_more": true,
  "next_cursor": "P-9F27C1E4KD"
}
i

has_moreがtrueの場合は、next_cursorをそのままstarting_afterとして渡してください。未知の、または重複した配列形式のクエリパラメータは、無視されるのではなく拒否されます。

APIリファレンス

決済を取得

GET/v1/payments/{id}240リクエスト/分/キー

作成時と同じ決済オブジェクトを、最新のステータス・着金額・トランザクションハッシュ・承認数とともに返します。キーは、自身の加盟店アカウントに属する決済のみを取得できます。

curl https://cryptopayin.com/v1/payments/P-9F27C1E4KD \
  --header "Authorization: Bearer $CPI_SECRET_KEY"
i

通常の注文更新はWebhookで駆動するようにしてください。タイムアウト後の突合、イベントの検証、バックエンドのステータスページ表示、配信漏れの復旧には、この取得エンドポイントを使用します。

状態モデル

決済のライフサイクル

常にAPIのステータスを正とみなしてください。ブラウザのリダイレクトや、お客様の「支払った」という申告から完了を推測しないでください。

created->pending->underpaidまたはconfirming->completed/overpaid
ステータス意味加盟店側の対応
created請求書とアドレスが割り当てられた状態。まだ入金は検出されていません。ホスト型チェックアウトを表示します。
pending利用可能なオンチェーン入金を待っている状態。注文をオープンのまま維持します。
underpaid加盟店の許容範囲を下回る金額が着金した状態。表示されている残額を送金するよう、支払人に依頼します。
confirming十分な金額が検出され、承認を待っている状態。まだ商品・サービスを提供しないでください。
completed必要な金額と承認数の両方に達した状態。1回だけ確実に商品・サービスを提供します。
overpaid想定より多い金額が承認された状態。商品・サービスを提供したうえで、超過分を確認します。
expired有効期限までに条件を満たす入金が検出されなかった状態。新しい決済を作成します。
failedアドレス割り当てまたは処理に失敗した状態。エラーを記録し、新しい決済を作成します。
!

オンチェーンの送金は取り消しができず、CryptoPayInには返金の仕組みがありません — 承認された決済は最終的なものです。任意の返金対応が必要な場合は、プラットフォームの外で、貴社とお客様の間で直接行ってください。

顧客体験

ホスト型チェックアウト

APIで作成された各決済には、レスポンシブ対応のcheckout_urlが含まれます。加盟店名、要求された表示金額、該当する場合はロックされたUSD換算額、正確な暗号資産の金額、入金アドレス、QRコード、ネットワークに関する注意事項、カウントダウン、リアルタイムの承認進捗が表示されます。

レートを固定

お客様には、その請求書の有効期間中、APIが返したものと同じcrypto_amountが表示されます。

顧客アカウント不要

支払人はCryptoPayInのアカウントを作成したり、認証情報を共有したりする必要はありません。

リアルタイムステータス

ページは安全に決済状況をポーリングし、「待機中」から「承認中」、そして「支払い完了」へと状態を更新します。

加盟店へのリダイレクト

成功後にはHTTPSのredirect_urlが提示されますが、これは支払いの証明にはなりません。

i

商品・サービスの提供判断は必ずバックエンドで行ってください。ブラウザの遷移は中断・繰り返し・偽装が可能であり、決済状態を証明できるのは検証済みのWebhookか、認証付きのGETリクエストのみです。

認証情報

権限とスコープ

各APIキーには、ダッシュボード → 開発者向けで作成する際に選択した、固定の権限セットが付与されます。すべてのエンドポイントは、処理を行う前にキーのスコープを確認します。キーに付与された範囲外の呼び出しには、不足している権限名を記載したX-Required-Scopeヘッダーとともに403 insufficient_scopeが返されます。スコープは作成時に一度だけ設定され、後から拡張することはできません — 拡張が必要な場合は新しいキーを発行してください。スコープが存在する前に作成されたキーは、元の権限(payments:readpayments:write)をそのまま維持します。

スコープ付与される権限エンドポイント
payments:read決済の一覧取得・取得GET /v1/payments, GET /v1/payments/{id}
payments:writeホスト型決済の作成POST /v1/payments
links:read決済リンクの一覧取得・取得GET /v1/links, GET /v1/links/{id}
links:write決済リンクの作成・編集・一時停止・削除POST/PATCH/DELETE /v1/links
shops:readショップおよびその商品の一覧取得・取得GET /v1/shops, GET .../products
shops:writeショップ・商品・バリエーションの作成・編集POST/PATCH/DELETE /v1/shops および商品
balance:read暗号資産残高とUSD概算額の参照GET /v1/balance
payouts:read出金の一覧取得・取得GET /v1/payouts, GET /v1/payouts/{id}
payouts:writeオンチェーン出金のリクエストPOST /v1/payouts
!

payouts:writeはオンチェーンで資金を移動させる、取り消し不能な操作です。完全に信頼できるキーにのみ付与し、それらのキーは必ずサーバーサイドで保管し、自動化された処理ごとに専用のキーを用意することをおすすめします。GET /v1/accountでは、呼び出し元キーのスコープとアカウントの上限を確認できます。

自動購入

エージェント決済

有効な決済リンクはすべて、機械可読なチェックアウトとしても機能します。AIエージェントや任意のスクリプトは、ブラウザなしで — さらにAPIキーすら不要で — それを検出し、請求書を作成し、配信内容を読み取ることができます。これらはリンクドメイン上の公開の購入者向けエンドポイントであり、加盟店向けのエンドポイントではないためです。完全な仕様と実例はcryptopayin.com/agentsをご覧ください。

GEThttps://cryptopaylink.co/pay/{link}.json公開 · 検出

状態、価格、対応アセット、そして請求書作成呼び出しの正確な入力仕様(必須フィールド、配送先スキーマ、バリエーション)を返します。

POSThttps://cryptopaylink.co/pay/{link}/invoice公開 · Idempotency-Key対応

ホスト型ページと同じコアロジック・価格スナップショット・不正利用防止の制限を通じて請求書を作成し、入金アドレス・正確な暗号資産金額・ウォレットURI・領収書URLを返します。その後、エージェントは自身が管理する任意のウォレットからオンチェーンで支払いを行います。

GEThttps://cryptopaylink.co/pay/{link}/receipt?p={payment}公開 · 5〜10秒ごとにポーリング

リアルタイムのステータスと承認数を返します。決済が完了すると、レスポンスにはその決済向けに確保された配信内容 — テキストコンテンツ、非公開URL、またはライセンスキー — に加え、成功メッセージとリダイレクトURLが含まれます。

ショップも同じプロトコルを話す

ストアフロントも、自身のドメイン上でまったく同じフローを提供します。リアルタイムの在庫状況を含むカタログを提示したうえで、カートを検証し、在庫を確保し、請求書を返す単一の呼び出しを行います。

GEThttps://shopycrypto.com/s/{shop}.json公開 · カタログ
POSThttps://shopycrypto.com/s/{shop}/order公開 · カート→請求書、Idempotency-Key対応
GEThttps://shopycrypto.com/s/{shop}/o/{order}/receipt?p={payment}公開 · 5〜10秒ごとにポーリング

販売者側の制御

エージェント決済はデフォルトで有効になっており、料金は同じ1%固定です。ダッシュボード → 設定 → 一般 → AI・エージェント決済から、アカウント全体で無効にできます。無効にすると、リンクおよびショップのマシン向けエンドポイントは403 agents_disabledを返すようになりますが、人間向けのチェックアウトページはそのまま機能し続けます。エージェントが作成した決済に特別なフラグは付きません — ダッシュボード・Webhook・エクスポートにおいて、通常の決済として扱われます。

加盟店向けリソース

ショップ

複数の商品を1つのブランドページにまとめる、ホスト型のストアフロントです。1つのアカウントにつき、ショップは最大10件まで保持できます。商品は、以下のネストされた商品エンドポイントを通じて管理します。

GET/v1/shopsshops:read
POST/v1/shopsshops:write
GET/v1/shops/{id}shops:read
PATCH/v1/shops/{id}shops:write
DELETE/v1/shops/{id}shops:write

リクエストボディ

フィールド必須/任意説明
name文字列必須2–80文字。
tagline文字列任意最大160文字。
theme文字列任意light(デフォルト)、またはdark
accent文字列任意GET /v1/shopsaccent_paletteとして返される、ショップのパレットに含まれるアクセントカラー(16進数)。
accepted_assets文字列の配列任意ショップの商品に対するデフォルトのアセット(例:["BTC","LTC","XMR"])。変更するとすべての商品に適用されます。
status文字列任意PATCHの場合のみ:activeまたはpaused
i

ポリシー上の理由でCryptoPayInにより無効化されたショップは、APIを通じて再有効化・削除することができず、admin_disabled(403)が返されます。ショップを削除するとその商品も削除されますが、過去の決済には影響しません。

加盟店向けリソース

商品とバリエーション

商品はショップの中に存在します。1つのショップにつき、商品は最大50件まで保持できます。商品はデジタル(即時配信あり)または物理(配送先国あり)のいずれかで、1–3個のオプショングループから構成される、最大30通りのバリエーションの組み合わせを持てます。

GET/v1/shops/{shop}/productsshops:read
POST/v1/shops/{shop}/productsshops:write
GET/v1/shops/{shop}/products/{id}shops:read
PATCH/v1/shops/{shop}/products/{id}shops:write
DELETE/v1/shops/{shop}/products/{id}shops:write

リクエストボディ

フィールド必須/任意説明
title文字列必須3–120文字。
description / blurb文字列任意詳細な説明文と、≤200文字のショップカード用の紹介文。
emoji文字列任意商品カードに表示される絵文字1つ。
featured真偽値任意1つのショップにつき、おすすめ商品として設定できるのは最大1件です。
product_type文字列任意digital(デフォルト)、またはphysical
shipping_countries文字列の配列条件付き物理商品の場合のみ:["FR","BE"]のようなISOコード、または全世界を対象とする場合は["*"]
amount_type / currency / amount / min / max複合条件付き基本価格設定で、決済リンクと同一のルールが適用されます。物理商品ではfixedである必要があります。
max_uses整数任意総販売数の上限(0は無制限を意味します)。
delivery_type + delivery_text/url/keys複合任意基本商品のデジタル配信設定で、決済リンクと同じ形式です。
variant_options配列任意{name, values[]}形式で1–3個のグループ、各グループ2–10個の値。組み合わせ数は30を超えてはいけません。
variants配列条件付き組み合わせごとに1オブジェクト(詳細は下記)。variant_optionsが指定されている場合は必須で、全組み合わせを網羅する必要があります。
status文字列任意PATCHの場合のみ:activeまたはpaused

バリエーションオブジェクト

フィールド説明
options文字列の配列オプショングループごとに1つの値を、グループの順序どおりに指定します(例:["Pro","Lifetime"])。
price数値または文字列商品の通貨建てでの、バリエーションの価格。
stock整数またはnull残り在庫数。無制限の場合はnullを指定します。
delivery_type + delivery_text/url/keys複合バリエーションごとのデジタル配信設定の上書き(省略可、デフォルトはinherit)。キーは商品全体を通じて一意である必要があります。
curl -X POST https://cryptopayin.com/v1/shops/SH-JYRK8TFJ/products \
  -H "Authorization: Bearer $CPI_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Software license",
    "amount": 30,
    "currency": "USD",
    "variant_options": [
      {"name": "Edition", "values": ["Standard", "Pro"]},
      {"name": "Term", "values": ["1 year", "Lifetime"]}
    ],
    "variants": [
      {"options": ["Standard","1 year"], "price": 30, "delivery_type": "keys", "delivery_keys": ["S1Y-1"]},
      {"options": ["Standard","Lifetime"], "price": 79, "stock": 10, "delivery_type": "keys", "delivery_keys": ["SLT-1"]},
      {"options": ["Pro","1 year"], "price": 59, "delivery_type": "keys", "delivery_keys": ["P1Y-1"]},
      {"options": ["Pro","Lifetime"], "price": 149, "stock": 5, "delivery_type": "keys", "delivery_keys": ["PLT-1"]}
    ]
  }'
i

PATCHは、既存の注文や配信済みのキーをそのまま維持します。価格や在庫を調整するには、対応するvariants配列を再送してください。省略した組み合わせは、注文があれば一時停止となり、なければ削除されます。商品は、基本商品とバリエーションを合わせて最大10,000件の有効なライセンスキーを保持でき、キーは商品内で一意である必要があります。

加盟店向けリソース

残高

GET/v1/balancebalance:read

アセットごとに確定済みの暗号資産残高を、ベストエフォートのUSD概算額および出金時に課されるネットワーク手数料とともに返します。内部会計は常にUSD建てで行われ、残高は加盟店手数料を差し引いた、完了済み決済から積み上がります。

{
  "object": "list",
  "accounting_currency": "USD",
  "minimum_payout_usd": 25,
  "data": [{
    "asset": "USDT",
    "network": "TRC20",
    "amount": "99.099",
    "usd_estimate": 99.02,
    "payout_network_fee": "2.445463"
  }]
}
i

検証済みのライブレートが一時的に取得できない場合、usd_estimatenullになりますが、残高そのものは正確です。これらの値は出金の判断に使用し、最終的な会計には使用しないでください。

加盟店向けリソース

出金

確定済みの暗号資産を外部ウォレットへ移動します。出金は取り消しができないため、このエンドポイントはダッシュボードと同じすべての安全策を適用します:アセットに対して有効な送金先、検証済みのライブレート、アカウントの最低金額、ネットワーク手数料を含めた十分な残高、そしてアカウントで2FAが有効な場合の二要素認証です。

GET/v1/payoutspayouts:read
POST/v1/payoutspayouts:write · 30リクエスト/分/キー
GET/v1/payouts/{id}payouts:read

リクエストボディ

フィールド必須/任意説明
asset文字列必須シンボルまたは省略形(例:LTCまたはUSDT.TRC20)。
network文字列条件付きシンボルが複数のネットワークに存在する場合に必須です。
amount数値または文字列必須送金する金額(ネットワーク手数料を除く)を、アセットの精度で指定します。USD換算額はアカウントの最低金額を満たす必要があります。
address文字列必須送金先アドレス。アセットのチェーンに対して検証されます。
note文字列任意貴社側の任意の参照情報(最大255文字)。
totp_code文字列条件付き現在の6桁コード、またはリカバリーコード。アカウントで2FAが有効な場合に必須です。
curl -X POST https://cryptopayin.com/v1/payouts \
  -H "Authorization: Bearer $CPI_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: withdraw-2026-07-19-01" \
  -d '{
    "asset": "USDT.TRC20",
    "amount": "50",
    "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
    "note": "weekly settlement"
  }'
{
  "id": "W-EM64ZCJB",
  "object": "payout",
  "status": "requested",
  "asset": "USDT",
  "network": "TRC20",
  "amount": "50",
  "fee": "2.445463",
  "total_debited": "52.445463",
  "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
  "txid": null,
  "confirmations": 0,
  "created_at": "2026-07-19T19:10:00+00:00"
}

ステータスのライフサイクル

ステータス意味
requested残高から確保された状態。運営側のレビュー、または自動承認を待っています。
approved / processing承認済みで、実行エンジンによるブロードキャストの待機列に入っています。
sentオンチェーンにブロードキャスト済みで、txidが設定されています。
confirmed必要な承認数に到達した、最終状態。
failed送金できなかった状態。理由はfailure_messageに記載され、残高は返却されます。
cancelledブロードキャスト前にキャンセルされた状態。確保されていた残高は返却されます。

Idempotency-Keyを送信することで、ネットワークの再試行によって出金が二重に作成されることはなくなります。同じキーで同じボディを送信した場合は、元の出金(Idempotent-Replayed: true)が返されます。同じキーで異なるボディを送信した場合は409 idempotency_conflictが返されます。2FAコードは、ローテーションによって誤った競合を引き起こさないよう、意図的に冪等性のフィンガープリントから除外されています。予約と同時に残高は即座に引き落とされ、出金が失敗またはキャンセルされた場合は返却されます。

加盟店向けリソース

アカウント

GET/v1/account有効な任意のキー

アカウントプロフィール、呼び出し元キーのスコープ、プラットフォーム手数料、そしてすべての現行の上限値を返します — 自己設定型の統合や事前チェックに役立ちます。

{
  "object": "account",
  "id": "MC67T3PHQZ",
  "fee_bps": 100,
  "fee_percent": 1,
  "default_currency": "USD",
  "two_factor_enabled": false,
  "api_key": {"label": "production", "scopes": ["payments:read","payments:write"]},
  "limits": {
    "shops": {"used": 1, "max": 10},
    "payment_links": {"used": 0, "max": 50},
    "products_per_shop_max": 50,
    "variant_combinations_per_product_max": 30,
    "license_keys_per_product_max": 10000,
    "active_api_keys_max": 50,
    "checkout_fields_per_link_max": 5
  },
  "minimum_payout_usd": 25
}
サーバー間イベント

Webhook

ダッシュボード → 開発者向けから、公開HTTPSエンドポイントを最大10件登録できます。各エンドポイントには、一度だけ表示される専用のwhsec_...署名シークレットが発行されます。アカウント全体を対象にすることも、特定の有効なAPIキーに紐づけることもでき、キーに紐づいたエンドポイントは、そのキーで作成された決済のみを受信します。

パース前に検証する

CryptoPayInは、エンドポイントのシークレットを使って、生のリクエストボディそのものに署名します。バージョン1ではtimestamp + "." + raw_bodyに署名します。イベントを受理する前に、古いタイムスタンプは必ず拒否してください。

import crypto from "node:crypto";

const timestamp = req.headers["x-cpi-timestamp"];
const signature = req.headers["x-cpi-signature"];
const rawBody = req.rawBody; // Buffer captured before JSON parsing

if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) {
  throw new Error("stale webhook");
}
const expected = "sha256=" + crypto
  .createHmac("sha256", process.env.CPI_WEBHOOK_SECRET)
  .update(Buffer.concat([Buffer.from(`${timestamp}.`), rawBody]))
  .digest("hex");
const valid = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
if (!valid) throw new Error("invalid webhook signature");

配信ヘッダー

ヘッダー用途
Content-Typeapplication/jsonUTF-8のJSON本文。
X-CPI-Timestamp1784293200署名対象メッセージに含まれる、Unix秒。
X-CPI-Signaturesha256=...16進数表記のHMAC-SHA256。
X-CPI-Signature-Versionv1署名方式のバージョン。
X-CPI-Event-Idevt_a12b...不変の論理イベントID。再試行時も同一です。
X-CPI-Delivery-Id1842不変の、エンドポイント配信レコードID。

決済のペイロード

{
  "event_id": "evt_a12b34c56d78e90f12345678",
  "event": "payment.completed",
  "id": "P-9F27C1E4KD",
  "status": "completed",
  "order_ref": "order_1042",
  "amount": 49.99,
  "amount_decimal": "49.99",
  "amount_minor": 4999,
  "currency_minor_units": 2,
  "currency": "USD",
  "amount_usd": 49.99,
  "amount_usd_cents": 4999,
  "fx_rate_usd": "1.000000000000",
  "fx_source": "fixed:USD",
  "fx_observed_at": "2026-07-17T13:00:00Z",
  "fx_discrepancy_bps": 0,
  "exchange_rate": "3600.00000000",
  "exchange_rate_currency": "USD",
  "exchange_rate_source": "median:cb,cg,cl",
  "exchange_rate_source_count": 3,
  "exchange_rate_observed_at": "2026-07-17T13:00:00Z",
  "exchange_rate_discrepancy_bps": 12,
  "asset": "ETH",
  "network": "mainnet",
  "crypto_amount": "0.01388612",
  "crypto_received": "0.01388612",
  "txid": "0x9d81...75af",
  "confirmations": 12,
  "confirmations_required": 12,
  "deposit_address": "0x71b8c3d4700000000000000000000000000084e2",
  "sent_at": "2026-07-17T13:12:42Z"
}

再試行とエンドポイントの安全性

2xx系のステータスを返す

配信はHTTP 200-299で成功と判定されます。重い処理は非同期に行い、応答は素早く返してください。

最大6回の試行

リクエストボディとイベントIDはそのまま保持され、失敗した場合はおよそ1分後、5分後、30分後、2時間後、6時間後に再試行されます。

リダイレクトなし

3xxのレスポンスは追跡されません。最終的なHTTPS URLを直接登録してください。

パブリックな宛先のみ

プライベートIP・ループバックIP・リンクローカルIP・予約IPへの配信はブロックされます。すべてのDNS応答は検証され、接続はピン留めされます。

!

配信は少なくとも1回(at-least-once)行われます。提供処理の前に、event_idを一意制約付きで記録することで、ハンドラーを冪等にしてください。想定外のイベントを突合する際は、APIオブジェクトを取得してください。

Webhook

イベントリファレンス

payment.completed想定額が承認されました。
payment.overpaid想定を上回る金額が承認されました。
payment.underpaid許容範囲を下回る入金を検出しました。
payment.expired未払いの請求書の有効期間が終了しました。
payment.failed決済の設定または処理に失敗しました。
payout.sent出金がオンチェーンにブロードキャストされました。
payout.confirmed出金が必要な承認数に達しました。
payout.failed出金を完了できませんでした。
webhook.test手動での接続テスト。

出金イベントの形式

{
  "event_id": "evt_b98c76d54e32a10f87654321",
  "event": "payout.sent",
  "id": "W-8J2K7M4RQP",
  "status": "sent",
  "asset": "ETH",
  "network": "mainnet",
  "amount": "0.25",
  "fee": "0.00081768",
  "address": "0x84f2...9bc1",
  "txid": "0xa1c4...07ee",
  "confirmations": 0,
  "note": "weekly treasury",
  "sent_at": "2026-07-17T14:08:31Z"
}
信頼性

エラーとレート制限

エラーは常に単一のJSON形式で返されます。分岐処理はerror.typeに基づいて行ってください。人が読むためのメッセージは、バージョンを変更せずに改善される場合があります。サポートに問い合わせる際は、error.request_idまたは対応するX-Request-Idレスポンスヘッダーを明記してください。

{
  "error": {
    "type": "ambiguous_asset",
    "message": "specify network (e.g. USDT.ERC20 or USDT.TRC20)",
    "request_id": "b942e21f8dca4b06b8672eb9"
  }
}
HTTP代表的なtype意味
400invalid_request, unknown_parameterJSON・クエリ・冪等性ヘッダーのいずれかの形式が不正です。
401unauthorized認証情報またはアカウントが未指定・無効・非アクティブのいずれかです。
403insufficient_scope, admin_disabled有効なキーに必要な権限がない場合(X-Required-Scopeを参照)、または管理者によってロックされたリソースです。
404not_found不明なエンドポイント、またはこの加盟店アカウントの範囲外のリソースです。
405method_not_allowedAllowヘッダーに示されたメソッドを使用してください。
409idempotency_conflict同じキーが異なるJSONで再利用されました。
413request_too_largeJSON本文が64 KiBを超えています。
415unsupported_media_typePOST本文がapplication/jsonとして宣言されていません。
422invalid, limit, invalid_amount, below_minimum, bad_address, 2fa_required, unsupported_asset形式は正しいリクエストが、決定的なバリデーションに失敗したか、リソースの上限に達しました。
429rate_limitedRetry-Afterだけ待機してください。
500server_error予期しない失敗です。同じ冪等性キーで安全に再試行してください。
503maintenance, temporarily_unavailable, asset_unavailable, no_rate, price_stale, fiat_rate_unavailable, fiat_rate_stale, derive_failedプラットフォーム・ノード・価格・アドレス割り当てにおける一時的な障害です。古いレートで代替されることはありません。

現在の制限

対象上限期間
Nginxの IPごとの安全上限10リクエスト/秒、バースト30常時
未認証IPの上限300リクエスト60秒
POST /v1/payments, links, shops, productsAPIキーごとに120リクエスト60秒
POST /v1/payoutsAPIキーごとに30リクエスト60秒
GETエンドポイントAPIキーごとに240リクエスト60秒

アカウントの上限

リソース上限
アカウントごとのショップ数10
アカウントごとの決済リンク数50
ショップごとの商品数50
商品ごとのバリエーション組み合わせ数30
商品/リンクごとのライセンスキー数10,000
リンクごとのチェックアウト質問数5
アカウントごとの有効なAPIキー数50

これらの上限に対する現在の使用状況は、GET /v1/accountから確認できます。

成功したアプリケーションレベルの制限付きレスポンスには、X-RateLimit-LimitX-RateLimit-RemainingX-RateLimit-Resetが含まれます。429500503については、指数バックオフとジッターを用いて再試行してください。POSTの場合は、必ず元のIdempotency-Keyと同一のJSONを再利用してください。

本番環境の安全性

統合のセキュリティ

APIシークレットはシークレットマネージャーで管理する

実行時に読み込み、値全体をログに出力したり、ソース管理にコミットしたりしないでください。

APIはバックエンドから呼び出す

ブラウザやモバイルクライアントは、加盟店のシークレットを安全に保持できません。

Webhookの生の本文を検証する

JSONをパースする前に、タイムスタンプの鮮度を確認し、署名の比較には定数時間比較を使用してください。

提供処理を冪等にする

処理済みのイベント・注文をトランザクションとして記録し、再試行によって二重に提供されないようにしてください。

リダイレクトではなく、APIの最終状態を信頼する

想定外のイベントを受信した場合や、ローカルの状態と食い違う場合は、決済情報を取得してください。

重複期間を設けてローテーションする

新しいキーを作成してデプロイし、トラフィックを確認したうえで、古いキーを削除してください。

!

アカウントへのアクセスは、復旧不可能な16桁の加盟店キーによって制御され、任意でTOTPによる保護を追加できます。加盟店アクセス情報とAPIシークレットは、いずれもウォレットの認証情報と同等の注意を払って保管してください。

リリース

本番移行チェックリスト

1
本番専用のAPIキーを作成する

開発者個人用のキーを複数のサービスで使い回さないでください。

2
2つのライブカタログを両方とも参照する

GET /v1/assetsGET /v1/currenciesを使用し、存在しかつavailable: trueな項目のみを表示してください。

3
Webhookエンドポイントを追加してテストする

署名シークレットは一度だけ保存し、タイムスタンプと署名を検証したうえで、不変のイベントIDにより重複を排除してください。

4
すべての注文で冪等性キーを使用する

重複した再試行を実際に試し、決済IDが1つしか存在しないことを確認してください。

5
レート障害・過小支払い・有効期限切れをテストする

古い法定通貨レート、利用不可なアセット、承認の遅延など、あらゆる非正常系を通じて、注文の状態が安全に保たれることを確認してください。

6
毎日突合する

自社の注文と、APIの決済状態・Webhookログ・加盟店台帳を突き合わせてください。

統合を始める準備はできましたか?

数秒でアカウントを作成し、キーを生成して、このリファレンスをコードのそばに置いておきましょう。

アカウント作成