Python SDK

Type hints included. Works with Django, Flask, FastAPI, or standalone scripts.

Installation

pip install satsrail

Or with poetry / pipenv:

poetry add satsrail
pipenv install satsrail

Requires Python 3.8+.

Configuration

import satsrail

sr = satsrail.Client("sk_test_your_key_here")

You can also pass options:

sr = satsrail.Client(
    api_key="sk_test_...",
    base_url="https://satsrail.com",  # default
    timeout=30,  # request timeout in seconds
)
Never hardcode your secret key. Use environment variables: os.environ["SATSRAIL_API_KEY"]

Creating Orders

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

print(order.id)               # "ord_..."
print(order.status)            # "pending"
print(order.lightning_invoice)  # bolt11 string (if auto-generated)

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

order = sr.orders.create(
    amount_usd=25.00,
    description="Subscription",
    generate_invoice=True,
    payment_method="lightning"
)
print(order.invoice.bolt11)  # lnbc...

Listing Orders

# List all orders
orders = sr.orders.list()

# Filter by status
pending = sr.orders.list(status="pending")

# Pagination
page2 = sr.orders.list(page=2, per_page=25)

for order in orders.data:
    print(f"{order.id}: {order.status} — ${order.amount_usd}")

Getting Order Details

order = sr.orders.retrieve("ord_abc123")

print(order.id)
print(order.status)
print(order.amount_usd)
print(order.created_at)

Generating Invoices

invoice = sr.invoices.generate(
    order_id="ord_abc123",
    payment_method="lightning"
)

print(invoice.id)          # "inv_..."
print(invoice.bolt11)       # Lightning payment string
print(invoice.amount_sats)

Checking Invoice Status

status = sr.invoices.status("inv_abc123")

print(status.paid)         # True or False
print(status.settled_at)    # timestamp if paid
print(status.amount_sats)

# Poll until paid
import time

def wait_for_payment(invoice_id: str):
    while True:
        s = sr.invoices.status(invoice_id)
        if s.paid:
            return s
        time.sleep(2)

Checkout Sessions

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

session = sr.checkout_sessions.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
print(session.url)  # https://satsrail.com/checkout/...

Webhook Verification

Verify webhook signatures to ensure events are genuinely from SatsRail.

Flask
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route("/webhooks/satsrail", methods=["POST"])
def handle_webhook():
    signature = request.headers.get("X-SatsRail-Signature")
    payload = request.data

    try:
        event = sr.webhooks.verify(payload, signature, "whsec_your_secret")

        if event.type == "order.paid":
            print(f"Order paid: {event.data.id}")
        elif event.type == "invoice.settled":
            print(f"Invoice settled: {event.data.id}")

        return jsonify(received=True)
    except satsrail.WebhookSignatureError as e:
        return str(e), 400
Django
from django.http import JsonResponse, HttpResponseBadRequest
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def satsrail_webhook(request):
    signature = request.headers.get("X-SatsRail-Signature")
    payload = request.body

    try:
        event = sr.webhooks.verify(payload, signature, "whsec_your_secret")

        if event.type == "order.paid":
            # Fulfill the order
            pass

        return JsonResponse({"received": True})
    except satsrail.WebhookSignatureError:
        return HttpResponseBadRequest("Invalid signature")

Async Support

The SDK includes an async client for use with asyncio and frameworks like FastAPI:

import satsrail

sr = satsrail.AsyncClient("sk_test_...")

async def create_order():
    order = await sr.orders.create(
        amount_usd=50.00,
        description="Async order"
    )
    return order

Error Handling

import satsrail

try:
    order = sr.orders.create(amount_usd=50.00)
except satsrail.AuthenticationError:
    print("Invalid API key")
except satsrail.RateLimitError as e:
    print(f"Rate limited — retry after {e.retry_after}")
except satsrail.SatsRailError as e:
    print(f"API error: {e.message} ({e.code})")

Type Hints

The SDK ships with full type annotations. Works with mypy, pyright, and IDE autocompletion.

from satsrail.types import Order, Invoice, CheckoutSession

def process_order(order: Order) -> None:
    print(order.id)
    print(order.amount_usd)

order: Order = sr.orders.create(
    amount_usd=50.00,
    description="Typed order"
)
process_order(order)

Start building with Python

Get your API key and accept Bitcoin payments in minutes.