# API kompatibel Cryptomus blockwallets

> API kompatibel Cryptomus dari blockwallets: tagihan dan dompet statis, tanda tangan, webhook dan verifikasi, mode uji, jaringan, error, dan pindah dari Cryptomus cukup dengan mengganti domain.
>
> HTML: https://blockwallets.io/docs/cryptomus?lang=id · English: https://blockwallets.io/docs/cryptomus.md?lang=en

## API kompatibel Cryptomus

blockwallets memungkinkan Anda menerima USDT dan USDC, plus BTC, LTC, DOGE, BCH, dan koin native (dikreditkan dalam dolar AS dengan kurs yang dikunci): pelanggan membayar, kami mengonfirmasinya di chain, lalu memberi tahu Anda. API, tanda tangan, dan webhook-nya sama dengan **Cryptomus** — jika Anda sudah mengintegrasikan Cryptomus, cukup ganti domain. Cara kerjanya dijelaskan dulu, baru API.

### Dua cara menerima pembayaran

Keduanya menerima **jumlah berapa pun**: pesanan berharga tetap maupun top-up yang jumlahnya diketik pelanggan. Setelah dibayar, Anda mengirim barang atau menambah saldo pelanggan. Satu-satunya beda adalah **apakah setiap pembayaran mendapat alamat baru**.

Disarankan · untuk kebanyakan integrasi**Tagihan**
Pelanggan memilih produk atau mengisi jumlah di halaman Anda, Anda membuat tagihan, lalu mereka mengirim jumlah yang tertera di halaman pembayaran. Setiap tagihan punya alamat baru dan hitung mundur; saat dana masuk, kami memberi tahu Anda dengan jumlah yang benar-benar diterima.

`POST /v1/payment` → webhook `type: payment`

Opsional**Dompet statis**
Tanpa jumlah di awal: setiap pelanggan mendapat satu alamat permanen per jaringan untuk disimpan di dompetnya dan dikirimi kapan saja. Setiap transfer memicu webhook-nya sendiri.

`POST /v1/wallet` → webhook `type: wallet`

Jika ragu, pakai tagihan. Tanpa kode, [tautan pembayaran](https://blockwallets.io/docs/cryptomus?lang=id#links) di dasbor adalah tagihan yang dibuatkan untuk Anda. Belum jadi merchant? Minta akses di [beranda](https://blockwallets.io/?lang=id#join); setelah disetujui, masuk ke [dasbor merchant](https://blockwallets.io/dashboard) dan mulai dari “Coba satu pembayaran” di beranda dasbor dengan jumlah kecil dulu (dananya masuk ke saldo Anda sendiri).

### Alur sebuah tagihan

Pembayaran melibatkan empat pihak: pelanggan, situs Anda, blockwallets, dan blockchain. Diagram berjalan dari atas ke bawah menurut waktu; kolom kanan adalah status tagihan di setiap langkah.

Singkatnya, lima langkah:

- Anda membuat tagihan (tautan pembayaran melakukannya untuk Anda, atau server Anda memanggil `/v1/payment`), mendapat `url` halaman pembayaran, lalu mengarahkan pelanggan ke sana.

- Di halaman pembayaran, pelanggan memilih koin dan jaringan, mendapat alamat dan jumlah khusus, lalu membayar dari dompet atau exchange.

- Kami melihat transfer di chain, menunggu cukup konfirmasi, lalu memeriksanya silang dengan penyedia node kedua (sehingga satu node tidak bisa memalsukannya).

- Tagihan menjadi `paid` dan kami langsung mengirim POST webhook bertanda tangan ke `url_callback` Anda; beberapa detik kemudian halaman pembayaran mengembalikan pelanggan ke `url_success` Anda.

- Dana dikreditkan ke saldo Anda; tarik ke dompet sendiri dari dasbor merchant.

#### Status tagihan

| status | Artinya | Yang perlu Anda lakukan |
| --- | --- | --- |
| `check` | Menunggu pembayaran | — |
| `confirm_check` | Transfer terlihat, menunggu konfirmasi | — |
| `wrong_amount_waiting` | Dana diterima tetapi kurang; pelanggan bisa menambah ke alamat yang sama (jika `is_payment_multiple` bernilai true; diberi tahu sekali) | — (Anda menerima `paid` setelah kekurangannya dibayar) |
| `paid` | Lunas | Kirim barang / kreditkan sesuai `payment_amount_usd` |
| `paid_over` | Lunas, dan kelebihan bayar | Sama (`payment_amount_usd` adalah jumlah yang diterima) |
| `wrong_amount` | Kedaluwarsa dengan jumlah kurang dari penuh (jika `is_payment_multiple` false: transfer pertama yang kurang) | Bisnis top-up bisa mengkreditkan `payment_amount_usd` yang diterima; toko meminta pelanggan membayar sisanya |
| `cancel` | Kedaluwarsa tanpa dana masuk | — (dana yang masuk belakangan tetap dikreditkan dan diberitahukan) |

Saat `is_final` bernilai `true`, status tidak akan berubah lagi (kecuali pembayaran terlambat).

### Tautan pembayaran (tanpa kode)

Dasbor merchant → “Pembayaran › Tautan pembayaran” → isi keterangan dan jumlah (tentukan jaringan atau biarkan pelanggan memilih) → buat. Setiap tautan punya URL dan kode QR.

- Setiap kali seseorang membuka tautan, tagihan baru dibuat, jadi satu tautan bisa dipakai berulang (misalnya “Keanggotaan $99”).

- Setiap pembayaran muncul di “Pembayaran › Pembayaran masuk”; tarik ke dompet Anda dari “Dana › Saldo & penarikan”.

- Jika Anda sudah membuat kredensial dan URL webhook di “Developer › Integrasi & kunci”, pembayaran lewat tautan juga diberitahukan dalam format di bawah.

- Untuk berhenti menerima, klik “Nonaktifkan” dan tautan langsung tidak berfungsi.

### Integrasi API

#### 1. Kredensial dan tanda tangan

Dasbor merchant → “Developer › Integrasi & kunci” → buat **merchant** (UUID) dan **API key**. Ada satu set untuk Live dan satu untuk Test: Live memakai uang sungguhan, Test berjalan di testnet. Tambahkan juga **domain situs web** Anda: `url_callback`, `url_return`, dan `url_success` harus berada di domain itu. API key hanya ditampilkan sekali — simpan dengan aman dan hanya di server Anda.

Base URL `https://blockwallets.io`. Setiap endpoint memakai `POST` + JSON, dengan header berikut:

- `merchant`: UUID merchant Anda (ini menentukan Live atau Test)

- `sign`: `md5(base64(request body) + API key)`, dengan body berupa string JSON persis seperti yang Anda kirim

Berhasil mengembalikan `{"state": 0, "result": {…}}`; gagal mengembalikan `{"state": 1, "message": "…"}` (lihat [Error](https://blockwallets.io/docs/cryptomus?lang=id#errors)).

Endpoint utama di bawah punya panel “Coba”: masukkan merchant dan API key Test Anda, lalu halaman menandatangani permintaan di browser Anda, memanggil endpoint, dan menampilkan permintaan serta respons lengkap (kredensial hanya ada di memori halaman). Jika tanda tangan tidak cocok, bandingkan langkah demi langkah dengan [pemeriksa tanda tangan](https://blockwallets.io/docs/sign?lang=id).

```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. Membuat tagihan POST /v1/payment

Saat pelanggan memesan, atau mengisi jumlah di halaman top-up Anda, panggil `https://blockwallets.io/v1/payment` dan arahkan mereka ke `result.url` yang dikembalikan.

```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"
}
```

| Parameter | Wajib | Keterangan |
| --- | --- | --- |
| `amount` | Ya | Jumlah sebagai string, maksimal dua desimal: `"42.00"`. Harga Anda atau angka yang diketik pelanggan; tidak di bawah minimum jaringan yang dipilih (lihat [jaringan](https://blockwallets.io/docs/cryptomus?lang=id#networks)) |
| `currency` | Ya | `USD`, `USDT`, atau `USDC`, semuanya 1:1 |
| `order_id` | Ya | Nomor pesanan Anda: huruf, angka, `-`, `_`, ≤ 100 karakter. Memanggil lagi dengan order_id yang sama mengembalikan tagihan yang sudah ada (tidak ada pesanan ganda) |
| `url_callback` | Tidak | URL webhook. Jika dikosongkan, webhook tidak dikirim |
| `url_return` | Tidak | Tujuan tombol “Kembali” sebelum membayar |
| `url_success` | Tidak | Tujuan pelanggan setelah membayar |
| `network` | Tidak | Pilih jaringan lebih dulu: `tron` / `bsc` / `eth` / `base` / `polygon` / `arbitrum` / `optimism` / `avalanche` / `xlayer` / `btc` / `ltc` / `doge` / `bch` / `sol` / `ton`; kosongkan agar pelanggan memilih di halaman pembayaran |
| `to_currency` | Tidak | Koin di jaringan itu: `USDT` / `USDC`; di `btc` / `ltc` / `doge` / `bch` berupa `BTC` / `LTC` / `DOGE` / `BCH` (opsional) |
| `lifetime` | Tidak | Masa berlaku tagihan dalam detik, 300 – 43200, default 3600; nilai di bawah 600 dihitung 600 |
| `accuracy_payment_percent` | Tidak | Seberapa besar kekurangan bayar yang masih dianggap lunas, 0 – 5, default 0. `100` = terima berapa pun yang masuk: `paid` segera setelah terkonfirmasi (`paid_over` jika lebih), kreditkan sesuai `payment_amount_usd` di webhook — cocok untuk top-up. Jika dikosongkan, berlaku “Aturan jumlah pembayaran” di “Pengaturan › Aturan pembayaran & tarif” pada dasbor: “kreditkan yang masuk” berarti 100 |
| `subtract` | Tidak | Bagian biaya platform yang ditanggung pelanggan, 0 – 100, ditambahkan ke `payer_amount` (biaya platform 1%, makin rendah pada volume lebih tinggi; pada 1%, dengan 100 tagihan $100 membuat pelanggan membayar $101.00; lihat [harga](https://blockwallets.io/pricing?lang=id)). Jika dikosongkan, berlaku pengaturan “Biaya dan kurang bayar” di “Pengaturan › Aturan pembayaran & tarif” pada dasbor (default 0) |
| `is_payment_multiple` | Tidak | Apakah pembayaran yang kurang boleh ditambah, default true: status `wrong_amount_waiting`, membayar sisanya ke alamat yang sama membuatnya `paid` (jika sisa waktu kurang dari 30 menit saat pembayaran kurang pertama, batas waktu diundur menjadi 30 menit kemudian). false: transfer pertama yang kurang membuatnya `wrong_amount`. Jika dikosongkan, berlaku pengaturan di dasbor |
| `additional_data` | Tidak | String apa pun (≤ 255), dikembalikan apa adanya di kueri dan 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`, dan `payer_amount` terisi setelah pelanggan memilih jaringan.

#### 3. Kueri tagihan

- `POST /v1/payment/info` `{"order_id": "…"}` atau `{"uuid": "…"}`: ambil satu tagihan dan sekalian periksa chain (paling sering sekali per 10 detik).

- `POST /v1/payment/list`: daftar, 15 per halaman, `date_from` / `date_to` opsional; halaman berikutnya lewat `paginate.nextCursor` yang dikembalikan (`?cursor=…`).

- `POST /v1/payment/services`: jaringan yang tersedia dan jumlah minimum tiap jaringan.

- `POST /v1/payment/resend` `{"order_id": "…"}`: kirim ulang webhook tagihan yang lunas / kurang bayar.

Webhook adalah kanal utama; kueri adalah cadangan (misalnya jika server Anda sedang mati dan melewatkan webhook).

#### 4. Dompet statis POST /v1/wallet

Membuka alamat permanen untuk satu pelanggan di satu jaringan. `order_id` yang sama (biasanya id pengguna Anda) + jaringan selalu menghasilkan alamat yang sama; semua chain EVM (BNB Chain, Ethereum, Base, Polygon, Arbitrum, Optimism, Avalanche, X Layer) berbagi satu alamat, sedangkan TRON, BTC, LTC, DOGE, BCH, Solana, dan TON masing-masing punya alamat sendiri. Apa pun yang dikirim pelanggan dikreditkan, dengan satu webhook per transfer; transfer BTC / LTC / DOGE / BCH / TRX / BNB / ETH / POL / AVAX / OKB / SOL / TON dikonversi ke dolar AS dengan kurs saat masing-masing terlihat (`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` adalah halaman setoran yang kami host (alamat + kode QR + setoran terbaru) yang bisa Anda berikan ke pelanggan. Transfer di bawah minimum jaringan (biasanya $1, BTC $5) tidak dikreditkan otomatis; hubungi kami agar dikreditkan. Pemblokiran alamat (`/v1/wallet/block-address`) belum didukung.

### Webhook

Saat status tagihan berubah (`paid`, `paid_over`, `wrong_amount_waiting`, `wrong_amount`, `cancel`) dan untuk setiap transfer ke dompet statis, kami mengirim POST JSON ke `url_callback`. Respons 2xx dianggap terkirim; jika tidak, kami mencoba lagi setelah 1 menit, 5 menit, 30 menit, 2 jam, 12 jam, 24 jam, dan 24 jam. Anda juga bisa mengirim ulang dari dasbor atau dengan `/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 | Kapan | Kredit |
| --- | --- | --- |
| `payment` | Status tagihan berubah — lihat `status` | Kreditkan `payment_amount_usd` pada `paid` / `paid_over`; hindari duplikat berdasarkan `uuid` |
| `wallet` | Sebuah transfer masuk ke dompet statis (`status` selalu `paid`; `order_id` adalah yang Anda pakai saat membuka dompet) | Kreditkan `payment_amount_usd`; setiap transfer punya `uuid` sendiri — hindari duplikat berdasarkan itu |

#### Verifikasi tanda tangan (wajib)

Tanda tangan adalah field `sign` di body webhook: hapus `sign`, encode ulang sisanya seperti `json_encode` PHP (ringkas, `/` di-escape menjadi `\/`, karakter non-ASCII tidak di-escape), lalu `md5(base64(encoded) + API key)` harus sama dengan `sign`. Pakai API key dari mode yang sama. Webhook yang sama bisa datang lebih dari sekali — hindari duplikat berdasarkan `uuid` + `status`.

Jika verifikasi gagal, tempel body webhook mentah ke [pemeriksa tanda tangan](https://blockwallets.io/docs/sign?lang=id): ia menampilkan hasil setiap langkah dan menandai di mana hasil Anda berbeda (semuanya berjalan di browser Anda; API key tidak pernah diunggah). Setiap webhook di “Developer › Log webhook” dasbor terbuka di pemeriksa dengan sekali klik.

```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)
```

### Mode uji

Tagihan yang dibuat dengan merchant dan API key Test berjalan di testnet, tanpa uang sungguhan. Halaman pembayaran menampilkan tombol “Simulasikan pembayaran” (penuh / setengah / lebih), sehingga Anda bisa melihat perubahan status dan webhook tanpa perlu koin testnet.

- `POST /v1/test-webhook/payment`, `/v1/test-webhook/wallet`: kirim contoh webhook bertanda tangan ke `url_callback` (sertakan `url_callback` — wajib, di domain situs terdaftar Anda — serta `currency`, `network`, opsional `status`, `order_id`) untuk men-debug kode verifikasi Anda.

- Dasbor “Developer › Integrasi & kunci” → “Kirim notifikasi uji”: mengirim contoh ke URL webhook Anda.

- Dasbor “Developer › Log webhook”: setiap percobaan pengiriman dengan waktu, URL tujuan, status HTTP, durasi, body permintaan, dan respons server Anda (4 KB pertama); filter berdasarkan pesanan atau status dan kirim ulang dengan satu klik. Disimpan 30 hari.

### Pindah dari Cryptomus

- Dasbor “Developer › Integrasi & kunci” → buat merchant dan API key.

- Ganti `https://api.cryptomus.com` di kode Anda dengan `https://blockwallets.io`, lalu pakai merchant dan API key yang baru.

- Tambahkan domain Anda di “Domain situs web” (`url_callback` / `url_return` / `url_success` hanya menerima domain ini).

Didukung: `/v1/payment`, `/v1/payment/info`, `/v1/payment/list`, `/v1/payment/services`, `/v1/payment/resend`, `/v1/wallet`, `/v1/test-webhook/payment`, `/v1/test-webhook/wallet`. Perbedaan: tagihan hanya dihargai dalam USD / USDT / USDC (semuanya 1:1, tanpa selisih kurs); `commission` adalah biaya platform kami (jumlah yang diterima × tarif merchant saat tagihan dibuat — 1% standar, turun hingga 0.5% sesuai volume; tidak ada yang ditagih dua kali pada bagian yang ditanggung pelanggan) dan `merchant_amount` = diterima − `commission`; saat pelanggan membayar dengan BTC / LTC / DOGE / BCH / TRX / BNB / ETH / POL / AVAX / OKB / SOL / TON kami memberi kutipan median beberapa exchange, dikunci selama 30 menit — `payer_amount` adalah jumlah koin yang harus dikirim, `payer_amount_exchange_rate` adalah nilai USD satu koin, dan pembayaran dikonversi ke `payment_amount_usd` dengan kurs terkunci (koin tetap pada kami, tidak ada yang ditukar); jaringan `tron` / `bsc` / `eth` / `base` / `polygon` / `arbitrum` / `optimism` / `avalanche` / `xlayer` / `btc` / `ltc` / `doge` / `bch` / `sol` / `ton`; masa berlaku tagihan minimum 10 menit; tidak ada `is_refresh` dan tidak ada pemblokiran dompet statis; webhook default-nya datang dari IP yang berubah-ubah; jika Anda memakai allow-list IP, aktifkan “Webhook dari IP tetap” di dasbor pada “Developer › Integrasi & kunci” dan webhook hanya datang dari `18.163.145.41` — allow-list adalah lapisan tambahan, tetap verifikasi `sign`.

Datang dari **NOWPayments** atau **Coinbase Commerce**? Kami punya API yang kompatibel untuk keduanya — ganti base URL dan kunci; lihat [panduan migrasi](https://blockwallets.io/docs/migrate?lang=id).

### Jaringan dan jumlah

| Koin | Jaringan | Parameter network | Minimum | Tiba |
| --- | --- | --- | --- | --- |
| USDT | TRON | `tron` | $1 | ~1 mnt |
| USDT | BNB Chain | `bsc` | $1 | ~1 mnt |
| USDC | BNB Chain | `bsc` | $1 | ~1 mnt |
| USDT | Ethereum | `eth` | $5 | ~1 mnt |
| USDC | Ethereum | `eth` | $5 | ~1 mnt |
| USDC | Base | `base` | $1 | ~1 mnt |
| USDT | Polygon | `polygon` | $1 | ~1 mnt |
| USDC | Polygon | `polygon` | $1 | ~1 mnt |
| USDT | Arbitrum | `arbitrum` | $1 | ~1 mnt |
| USDC | Arbitrum | `arbitrum` | $1 | ~1 mnt |
| USDT | Optimism | `optimism` | $1 | ~1 mnt |
| USDC | Optimism | `optimism` | $1 | ~1 mnt |
| USDT | Avalanche | `avalanche` | $1 | ~1 mnt |
| USDC | Avalanche | `avalanche` | $1 | ~1 mnt |
| USDT | X Layer | `xlayer` | $1 | ~1 mnt |
| USDC | X Layer | `xlayer` | $1 | ~1 mnt |
| USD1 | BNB Chain | `bsc` | $1 | ~1 mnt |
| FDUSD | BNB Chain | `bsc` | $1 | ~1 mnt |
| DAI | Ethereum | `eth` | $5 | ~1 mnt |
| DAI | Arbitrum | `arbitrum` | $1 | ~1 mnt |
| DAI | Base | `base` | $1 | ~1 mnt |
| BTC | Bitcoin | `btc` | $5 | ~10 mnt |
| LTC | Litecoin | `ltc` | $1 | ~3 mnt |
| DOGE | Dogecoin | `doge` | $1 | ~1 mnt |
| BCH | Bitcoin Cash | `bch` | $1 | ~10 mnt |
| TRX | TRON | `tron` | $1 | ~1 mnt |
| BNB | BNB Chain | `bsc` | $1 | ~1 mnt |
| ETH | Ethereum | `eth` | $5 | ~1 mnt |
| ETH | Base | `base` | $1 | ~1 mnt |
| ETH | Arbitrum | `arbitrum` | $1 | ~1 mnt |
| ETH | Optimism | `optimism` | $1 | ~1 mnt |
| POL | Polygon | `polygon` | $1 | ~1 mnt |
| AVAX | Avalanche | `avalanche` | $1 | ~1 mnt |
| OKB | X Layer | `xlayer` | $1 | ~1 mnt |
| USDT | Solana | `sol` | $1 | ~1 mnt |
| USDC | Solana | `sol` | $1 | ~1 mnt |
| SOL | Solana | `sol` | $1 | ~1 mnt |
| USDT | TON | `ton` | $1 | ~1 mnt |
| TON | TON | `ton` | $1 | ~1 mnt |

Biaya ERC-20 tinggi, jadi minimumnya $5; biaya Bitcoin juga tidak rendah, minimum $5; sisanya $1. Pelanggan harus mengirim lewat jaringan yang tertera di halaman pembayaran — dana yang dikirim lewat jaringan lain tidak dikreditkan otomatis. BTC / LTC / DOGE / BCH tampil “terdeteksi” begitu masuk mempool dan dihitung setelah cukup konfirmasi; transaksi yang diganti (RBF) atau dibuang tidak dihitung. Koin native (TRX, BNB, ETH, POL, AVAX, OKB, SOL, TON) dikutip dengan kurs terkunci dan dikreditkan dalam dolar AS seperti BTC / LTC / DOGE / BCH; tentukan jaringan dan koin: tagihan `network: "bsc", to_currency: "BNB"`, dompet statis `network: "bsc", currency: "BNB"`. Jaringan saja berarti USDT di chain itu (USDC di Base). Transfer yang dilakukan kontrak (multisig, pembayaran massal) juga diterima; di beberapa chain hash transaksinya tidak tersedia dan `txid` di webhook bernilai `null`.

### Error

```json
{ "state": 1, "message": "amount must be a number like 10.28" }
```

| HTTP | Penyebab umum |
| --- | --- |
| 422 | Parameter hilang atau salah format; jumlah di bawah minimum jaringan; URL callback / pengalihan tidak berada di domain terdaftar Anda; koin / jaringan tidak didukung di `/v1/payment` |
| 401 | Merchant salah, `sign` salah (`Invalid Sign.`), atau API key sudah diganti |
| 404 | Tagihan tidak ada atau bukan milik Anda (`Payment not found`); di `/v1/wallet`, kombinasi koin / jaringan tidak didukung (`The service was not found`) |
| 503 | Jaringan sedang tidak tersedia sementara — pilih yang lain atau jangan pilih lebih dulu |

Saat tanda tangan salah (`Invalid Sign.`), respons memuat objek `debug`: `body_base64` adalah base64 dari body permintaan yang kami terima (isi milik Anda sendiri, bukan API key) dan `body_bytes` panjangnya. Bandingkan dengan base64 yang Anda tandatangani: jika berbeda, body yang Anda kirim bukan string yang Anda tandatangani (framework Anda men-serialisasi ulang, proxy mengubah encoding, ada baris baru di akhir); jika sama, API key salah. Tempel ke [pemeriksa tanda tangan](https://blockwallets.io/docs/sign?lang=id) untuk melihat perbedaan pertama.

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

### Tanya jawab

#### Pelanggan top-up dengan jumlah bebas — pakai mode apa?

Tagihan. Biarkan pelanggan mengisi jumlah di halaman top-up Anda, buat tagihan untuk jumlah itu, lalu kreditkan `payment_amount_usd` saat dana masuk. Pakai dompet statis hanya jika pelanggan sebaiknya menyimpan satu alamat dan berulang kali mengirim ke sana.

#### Bagaimana jika pelanggan kurang bayar?

Sebelum kedaluwarsa pelanggan bisa mengirim selisihnya di halaman pembayaran (halaman menampilkan sisa yang masih harus dibayar; status `wrong_amount_waiting`, dan jika sisa waktu kurang dari 30 menit saat pembayaran kurang pertama, batas waktu diundur menjadi 30 menit kemudian). Jika masih kurang saat kedaluwarsa, tagihan menjadi `wrong_amount` dan `payment_amount_usd` di webhook adalah jumlah yang diterima; bisnis top-up cukup mengkreditkan jumlah itu.

#### Bagaimana jika pelanggan membayar terlambat, atau dua kali?

Dana yang masuk setelah kedaluwarsa tetap dikreditkan dan diberitahukan; dana yang masuk setelah tagihan lunas penuh juga dicatat dan terlihat di dasbor.

#### Bagaimana jika pelanggan mengirim lewat jaringan yang salah?

Misalnya tagihan di TRON dan mereka mengirim dari BNB Chain: dana tidak dikreditkan otomatis — hubungi kami dan kami tangani secara manual.

#### Berapa biayanya?

1% dari setiap pembayaran yang diterima, turun otomatis sesuai volume bulan lalu (0.9% mulai $50,000, 0.8% mulai $100,000, 0.7% mulai $250,000, 0.6% mulai $500,000, dan 0.5% mulai $1,000,000), tanpa biaya bulanan atau pendaftaran. Pelanggan membayar biaya jaringan saat mengirim; untuk meneruskan biaya ke pelanggan, atur `subtract` saat membuat tagihan atau sebagai default di dasbor. Penarikan tidak dikenai biaya tambahan. Lihat [harga](https://blockwallets.io/pricing?lang=id).

#### Kapan dana sampai ke saya?

Dana dikreditkan ke saldo Anda begitu pembayaran terkonfirmasi. Ajukan penarikan ke dompet Anda sendiri di “Dana › Saldo & penarikan”; setelah kami setujui, kami membayarkan, dan transaksi on-chain muncul di riwayat penarikan Anda.

Anda juga bisa mengaktifkan penarikan otomatis: saat saldo tersedia mencapai jumlah yang Anda tentukan, atau sekali sehari pukul 00:00 UTC, seluruh saldo tersedia ditarik. Penarikan otomatis ditinjau dengan cara yang sama, dan setiap perubahan pengaturan mengirim pemberitahuan ke email Anda.
