API kompatibel NOWPayments

Buka di ChatGPTBuka di Claude

Path, header x-api-key, field permintaan dan respons, status, serta tanda tangan IPN x-nowpayments-sig mengikuti dokumentasi NOWPayments, sehingga kode yang ada biasanya hanya perlu base URL, API key, dan IPN secret baru. Datang dari tempat lain? Lihat ringkasan migrasi.

Di baliknya adalah tagihan blockwallets biasa: alamat penerima milik Anda, halaman pembayaran adalah kasir yang kami host, dan pembayaran baru dihitung setelah terkonfirmasi di chain dan diperiksa silang dengan node kedua. Di bawah ini: tiga langkah, lalu apa yang didukung setiap API dan apa bedanya dengan aslinya — parameter yang tidak kami implementasikan mengembalikan error, bukan diabaikan diam-diam.

Tiga langkah

  1. Dapatkan akun merchant (ajukan di beranda) dan tambahkan domain Anda di “Domain situs web” pada “Developer › Integrasi & kunci” di dasbor. URL callback (ipn_callback_url) dan URL pengalihan (success_url / cancel_url / redirect_url) harus berada di domain itu atau di domain URL callback Anda — kunci yang bocor tidak bisa mengarahkan webhook ke tempat lain.
  2. Buat kredensial kompatibel di dasbor merchant pada “Developer › Integrasi & kunci”, satu set untuk live dan satu untuk uji: NOWPayments mendapat API key + IPN secret, Coinbase Commerce mendapat API key + webhook shared secret. Semuanya ditampilkan sekali; kami hanya menyimpan hash / ciphertext.
  3. Arahkan kode Anda ke base URL di bawah dan pakai kunci baru. Jalankan dulu di testnet dengan kredensial uji, lalu beralih ke live.
SebelumSesudahHeader autentikasiTanda tangan webhook
https://api.nowpayments.io/v1https://blockwallets.io/nowpayments/v1x-api-keyx-nowpayments-sig (HMAC-SHA512)

NOWPayments

JavaScript
- const NP = "https://api.nowpayments.io/v1";
+ const NP = "https://blockwallets.io/nowpayments/v1";

const res = await fetch(`${NP}/payment`, {
  method: "POST",
  headers: { "x-api-key": process.env.NOWPAYMENTS_API_KEY, "content-type": "application/json" },
  body: JSON.stringify({
    price_amount: 49.9, price_currency: "usd", pay_currency: "usdttrc20",
    order_id: "A-1001", order_description: "Pro plan",
    ipn_callback_url: "https://shop.example/ipn/nowpayments",
  }),
});
const { payment_id, pay_address, pay_amount } = await res.json();

Endpoint yang didukung

EndpointCatatan
GET /status{"message":"OK"}, tanpa kunci
GET /currencies · /merchant/coins · /full-currenciesKoin yang bisa Anda terima saat ini (ticker di bawah); fixed_rate diabaikan
GET /min-amount · GET /estimateMinimum dan estimasi; hanya harga USD (USDT / USDC dihitung 1:1)
POST /paymentMembuat pembayaran; langsung mengembalikan pay_address / pay_amount (white-label)
POST /invoiceMembuat invoice; invoice_url adalah kasir yang kami host tempat pelanggan memilih koin dan jaringan
POST /invoice-paymentMemilih koin untuk sebuah invoice, mengembalikan pembayarannya
GET /payment/:idStatus pembayaran
GET /payment/Daftar: limit (1–500) / page / orderBy / dateFrom / dateTo / invoiceId; sortBy hanya created_at
POST /authDaftar hanya butuh x-api-key, tanpa JWT; endpoint ini mengembalikan token placeholder yang tidak diperiksa agar kode “login lalu tampilkan daftar” tetap berjalan (email / password tidak diperiksa)

Tidak tersedia: payout, konversi, sub-partner kustodian, langganan, update-merchant-estimate, pembayaran fiat. Path tersebut mengembalikan 404.

Callback IPN

Saat pembayaran mencapai status akhir, kami mengirim POST ke ipn_callback_url yang diberikan saat pembuatan, dengan x-nowpayments-sig = HMAC-SHA512(IPN secret, JSON yang diurutkan berdasarkan key secara rekursif) — persis kode verifikasi NOWPayments. Body yang kami kirim sudah berupa JSON ringkas yang terurut, jadi HMAC atas body mentah juga berfungsi (dan paling aman di PHP / Python, yang encode ulang desimal sangat kecil bisa berbeda dari JS). Callback yang gagal dicoba lagi setelah 1 mnt, 5 mnt, 30 mnt, … — total 8 percobaan.

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

// Same as the NOWPayments docs (our body is already sorted, so hashing the raw body works too)
function sortObject(obj) {
  return Object.keys(obj).sort().reduce((r, k) => {
    r[k] = obj[k] && typeof obj[k] === "object" ? sortObject(obj[k]) : obj[k];
    return r;
  }, {});
}
function verifyIpn(params, sig, ipnSecret) {
  const hmac = crypto.createHmac("sha512", ipnSecret).update(JSON.stringify(sortObject(params))).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(hmac), Buffer.from(sig || ""));
}
// verifyIpn(req.body, req.headers["x-nowpayments-sig"], process.env.NOWPAYMENTS_IPN_SECRET)
PHP
$raw = file_get_contents('php://input');
$data = json_decode($raw, true);
tksort($data);  // the recursive ksort from the NOWPayments docs
$hmac = hash_hmac('sha512', json_encode($data, JSON_UNESCAPED_SLASHES), trim($ipnSecret));
$ok = hash_equals($hmac, $_SERVER['HTTP_X_NOWPAYMENTS_SIG'] ?? '');
payment_statusKapanIPN yang dikirim
waitingMenunggu pembayaran (juga invoice yang belum dipilih koinnya)—
confirmingPembayaran terlihat di chain, menunggu konfirmasi— (terlihat saat Anda melakukan kueri)
finishedLunas (termasuk kelebihan bayar; actually_paid adalah jumlah yang masuk)✓
partially_paidKurang: pelanggan masih bisa menambah ke alamat yang sama sebelum kedaluwarsa (dikirim sekali saat pembayaran kurang pertama), dan lagi jika masih kurang saat kedaluwarsa✓
expiredKedaluwarsa tanpa pembayaran✓
refundedAnda me-refund seluruh pembayaran dari dasbor dan sudah terkirim— (terlihat saat Anda melakukan kueri)

confirmed, sending, dan failed tidak pernah muncul: setelah terkonfirmasi statusnya finished dan dikreditkan ke saldo Anda; tidak ada yang diteruskan.

Ticker mata uang

KoinJaringanpay_currencynetworkMinimum
USDTTRONusdttrc20trx$1
USDTBNB Chainusdtbsc usdtbep20bsc$1
USDCBNB Chainusdcbsc usdcbep20bsc$1
USDTEthereumusdterc20eth$5
USDCEthereumusdc usdcerc20eth$5
USDCBaseusdcbasebase$1
USDTPolygonusdtmatic usdtpolygonmatic$1
USDCPolygonusdcmatic usdcpolygonmatic$1
USDTArbitrumusdtarbarbitrum$1
USDCArbitrumusdcarbarbitrum$1
USDTOptimismusdtopop$1
USDCOptimismusdcopop$1
USDTAvalancheusdtarc20 usdtavax / usdtavaxcavaxc$1
USDCAvalancheusdcarc20 usdcavax / usdcavaxcavaxc$1
USDTX Layerusdtxlayerxlayer$1
USDCX Layerusdcxlayerxlayer$1
USD1BNB Chainusd1bscbsc$1
FDUSDBNB Chainfdusdbscbsc$1
DAIEthereumdai daierc20eth$5
DAIArbitrumdaiarbarbitrum$1
DAIBasedaibasebase$1
BTCBitcoinbtcbtc$5
LTCLitecoinltcltc$1
DOGEDogecoindogedoge$1
BCHBitcoin Cashbchbch$1
TRXTRONtrxtrx$1
BNBBNB Chainbnbbsc bnbbsc$1
ETHEthereumetheth$5
ETHBaseethbasebase$1
ETHArbitrumetharbarbitrum$1
ETHOptimismethopop$1
POLPolygonmaticmainnet pol / polmainnet / maticmatic$1
AVAXAvalancheavaxc avaxavaxc$1
OKBX Layerokbxlayerxlayer$1
USDTSolanausdtsolsol$1
USDCSolanausdcsolsol$1
SOLSolanasolsol$1
USDTTONusdttonton$1
TONTONtonton$1

Perbedaan dari NOWPayments

Mode uji

Charge dan pembayaran yang dibuat dengan kredensial uji berjalan di testnet tiap chain dan webhook-nya ditandatangani dengan IPN secret / shared secret uji — sepenuhnya terpisah dari live: kunci uji tidak bisa melihat pembayaran live.

Sisanya (kasir, konfirmasi, jaringan dan minimum, refund) bekerja seperti di dokumentasi utama.