Best Free BTCPay Server Alternative
If you're looking for the best BTCPay Server alternative to receive instant Bitcoin payments with very low fees and seamlessly communicate with your app to mark orders as paid, Rizful.com is one of the simplest options available.
BTCPay Server is powerful, but for many people it is more infrastructure than they actually need. If your real goal is to receive Bitcoin payments instantly, confirm them programmatically, and mark orders as paid inside your own app — Rizful can do all of that without a self-hosted server.
Rizful is built around Nostr Wallet Connect (NWC), a standard protocol that lets your app talk directly to a Lightning wallet. That means your app can create invoices, detect when they are paid, and react immediately — all through a simple API.
Why Rizful Is a Strong Alternative
Rizful gives you two things that matter most for accepting payments:
- Instant Bitcoin payments with very low fees — Lightning invoices settle in seconds, and fees are a fraction of a cent.
- Your app knows immediately when an order is paid — poll
lookup_invoicevia NWC and mark orders as paid the moment the payment confirms.
Beyond that, you can also use Rizful to:
- Send Lightning payments
- Move between Lightning and on-chain Bitcoin using swaps
- Send USDT from your Lightning balance
- Create separate NWC connections with names, limits, and expiration dates for safer integrations
That makes Rizful especially useful if you want one wallet layer that can power:
- Checkout flows that mark orders as paid automatically
- Vibe-coded apps
- Nostr apps and AI agents
- Internal tools, side projects, and prototypes that need payments fast
How Your App Marks Orders as Paid
The key to replacing BTCPay Server is that your app needs to know when a payment arrives so it can mark the order as paid. With Rizful and NWC, the flow is:
- Your app creates a Lightning invoice via
make_invoice— the customer sees a QR code or payment link. - Your app polls
lookup_invoice— checking every few seconds whether the invoice has been settled. - The moment it settles, your app reacts — mark the order as paid, send a confirmation, unlock access, or whatever your business logic requires.
This is exactly how BLFS (Bitcoin Lightning For Shopify) works in production: it creates invoices through Rizful via NWC, polls for settlement, and marks Shopify orders as paid — all without running a Lightning node.
For developers this means:
- No custom wallet backend to build or maintain
- No Lightning node to run
- Your app seamlessly detects payments and marks orders as paid
- Works for web apps, mobile apps, checkout flows, and vibe-coded apps
Use a Read-Only NWC Code for Merchant Integrations
When integrating Rizful as a merchant — whether with BLFS, your own checkout flow, or any third-party app — you should always use a receive-only NWC code, not a full-access one.
A receive-only NWC code can only create invoices (make_invoice) and check their status (lookup_invoice). It cannot send payments. That means even if the code is compromised, your funds stay safe — the worst an attacker could do is generate invoices to your wallet.
This is exactly how BLFS merchants onboard in production: the merchant creates a receive-only NWC code from Rizful and hands it to the BLFS developer. The BLFS server uses that code to create Lightning invoices for Shopify checkouts and poll for settlement — but it never has the ability to spend funds.
To get a receive-only NWC code from Rizful, follow the steps in Get A Read-Only NWC Code from Rizful. In short: open NWC settings in Rizful, tap Receive-only NWC Code, and copy the connection string.
Only use a full send-and-receive NWC code if your app genuinely needs to send payments (e.g., payouts, withdrawals). For accepting payments as a merchant, receive-only is always the right choice.
Simple Node.js Example: Receive a Payment and Mark It as Paid
This pattern is based on how BLFS handles real Shopify checkouts. Create an invoice, poll every 3 seconds until paid, then run your own settlement logic (mark the order as paid, send a receipt, etc.):
import { NWCClient } from "@getalby/sdk";
const NWC_URL = "nostr+walletconnect://...your-rizful-nwc-code...";
async function createAndPollInvoice(amountMsats, memo) {
// 1. Create the invoice
const client = new NWCClient({ nostrWalletConnectUrl: NWC_URL });
const { invoice, payment_hash } = await client.makeInvoice({
amount: amountMsats,
description: memo,
});
console.log("Invoice created:", invoice);
// 2. Poll every 3 seconds until paid or timed out
const startTime = Date.now();
const TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes
while (Date.now() - startTime < TIMEOUT_MS) {
const result = await client.lookupInvoice({ payment_hash });
const settled = !!(result.settled_at || result.preimage);
if (settled) {
console.log("Paid! Preimage:", result.preimage);
client.close();
// ← This is where you mark the order as paid in your app
return result;
}
await new Promise((r) => setTimeout(r, 3_000));
}
client.close();
throw new Error("Invoice expired — no payment received");
}
// Example: create a 1 000 sat invoice (1 000 000 msats)
createAndPollInvoice(1_000_000, "Order #1234")
.then((result) => {
// Mark order as paid in your database
console.log("Order paid — preimage:", result.preimage);
})
.catch((e) => console.error(e));
That is the same core loop that powers real Shopify Lightning checkouts in BLFS. Your app receives instant Bitcoin payments with very low fees, and the lookupInvoice poll tells your app exactly when to mark the order as paid. The only dependency is @getalby/sdk — no self-hosted server required.
Belt and Suspenders: Notifications + Polling
The polling example above is the simplest way to get started and works reliably on its own. But in production, BLFS actually uses both polling and NWC notification subscriptions at the same time — a belt-and-suspenders approach.
Here is how it works:
- Polling runs as a background loop, checking
lookup_invoiceevery few seconds for all pending invoices. This is the reliable fallback that always works. - Notifications subscribe to Nostr relay events (kinds
23196and23197) from the wallet. When a payment settles, the wallet publishes a notification event to the relay, and your app can react immediately — often faster than polling catches it.
BLFS subscribes to these notification events using nostr-tools and listens for incoming events from the wallet's pubkey on the relay specified in the NWC connection string. When a notification arrives, it looks up the matching order and settles it right away. But polling keeps running in parallel just in case a notification is missed due to a relay hiccup or a dropped connection.
Here is a simplified version of how BLFS subscribes to wallet notifications, adapted from its notifications.ts and nip47.ts modules:
import { SimplePool } from "nostr-tools";
const NWC_URL = "nostr+walletconnect://...your-rizful-nwc-code...";
function parseNwcUri(uri) {
const u = new URL(uri.replace("nostr+walletconnect://", "http://"));
const walletPubkey = u.hostname;
const relayUrl = u.searchParams.get("relay");
return { walletPubkey, relayUrl };
}
function listenForPayments(onPayment) {
const { walletPubkey, relayUrl } = parseNwcUri(NWC_URL);
if (!relayUrl) throw new Error("No relay URL in NWC URI");
const pool = new SimplePool();
// kinds 23196 (nip04) and 23197 (nip44) are NWC notification events
const subscription = pool.subscribeMany(
[relayUrl],
{ kinds: [23196, 23197], authors: [walletPubkey] },
{
onevent: (event) => {
// Extract payment hash or invoice from the event content
const text = event.content || "";
const paymentHash = (text.match(/[a-f0-9]{64}/i) || [])[0];
const invoice = (text.match(/lnbc[0-9a-z]+/i) || [])[0];
if (paymentHash || invoice) {
onPayment({ paymentHash, invoice, event });
}
},
},
);
// Return a cleanup function
return () => subscription.close();
}
// Usage: start listening alongside your polling loop
const stopListening = listenForPayments(({ paymentHash, invoice }) => {
console.log("Notification received!", { paymentHash, invoice });
// Look up the order by paymentHash or invoice and mark it as paid
});
// Call stopListening() when you want to unsubscribe
In production, BLFS runs this notification listener in parallel with the polling loop from the earlier example. If a notification arrives first, the order settles immediately. If the notification is missed, polling catches it within a few seconds. That is the belt-and-suspenders pattern.
For most apps, polling alone is enough. It is simpler, has no extra dependencies beyond @getalby/sdk, and catches every payment within a few seconds. Add notification subscriptions later if you need sub-second settlement or if you are handling high volume and want to reduce the number of lookup_invoice calls.
Why Some People May Still Choose BTCPay Server
BTCPay Server is still a great option in some cases.
Its biggest advantage is that it is a self-hosted Bitcoin and Lightning payment server. You can run your own infrastructure and connect your own Bitcoin and Lightning stack.
The main reason you may still prefer BTCPay Server is if you want direct on-chain receiving or a fully self-hosted merchant stack.
That matters because NWC is a Lightning wallet protocol, not a general on-chain Bitcoin wallet protocol. The NIP-47 spec describes NWC as a way for clients to access a remote Lightning wallet, so NWC does not natively cover full on-chain wallet operations in the way BTCPay's broader Bitcoin payment stack can.
If your main priority is:
- Direct on-chain Bitcoin receiving
- Full self-hosted merchant infrastructure
- A more traditional self-run payment server setup
then BTCPay Server may still be the better fit.
But for Many Apps, Rizful Is Easier
If you do not need that full self-hosted server model, Rizful is often the easier choice.
Instead of setting up and maintaining a larger server stack, you can use Rizful as a wallet layer that receives instant Bitcoin payments with very low fees and lets your app mark orders as paid automatically. That makes it a strong BTCPay Server alternative for builders who care more about:
- Instant payment confirmation
- Very low fees
- Seamless order settlement in your app
- Modern app integration
- Nostr compatibility
- Easy developer workflows
Final Takeaway
If you want a BTCPay Server alternative that is easier to integrate into modern apps, Rizful.com is one of the best options.
Choose Rizful if you want:
- Instant Bitcoin payments with very low fees
- Your app to seamlessly mark orders as paid via NWC
- No server to set up or maintain
- Support for swaps and USDT-related workflows inside the Rizful ecosystem
- A faster way to build payment-enabled apps
Choose BTCPay Server if you specifically want:
- A self-hosted payments stack
- Direct on-chain receiving as a core part of the setup
- More server-level control over your Bitcoin payment infrastructure
For a lot of builders, the answer is simple: if you want to receive instant Bitcoin payments with very low fees and have your app seamlessly mark orders as paid, Rizful is the better choice.