Cryptomus 互換 API

ChatGPT で開くClaude で開くAI で連携 →

blockwallets では USDT と USDC のほか、BTC、LTC、DOGE、BCH、各チェーンのネイティブ通貨(固定したレートで米ドル建てに計上)を受け取れます。お客様が支払い、当社がオンチェーンで確認し、あなたに通知します。API、署名、Webhook は Cryptomus と同じなので、Cryptomus を連携済みならドメインを変えるだけで完了です。まず仕組みを説明し、そのあと API を説明します。

2つの受け取り方

どちらも任意の金額に対応します。定額の注文も、お客様が金額を入力するチャージも可能です。入金を確認したら、商品を発送するか、お客様の残高に加算します。違いは支払いごとに新しいアドレスを発行するかどうかだけです。

おすすめ · ほとんどの連携請求

お客様があなたのページで商品を選ぶか金額を入力し、あなたが請求を作成して、お客様は決済ページに表示された金額を送金します。請求ごとに新しいアドレスとカウントダウンがあり、入金されると実際に受け取った金額を通知します。

POST /v1/payment → Webhook type: payment

オプション固定アドレス

事前の金額指定はありません。お客様ごとにネットワーク別の恒久アドレスを発行し、お客様はそれをウォレットに保存していつでも送金できます。送金ごとに個別の Webhook が届きます。

POST /v1/wallet → Webhook type: wallet

迷ったら請求を使ってください。コードを書かない場合は、管理画面の決済リンクが自動で請求を作成します。まだ加盟店でない場合はトップページから利用を申し込み、承認後に加盟店管理画面にログインして、まず管理画面ホームの「試しに 1 件決済」から少額で試してください(お金はご自身の残高に入ります)。

請求の流れ

1件の決済には、お客様、あなたのサイト、blockwallets、ブロックチェーンの4者が関わります。図は上から下へ時間順に進み、右の列は各ステップでの請求の状態です。

① 作成② 支払い③ 確認④ 通知⑤ 完了 お客様ブラウザー + ウォレットあなたのサイトページ + サーバーblockwallets決済ページ + スキャナーブロックチェーンTRON ほか 14 件 請求の状態status 1「チャージ」をクリック2POST /v1/payment3uuid + urlcheck4url へリダイレクト5通貨とネットワークを選ぶ6専用アドレス + 金額7そのアドレスへ送金8毎分スキャン9検知、承認待ちconfirm_check102つ目のノードで照合paid11POST url_callback122xx を返す13検証して発送 / 入金処理14url_success へ戻る15残高に計上

図は横に長いので、横にスクロールしてください。

15 ステップを、上から下へ時間順に。「再生」を押して見るか、各ステップをタップすると詳細が表示されます。

要点は5つのステップです。

  1. 請求を作成し(決済リンクなら自動、サーバーからなら /v1/payment を呼び出し)、決済ページの url を受け取って、お客様をそこへリダイレクトします。
  2. 決済ページでお客様が通貨とネットワークを選ぶと、専用のアドレスと金額が表示され、ウォレットまたは取引所から支払います。
  3. 当社がオンチェーンで送金を検知し、十分な承認数を待ってから、2つ目のノード事業者でも照合します(ノードによる偽装を防ぐため)。
  4. 請求は paid になり、署名付きの Webhook をすぐ url_callback に POST します。数秒後、決済ページがお客様を url_success に戻します。
  5. 代金は残高に計上されます。加盟店管理画面からご自身のウォレットへ出金できます。

請求の状態

status意味あなたの対応
check支払い待ち—
confirm_check送金を検知、承認待ち—
wrong_amount_waiting受取額が不足。お客様は同じアドレスに追加で送金できます(is_payment_multiple が true の場合。通知は1回)—(追加入金されると paid が届きます)
paid支払済みpayment_amount_usd に従って発送または入金処理
paid_over支払済み(超過払い)同じ(payment_amount_usd は受取額)
wrong_amount全額に満たないまま期限切れ(is_payment_multiple が false の場合は最初の不足した送金)チャージ型の事業は受け取った payment_amount_usd を計上できます。ショップは残りの支払いをお客様に依頼します
cancel入金なしで期限切れ—(あとから届いた入金も計上され、通知されます)

is_final が true のとき、状態はそれ以上変わりません(遅れて届く入金を除く)。

加盟店管理画面 →「入金 › 支払いリンク」→ 説明と金額を入力(ネットワークを固定するか、お客様に選ばせる)→ 作成。リンクごとに URL と QR コードが発行されます。

API 連携

1. 認証情報と署名

加盟店管理画面 →「開発者 › 連携とキー」で merchant(UUID)と API key を発行します。Live 用と Test 用が1組ずつあります。Live は本物のお金、Test はテストネットで動きます。サイトのドメインも登録してください。url_callback、url_return、url_success はそのドメイン上である必要があります。API key は一度しか表示されません。安全に保管し、サーバー上だけで使ってください。

ベース URL は https://blockwallets.io です。すべてのエンドポイントは POST + JSON で、次のヘッダーを付けます。

成功すると {"state": 0, "result": {…}}、失敗すると {"state": 1, "message": "…"} が返ります(エラーを参照)。

主なエンドポイントには「試す」パネルがあります。Test の merchant と API key を入力すると、ページがブラウザー内でリクエストに署名してエンドポイントを呼び出し、リクエストとレスポンスの全文を表示します(認証情報はページのメモリ内だけに保持されます)。署名が一致しないときは、署名チェッカーで手順ごとに照合してください。

Node.js
import crypto from "node:crypto";

async function call(path, data) {
  const body = JSON.stringify(data);
  const sign = crypto.createHash("md5").update(Buffer.from(body).toString("base64") + process.env.BW_API_KEY).digest("hex");
  const res = await fetch("https://blockwallets.io" + path, {
    method: "POST",
    headers: { merchant: process.env.BW_MERCHANT, sign, "Content-Type": "application/json" },
    body,
  });
  return res.json();
}
PHP
function bw_call(string $path, array $data): array {
    $body = json_encode($data, JSON_UNESCAPED_UNICODE);
    $sign = md5(base64_encode($body) . getenv('BW_API_KEY'));
    $ch = curl_init('https://blockwallets.io' . $path);
    curl_setopt_array($ch, [
        CURLOPT_POST => true, CURLOPT_POSTFIELDS => $body, CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => ['merchant: ' . getenv('BW_MERCHANT'), 'sign: ' . $sign, 'Content-Type: application/json'],
    ]);
    return json_decode(curl_exec($ch), true);
}
Python
import base64, hashlib, json, os, requests

def bw_call(path: str, data: dict) -> dict:
    body = json.dumps(data, separators=(",", ":"), ensure_ascii=False)
    sign = hashlib.md5((base64.b64encode(body.encode()).decode() + os.environ["BW_API_KEY"]).encode()).hexdigest()
    headers = {"merchant": os.environ["BW_MERCHANT"], "sign": sign, "Content-Type": "application/json"}
    return requests.post("https://blockwallets.io" + path, data=body.encode(), headers=headers).json()

2. 請求を作成 POST /v1/payment

お客様が注文したとき、またはチャージページで金額を入力したときに https://blockwallets.io/v1/payment を呼び出し、返された result.url へリダイレクトします。

json
{
  "amount": "42.00",
  "currency": "USD",
  "order_id": "order_1042",
  "url_callback": "https://shop.example/webhooks/crypto",
  "url_return": "https://shop.example/cart",
  "url_success": "https://shop.example/thanks?order=1042"
}
パラメーター必須説明
amountはい金額を文字列で、小数点以下 2 桁まで:"42.00"。あなたの価格、またはお客様が入力した数値。選んだネットワークの最低額を下回ってはいけません(ネットワークを参照)
currencyはいUSD、USDT、USDC。いずれも 1:1
order_idはい注文番号:英字、数字、-、_、100 文字以内。同じ order_id で再度呼び出すと既存の請求が返ります(注文の重複なし)
url_callbackいいえWebhook の URL。省略すると Webhook は送信されません
url_returnいいえ支払い前に「戻る」を押したときの遷移先
url_successいいえ支払い後にお客様が移動する先
networkいいえネットワークを事前に選択:tron / bsc / eth / base / polygon / arbitrum / optimism / avalanche / xlayer / btc / ltc / doge / bch / sol / ton。省略すると決済ページでお客様が選びます
to_currencyいいえそのネットワークの通貨:USDT / USDC。btc / ltc / doge / bch では BTC / LTC / DOGE / BCH(任意)
lifetimeいいえ請求の有効期間(秒)、300〜43200、既定 3600。600 未満は 600 として扱われます
accuracy_payment_percentいいえ不足払いをどこまで支払い済みとみなすか、0〜5、既定 0。100 = 届いた分をすべて受け入れる:承認され次第 paid(超過なら paid_over)となり、Webhook の payment_amount_usd で入金処理します。チャージに向いています。省略すると、管理画面「設定 › 支払いルールと料率」の「受取金額のルール」が適用されます。「届いた分を計上」は 100 を意味します
subtractいいえプラットフォーム手数料のうちお客様が負担する割合、0〜100。payer_amount に上乗せされます(プラットフォーム手数料は 1%、取扱高が増えると下がります。1% の場合、100 を指定すると 100 ドルの請求でお客様の支払いは $101.00 になります。料金を参照)。省略すると、管理画面「設定 › 支払いルールと料率」の「手数料と支払い不足」の設定が適用されます(既定 0)
is_payment_multipleいいえ不足した支払いに追加入金できるかどうか、既定 true:状態は wrong_amount_waiting で、残りを同じアドレスに支払うと paid になります(最初の不足時に残り 30 分未満なら、期限はその 30 分後に延長されます)。false:最初の不足した送金で wrong_amount になります。省略すると管理画面の設定が適用されます
additional_dataいいえ任意の文字列(255 文字以内)。照会と Webhook でそのまま返されます
json
{
  "state": 0,
  "result": {
    "uuid": "6f1c2a7e-…",
    "order_id": "order_1042",
    "amount": "42.00",
    "currency": "USD",
    "network": null,
    "address": null,
    "payer_amount": null,
    "payment_amount": null,
    "url": "https://blockwallets.io/pay/inv_01J8…",
    "expired_at": 1760965200,
    "status": "check",
    "is_final": false
  }
}

network、address、payer_amount は、お客様がネットワークを選んだあとに設定されます。

3. 請求を照会

Webhook が基本の通知手段で、照会は補助です(たとえばサーバーが停止していて Webhook を受け取り損ねた場合)。

4. 固定アドレス POST /v1/wallet

お客様1人につき、1つのネットワークで恒久アドレスを発行します。同じ order_id(通常はあなたのユーザー ID)とネットワークからは常に同じアドレスが得られます。すべての EVM チェーン(BNB Chain、Ethereum、Base、Polygon、Arbitrum、Optimism、Avalanche、X Layer)は1つのアドレスを共有し、TRON、BTC、LTC、DOGE、BCH、Solana、TON はそれぞれ別のアドレスです。お客様が送った分はすべて計上され、送金ごとに Webhook が届きます。BTC / LTC / DOGE / BCH / TRX / BNB / ETH / POL / AVAX / OKB / SOL / TON の送金は、検知した時点のレートで米ドルに換算されます(payment_amount_usd)。

json
{
  "order_id": "user_42",
  "currency": "USDT",
  "network": "tron",
  "url_callback": "https://shop.example/webhooks/crypto"
}
json
{
  "state": 0,
  "result": {
    "wallet_uuid": "0b9d…",
    "uuid": "5e2f…",
    "order_id": "user_42",
    "currency": "USDT",
    "network": "tron",
    "address": "TXy4…8kQ2",
    "url": "https://blockwallets.io/deposit/dac_01J8…"
  }
}

result.url は入金用のホスト型ページ(アドレス + QR コード + 最近の入金)で、お客様にそのまま渡せます。そのネットワークの最低額(通常 $1、BTC $5)未満の送金は自動では計上されません。計上が必要な場合はご連絡ください。アドレスのブロック(/v1/wallet/block-address)にはまだ対応していません。

Webhook

請求の状態が変わったとき(paid、paid_over、wrong_amount_waiting、wrong_amount、cancel)と、固定アドレスへの送金ごとに、url_callback へ JSON を POST します。2xx の応答で配信済みとみなし、それ以外は 1 分後、5 分後、30 分後、2 時間後、12 時間後、24 時間後、24 時間後に再試行します。管理画面から、または /v1/payment/resend で再送もできます。

json
{
  "type": "payment",
  "uuid": "6f1c2a7e-…",
  "order_id": "order_1042",
  "amount": "42.00",
  "payment_amount": "42",
  "payment_amount_usd": "42.00",
  "merchant_amount": "41.58",
  "commission": "0.42",
  "is_final": true,
  "status": "paid",
  "from": "TQ8m…",
  "wallet_address_uuid": null,
  "network": "tron",
  "currency": "USD",
  "payer_currency": "USDT",
  "payer_amount": "42",
  "payer_amount_exchange_rate": "1",
  "additional_data": null,
  "txid": "9c1e…",
  "sign": "5f0c9b…"
}
typeタイミング入金処理
payment請求の状態が変わった — status を参照paid / paid_over のとき payment_amount_usd を計上し、uuid で重複を排除します
wallet固定アドレスに送金があった(status は常に paid、order_id はアドレス発行時に指定したもの)payment_amount_usd を計上します。送金ごとに固有の uuid があるので、それで重複を排除します

署名の検証(必須)

署名は Webhook ボディの sign フィールドです。sign を取り除き、残りを PHP の json_encode と同じ方法で再エンコードします(コンパクト、/ は \/ にエスケープ、非 ASCII 文字はエスケープしない)。そのうえで md5(base64(エンコード結果) + API key) が sign と一致しなければなりません。同じモードの API key を使ってください。同じ Webhook が複数回届くことがあるため、uuid + status で重複を排除してください。

検証に失敗したら、Webhook の生のボディを署名チェッカーに貼り付けてください。各ステップの結果が表示され、あなたの結果が異なる箇所に印が付きます(すべてブラウザー内で動作し、API key がアップロードされることはありません)。管理画面の「開発者 › Webhook ログ」にある Webhook は、どれもワンクリックでチェッカーで開けます。

Node.js
import crypto from "node:crypto";

function verify(rawBody, apiKey) {
  const { sign, ...data } = JSON.parse(rawBody);
  const json = JSON.stringify(data).replaceAll("/", "\\/");
  const expected = crypto.createHash("md5").update(Buffer.from(json).toString("base64") + apiKey).digest("hex");
  return typeof sign === "string" && sign.length === expected.length && crypto.timingSafeEqual(Buffer.from(sign), Buffer.from(expected));
}
PHP
$data = json_decode(file_get_contents('php://input'), true);
$sign = $data['sign'] ?? '';
unset($data['sign']);
$expected = md5(base64_encode(json_encode($data, JSON_UNESCAPED_UNICODE)) . $apiKey);
if (!hash_equals($expected, $sign)) {
    http_response_code(401); exit;
}
Python
import base64, hashlib, hmac, json

def verify(raw_body: bytes, api_key: str) -> bool:
    data = json.loads(raw_body)
    sign = data.pop("sign", "")
    encoded = json.dumps(data, separators=(",", ":"), ensure_ascii=False).replace("/", "\\/")
    expected = hashlib.md5((base64.b64encode(encoded.encode()).decode() + api_key).encode()).hexdigest()
    return hmac.compare_digest(expected, sign)

テストモード

Test の merchant と API key で作成した請求はテストネットで動き、本物のお金は動きません。決済ページには「決済をシミュレート」ボタン(全額 / 半額 / 超過払い)が表示されるので、テストネットのコインを用意しなくても、状態の変化と Webhook を確認できます。

Cryptomus からの移行

  1. 管理画面「開発者 › 連携とキー」で merchant と API key を発行します。
  2. コード内の https://api.cryptomus.com を https://blockwallets.io に置き換え、新しい merchant と API key を使います。
  3. 「サイトのドメイン」にドメインを登録します(url_callback / url_return / url_success は登録済みのドメインだけを受け付けます)。

対応:/v1/payment、/v1/payment/info、/v1/payment/list、/v1/payment/services、/v1/payment/resend、/v1/wallet、/v1/test-webhook/payment、/v1/test-webhook/wallet。 相違点:請求の価格指定は USD / USDT / USDC のみ(いずれも 1:1、為替スプレッドなし)。commission は当社のプラットフォーム手数料(受取額 × 請求作成時の加盟店の料率。標準 1%、取扱高に応じて最低 0.5% まで。お客様が負担した分に二重に課金されることはありません)で、merchant_amount = 受取額 − commission です。お客様が BTC / LTC / DOGE / BCH / TRX / BNB / ETH / POL / AVAX / OKB / SOL / TON で支払う場合は複数の取引所の中央値で見積もり、30 分間固定します。payer_amount は送金するコイン数、payer_amount_exchange_rate はコイン1枚の米ドル価値で、支払いは固定レートで payment_amount_usd に換算されます(コインは当社に残り、スワップはしません)。ネットワークは tron / bsc / eth / base / polygon / arbitrum / optimism / avalanche / xlayer / btc / ltc / doge / bch / sol / ton。請求の最短有効期間は 10 分。is_refresh はなく、固定アドレスのブロックもありません。Webhook は既定では変動する IP から届きます。IP で許可リストを作る場合は、管理画面の「開発者 › 連携とキー」で「固定 IP の Webhook」をオンにすると、Webhook は 18.163.145.41 からのみ届きます。許可リストは追加の防御層なので、sign の検証は続けてください。

NOWPayments や Coinbase Commerce からの移行ですか?どちらにも互換 API があり、ベース URL とキーを変えるだけです。移行ガイドを参照してください。

ネットワークと金額

通貨ネットワークnetwork パラメーター最低額着金時間
USDTTRONtron$1約 1 分
USDTBNB Chainbsc$1約 1 分
USDCBNB Chainbsc$1約 1 分
USDTEthereumeth$5約 1 分
USDCEthereumeth$5約 1 分
USDCBasebase$1約 1 分
USDTPolygonpolygon$1約 1 分
USDCPolygonpolygon$1約 1 分
USDTArbitrumarbitrum$1約 1 分
USDCArbitrumarbitrum$1約 1 分
USDTOptimismoptimism$1約 1 分
USDCOptimismoptimism$1約 1 分
USDTAvalancheavalanche$1約 1 分
USDCAvalancheavalanche$1約 1 分
USDTX Layerxlayer$1約 1 分
USDCX Layerxlayer$1約 1 分
USD1BNB Chainbsc$1約 1 分
FDUSDBNB Chainbsc$1約 1 分
DAIEthereumeth$5約 1 分
DAIArbitrumarbitrum$1約 1 分
DAIBasebase$1約 1 分
BTCBitcoinbtc$5約 10 分
LTCLitecoinltc$1約 3 分
DOGEDogecoindoge$1約 1 分
BCHBitcoin Cashbch$1約 10 分
TRXTRONtron$1約 1 分
BNBBNB Chainbsc$1約 1 分
ETHEthereumeth$5約 1 分
ETHBasebase$1約 1 分
ETHArbitrumarbitrum$1約 1 分
ETHOptimismoptimism$1約 1 分
POLPolygonpolygon$1約 1 分
AVAXAvalancheavalanche$1約 1 分
OKBX Layerxlayer$1約 1 分
USDTSolanasol$1約 1 分
USDCSolanasol$1約 1 分
SOLSolanasol$1約 1 分
USDTTONton$1約 1 分
TONTONton$1約 1 分

ERC-20 は手数料が高いため最低額は $5、Bitcoin も手数料が低くないため最低額は $5、それ以外は $1 です。お客様は決済ページに表示されたネットワークで送金する必要があります。別のネットワークで送られたお金は自動では計上されません。 BTC / LTC / DOGE / BCH は mempool に入った時点で「検知」と表示され、十分な承認数に達したときに計上されます。置き換えられた(RBF)トランザクションや破棄されたトランザクションは計上されません。 ネイティブ通貨(TRX、BNB、ETH、POL、AVAX、OKB、SOL、TON)は BTC / LTC / DOGE / BCH と同様に固定レートで見積もり、米ドルで計上します。ネットワークと通貨の両方を指定してください:請求は network: "bsc", to_currency: "BNB"、固定アドレスは network: "bsc", currency: "BNB"。ネットワークだけを指定した場合は、そのチェーンの USDT が既定です(Base は USDC)。 コントラクトによる送金(マルチシグ、一括送金)も受け取れます。チェーンによってはトランザクションハッシュを取得できず、その場合 Webhook の txid は null になります。

エラー

json
{ "state": 1, "message": "amount must be a number like 10.28" }
HTTP主な原因
422パラメーターの不足または形式不正。金額がネットワークの最低額未満。コールバック / リダイレクト URL が登録済みのドメインに含まれていない。/v1/payment でサポート外の通貨 / ネットワークを指定した
401merchant の誤り、sign の誤り(Invalid Sign.)、または API key のローテーション
404請求が存在しない、またはあなたのものではない(Payment not found)。/v1/wallet でサポート外の通貨 / ネットワークの組み合わせ(The service was not found)
503ネットワークが一時的に利用できません。別のネットワークを選ぶか、事前選択をやめてください

署名が誤っている場合(Invalid Sign.)、レスポンスに debug オブジェクトが含まれます。body_base64 は当社が受け取ったリクエストボディの base64(あなた自身の内容であり、API key は含まれません)、body_bytes はその長さです。署名に使った base64 と比べてください。異なる場合、送信したボディが署名した文字列と一致していません(フレームワークによる再シリアライズ、プロキシによるエンコード変更、末尾の改行など)。一致している場合は API key が誤っています。署名チェッカーに貼り付けると、最初の相違箇所がわかります。

json
{
  "state": 1,
  "message": "Invalid Sign.",
  "debug": {
    "body_base64": "eyJhbW91bnQiOiI0Mi4wMCIsImN1cnJlbmN5IjoiVVNEIiwi…",
    "body_bytes": 158,
    "sign_formula": "md5(body_base64 + API key)"
  }
}

よくある質問

お客様が好きな金額をチャージします。どのモードを使えばよいですか?

請求です。チャージページでお客様に金額を入力してもらい、その金額で請求を作成して、入金されたら payment_amount_usd を計上します。固定アドレスは、お客様が1つのアドレスを保存して繰り返し送金する場合にだけ使ってください。

お客様が不足して支払った場合は?

期限前なら、お客様は決済ページで差額を送金できます(ページには残りの支払額が表示されます。状態は wrong_amount_waiting で、最初の不足時に残り 30 分未満なら、期限はその 30 分後に延長されます)。期限になってもなお不足している場合、請求は wrong_amount になり、Webhook の payment_amount_usd は受取額です。チャージ型の事業はそのまま計上できます。

お客様が期限後に支払った、または二重に支払った場合は?

期限後に届いた入金も計上され、通知されます。請求が全額支払われたあとに届いた入金も記録され、管理画面で確認できます。

お客様が間違ったネットワークで送金した場合は?

たとえば請求は TRON なのに、BNB Chain から送金された場合です。自動では計上されません。ご連絡いただければ、当社が手動で対応します。

費用はいくらですか?

受け取った決済1件につき 1%。前月の取扱高に応じて自動で下がります($50,000 以上で 0.9%、$100,000 以上で 0.8%、$250,000 以上で 0.7%、$500,000 以上で 0.6%、$1,000,000 以上で 0.5%)。月額費用や初期費用はありません。ネットワーク手数料は、お客様が送金時に支払います。お客様に手数料を転嫁するには、請求作成時に subtract を設定するか、管理画面で既定値を設定してください。出金に追加手数料はかかりません。料金を参照してください。

お金はいつ届きますか?

支払いが承認されると、すぐに残高に計上されます。「資金 › 残高と出金」からご自身のウォレットへの出金を申請してください。当社が承認すると送金され、オンチェーンのトランザクションが出金履歴に表示されます。

自動出金も設定できます。出金可能残高が設定した金額に達したとき、または毎日 00:00 UTC に、出金可能残高の全額が出金されます。自動出金も同じ確認を経ます。設定を変更するたびに、メールで通知が届きます。