Merchant APIリファレンス
すべてのメソッドに共通する決まりと、読み取り専用のカタログ系メソッドをまとめます。 メソッドごとのページは請求書と返金、送金と送金リンク、サブスクリプション、Webhookです。
ここで説明するAPIメソッドは、Crypto Botの規則に沿っています。既存の実装ではベースURLとトークンを変更し、利用するメソッドをテストネットで確認してください。独自の追加機能は、以下で拡張と記します。
機械可読のOpenAPI 3.1仕様も公開しています。crypto-pay-openapi.yaml・crypto-pay-openapi.jsonです。 コードジェネレーター、APIクライアント、AIツールで利用できますが、新しい拡張がまだ反映されていない場合があるため、各メソッドのページも確認してください。
ベースURLと認証
すべてのメソッドはhttps://app.tgpaycrypto.com/pay/api/<methodName>にあります。
テストネットでは、ベースURLはhttps://testnet.tgpaycrypto.com/pay/apiです。アプリとトークンは別で、テスト用の暗号資産に金銭的価値はありません。
リクエストは必ず**TgPayCrypto-API-Token**ヘッダーのトークンで認証します(2026-09-07より前の名前であるTgCryptoPay-API-Tokenと、Crypto-Pay-API-Tokenも互換の別名として受け付けます。複数送られた場合は正式なほうが優先されます)。
トークンがない、無効、無効化済み、制限付きトークンの期限切れ、アプリが削除済み、または所有者がブロックされている場合は、401 unauthorizedが返ります。
トークンは<app_id>:<secret>という形で、作成時と再発行時に一度だけ表示されます。
サーバーはハッシュだけを保存します。開発者向けのはじめかたで説明しています。
トークンとスコープ
認証のしかたが同じ、2種類の資格情報があります。
- メイントークン:すべてのメソッドを呼べます。Webhookに署名できる鍵は、これだけです。
- 制限付きトークン(拡張):無効化していないトークンを、期限切れのものも含めてアプリごとに最大10個まで持てます。 その他 → Merchant APIでアプリを選び、アクセスとトークンを開きます。制限付きトークンから作成し、それぞれにラベルとスコープの組み合わせを設定します。1つを無効化してもほかには影響せず、メイントークンを再発行しても制限付きトークンは変わりません。有効期限を設定したトークンは、その期限を過ぎると認証に使えなくなります。
| スコープ | 呼べるメソッド |
|---|---|
| (有効なトークンであればどれでも) | getMe, getCurrencies, getExchangeRates |
read | getBalance, getStats, getInvoices, getChecks, getTransfers, getSubscriptionPlans, getSubscriptions |
invoices | createInvoice, deleteInvoice |
refunds | refundInvoice |
payouts | transfer, transferBatch |
checks | createCheck, deleteCheck |
subscriptions | createSubscriptionPlan, archiveSubscriptionPlan, cancelSubscription |
webhooks | updateApp |
スコープは組み合わせて付与でき、それぞれ独立しています。
invoicesはreadを含まないので、請求書を作るだけのサーバーには、残高や支払い履歴を読めないトークンを渡せます。
トークンが持たないスコープのメソッドを呼ぶと、403 scope_requiredが返ります。
getMeは今のトークンのscopes(メイントークンではnull)とtoken_nameを返すので、手元のトークンが何かはいつでも確かめられます。
支払いモード
スコープは、トークンがどのメソッドを呼べるかを決めます。アプリの支払いモードは、メイントークンを含むどのトークンであっても、誰に支払えるかを決めます。
新しいアプリは、作成した直後から誰にでも支払えます。所有者はその他 → Merchant APIでアプリを開き、送金設定 → API経由の送金で範囲を絞り込めます。1日の支払限度額と同じく、トークンが漏れた場合の被害を抑えるための備えです。
再び広げるにはPINまたは生体認証が必要です。APIにできるのは読み取りだけです(getMe → payout_mode)。
payout_mode | transfer・transferBatch・createCheckにできること |
|---|---|
any | どのユーザーにも支払える。知らない@username宛ての支払いをエスクローで預かる。誰でも受け取れる送金リンクを作れる。既定であり、Crypto Botと同じ動作 |
allowlist | 許可された一覧にあるTelegramユーザーにだけ支払える。送金リンクの受取人は、単独指定でも一覧指定でも、全員が許可されている必要があります。それ以外の相手、未登録の@username、受取人を指定しないリンクは403 recipient_not_allowedになる |
off | 何もできない。これらのメソッドはすべて403 payouts_disabledを返す。請求書、サブスクリプション、返金、Webhookは通常どおり動く |
APIからの支払いが拒否されると、所有者にTelegramで通知が届き、モードを変更できます。 1日の支払限度額は、モードとは別に適用されます。 どのような目的の支払いが認められるかは、Merchant API利用規約に定めています。
リクエストとレスポンス
- **読み取り系のメソッドは
GET**で、パラメーターはクエリ文字列で渡します。資金を動かすメソッドはPOSTのみで、パラメーターはJSONボディ、form-urlencoded、クエリパラメーターのいずれでも渡せます(食い違う場合はボディが優先されます)。multipart/form-dataは受け付けません。 - APIの処理が返すレスポンスは、同じ形のJSONです。
成功は
{"ok": true, "result": …}、エラーは{"ok": false, "error": {"code": <HTTP status>, "name": "<error_name>"}}です。 分岐はerror.nameで行ってください。これが機械可読の、変わらない文字列です。 - GETメソッドのクエリに不正な型の値を渡すと(たとえば
offset=abc)、APIの処理に入る前に拒否されることがあります。すべてのエラーが上記のJSON形式になるとは限らないため、HTTPステータスも確認してください。クエリの値は型を合わせて送ってください。
金額
- 暗号資産の金額は、その資産の単位で表した10進数の文字列です(
"10.5")。JSONの数値ではありません。レスポンスにはamount_minor(拡張)も入ります。これは最小単位の整数を文字列にしたもので、wei規模の大きな整数はJavaScriptのNumberでは正確に表せないことがあるためです。 - 資産ごとの
decimalsはgetCurrenciesから取れます。決め打ちにせず、ここを基準に金額の計算を組んでください。 - 法定通貨の金額は、小数点以下2桁までです。
- レートは固定小数点の文字列で、数値ではありません。
ページネーション
一覧系のメソッド(getInvoices・getChecks・getTransfers・getSubscriptions)は、offset(既定は0)とcount(既定は100、最大1000。getSubscriptionsは最大500)を受け取り、{"items": […]}を新しい順に返します。IDでの絞り込み(invoice_ids・check_ids・transfer_ids)は、カンマ区切りの整数のリストです。
日時はどこでもISO 8601の文字列です。
べき等性:spend_id
資金を動かすメソッドは、呼び出す側が生成する**spend_id**キー(1〜64文字)を受け取ります。
transferとtransferBatchの各項目では必須、createCheckとrefundInvoiceでは任意です(拡張。任意でも使ってください)。
同じキーと同じパラメーターで送り直すと、資金を二重に動かさず、元の結果をそのまま返すので、タイムアウトしたリクエストはいつでも安全に再送できます。
同じキーで違うパラメーターを送ると409 idempotency_conflictが返り、元の処理がまだ動いているうちに送り直すと409 idempotency_in_progressが返ります。
呼び出し回数の制限
アプリごとで、そのアプリのすべてのトークンで共有します。
超えると429 rate_limitedが返ります。
| メソッド | 上限 |
|---|---|
createInvoice, createCheck | 1分間:60 |
refundInvoice | 1分間:30 |
transfer | 1分間:30 |
transferBatch | 1分間:10 |
updateApp | 1分間に10回 |
createSubscriptionPlan | 1分間に20回 |
追加のリクエスト制限が適用される場合があります。429 rate_limitedが返ったら、再試行までの間隔を延ばしてください。
プラットフォームのメンテナンス中は、書き込み系のメソッドが503 maintenanceを返し、読み取りは動き続けます。
カタログとアカウントのメソッド
getMe
GET /pay/api/getMe、パラメーターはありません。
アプリの情報を返します。
app_id・name・payment_processing_bot_username・webhook_url・webhook_events(アプリが選んだ拡張のWebhook種別)、前述のトークンのscopes・token_nameと、payout_mode(off・allowlist・any)、daily_payout_max_usd_cents(0なら所有者による限度額の設定なし)、daily_payout_spent_usd_cents(直近24時間の支払額)です。
updateApp
POST /pay/api/updateApp、スコープはwebhooksです。任意のパラメーターは、name(1〜64文字)、webhook_url(公開HTTPS URL。空文字列で削除)、webhook_events(対応する拡張イベント名の配列またはカンマ区切りの文字列)です。イベント一覧を空にすると、invoice_paidだけが残ります。getMeと同じアプリ情報を返します。
getBalance
GET /pay/api/getBalance、パラメーターはありません。
対応するすべての資産について、残高が0でも1行ずつ返します。
currency_code・available(使える残高)・onhold(未受取の送金リンクの資金と、@username宛ての保留中の支払い)・amount_minorです。
getCurrencies
GET /pay/api/getCurrencies、パラメーターはありません。APIが対応しているものの正式な一覧です。
暗号資産の行(is_blockchain: true)と、請求書の値づけに使える法定通貨の行(is_fiat: true)が入ります。
どの行にもcode・name・decimalsとis_stablecoinフラグがあります。
getExchangeRates
GET /pay/api/getExchangeRates、パラメーターはありません。
暗号資産から法定通貨への交換レートを返します。
source・target・rate(固定小数点の文字列)・is_validです。
レートは目安として扱ってください。is_valid: trueでも、最新のレートであるとは限りません。レートを取得できない場合は空の配列が返ることがあります。実際の支払いを照合する際は、請求書に記録された金額とレートを使ってください。
getStats
GET /pay/api/getStats、start_atとend_atは任意です(ISO 8601。既定の期間は直近24時間)。
volume(期間内に支払われた請求書の、現在のレートによる米ドル換算額。レートのない資産は0として計算)・conversion(作成に対する支払い済みの割合、パーセント)・unique_users_count・created_invoice_count・paid_invoice_countと、実際の期間の範囲を返します。
日付を読み取れない場合は、400 invalid_dateが返ります。
すべてのメソッドが返しうるエラー
| HTTP | error.name | 発生する場面 |
|---|---|---|
| 401 | unauthorized | トークンがない、無効、または無効化済み |
| 403 | scope_required | トークンにそのメソッドのスコープがない |
| 403 | payouts_disabled | アプリの支払いモードがoff(支払い系のメソッドのみ) |
| 403 | recipient_not_allowed | 受取人がアプリの受取人の一覧にない(支払い系のメソッドのみ) |
| 400 | invalid_request | パラメーターを読み取れない、または不正(POST) |
| 403 | daily_cap_exceeded | アプリの1日の支払限度額を超える |
| 403 | verification_required | 所有者の送金・出金が制限されている。送金、送金リンク、返金に適用 |
| 503 | merchant_payouts_paused | アプリ残高からの引き落としが一時停止中 |
| 429 | rate_limited | 回数の上限を超えた |
| 503 | maintenance | プラットフォームのメンテナンス中(書き込み系のメソッド) |
| 500 | internal_error | 予期しないサーバーエラー |
メソッドごとのエラーは、それぞれのメソッドのページにまとめています。
JSON形式ではないエラー
エラーがプレーンテキストやHTMLで返されたというだけでは、どの段階で発生したかは分かりません。HTTPステータス、レスポンス本文、レスポンスヘッダーを確認してください。
Cloudflareがerror code: 1010を返した場合は、リクエストがAPIに到達する前に、ブラウザーのシグネチャに基づいてクライアントが拒否されています。このCloudflareエラーはトークンのスコープが原因ではありません。User-Agentがない場合や一般的でない値の場合に、ネットワーク保護が作動することがあります。MyShop/1.0など、クライアントを識別できるUser-Agentヘッダーを指定して再試行してください。ただし、解決するとは限りません。エラーが続く場合は、トークンとCookieを取り除いたうえで、HTTPステータス、レスポンス本文、レスポンスヘッダーをサポートに送ってください。
この記事は役に立ちましたか?
ご意見ありがとうございます。