NowPayments IPN signatures use HMAC-SHA512 — the same algorithm we use, against a different key. Most merchants move the invoice surface in under an hour. Concrete mapping below.
POST api.nowpayments.io/v1/invoiceRENAMEPOST orbchain.io/v1/payment/invoiceORBPOST api.nowpayments.io/v1/paymentMAPPOST orbchain.io/v1/payment/white-labelORBPOST orbchain.io/v1/payment/static-addressORBPOST api.nowpayments.io/v1/payoutRENAMEPOST orbchain.io/v1/payout/batchORBGET api.nowpayments.io/v1/payment/:idRESHAPEGET orbchain.io/v1/payment/:track_idORBprice_amountamountRENAMEprice_currencycurrencyRENAMEpay_currency (single, required)pay_currency (single) OR accepted_coins (multiple)MULTI-OKorder_idorder_idSAMEorder_descriptiondescriptionRENAMEipn_callback_urlcallback_urlRENAMEsuccess_urlreturn_urlRENAMEcancel_urlcancel_urlSAME// NowPayments — before curl https://api.nowpayments.io/v1/invoice \ -H "x-api-key: NP_…" \ -H "Content-Type: application/json" \ -d '{ "price_amount": 50, "price_currency": "USD", "pay_currency": "usdt", "order_id": "order_7f92a1", "ipn_callback_url": "https://shop.example/ipn", "success_url": "https://shop.example/ok" }' // OrbChain — after curl https://orbchain.io/v1/payment/invoice \ -H "merchant_api_key: mk_live_…" \ -H "Content-Type: application/json" \ -d '{ "amount": 50, "currency": "USD", "accepted_coins": ["USDT_TRC20", "USDC_TRC20"], "order_id": "order_7f92a1", "callback_url": "https://shop.example/webhooks/orb", "return_url": "https://shop.example/ok" }'
// NowPayments — HMAC-SHA512 with `NP_IPN_SECRET`, header `x-nowpayments-sig` function verifyNP(rawBody, header) { const expected = crypto.createHmac("sha512", process.env.NP_IPN_SECRET) .update(rawBody).digest("hex"); return crypto.timingSafeEqual( Buffer.from(expected, "hex"), Buffer.from(header, "hex") ); } // OrbChain — HMAC-SHA512 with `ORB_WEBHOOK_SECRET`, header `HMAC` function verifyOrb(rawBody, header) { const expected = crypto.createHmac("sha512", process.env.ORB_WEBHOOK_SECRET) .update(rawBody).digest("hex"); return crypto.timingSafeEqual( Buffer.from(expected, "hex"), Buffer.from(header, "hex") ); } // Upgrade: dedupe with OrbChain's deterministic event_id // — NowPayments uses a random UUID that requires your own dedup table. if (seenEventIds.has(payload.event_id)) return res.sendStatus(200);
Most stacks move the invoice surface in under an hour. No custody transfer required — both sides non-live until you flip.