
Crypto Pay API 2026: Developer Comparison of NOWPayments, CoinGate, BTCPay, Plisio
Hands-on comparison of the top 4 crypto payment APIs in 2026, auth, webhooks, idempotency, settlement, sandbox quality, and code samples for each.
Key Takeaways
- Best general-purpose crypto pay API: NOWPayments [Gold tier], 300+ coins, HMAC-SHA512 IPN, libraries in JS, Python, PHP, Go, full sandbox
- Best for EU SaaS with MiCA compliance: CoinGate [Bronze tier], regulated fiat settlement, SEPA payouts, POS API for in-store
- Best for self-sovereignty: BTCPay Server [Bronze tier], you host the API yourself, 0% fees, Greenfield REST endpoints
- Best lightweight integration: Plisio [Gold tier], 0.5% fee, minimal endpoint surface, fastest to wire up in a weekend
- Common gotcha: three of the four APIs require an idempotency key on retries; only BTCPay treats every PUT as idempotent by default
Table of Contents
What makes a crypto pay API "good"
If you have wired up Stripe before, you have a rubric in your head already: clean auth, predictable error envelopes, signed webhooks, idempotency keys, a real sandbox, official libraries. Crypto pay APIs are a younger product category and most of them get one or two of those right, not all six. After integrating dozens of them across client work, here is the developer-grade rubric I use to filter them.
| Criterion | What "good" looks like | Why it matters |
|---|---|---|
| Auth | Bearer token or x-api-key header, rotatable | No basic auth, no key-in-querystring |
| Webhook signing | HMAC over raw body, secret rotatable | Stops forged callbacks crediting orders |
| Idempotency | Idempotency-Key header or stable payment id | Retries during net blips do not double-charge |
| Sandbox | Testnet-backed, free, parity with prod | CI tests without spending real BTC |
| Libraries | Official Node, Python, PHP, Go SDKs | Less boilerplate, fewer signing bugs |
| Settlement | Crypto wallet plus optional fiat payout | Lets finance keep books in fiat |
If you want a higher-level intro before diving in, our crypto payment API guide walks through the general architecture; this article is the head-to-head developer comparison.
The 4-API shortlist, ranked
There are easily 20 crypto pay APIs in the wild. After cutting out the ones with broken sandboxes, dead libraries, or unsigned webhooks, four are worth your time in 2026. This is the order they land in when scored on the rubric above.
| API | Tier | Auth | Webhook sig | Sandbox | Libraries |
|---|---|---|---|---|---|
| NOWPayments | Gold | x-api-key | HMAC-SHA512 | Full | JS, PY, PHP, Go |
| Plisio | Gold | api_key query | SHA1 hash | Limited | PHP, JS only |
| CoinGate | Bronze | Bearer token | Token + token-in-URL | Full (sandbox.coingate.com) | Ruby, PHP, Node |
| BTCPay Server | Bronze | API key header | HMAC-SHA256 | Regtest/testnet | C#, JS, PY, Go |
Tier reflects payyd's overall recommendation across all merchant use cases. For pure developer ergonomics NOWPayments still leads, but BTCPay is unmatched if you want to own the entire stack. Plisio earns Gold despite a smaller library footprint because its API surface is small enough that you barely need an SDK.
The default developer pick
NOWPayments, REST API, 300+ coins, HMAC-signed webhooks, sandbox, 4 official SDKs
Get a NOWPayments API key →Authentication and API keys compared
Auth is where most crypto APIs reveal their age. Some still ship API keys in querystrings; a few use unrotatable single-secret models. Here is what each of the four uses in 2026.
NOWPayments [Gold tier] uses a single x-api-key request header against https://api.nowpayments.io/v1. Keys are scoped per project in the merchant dashboard and you can issue multiple keys with different permission sets (read-only vs full). IPN secrets are separate from API keys, which means you can rotate one without invalidating the other. This separation is a key reason NOWPayments earns Gold on the dev rubric, your customer-facing webhook verification logic does not break when you cycle the outbound API key. Full review: NOWPayments review.
CoinGate [Bronze tier] uses a bearer token against https://api.coingate.com/v2. Tokens are scoped to one merchant account. Webhook auth is the awkward bit, CoinGate echoes a per-order token back in the callback URL so you can verify the request originated from a real order you created. It works but it is less robust than HMAC. The auth model is one of the reasons CoinGate sits at Bronze in the overall ranking even though everything else (MiCA license, SEPA settlement, sandbox) is excellent. See: CoinGate review.
BTCPay Server [Bronze tier] Greenfield uses an API key in the Authorization: token <key> header. You generate keys in your own self-hosted instance with fine-grained per-store permissions (view invoices, create invoices, manage server, etc.). Because you own the server, key rotation is instant. This is the cleanest auth model on the list once you accept the operational cost of running your own node. Setup: BTCPay Server setup guide.
Plisio [Gold tier] takes the simplest, oldest approach, an api_key querystring parameter on every request to https://api.plisio.net/api/v1. It works, it is easy to integrate, but you must be careful never to log full request URLs since the key sits in plaintext. We keep Plisio at Gold because the rest of the integration is so clean that this is a manageable tradeoff. Full review: Plisio review.
Creating a payment, code snippets per API
The shortest path to evaluating an API is to wire up "create one payment, log the response" and see how rough the developer experience is. Here are the four equivalent calls, all creating a $100 USD invoice payable in USDT-TRC20.
NOWPayments (curl):
curl -X POST https://api.nowpayments.io/v1/payment \
-H "x-api-key: $NP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"price_amount": 100,
"price_currency": "usd",
"pay_currency": "usdttrc20",
"order_id": "order_8421",
"order_description": "Pro plan, monthly",
"ipn_callback_url": "https://example.com/webhooks/nowpayments"
}'
The response includes a payment_id, pay_address, pay_amount in USDT, and a 20-minute price-lock window. Persist payment_id against your internal order_id immediately; it is your idempotency anchor for the rest of the flow.
CoinGate (Node):
const res = await fetch("https://api.coingate.com/v2/orders", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.COINGATE_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
order_id: "order_8421",
price_amount: 100,
price_currency: "USD",
receive_currency: "EUR",
callback_url: "https://example.com/webhooks/coingate",
title: "Pro plan, monthly",
}),
});
const order = await res.json();
Notice the receive_currency field, this is CoinGate's killer feature for EU SaaS, the invoice is priced in USD, paid in any of 70 supported coins, and settled to your bank in EUR. For a deeper comparison of the two top players see our NOWPayments vs CoinGate head-to-head.
BTCPay Server Greenfield (curl):
curl -X POST https://btcpay.example.com/api/v1/stores/$STORE_ID/invoices \
-H "Authorization: token $BTCPAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": "100",
"currency": "USD",
"metadata": { "orderId": "order_8421" },
"checkout": { "redirectURL": "https://example.com/thanks" }
}'
BTCPay's response includes the invoice id, the payment URLs for every configured payment method on your store (BTC on-chain, Lightning, altcoins via Liquid), and the expiration. Because you host the API yourself, latency is whatever your VPS gives you, typically 30 to 80 ms in our tests on a $5 Hetzner box.
Plisio (Node):
const url = new URL("https://api.plisio.net/api/v1/invoices/new");
url.searchParams.set("api_key", process.env.PLISIO_KEY);
url.searchParams.set("order_number", "order_8421");
url.searchParams.set("order_name", "Pro plan, monthly");
url.searchParams.set("source_amount", "100");
url.searchParams.set("source_currency", "USD");
url.searchParams.set("currency", "USDT_TRX");
url.searchParams.set("callback_url", "https://example.com/webhooks/plisio");
const invoice = await fetch(url).then(r => r.json());
The smallest API surface of the four; a single GET kicks off a hosted invoice. That simplicity is exactly why Plisio is a Gold-tier pick for one-off invoice flows where you do not need subscriptions or POS.
Webhooks and idempotency, the part that bites you in production
Three production bugs in four come from webhook handling, not from creating payments. Signature verification, retry behaviour, and idempotency are where the four APIs really separate.
| API | Signature | Retries | Idempotency anchor |
|---|---|---|---|
| NOWPayments | HMAC-SHA512 header | Exp backoff over 24h | payment_id |
| CoinGate | Per-order token in URL | 10 retries over 24h | id |
| BTCPay Server | HMAC-SHA256 header | Configurable | invoiceId |
| Plisio | SHA1 of body + secret | 5 retries over 12h | txn_id |
Here is the canonical webhook handler for NOWPayments in Node. The pattern is the same one you would use for BTCPay (swap SHA512 for SHA256).
import crypto from "node:crypto";
import express from "express";
const app = express();
app.post(
"/webhooks/nowpayments",
express.raw({ type: "application/json" }),
async (req, res) => {
const signature = req.header("x-nowpayments-sig");
const body = req.body.toString("utf8");
const expected = crypto
.createHmac("sha512", process.env.NP_IPN_SECRET)
.update(sortKeys(JSON.parse(body)))
.digest("hex");
if (
!signature ||
!crypto.timingSafeEqual(
Buffer.from(signature, "hex"),
Buffer.from(expected, "hex"),
)
) {
return res.status(401).end();
}
const event = JSON.parse(body);
// payment_id is your idempotency key, dedupe on it
await queue.enqueue("payment.updated", {
paymentId: event.payment_id,
orderId: event.order_id,
status: event.payment_status,
});
res.status(200).end();
},
);
function sortKeys(obj) {
return JSON.stringify(
Object.keys(obj).sort().reduce((acc, k) => ({ ...acc, [k]: obj[k] }), {}),
);
}
Three things to call out. First, parse the body as raw bytes, not JSON, otherwise your HMAC will mismatch. Second, NOWPayments sorts keys alphabetically before signing, so you must re-sort before verifying. Third, return 200 fast and process in a queue, your handler should not do database writes in the request lifecycle. The same advice applies for SaaS recurring-billing flows in our recurring crypto payments guide.
Sandbox and testing quality
Sandbox parity is the single biggest factor in whether you can ship a crypto integration without burning real coins on QA. The four shake out very differently here.
NOWPayments [Gold tier] runs api-sandbox.nowpayments.io with full feature parity. You get a separate sandbox API key, all coins on testnet (BTC testnet3, ETH Sepolia, TRX Shasta), and a 200 calls/minute quota that resets on the hour. CI runs roughly 40 payment-create + webhook-receive cycles per pipeline in our setup and we have never hit the cap.
CoinGate [Bronze tier] exposes api.sandbox.coingate.com with the same auth model as production and a fake "test" payment status you can transition manually from the dashboard. Sandbox quotas are unpublished but generous; in practice we never get rate-limited.
BTCPay Server [Bronze tier] wins this category outright. Spin a local instance in Docker pointed at Bitcoin regtest and you can mint blocks at will, simulate confirmations instantly, and run integration tests entirely offline. No rate limits, no quota, no shared sandbox to share with thousands of other developers.
Plisio [Gold tier] is the weakest here. There is no full sandbox; testing relies on tiny live-net invoices (5 USDT or similar) plus careful dashboard inspection. For most production teams that is enough, but if you have a strict no-mainnet-in-CI policy, Plisio will not fit.
Settlement and fiat payouts
Where does the money actually land at the end of the API call chain? This is the question your CFO will ask, and the answer differs sharply across the four.
| API | Crypto wallet payout | Fiat payout | Fee |
|---|---|---|---|
| NOWPayments | Yes, any address | No direct fiat | 0.5% |
| CoinGate | Yes | EUR/USD SEPA/SWIFT | 1% (0.5% at volume) |
| BTCPay Server | Direct to your wallet | No, bring own off-ramp | 0% |
| Plisio | Yes, mass payout API | No direct fiat | 0.5% |
CoinGate is the only API on the list that closes the loop from crypto invoice to fiat in your bank with one provider. That is exactly why it earns its place on the shortlist despite Bronze tier elsewhere, EU SaaS finance teams want regulated fiat settlement and CoinGate's MiCA license delivers it. For a broader comparison see our best crypto payment gateways 2026.
EU SaaS, MiCA-compliant fiat settlement
CoinGate, regulated processor, EUR/USD SEPA payouts, 70 supported coins
Open a CoinGate account →Pick by use case
"SaaS with recurring crypto billing"
NOWPayments [Gold tier]. The /v1/subscriptions endpoint plus signed IPN callbacks make this the only API on the list that ships native recurring crypto. NOWPayments earns Gold here because no competing API has subscription primitives, you would otherwise have to roll your own rebill logic. See our accept crypto payments SaaS walkthrough for the full architecture.
"One-off invoices for a freelance or e-commerce flow"
Plisio [Gold tier]. The smallest API surface area on the shortlist, four endpoints cover create-invoice, fetch-invoice, mass-payout, and balance. Plisio holds Gold despite a smaller library set because for the one-off-invoice use case you barely need an SDK at all; a single fetch call wires it up. 0.5% fee, no fiat conversion required.
"EU-based SaaS, need MiCA-licensed processor in the books"
CoinGate [Bronze tier]. CoinGate sits at Bronze on the overall ranking (the 1% fee and weaker webhook auth pull it down) but it is the only MiCA-licensed API in this comparison. If your finance team needs a regulated processor name on the invoice, this is the answer, full stop. SEPA settlement to EUR, USD via SWIFT, full sandbox at sandbox.coingate.com.
"Self-host, no third party touches my coins or my data"
BTCPay Server [Bronze tier]. Bronze because it is not turnkey, you run the infra, the node, the database, the backups. But it owns the entire stack including the API surface, which means no rate limits, instant key rotation, regtest sandbox parity, and 0% merchant fees forever. The right pick if you have a competent ops team and a privacy-sensitive customer base. Setup: BTCPay Server setup guide and full review at BTCPay Server review.
"Marketplace with split payouts to many sellers"
NOWPayments [Gold tier] or Plisio [Gold tier]. Both expose a mass-payout endpoint, NOWPayments' is more battle-tested with permission-scoped API keys (issue one read-only key for analytics, one payout-only key for the cron job that fans out earnings). NOWPayments edges ahead for the marketplace use case because of the per-key permission model, you can keep payout secrets out of your customer-facing service.
Affiliate disclosure: payyd.co uses affiliate links for NOWPayments, CoinGate, and select other providers. We earn a commission if you sign up through these links, at no extra cost to you. Tier rankings and use-case picks are determined by our editorial rubric, not by payout rates. See our overall best gateways comparison for the full methodology.
FAQ
Which crypto pay API is best for a SaaS in 2026?
For SaaS with recurring billing, NOWPayments wins because of its native subscription endpoints, HMAC-SHA512 signed IPN webhooks, and stable libraries for Node, Python, PHP, and Go. Plisio is a close second when you want a thinner API surface and don't need subscriptions.
Does the NOWPayments API support idempotency keys?
There is no explicit Idempotency-Key header. Instead, the payment_id NOWPayments returns acts as a natural idempotency anchor. Persist it against your internal order_id immediately on create, then dedupe webhook events by payment_id. Retries follow an exponential schedule over roughly 24 hours.
Is BTCPay Server Greenfield compatible with the legacy BitPay API?
Yes. BTCPay ships two APIs side by side, the modern Greenfield REST API and a BitPay-compatible legacy shim. The legacy shim is the easy migration path if you already integrated BitPay and want to switch hosts without rewriting code. Greenfield is the recommended path for new builds.
What HTTP status codes should I expect from a crypto pay API?
Standard REST conventions across all four, 200 or 201 on success, 400 on validation errors, 401 on bad API keys, 403 on permission scope errors, 429 on rate limit, 5xx on transient failures. NOWPayments and CoinGate both rate-limit at roughly 6 requests per second per key; BTCPay Greenfield is unrestricted on your own self-hosted instance.
How long should my webhook handler take to respond?
Aim for under 3 seconds. NOWPayments retries on any non-2xx response, BTCPay Server retries on a configurable schedule (default exponential), CoinGate retries up to 10 times over 24 hours, Plisio retries 5 times over 12 hours. Acknowledge fast (verify signature, enqueue), then do the heavy work in a background worker.
Can I run multiple crypto pay APIs in parallel?
Yes, and many production setups do exactly that, NOWPayments for breadth of coins and recurring billing, BTCPay Server for BTC-only privacy-sensitive customers, CoinGate for the few buyers who want a EUR receipt from a MiCA-licensed processor. Route at checkout based on customer geography or coin selection.
- Crypto Payment API Guide, Architecture and Concepts
- NOWPayments Review, Full API Walkthrough
- CoinGate Review, MiCA Compliance and EU Settlement
- Plisio Review, 0.5% Lightweight Crypto API
- BTCPay Server Setup Guide, Self-Host in 30 Minutes
- Accept Crypto Payments in a SaaS
- Recurring Crypto Payments, Subscription Patterns