API Checkout Flow
Server-to-server integration — from checkout creation to webhook delivery.
Flow Overview
This diagram shows the full developer integration using the SatsRail REST API. The merchant's backend creates checkout sessions server-side using the secret key (
sk_live_
), redirects customers to the hosted checkout page, and receives payment confirmations via signed webhooks. Funds settle directly to the merchant's Lightning wallet (non-custodial).
Sequence Diagram
API Endpoints
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| POST | /api/v1/checkout_sessions |
Create a new checkout session | sk_live_ |
| GET | /api/v1/checkout_sessions/{id} |
Retrieve checkout status | sk_live_ |
| GET | /api/v1/m/products |
List all products | sk_live_ |
| POST | /api/v1/m/products |
Create a product | sk_live_ |
| GET | /api/v1/transactions |
List transactions with filters | sk_live_ |
| GET | /api/v1/rates |
Current BTC/USD exchange rate | pk_live_ or sk_live_ |
Step-by-Step Detail
Phase 1: Setup & Authentication
Obtain API Keys
Merchant registers on SatsRail and receives two API keys:
pk_live_...— Publishable key (safe for client-side/frontend)sk_live_...— Secret key (server-side only, never exposed to clients)
Connect Wallet & Configure Webhook
Connect a Lightning wallet via the Dashboard or API. Configure a webhook endpoint URL where SatsRail will send payment event notifications.
Phase 2: Checkout Creation
Customer Initiates Checkout
Customer adds items to cart on the merchant's frontend, clicks "Checkout with Bitcoin." The frontend sends cart data to the merchant's backend server.
Backend Creates Checkout Session
Merchant backend sends a POST request to SatsRail:
POST /api/v1/checkout_sessions
Authorization: Bearer sk_live_...
Content-Type: application/json
{
"checkout_session": {
"amount_cents": 5000,
"currency": "usd",
"customer_email": "buyer@example.com",
"success_url": "https://store.com/success",
"cancel_url": "https://store.com/cart",
"metadata": { "order_id": "ORD-1234" }
}
}
SatsRail validates the secret key, checks rate limits, validates the payload schema, then creates a CheckoutSession with a 15-minute TTL.
Redirect Customer
SatsRail returns:
{
"checkout_url": "https://satsrail.com/checkout/cs_abc123",
"token": "cs_abc123",
"status": "pending",
"expires_at": "2024-01-15T10:15:00Z"
}
The merchant backend returns the checkout_url to the frontend, which redirects the customer to the SatsRail hosted checkout page.
Phase 3: Payment Execution
Checkout Page & Payment
The SatsRail checkout page shows line items, total in USD and sats, and generates a Lightning invoice from the merchant's wallet (non-custodial). Customer pays via QR scan, copy, or WebLN.
Payment routes through Lightning and settles instantly to the merchant's wallet.
Phase 4: Post-Payment & Webhooks
Webhook Delivery
SatsRail sends a POST to the merchant's webhook endpoint:
POST https://merchant.com/webhooks/satsrail
X-SatsRail-Signature: sha256=abc123...
{
"event": "checkout.completed",
"checkout_id": "cs_abc123",
"payment_hash": "abc123...",
"amount_sats": 50000,
"amount_usd": "50.00",
"metadata": { "order_id": "ORD-1234" },
"timestamp": "2024-01-15T10:02:30Z"
}
The merchant verifies the HMAC signature using their webhook secret, processes the order, and returns 200 OK. On failure, SatsRail retries: 1 min → 5 min → 30 min → 2 hr.
Client-Side Confirmation
Customer is redirected to the merchant's
success_url
with
checkout_id
as a query param. The merchant frontend calls
GET /api/v1/checkout_sessions/{checkout_id}
to verify the status is "completed" before showing the success page. Never trust the redirect alone — always verify server-side.
Error Paths
| HTTP Status | Error | Trigger | Recovery |
|---|---|---|---|
| 401 | Unauthorized | Invalid or missing API key | Check sk_live_ key in Authorization header |
| 422 | Validation Error | Malformed payload, missing required fields | Check field-level error messages in response body |
| 429 | Rate Limited | Too many requests per minute | Implement backoff; check Retry-After header |
| 410 | Gone | Checkout session expired (15 min TTL) | Create a new checkout session |
| 200 | Double Payment | Idempotency check detects existing payment | Returns existing payment record (no double-charge) |
| 5xx | Webhook Failure | Merchant endpoint unreachable or returns error | SatsRail retries: 1 min → 5 min → 30 min → 2 hr |
Build your custom checkout
One API call to create a checkout. Lightning settlement. Webhook confirmation.