REST API native

Buka di ChatGPTBuka di Claude

API native adalah antarmuka REST milik blockwallets sendiri: invoice berharga sen AS, ref idempoten untuk setiap pesanan, akun deposit statis yang mencakup semua jaringan, dan webhook bertanda tangan HMAC-SHA256. API ini membuat tagihan yang sama di halaman pembayaran yang sama dengan API kompatibel Cryptomus, dengan biaya dan saldo yang sama.

Buat kunci Anda sendiri di dasbor pada “Developer › Integrasi & kunci”: satu kunci Live dan satu kunci Test beserta webhook signing secret-nya. Masing-masing hanya ditampilkan sekali; daftar hanya menampilkan awalannya. Jika akun Anda mengaktifkan verifikasi dua langkah, membuat atau merotasi kunci Live akan meminta kode. Belum punya akun merchant? Minta akses. Sudah memakai Cryptomus? Lihat API kompatibel Cryptomus (cara memilih).

Kunci dan permintaan

Base URL https://blockwallets.io. Permintaan dan respons berupa JSON. Setiap permintaan membawa:

Error mengembalikan status HTTP dan {"error": {"code": "…", "message": "…"}}: 400 invalid_request (field hilang atau formatnya salah), 401 unauthorized (kunci tidak ada, tidak dikenal, atau dinonaktifkan), 404 not_found, 409 conflict (permintaan bertentangan dengan status invoice saat ini), 422 currency_unsupported.

Endpoint

EndpointFungsinya
GET /v1/networksJaringan yang bisa Anda terima saat ini pada mode kunci ini: minimum, konfirmasi, perkiraan waktu tiba, dan perkiraan biaya; koin berharga menyertakan kurs saat ini
POST /v1/invoicesMembuat invoice (201), atau mengembalikan yang sudah ada untuk ref yang sama (200)
GET /v1/invoices?ref=…Mencari invoice berdasarkan ref Anda
GET /v1/invoices/:idMencari invoice berdasarkan id
POST /v1/invoices/:id/networkMemilih sendiri jaringan untuk invoice (halaman pembayaran white-label): mengembalikan address dan pay_amount untuk ditampilkan
POST /v1/invoices/:id/closeMenutup invoice tertunda yang belum menerima transfer apa pun
POST /v1/deposit-accountsMembuka (201) atau mengambil (200) akun deposit satu pelanggan: alamat permanen di setiap jaringan
GET /v1/deposit-accounts?customer_ref=…Mencari akun deposit berdasarkan customer_ref
GET /v1/deposit-accounts/:idMencari akun deposit berdasarkan id
GET /v1/depositsMenampilkan daftar deposit satu akun (account_id atau customer_ref, limit 1–200, default 50)
GET /v1/deposits/:idMencari satu deposit
GET /v1/eventsPengiriman webhook untuk satu invoice atau deposit (invoice_id atau deposit_id)
POST /v1/events/:id/redeliverMengirim ulang webhook (202)

Tambahkan ?probe=1 pada pencarian invoice atau akun deposit untuk memeriksa chain saat itu juga (paling banyak sekali per 10 detik); jika tidak, Anda mendapat status terbaru dari pemindai kami, yang memeriksa setiap menit.

Membuat invoice POST /v1/invoices

Panggil POST /v1/invoices saat pelanggan checkout dan arahkan mereka ke pay_url dalam respons.

curl
curl -X POST https://blockwallets.io/v1/invoices \
  -H "Authorization: Bearer $BW_KEY" -H "Content-Type: application/json" \
  -d '{"ref":"order_1042","amount":4200,"title":"Order #1042",
       "return_url":"https://shop.example/cart","success_url":"https://shop.example/thanks?order=1042",
       "meta":{"user_id":42}}'
FieldWajibDeskripsi
refYaNomor pesanan Anda: 1–64 karakter berupa huruf, angka, dan _ . : -. Unik per mode; mengirim ref yang sama dengan field yang sama lagi mengembalikan invoice yang sama, dengan field berbeda mengembalikan 409
amountYaJumlah dalam sen AS sebagai bilangan bulat: 4200 = $42.00. Tidak di bawah minimum jaringan setelah jaringan dipilih
titleYaYang dilihat pelanggan di halaman pembayaran, maksimal 64 karakter
return_urlYaTujuan tombol “Kembali” di halaman pembayaran; harus berada di salah satu domain situs Anda
success_urlTidakTujuan pelanggan setelah membayar; defaultnya return_url
networkTidakPilih lebih dulu id jaringan dari tabel jaringan; kosongkan agar pelanggan memilih di halaman pembayaran
customer_refTidakId pelanggan Anda, maksimal 64 karakter, dikembalikan apa adanya
lifetimeTidakMasa berlaku dalam detik, 600 – 43200, default 3600
amount_ruleTidak"any" = kreditkan berapa pun yang masuk (top-up): paid segera setelah terkonfirmasi. Kosongkan untuk memakai “Aturan jumlah pembayaran” di “Pengaturan › Aturan pembayaran & tarif” pada dasbor
accuracy_percentTidakSeberapa besar kekurangan bayar yang masih dianggap lunas, 0 – 5 (persen), default 0
subtract_percentTidakBagian biaya platform yang dibayar pelanggan, 0 – 100 (persen), ditambahkan ke pay_amount; kosongkan untuk memakai default dasbor
payment_multipleTidakApakah pembayaran yang kurang boleh dilengkapi ke alamat yang sama, default dari dasbor (aktif kecuali Anda ubah); false: transfer pertama yang kurang berakhir sebagai wrong_amount
metaTidakObjek JSON apa pun hingga 2 KB, dikembalikan apa adanya dalam pencarian dan webhook
currencyTidakHanya USD (default); selain itu mengembalikan 422

Setiap URL harus berada di salah satu domain situs Anda (dasbor → “Developer › Integrasi & kunci”). Responsnya adalah objek invoice di bawah; network, address, dan pay_amount terisi setelah jaringan dipilih.

Objek invoice

Id diawali inv_. amount dalam sen AS; pay_amount dan paid_amount adalah jumlah koin sebagai string desimal pada jaringan yang dipilih.

json
{
  "id": "inv_01J8…",
  "ref": "order_1042",
  "mode": "live",
  "status": "pending",
  "amount": 4200,
  "currency": "USD",
  "title": "Order #1042",
  "meta": { "user_id": 42 },
  "network": null,
  "address": null,
  "pay_amount": null,
  "paid_amount": null,
  "payments": [],
  "pay_url": "https://blockwallets.io/pay/inv_01J8…",
  "return_url": "https://shop.example/cart",
  "success_url": "https://shop.example/thanks?order=1042",
  "created_at": "2026-11-03T08:00:00.000Z",
  "expires_at": "2026-11-03T09:00:00.000Z",
  "paid_at": null,
  "closed_at": null
}
statusArtinyaYang perlu Anda lakukan
pendingMenunggu pembayaran—
confirmingTransfer terlihat dan sedang dikonfirmasi, atau datang kurang dan masih bisa dilengkapi—
paidLunasKirim barang / kreditkan pesanan
paid_overLunas, dan kelebihan bayarSama; kelebihannya ada di saldo Anda
wrong_amountBerakhir dengan jumlah kurang dari penuh (saat kedaluwarsa, atau pada transfer pertama yang kurang jika payment_multiple false)Bisnis top-up bisa mengkreditkan yang masuk (paid_amount; koin berkurs juga punya paid_cents); toko meminta pelanggan membayar sisanya
closedKedaluwarsa tanpa dana masuk, atau Anda menutupnya— (dana yang masuk belakangan tetap dikreditkan dan diberitahukan)

Field lain: pay_url (halaman pembayaran), payments (setiap transfer dengan txid, amount, confirmations, dan confirmed), expires_at, paid_at, closed_at; BTC, LTC, DOGE, BCH, dan koin native juga membawa rate (dolar AS per koin, dikunci 30 menit), rate_locked_until, dan paid_cents (yang sudah masuk, dalam sen AS).

Jaringan

Berikan id sebagai network. GET /v1/networks mengembalikan jaringan yang terbuka saat ini pada mode Anda; jaringan bisa dijeda, jadi lebih baik membacanya daripada menulis nilai secara permanen di kode.

networkKoinChainMinimum
USDT_TRC20USDTTRON$1
USDT_BEP20USDTBNB Chain$1
USDC_BEP20USDCBNB Chain$1
USDT_ERC20USDTEthereum$5
USDC_ERC20USDCEthereum$5
USDC_BASEUSDCBase$1
USDT_POLYGONUSDTPolygon$1
USDC_POLYGONUSDCPolygon$1
USDT_ARBITRUMUSDTArbitrum$1
USDC_ARBITRUMUSDCArbitrum$1
USDT_OPTIMISMUSDTOptimism$1
USDC_OPTIMISMUSDCOptimism$1
USDT_AVALANCHEUSDTAvalanche$1
USDC_AVALANCHEUSDCAvalanche$1
USDT_XLAYERUSDTX Layer$1
USDC_XLAYERUSDCX Layer$1
USD1_BEP20USD1BNB Chain$1
FDUSD_BEP20FDUSDBNB Chain$1
DAI_ERC20DAIEthereum$5
DAI_ARBITRUMDAIArbitrum$1
DAI_BASEDAIBase$1
BTCBTCBitcoin$5
LTCLTCLitecoin$1
DOGEDOGEDogecoin$1
BCHBCHBitcoin Cash$1
TRXTRXTRON$1
BNBBNBBNB Chain$1
ETHETHEthereum$5
ETH_BASEETHBase$1
ETH_ARBITRUMETHArbitrum$1
ETH_OPTIMISMETHOptimism$1
POLPOLPolygon$1
AVAXAVAXAvalanche$1
OKBOKBX Layer$1
USDT_SOLUSDTSolana$1
USDC_SOLUSDCSolana$1
SOLSOLSolana$1
USDT_TONUSDTTON$1
TONTONTON$1

Akun deposit (alamat statis) POST /v1/deposit-accounts

POST /v1/deposit-accounts dengan {"customer_ref": "user_42"} memberi pelanggan itu alamat permanen di setiap jaringan (semua chain EVM memakai satu alamat). Apa pun yang mereka kirim dikreditkan dalam dolar AS, dengan satu webhook deposit.credited per transfer.

curl
curl -X POST https://blockwallets.io/v1/deposit-accounts \
  -H "Authorization: Bearer $BW_KEY" -H "Content-Type: application/json" \
  -d '{"customer_ref":"user_42"}'
json
{
  "id": "dac_01J8…",
  "mode": "live",
  "customer_ref": "user_42",
  "deposit_url": "https://blockwallets.io/deposit/dac_01J8…",
  "min_amount": 100,
  "currency": "USD",
  "networks": [
    { "id": "USDT_TRC20", "chain": "tron", "token": "USDT", "address": "TXy4…8kQ2", "min_amount": 100, "confirmations": 1, … },
    { "id": "USDC_BASE", "chain": "base", "token": "USDC", "address": "0x5aE1…", "min_amount": 100, "confirmations": 20, … }
  ]
}

Transfer di bawah minimum (biasanya $1, BTC $5) dicatat sebagai below_min dan tidak dikreditkan otomatis; hubungi kami agar dikreditkan.

Webhook

Kami mengirim POST JSON ke URL webhook di dasbor (“Developer › Integrasi & kunci”; Live dan Test masing-masing punya URL dan secret sendiri). Body-nya adalah event:

http
POST /your/webhook
X-BW-Event: ev_01J8…
X-BW-Delivery: 1
X-BW-Signature: t=1793693052,v1=5f0c9b…

{"id":"ev_01J8…","type":"invoice.paid","created_at":"2026-11-03T08:04:12.000Z","invoice":{"id":"inv_01J8…","ref":"order_1042","status":"paid","amount":4200,…}}
EventKapan
invoice.paidInvoice menjadi paid atau paid_over (termasuk dana yang masuk setelah kedaluwarsa)
invoice.wrong_amountInvoice berakhir sebagai wrong_amount
invoice.closedInvoice kedaluwarsa tanpa dana masuk, atau Anda menutupnya
deposit.creditedTransfer ke akun deposit telah dikreditkan

Verifikasi terhadap body mentah sebelum mem-parse-nya, tolak t yang selisihnya lebih dari 300 detik dari jam Anda, dan bandingkan dalam waktu konstan. invoice / deposit di body adalah objek yang sama dengan hasil pencarian.

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

// rawBody: the request body exactly as received (a string), header: X-BW-Signature
function verify(rawBody, header, secret) {
  const parts = Object.fromEntries(header.split(",").map((p) => p.trim().split("=")));
  const t = Number(parts.t);
  if (!t || Math.abs(Date.now() / 1000 - t) > 300) return false;
  const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
  return typeof parts.v1 === "string" && parts.v1.length === expected.length
    && crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected));
}

Respons 2xx dianggap terkirim; jika tidak, kami coba lagi setelah 1 menit, 5 menit, 30 menit, 2 jam, 12 jam, 24 jam, dan 24 jam (total 8 percobaan).

Events dan pengiriman ulang

GET /v1/events?invoice_id=inv_… (atau deposit_id=dep_…) menampilkan webhook satu invoice atau deposit beserta state, attempts, last_status, dan last_error. POST /v1/events/ev_…/redeliver langsung mengantrekannya lagi, misalnya setelah Anda memperbaiki endpoint. “Developer › Log webhook” di dasbor menampilkan setiap percobaan beserta permintaan dan responsnya.

Mode uji

Invoice yang dibuat dengan kunci bw_test_ berjalan di testnet dan tidak pernah menyentuh uang sungguhan. Halaman pembayaran menampilkan tombol “Simulasikan pembayaran” (penuh / setengah / lebih), sehingga Anda bisa melihat status dan webhook tanpa koin testnet.