NOWPayments uyumlu API

ChatGPT'de açClaude'da aç

Yollar, x-api-key başlığı, istek ve yanıt alanları, durumlar ve x-nowpayments-sig IPN imzası NOWPayments dokümanlarını izler; bu yüzden mevcut kod genellikle yalnızca yeni bir temel URL, API key ve IPN secret ister. Başka bir yerden mi geliyorsunuz? Geçişe genel bakışa bakın.

Altta düzenli bir blockwallets faturası vardır: alım adresleri sizindir, ödeme sayfası bizim barındırdığımız ödeme sayfasıdır ve bir ödeme ancak zincirde onaylanıp ikinci bir node ile çapraz kontrol edildiğinde sayılır. Aşağıda: üç adım, ardından her API'nin neyi desteklediği ve orijinalinden nasıl farklı olduğu — uygulamadığımız parametreler sessizce yok sayılmak yerine hata döndürür.

Üç adım

  1. Bir satıcı hesabı edinin (ana sayfadan başvurun) ve panelde “Geliştiriciler › Entegrasyon ve anahtarlar” sayfasındaki “Web sitesi alan adları” altına alan adlarınızı ekleyin. Callback URL'leri (ipn_callback_url) ve yönlendirme URL'leri (success_url / cancel_url / redirect_url) bu alan adlarında ya da callback URL'nizin alan adında olmalıdır — sızan bir anahtar webhook'ları başka yere yönlendiremez.
  2. Satıcı panelinde “Geliştiriciler › Entegrasyon ve anahtarlar” altında uyumlu kimlik bilgileri oluşturun; canlı için bir, test için bir takım: NOWPayments için bir API key + IPN secret, Coinbase Commerce için bir API key + webhook shared secret. Bir kez gösterilirler; biz yalnızca hash / şifreli metin saklarız.
  3. Kodunuzu aşağıdaki temel URL'ye yönlendirin ve yeni anahtarları kullanın. Önce test kimlik bilgileriyle testnet'lerde çalıştırın, sonra canlıya geçin.
ÖnceSonraKimlik doğrulama başlığıWebhook imzası
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();

Desteklenen endpoint'ler

EndpointNotlar
GET /status{"message":"OK"}, anahtar gerekmez
GET /currencies · /merchant/coins · /full-currenciesŞu anda kabul edebileceğiniz coin'ler (kodlar aşağıda); fixed_rate yok sayılır
GET /min-amount · GET /estimateAsgari tutarlar ve tahminler; yalnızca USD fiyatlandırma (USDT / USDC 1:1 sayılır)
POST /paymentÖdeme oluşturur; hemen pay_address / pay_amount döndürür (white-label)
POST /invoiceFatura (invoice) oluşturur; invoice_url, müşterinin coin ve ağ seçtiği, bizim barındırdığımız ödeme sayfasıdır
POST /invoice-paymentBir fatura için coin seçer, ödemeyi döndürür
GET /payment/:idÖdeme durumu
GET /payment/Liste: limit (1–500) / page / orderBy / dateFrom / dateTo / invoiceId; sortBy yalnızca created_at
POST /authListe yalnızca x-api-key ister, JWT gerekmez; bu endpoint doğrulanmayan bir yer tutucu token döndürür, böylece “giriş yap, sonra listele” kodu çalışmaya devam eder (e-posta / parola denetlenmez)

Mevcut değil: ödemeler (payout), dönüşümler, saklama alt ortakları, abonelikler, update-merchant-estimate, fiat ödemeler. Bu yollar 404 döndürür.

IPN callback'leri

Bir ödeme son duruma ulaştığında oluşturma sırasında verilen ipn_callback_url adresine POST'larız; x-nowpayments-sig = HMAC-SHA512(IPN secret, anahtarlara göre özyinelemeli sıralanmış JSON) — tam olarak NOWPayments'ın doğrulama kodu. Gönderdiğimiz gövde zaten sıralı, sıkıştırılmış JSON'dur; bu yüzden ham gövde üzerinden HMAC de çalışır (ve çok küçük ondalıkları yeniden kodlaması JS'ten farklı olabilen PHP / Python'da en güvenli seçimdir). Başarısız callback'ler 1 dk, 5 dk, 30 dk, … sonra yeniden denenir — toplam 8 deneme.

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_statusNe zamanGönderilen IPN
waitingÖdeme bekleniyor (henüz coin seçilmemiş bir fatura da dahil)—
confirmingÖdeme zincirde görüldü, onaylar bekleniyor— (sorguladığınızda görünür)
finishedÖdendi (fazla ödenmiş dahil; actually_paid gelen tutardır)✓
partially_paidEksik: müşteri süre dolmadan aynı adrese tamamlayabilir (ilk eksik ödemede bir kez gönderilir), süre dolduğunda hâlâ eksikse yine gönderilir✓
expiredÖdenmeden süresi doldu✓
refundedÖdemenin tamamını panelden iade ettiniz ve gönderildi— (sorguladığınızda görünür)

confirmed, sending ve failed hiç görünmez: onaylandığında finished olur ve bakiyenize yatırılır; hiçbir şey başka yere iletilmez.

Coin kodları

CoinAğpay_currencynetworkAsgari
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

NOWPayments'tan farklar

Test modu

Test kimlik bilgileriyle oluşturulan charge'lar ve ödemeler her zincirin testnet'inde çalışır ve webhook'ları test IPN secret / shared secret ile imzalanır — canlıdan tamamen ayrıdır: bir test anahtarı canlı ödemeleri göremez.

Geri kalan her şey (ödeme sayfası, onaylar, ağlar ve asgari tutarlar, iadeler) ana dokümanlardaki gibi çalışır.