Integrate invoices via API

Endpoints, callbacks, and signature checks — a robust, gateway‑agnostic pattern you can plug into any stack.

The payment flow

  1. Create an Order in your system (id, amount, currency).
  2. Call the gateway Create Invoice endpoint with the order id and amount.
  3. Show the returned invoice (on‑chain address and/or Lightning invoice) with a countdown.
  4. Receive a Webhook on confirmed payment; verify signature and fetch a trusted read.
  5. Mark the order Paid and issue a Receipt with a proof link (txid/payment hash).

Example endpoints

POST /api/invoices
Body: {
  "order_id": "ord_12345",
  "amount": 49.00,
  "currency": "USD",
  "success_url": "https://your.site/order/ord_12345",
  "webhook_url": "https://your.site/webhooks/bitcoin"
}

Response: {
  "invoice_id": "inv_abcde",
  "expires_at": "2025-12-01T12:00:00Z",
  "lightning": { "bolt11": "lnbc1..." },
  "onchain": { "address": "bc1q...", "amount_sats": 94000 }
}

Webhook verification

// Pseudocode (Node.js style)
const sig = req.headers['x-webhook-signature']
const body = rawBody // exact bytes received
const expected = hmacSHA256(secret, timestamp + '.' + body)
if (!timingSafeEqual(sig, expected)) return res.status(400)

const event = JSON.parse(body)
if (event.type === 'invoice.paid') {
  const invoice = await gateway.getInvoice(event.data.id)
  if (invoice.status === 'paid') markOrderPaid(invoice.order_id)
}
res.status(200)
Tip: Accept the webhook, queue work, and return 200 OK quickly. Do the secondary read asynchronously.

Idempotency & retries

  • Use an Idempotency‑Key header on create‑invoice calls to avoid duplicates.
  • Make your fulfillment endpoint idempotent — e.g., updating the same order is safe to repeat.
  • Store webhook delivery ids; ignore already‑processed events.

Receipts

Generate a user‑facing receipt containing order id, amount (fiat + sats), timestamp, and a proof link — on‑chain txid explorer or a Lightning payment hash lookup. For privacy, avoid embedding raw addresses; link to proofs instead.

Security notes

  • Rotate webhook secrets; support multiple active secrets during rotations.
  • Verify TLS on callbacks; pin allowed IPs if your provider publishes ranges.
  • Log only what you need; avoid PII and raw seed data entirely.

Testing checklist

  • Create, pay, expire, and refund invoices using sandbox/test keys.
  • Simulate webhook retries and out‑of‑order delivery.
  • Confirm idempotency by sending duplicate events.
  • Validate receipts show proof links and reconcile to your GL.