Invoices
Invoices are the core of BTC Checkout. Each invoice represents a payment request with a unique Bitcoin address, a USD amount converted to BTC at the current rate, and a time-to-live countdown.
Create an invoice
POST /api/checkout/invoicesRequest body:
| Field | Type | Required | Description |
|---|---|---|---|
amountUsd | number | Yes | Amount in USD (minimum 0.01) |
ttlMinutes | integer | No | Override default TTL. 1–1440 minutes. |
productName | string | No | Product/service description (max 200 chars) |
redirectUrl | string | No | Override the config-level redirect URL for this invoice |
metadata | object | No | Arbitrary key-value data attached to the invoice |
Example:
curl -X POST \
-H "X-Api-Key: fc_live_..." \
-H "Content-Type: application/json" \
-d '{
"amountUsd": 49.99,
"productName": "Pro Plan - Monthly",
"metadata": {"orderId": "order_123"}
}' \
https://fincobra.com/api/checkout/invoicesResponse (HTTP 201):
{
"id": "a1b2c3d4-...",
"amountUsd": 49.99,
"amountBtc": 0.0005,
"btcRate": 99980,
"btcAddress": "bc1q...",
"qrCode": "data:image/png;base64,...",
"status": "pending",
"productName": "Pro Plan - Monthly",
"redirectUrl": "https://yoursite.com/thank-you",
"expiresAt": "2025-01-15T10:50:00.000Z",
"ttlMinutes": 20,
"createdAt": "2025-01-15T10:30:00.000Z"
}The qrCode field contains a base64-encoded PNG of a BIP-21 payment URI (bitcoin:<address>?amount=<btc>), ready to display in an <img> tag.
List invoices
GET /api/checkout/invoicesQuery parameters:
| Param | Type | Default | Description |
|---|---|---|---|
status | string | — | Filter by status: pending, paid, confirmed, expired, cancelled, underpaid |
limit | integer | 50 | Max results (1–200) |
offset | integer | 0 | Pagination offset |
Response:
{
"invoices": [
{
"id": "a1b2c3d4-...",
"amountUsd": 49.99,
"amountBtc": 0.0005,
"btcAddress": "bc1q...",
"status": "confirmed",
"paymentState": "exact",
"receivedBtc": 0.0005,
"remainingBtc": 0,
"overpaidBtc": 0,
"..."
}
],
"total": 42
}Get invoice detail
GET /api/checkout/invoices/:idReturns full invoice data including QR code and time remaining.
Get invoice status
GET /api/checkout/invoices/:id/statusLightweight endpoint for polling. Returns only status-related fields:
{
"status": "paid",
"confirmations": 0,
"txHash": "abc123...",
"txHashes": ["abc123..."],
"paidAt": "2025-01-15T10:35:00.000Z",
"confirmedAt": null,
"paymentState": "exact",
"receivedBtc": 0.0005,
"remainingBtc": 0,
"overpaidBtc": 0,
"timeRemainingSeconds": 0
}Get invoice stats
GET /api/checkout/invoices/statsReturns aggregate counts across all your invoices:
{
"total": 100,
"pending": 5,
"paid": 10,
"confirmed": 75,
"expired": 8,
"underpaid": 2
}Invoice status lifecycle
pending ──→ paid ──→ confirmed
│
├──→ expired (no payment received before TTL + grace)
│
└──→ underpaid (partial payment received, then TTL + grace elapsed)| Status | Description |
|---|---|
pending | Invoice created, waiting for payment. Countdown is active. |
paid | Full BTC amount detected on-chain (0 confirmations). Waiting for block confirmation. |
confirmed | Payment has at least 1 block confirmation. This is the terminal success state. |
expired | TTL elapsed with no payment detected. |
underpaid | Some BTC was received but less than required, and the grace period has elapsed. |
Payment states
Each invoice also has a paymentState indicating how much BTC has been received relative to the required amount:
| State | Description |
|---|---|
unpaid | No BTC received yet |
partial | Some BTC received, but less than amountBtc |
exact | Received amount matches amountBtc (within 1 satoshi tolerance) |
overpaid | Received more than amountBtc |
The payment summary fields are:
receivedBtc— total BTC received at the invoice addressremainingBtc— BTC still needed (0 if exact or overpaid)overpaidBtc— excess BTC received (0 if exact or underpaid)
Grace period
When an invoice expires but has received a partial payment, the system waits for an additional grace period (unconfirmedWaitMinutes, default 8 hours) before marking it as underpaid. This gives time for in-flight transactions to confirm. Invoices with no payment at all are expired immediately.