Node.js SDK

Full TypeScript support. Zero dependencies. Works with Express, Next.js, Deno, Bun — anything JavaScript.

Installation

npm install satsrail

Or with yarn / pnpm:

yarn add satsrail
pnpm add satsrail

Configuration

import SatsRail from 'satsrail';

const sr = new SatsRail('sk_test_your_key_here');

You can also pass options:

const sr = new SatsRail('sk_test_...', {
  baseUrl: 'https://satsrail.com', // default
  timeout: 30000, // request timeout in ms
});
Never expose your secret key client-side. Use environment variables: process.env.SATSRAIL_API_KEY

Creating Orders

const order = await sr.orders.create({
  amount_usd: 50.00,
  description: 'Order #1234',
  metadata: {
    customer_id: 'cust_abc',
    sku: 'premium-plan'
  }
});

console.log(order.id);               // "ord_..."
console.log(order.status);            // "pending"
console.log(order.lightning_invoice);  // bolt11 string (if auto-generated)

Pass generate_invoice: true to get a Lightning invoice in the same call:

const order = await sr.orders.create({
  amount_usd: 25.00,
  description: 'Subscription',
  generate_invoice: true,
  payment_method: 'lightning'
});
console.log(order.invoice.bolt11); // lnbc...

Listing Orders

// List all orders
const orders = await sr.orders.list();

// Filter by status
const pending = await sr.orders.list({ status: 'pending' });

// Pagination
const page2 = await sr.orders.list({ page: 2, per_page: 25 });

for (const order of orders.data) {
  console.log(`${order.id}: ${order.status} — $${order.amount_usd}`);
}

Getting Order Details

const order = await sr.orders.retrieve('ord_abc123');

console.log(order.id);
console.log(order.status);
console.log(order.amount_usd);
console.log(order.created_at);

Generating Invoices

const invoice = await sr.invoices.generate({
  order_id: 'ord_abc123',
  payment_method: 'lightning'
});

console.log(invoice.id);     // "inv_..."
console.log(invoice.bolt11);  // Lightning payment string
console.log(invoice.amount_sats);

Checking Invoice Status

const status = await sr.invoices.status('inv_abc123');

console.log(status.paid);        // true or false
console.log(status.settled_at);   // timestamp if paid
console.log(status.amount_sats);

// Poll until paid
const waitForPayment = async (invoiceId: string) => {
  while (true) {
    const s = await sr.invoices.status(invoiceId);
    if (s.paid) return s;
    await new Promise(r => setTimeout(r, 2000));
  }
};

Checkout Sessions

Create a hosted checkout page — perfect when you don't want to build your own payment UI.

const session = await sr.checkoutSessions.create({
  amount_usd: 99.00,
  description: 'Annual Plan',
  success_url: 'https://yoursite.com/success',
  cancel_url: 'https://yoursite.com/cancel',
  metadata: { plan: 'annual' }
});

// Redirect customer to hosted checkout
console.log(session.url); // https://satsrail.com/checkout/...

Webhook Verification

Verify webhook signatures to ensure events are genuinely from SatsRail.

import express from 'express';

const app = express();

app.post('/webhooks/satsrail', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-satsrail-signature'];
  const payload = req.body;

  try {
    const event = sr.webhooks.verify(payload, signature, 'whsec_your_secret');

    switch (event.type) {
      case 'order.paid':
        console.log('Order paid:', event.data.id);
        break;
      case 'invoice.settled':
        console.log('Invoice settled:', event.data.id);
        break;
    }

    res.json({ received: true });
  } catch (err) {
    console.error('Invalid signature:', err.message);
    res.status(400).send('Invalid signature');
  }
});

Error Handling

import SatsRail, { SatsRailError, AuthenticationError, RateLimitError } from 'satsrail';

try {
  const order = await sr.orders.create({ amount_usd: 50.00 });
} catch (err) {
  if (err instanceof AuthenticationError) {
    console.error('Invalid API key');
  } else if (err instanceof RateLimitError) {
    console.error('Rate limited — retry after', err.retryAfter);
  } else if (err instanceof SatsRailError) {
    console.error(`API error: ${err.message} (${err.code})`);
  } else {
    throw err;
  }
}

TypeScript Support

The SDK ships with full TypeScript definitions. All methods, parameters, and responses are typed.

import SatsRail, { Order, Invoice, CheckoutSession } from 'satsrail';

const sr = new SatsRail(process.env.SATSRAIL_API_KEY!);

const order: Order = await sr.orders.create({
  amount_usd: 50.00,
  description: 'Typed order'
});

const invoice: Invoice = await sr.invoices.generate({
  order_id: order.id,
  payment_method: 'lightning'
});

Start building with Node.js

Get your API key and accept Bitcoin payments in minutes.