# blockwallets Cryptomus 互換 API

> blockwallets の Cryptomus 互換 API:請求と固定アドレス、署名、Webhook と検証、テストモード、ネットワーク、エラー、ドメインを変えるだけの Cryptomus からの移行。
>
> HTML: https://blockwallets.io/docs/cryptomus?lang=ja · English: https://blockwallets.io/docs/cryptomus.md?lang=en

## Cryptomus 互換 API

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`

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

### 請求の流れ

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

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

- 請求を作成し(決済リンクなら自動、サーバーからなら `/v1/payment` を呼び出し)、決済ページの `url` を受け取って、お客様をそこへリダイレクトします。

- 決済ページでお客様が通貨とネットワークを選ぶと、専用のアドレスと金額が表示され、ウォレットまたは取引所から支払います。

- 当社がオンチェーンで送金を検知し、十分な承認数を待ってから、2つ目のノード事業者でも照合します(ノードによる偽装を防ぐため)。

- 請求は `paid` になり、署名付きの Webhook をすぐ `url_callback` に POST します。数秒後、決済ページがお客様を `url_success` に戻します。

- 代金は残高に計上されます。加盟店管理画面からご自身のウォレットへ出金できます。

#### 請求の状態

| 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 コードが発行されます。

- リンクが開かれるたびに新しい請求が作成されるため、1つのリンクを使い回せます(例:「会員プラン $99」)。

- 支払いはすべて「入金 › 入金履歴」に表示されます。「資金 › 残高と出金」からご自身のウォレットへ出金できます。

- 「開発者 › 連携とキー」で認証情報と Webhook URL を作成済みなら、リンク経由の支払いも以下の形式で通知されます。

- 受け付けを止めるには「無効にする」を押すと、リンクはすぐに使えなくなります。

### 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 で、次のヘッダーを付けます。

- `merchant`:あなたの merchant UUID(これで Live か Test かが決まります)

- `sign`:`md5(base64(リクエストボディ) + API key)`。ボディは送信する JSON 文字列そのものです

成功すると `{"state": 0, "result": {…}}`、失敗すると `{"state": 1, "message": "…"}` が返ります([エラー](https://blockwallets.io/docs/cryptomus?lang=ja#errors)を参照)。

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

```nodejs
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"`。あなたの価格、またはお客様が入力した数値。選んだネットワークの最低額を下回ってはいけません([ネットワーク](https://blockwallets.io/docs/cryptomus?lang=ja#networks)を参照) |
| `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 になります。[料金](https://blockwallets.io/pricing?lang=ja)を参照)。省略すると、管理画面「設定 › 支払いルールと料率」の「手数料と支払い不足」の設定が適用されます(既定 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. 請求を照会

- `POST /v1/payment/info` `{"order_id": "…"}` または `{"uuid": "…"}`:請求を1件取得し、その際にチェーンも確認します(10 秒に1回まで)。

- `POST /v1/payment/list`:一覧、1 ページ 15 件、`date_from` / `date_to` は任意。次ページは返された `paginate.nextCursor` を使います(`?cursor=…`)。

- `POST /v1/payment/services`:利用可能なネットワークと、各ネットワークの最低額。

- `POST /v1/payment/resend` `{"order_id": "…"}`:支払済みまたは不足払いの請求の Webhook を再送します。

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 の生のボディを[署名チェッカー](https://blockwallets.io/docs/sign?lang=ja)に貼り付けてください。各ステップの結果が表示され、あなたの結果が異なる箇所に印が付きます(すべてブラウザー内で動作し、API key がアップロードされることはありません)。管理画面の「開発者 › Webhook ログ」にある Webhook は、どれもワンクリックでチェッカーで開けます。

```nodejs
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 を確認できます。

- `POST /v1/test-webhook/payment`、`/v1/test-webhook/wallet`:署名付きのサンプル Webhook を `url_callback` に送ります(必須の `url_callback`(登録済みのサイトドメイン配下のアドレス)と `currency`、`network`、必要に応じて `status`、`order_id` を渡します)。検証コードのデバッグに使えます。

- 管理画面「開発者 › 連携とキー」→「テスト通知を送る」:Webhook URL にサンプルを送ります。

- 管理画面「開発者 › Webhook ログ」:配信試行ごとに、時刻、送信先 URL、HTTP ステータス、所要時間、リクエストボディ、あなたのサーバーの応答(先頭 4 KB)を確認できます。注文や状態で絞り込み、ワンクリックで再送できます。30 日間保存されます。

### Cryptomus からの移行

- 管理画面「開発者 › 連携とキー」で merchant と API key を発行します。

- コード内の `https://api.cryptomus.com` を `https://blockwallets.io` に置き換え、新しい merchant と API key を使います。

- 「サイトのドメイン」にドメインを登録します(`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 とキーを変えるだけです。[移行ガイド](https://blockwallets.io/docs/migrate?lang=ja)を参照してください。

### ネットワークと金額

| 通貨 | ネットワーク | network パラメーター | 最低額 | 着金時間 |
| --- | --- | --- | --- | --- |
| USDT | TRON | `tron` | $1 | 約 1 分 |
| USDT | BNB Chain | `bsc` | $1 | 約 1 分 |
| USDC | BNB Chain | `bsc` | $1 | 約 1 分 |
| USDT | Ethereum | `eth` | $5 | 約 1 分 |
| USDC | Ethereum | `eth` | $5 | 約 1 分 |
| USDC | Base | `base` | $1 | 約 1 分 |
| USDT | Polygon | `polygon` | $1 | 約 1 分 |
| USDC | Polygon | `polygon` | $1 | 約 1 分 |
| USDT | Arbitrum | `arbitrum` | $1 | 約 1 分 |
| USDC | Arbitrum | `arbitrum` | $1 | 約 1 分 |
| USDT | Optimism | `optimism` | $1 | 約 1 分 |
| USDC | Optimism | `optimism` | $1 | 約 1 分 |
| USDT | Avalanche | `avalanche` | $1 | 約 1 分 |
| USDC | Avalanche | `avalanche` | $1 | 約 1 分 |
| USDT | X Layer | `xlayer` | $1 | 約 1 分 |
| USDC | X Layer | `xlayer` | $1 | 約 1 分 |
| USD1 | BNB Chain | `bsc` | $1 | 約 1 分 |
| FDUSD | BNB Chain | `bsc` | $1 | 約 1 分 |
| DAI | Ethereum | `eth` | $5 | 約 1 分 |
| DAI | Arbitrum | `arbitrum` | $1 | 約 1 分 |
| DAI | Base | `base` | $1 | 約 1 分 |
| BTC | Bitcoin | `btc` | $5 | 約 10 分 |
| LTC | Litecoin | `ltc` | $1 | 約 3 分 |
| DOGE | Dogecoin | `doge` | $1 | 約 1 分 |
| BCH | Bitcoin Cash | `bch` | $1 | 約 10 分 |
| TRX | TRON | `tron` | $1 | 約 1 分 |
| BNB | BNB Chain | `bsc` | $1 | 約 1 分 |
| ETH | Ethereum | `eth` | $5 | 約 1 分 |
| ETH | Base | `base` | $1 | 約 1 分 |
| ETH | Arbitrum | `arbitrum` | $1 | 約 1 分 |
| ETH | Optimism | `optimism` | $1 | 約 1 分 |
| POL | Polygon | `polygon` | $1 | 約 1 分 |
| AVAX | Avalanche | `avalanche` | $1 | 約 1 分 |
| OKB | X Layer | `xlayer` | $1 | 約 1 分 |
| USDT | Solana | `sol` | $1 | 約 1 分 |
| USDC | Solana | `sol` | $1 | 約 1 分 |
| SOL | Solana | `sol` | $1 | 約 1 分 |
| USDT | TON | `ton` | $1 | 約 1 分 |
| TON | TON | `ton` | $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` でサポート外の通貨 / ネットワークを指定した |
| 401 | merchant の誤り、`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 が誤っています。[署名チェッカー](https://blockwallets.io/docs/sign?lang=ja)に貼り付けると、最初の相違箇所がわかります。

```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` を設定するか、管理画面で既定値を設定してください。出金に追加手数料はかかりません。[料金](https://blockwallets.io/pricing?lang=ja)を参照してください。

#### お金はいつ届きますか?

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

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