Type hints included. Works with Django, Flask, FastAPI, or standalone scripts.
pip install satsrail
Or with poetry / pipenv:
poetry add satsrail
pipenv install satsrail
Requires Python 3.8+.
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
)
os.environ["SATSRAIL_API_KEY"]
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...
# 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}")
order = sr.orders.retrieve("ord_abc123")
print(order.id)
print(order.status)
print(order.amount_usd)
print(order.created_at)
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)
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)
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/...
Verify webhook signatures to ensure events are genuinely from SatsRail.
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
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")
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
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})")
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)
Get your API key and accept Bitcoin payments in minutes.