Skip to main content

NOWPayments

NOWPayments crypto payment integration — accept 150+ cryptocurrencies with sandbox support.

Installation

npm install @foxses/pay-nowpayments

How It Works

NOWPayments uses a hosted invoice page:

  1. Create Invoice — POST to NOWPayments API → get invoice_url
  2. Redirect user to the NOWPayments invoice page
  3. User pays with any supported crypto
  4. NOWPayments confirms on-chain
  5. Verify — check payment status via API or IPN webhook

Configuration

gateway.use("nowpayments", {
apiKey: "YOUR_NOWPAYMENTS_API_KEY", // required
successUrl: "https://yoursite.com/success", // required
failureUrl: "https://yoursite.com/cancel", // required
ipnSecretKey: "YOUR_IPN_SECRET", // optional — for IPN webhook
sandbox: true, // optional, default: false
});
FieldTypeDescription
apiKeystringNOWPayments API key
successUrlstringRedirect after payment
failureUrlstringRedirect on cancel
ipnSecretKeystringIPN secret for webhook verification (optional)
sandboxbooleanUse sandbox environment (true = sandbox)

Getting API Key

Production:

  1. Go to nowpayments.io
  2. Store Settings → API Keys → Add API key

Sandbox:

  1. Go to sandbox.nowpayments.io
  2. Store Settings → API Keys → Add API key

Create Payment

const payment = await gateway.createPayment("nowpayments", {
amount: 100,
currency: "USD", // fiat pricing currency
orderId: "ORDER-001",
});

Response:

{
transactionId: "abc123-invoice-id",
provider: "nowpayments",
amount: 100,
currency: "USD",
status: "pending",
checkoutUrl: "https://nowpayments.io/payment/?iid=abc123",
}

Verify Payment

After NOWPayments redirects or via IPN, verify using the payment ID:

const result = await gateway.verifyPayment("nowpayments", {
transactionId: "PAYMENT_ID", // numeric payment ID
});

Response:

{
transactionId: "5678901",
provider: "nowpayments",
amount: 100,
currency: "USD",
status: "completed",
}

Get Payment Status

const status = await gateway.getPaymentStatus("nowpayments", "PAYMENT_ID");

Status Mapping

NOWPayments Statusfoxses-pay Status
waitingpending
confirmingpending
confirmedcompleted
finishedcompleted
failedfailed
refundedrefunded
expiredcancelled

IPN Webhook (Optional)

NOWPayments sends IPN callbacks when payment status changes.

app.post("/nowpayments/ipn", express.json(), async (req, res) => {
const crypto = require("crypto");

// Verify IPN signature
const sig = req.headers["x-nowpayments-sig"] as string;
const sorted = JSON.stringify(
Object.fromEntries(Object.entries(req.body).sort())
);
const expected = crypto
.createHmac("sha512", process.env.NP_IPN_SECRET)
.update(sorted)
.digest("hex");

if (sig !== expected) {
return res.status(400).send("Invalid signature");
}

const { payment_status, order_id, payment_id } = req.body;

if (payment_status === "finished") {
await fulfillOrder(order_id);
}

res.sendStatus(200);
});

Supported Cryptocurrencies

150+ cryptos including:

CryptoSymbol
BitcoinBTC
EthereumETH
TetherUSDT
BNBBNB
SolanaSOL
CardanoADA
PolygonMATIC
DogecoinDOGE

Full list: nowpayments.io/supported-coins

Important Notes

  • No programmatic refunds — refund manually from the NOWPayments dashboard.
  • Sandbox is a separate environment at sandbox.nowpayments.io — needs a separate API key.
  • Underpayment — if user pays less than required, NOWPayments marks it as partially paid. Handle via IPN.

Credentials