API Reference
Base URL: https://fincobra.com
Use the FinCobra dashboard to configure Checkout, payment methods, webhook settings, and API keys. Use the API from your server to create invoices and read known invoice state.
Authentication
Merchant endpoints require an API key:
X-Api-Key: fc_live_...API keys can create invoices and read known invoice data. They cannot list all invoices or change Checkout configuration.
Merchant Endpoints
| Method | Path | Description |
|---|---|---|
POST | /api/checkout/invoices | Create an invoice |
GET | /api/checkout/invoices/:id | Get invoice detail |
GET | /api/checkout/invoices/:id/status | Get invoice status |
POST | /api/checkout/invoices/:id/void | Void an unpaid invoice |
POST | /api/checkout/invoices/:id/record-payment | Record an external payment |
Create Invoice
POST /api/checkout/invoicesCreates a checkout invoice using your configured payment methods.
Request
curl -X POST https://fincobra.com/api/checkout/invoices \
-H "X-Api-Key: fc_live_..." \
-H "Content-Type: application/json" \
-d '{
"amountUsd": 49.99,
"productName": "Pro Plan - Monthly",
"merchantReference": "order_123",
"customerEmail": "buyer@example.com"
}'Request Body
| Field | Type | Required | Description |
|---|---|---|---|
amountUsd | number | Yes | Invoice amount in USD. Minimum 0.01. |
paymentTiming | object | No | Per-invoice timing override. Omit to use the dashboard default. |
productName | string | No | Product or service label. Max 200 chars. |
issuedBy | string | No | Invoice issuer name. Defaults to the dashboard setting. Max 120 chars. |
billTo | string | No | Customer or company name shown on the invoice. Max 120 chars. |
redirectUrl | string | No | Redirect URL after the payer-facing flow completes. |
merchantReference | string | No | Your order, cart, or internal reference. Max 200 chars. |
customerId | string | No | Your internal customer ID. Max 200 chars. |
customerEmail | string | No | Customer email for reconciliation. Max 320 chars. |
metadata | object | No | JSON object stored with the invoice. metadata.notes, when present, must be a string up to 140 chars. |
Response
Returns HTTP 201 with an Invoice object:
{
"id": "a1b2c3d4-1111-4222-8333-abcdefabcdef",
"paymentUrl": "https://fincobra.com/pay/a1b2c3d4-1111-4222-8333-abcdefabcdef",
"amountUsd": 49.99,
"status": "awaiting_payment",
"paymentCoverage": "no_payment",
"receivedAmountUsd": 0,
"confirmedAmountUsd": 0,
"confirmations": 0,
"paymentTiming": {
"mode": "immediate",
"expiresAfterMinutes": 20,
"payableUntilAt": "2026-04-29T10:20:00.000Z"
},
"paymentDetectedAt": null,
"confirmedAt": null,
"createdAt": "2026-04-29T10:00:00.000Z",
"productName": "Pro Plan - Monthly",
"issuedBy": "Acme, Inc.",
"billTo": null,
"redirectUrl": "https://example.com/thanks",
"lastTransactionHash": null,
"merchantReference": "order_123",
"customerId": null,
"customerEmail": "buyer@example.com",
"metadata": null,
"paymentSummary": {
"paymentCoverage": "no_payment",
"receivedAmountUsd": 0,
"confirmedAmountUsd": 0,
"remainingAmountUsd": 49.99,
"overpaymentAmountUsd": 0
},
"paymentOptions": [
{
"id": "payment-option-1",
"railType": "wallet_contract",
"assetCode": "USDT",
"network": "ethereum",
"tokenContract": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
"quotedAmount": 49.99,
"quoteRate": 1,
"destinationAddress": null,
"status": "active",
"isDefault": true,
"paymentUri": null,
"qrCode": null,
"optionPayload": {
"railType": "wallet_contract",
"chainId": 1,
"contractAddress": "0x...",
"tokenContract": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
"recipient": "0x1111111111111111111111111111111111111111",
"decimals": 6,
"requiredConfirmations": 14,
"paymentAmountAtomic": "49990000"
}
}
],
"defaultPaymentOptionId": "payment-option-default",
"lastPaymentOptionId": "payment-option-1",
"lastPaymentObservedAt": null
}Use paymentUrl for hosted checkout. Use paymentOptions[] only when building custom payment UI.
Get Invoice Detail
GET /api/checkout/invoices/:idReturns a known invoice by id.
curl https://fincobra.com/api/checkout/invoices/a1b2c3d4-1111-4222-8333-abcdefabcdef \
-H "X-Api-Key: fc_live_..."Returns an Invoice object, including payments[] when payment events have been observed:
{
"id": "a1b2c3d4-1111-4222-8333-abcdefabcdef",
"paymentUrl": "https://fincobra.com/pay/a1b2c3d4-1111-4222-8333-abcdefabcdef",
"amountUsd": 49.99,
"status": "payment_detected",
"paymentCoverage": "exact_payment",
"receivedAmountUsd": 49.99,
"confirmedAmountUsd": 0,
"confirmations": 1,
"paymentTiming": {
"mode": "immediate",
"expiresAfterMinutes": 20,
"payableUntilAt": "2026-04-29T10:20:00.000Z"
},
"paymentDetectedAt": "2026-04-29T10:05:00.000Z",
"confirmedAt": null,
"createdAt": "2026-04-29T10:00:00.000Z",
"productName": "Pro Plan - Monthly",
"issuedBy": "Acme, Inc.",
"billTo": null,
"redirectUrl": "https://example.com/thanks",
"lastTransactionHash": "0xabc123...",
"merchantReference": "order_123",
"customerId": null,
"customerEmail": "buyer@example.com",
"metadata": {
"orderId": "order_123"
},
"paymentSummary": {
"paymentCoverage": "exact_payment",
"receivedAmountUsd": 49.99,
"confirmedAmountUsd": 0,
"remainingAmountUsd": 0,
"overpaymentAmountUsd": 0
},
"paymentOptions": [
{
"id": "payment-option-1",
"railType": "wallet_contract",
"assetCode": "USDT",
"network": "ethereum",
"tokenContract": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
"quotedAmount": 49.99,
"quoteRate": 1,
"destinationAddress": null,
"status": "active",
"isDefault": true,
"paymentUri": null,
"qrCode": null,
"optionPayload": {
"railType": "wallet_contract",
"chainId": 1,
"contractAddress": "0x...",
"tokenContract": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
"recipient": "0x1111111111111111111111111111111111111111",
"decimals": 6,
"requiredConfirmations": 14,
"paymentAmountAtomic": "49990000"
}
}
],
"defaultPaymentOptionId": "payment-option-default",
"lastPaymentOptionId": "payment-option-1",
"payments": [
{
"id": "payment-1",
"paymentOptionId": "payment-option-1",
"assetCode": "USDT",
"network": "ethereum",
"destinationAddress": null,
"transactionHash": "0xabc123...",
"amountReceived": 49.99,
"observedTotalAmount": 49.99,
"confirmations": 1,
"observedAt": "2026-04-29T10:05:00.000Z",
"confirmedAt": null,
"invalidatedAt": null,
"invalidationReason": null
}
],
"lastPaymentObservedAt": "2026-04-29T10:05:00.000Z"
}Get Invoice Status
GET /api/checkout/invoices/:id/statusReturns a polling-friendly status payload for a known invoice:
curl https://fincobra.com/api/checkout/invoices/a1b2c3d4-1111-4222-8333-abcdefabcdef/status \
-H "X-Api-Key: fc_live_..."{
"status": "payment_detected",
"paymentCoverage": "exact_payment",
"receivedAmountUsd": 49.99,
"confirmedAmountUsd": 0,
"confirmations": 1,
"paymentDetectedAt": "2026-04-29T10:05:00.000Z",
"confirmedAt": null,
"paidOutOfBandAt": null,
"paidOutOfBandNote": null,
"paymentTiming": {
"mode": "immediate",
"expiresAfterMinutes": 20,
"payableUntilAt": "2026-04-29T10:20:00.000Z"
},
"paymentSummary": {
"paymentCoverage": "exact_payment",
"receivedAmountUsd": 49.99,
"confirmedAmountUsd": 0,
"remainingAmountUsd": 0,
"overpaymentAmountUsd": 0
},
"paymentOptions": [
{
"id": "payment-option-1",
"railType": "wallet_contract",
"assetCode": "USDT",
"network": "ethereum",
"tokenContract": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
"quotedAmount": 49.99,
"quoteRate": 1,
"destinationAddress": null,
"status": "active",
"isDefault": true,
"paymentUri": null,
"qrCode": null,
"optionPayload": {
"railType": "wallet_contract",
"chainId": 1,
"contractAddress": "0x...",
"tokenContract": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
"recipient": "0x1111111111111111111111111111111111111111",
"decimals": 6,
"requiredConfirmations": 14,
"paymentAmountAtomic": "49990000"
}
}
],
"defaultPaymentOptionId": "payment-option-default",
"lastPaymentOptionId": "payment-option-1",
"payments": [
{
"id": "payment-1",
"paymentOptionId": "payment-option-1",
"assetCode": "USDT",
"network": "ethereum",
"destinationAddress": null,
"transactionHash": "0xabc123...",
"amountReceived": 49.99,
"observedTotalAmount": 49.99,
"confirmations": 1,
"observedAt": "2026-04-29T10:05:00.000Z",
"confirmedAt": null,
"invalidatedAt": null,
"invalidationReason": null
}
],
"lastPaymentObservedAt": "2026-04-29T10:05:00.000Z"
}Void Invoice
POST /api/checkout/invoices/:id/voidVoids an invoice that is still awaiting_payment.
curl -X POST https://fincobra.com/api/checkout/invoices/a1b2c3d4-1111-4222-8333-abcdefabcdef/void \
-H "X-Api-Key: fc_live_..." \
-H "Content-Type: application/json" \
-d '{}'Returns the updated invoice object. Requests for invoices in any other status return HTTP 409.
Record Payment
POST /api/checkout/invoices/:id/record-paymentRecords an external payment for an invoice in awaiting_payment, partially_paid, or expired.
curl -X POST https://fincobra.com/api/checkout/invoices/a1b2c3d4-1111-4222-8333-abcdefabcdef/record-payment \
-H "X-Api-Key: fc_live_..." \
-H "Content-Type: application/json" \
-d '{
"note": "Paid by wire transfer"
}'Request Body
| Field | Type | Required | Description |
|---|---|---|---|
note | string | Yes | Reconciliation note for the external payment. Max 2000 chars. |
Returns the updated invoice object with status: "paid_out_of_band", paidOutOfBandAt, and paidOutOfBandNote.
Public Payment Page API
These unauthenticated endpoints power the hosted payment page and can be used for custom payment pages. Do not use them for private merchant metadata or server-side reconciliation.
| Method | Path | Description |
|---|---|---|
GET | /api/checkout/pay/:id | Get customer-facing invoice data |
GET | /api/checkout/pay/:id/status | Poll customer-facing invoice status |
Get Public Invoice
GET /api/checkout/pay/:idReturns customer-facing invoice data, payment instructions, and public payment status. It does not require an API key.
Public responses intentionally exclude merchant-only fields such as merchantReference, customerId, customerEmail, and metadata. Customer-facing fields such as issuedBy, billTo, productName, paymentTiming, and redirectUrl may be included. Merchant reconciliation notes for out-of-band payments are not returned by public endpoints.
{
"id": "a1b2c3d4-1111-4222-8333-abcdefabcdef",
"paymentUrl": "https://fincobra.com/pay/a1b2c3d4-1111-4222-8333-abcdefabcdef",
"amountUsd": 49.99,
"status": "awaiting_payment",
"paymentCoverage": "no_payment",
"receivedAmountUsd": 0,
"confirmedAmountUsd": 0,
"confirmations": 0,
"paymentTiming": {
"mode": "immediate",
"expiresAfterMinutes": 20,
"payableUntilAt": "2026-04-29T10:20:00.000Z"
},
"paymentDetectedAt": null,
"confirmedAt": null,
"createdAt": "2026-04-29T10:00:00.000Z",
"productName": "Pro Plan - Monthly",
"issuedBy": "Acme, Inc.",
"billTo": null,
"redirectUrl": "https://example.com/thanks",
"lastTransactionHash": null,
"paymentSummary": {
"paymentCoverage": "no_payment",
"receivedAmountUsd": 0,
"confirmedAmountUsd": 0,
"remainingAmountUsd": 49.99,
"overpaymentAmountUsd": 0
},
"paymentOptions": [
{
"id": "payment-option-1",
"railType": "address_transfer",
"assetCode": "BTC",
"network": "bitcoin",
"tokenContract": null,
"quotedAmount": 0.00073,
"quoteRate": 68479.45,
"destinationAddress": "bc1qexample...",
"status": "active",
"isDefault": true,
"paymentUri": "bitcoin:bc1qexample...?amount=0.00073",
"qrCode": "<svg>...</svg>",
"optionPayload": {
"railType": "address_transfer",
"requiredConfirmations": 1
}
}
],
"defaultPaymentOptionId": "payment-option-default",
"lastPaymentOptionId": "payment-option-1",
"payments": [],
"lastPaymentObservedAt": null
}Get Public Invoice Status
GET /api/checkout/pay/:id/statusReturns the current customer-facing status for an invoice. Use this endpoint when building a custom payment page that polls for payment progress.
{
"status": "payment_detected",
"paymentCoverage": "exact_payment",
"receivedAmountUsd": 49.99,
"confirmedAmountUsd": 0,
"confirmations": 1,
"paymentDetectedAt": "2026-04-29T10:05:00.000Z",
"confirmedAt": null,
"paidOutOfBandAt": null,
"paidOutOfBandNote": null,
"paymentTiming": {
"mode": "immediate",
"expiresAfterMinutes": 20,
"payableUntilAt": "2026-04-29T10:20:00.000Z"
},
"paymentSummary": {
"paymentCoverage": "exact_payment",
"receivedAmountUsd": 49.99,
"confirmedAmountUsd": 0,
"remainingAmountUsd": 0,
"overpaymentAmountUsd": 0
},
"paymentOptions": [
{
"id": "payment-option-1",
"railType": "address_transfer",
"assetCode": "BTC",
"network": "bitcoin",
"tokenContract": null,
"quotedAmount": 0.00073,
"quoteRate": 68479.45,
"destinationAddress": "bc1qexample...",
"status": "active",
"isDefault": true,
"paymentUri": "bitcoin:bc1qexample...?amount=0.00073",
"qrCode": null,
"optionPayload": {
"railType": "address_transfer",
"requiredConfirmations": 1
}
}
],
"defaultPaymentOptionId": "payment-option-default",
"lastPaymentOptionId": "payment-option-1",
"payments": [
{
"id": "payment-1",
"paymentOptionId": "payment-option-1",
"assetCode": "BTC",
"network": "bitcoin",
"destinationAddress": "bc1qexample...",
"transactionHash": "btc_tx_hash",
"amountReceived": 0.00073,
"observedTotalAmount": 0.00073,
"confirmations": 1,
"observedAt": "2026-04-29T10:05:00.000Z",
"confirmedAt": null,
"invalidatedAt": null,
"invalidationReason": null
}
],
"lastPaymentObservedAt": "2026-04-29T10:05:00.000Z"
}Objects
Invoice Object
| Field | Type | Description |
|---|---|---|
id | string | Invoice UUID. Store this with your order. |
paymentUrl | string | Hosted payment page URL. |
amountUsd | number | Invoice amount in USD. |
status | string | Main invoice state. See Status values. |
paymentCoverage | string | Whether payment is missing, partial, exact, or overpaid. |
receivedAmountUsd | number | USD amount received across all valid payment options. |
confirmedAmountUsd | number | USD amount that has reached the confirmation threshold. |
confirmations | number | Confirmations observed for the invoice-counted payment. |
productName | string or null | Product or service label. |
issuedBy | string or null | Invoice issuer name shown on the hosted page. |
billTo | string or null | Customer or company name shown on the hosted page. |
redirectUrl | string or null | URL used after the payer-facing flow completes. |
lastTransactionHash | string or null | Latest transaction hash observed for invoice-counted payment evidence. |
merchantReference | string or null | Your order, cart, or internal reference. |
customerId | string or null | Your internal customer ID. |
customerEmail | string or null | Customer email for reconciliation. |
metadata | object or null | Merchant metadata stored with the invoice. |
paymentSummary | object | Amount received, remaining, and overpaid. |
paymentTiming | object | Immediate or due-date timing. |
paymentOptions | array | Payment instructions available for this invoice. |
defaultPaymentOptionId | string or null | Initial hosted page payment option for the invoice. |
lastPaymentOptionId | string or null | Latest observed payment option for the invoice. |
payments | array | Observed payment events. Present on detail/status responses. |
paymentDetectedAt | string or null | ISO timestamp when sufficient payment was first detected. |
confirmedAt | string or null | ISO timestamp when sufficient payment reached the confirmation threshold. |
paidOutOfBandAt | string or null | ISO timestamp when an external payment was recorded. |
paidOutOfBandNote | string or null | Reconciliation note for an external payment. |
exceptionType | late_payment, partial_payment, or null | Exception type when merchant review is needed. |
exceptionStatus | open, closed, or null | Current exception state. |
exceptionAction | accept_late_payment, mark_paid_out_of_band, close_unpaid, or null | Merchant action used when the exception was closed. |
exceptionNote | string or null | Merchant note recorded when the exception was closed. |
exceptionClosedAt | string or null | ISO timestamp when the exception was closed. |
createdAt | string | ISO timestamp when the invoice was created. |
lastPaymentObservedAt | string or null | ISO timestamp for the latest observed payment event. |
Payment Summary Object
| Field | Type | Description |
|---|---|---|
paymentCoverage | string | Whether payment is missing, partial, exact, or overpaid. |
receivedAmountUsd | number | USD amount received across all valid payment options. |
remainingAmountUsd | number | USD amount still due. |
overpaymentAmountUsd | number | USD amount overpaid. |
Payment Timing Object
Immediate timing:
{
"mode": "immediate",
"expiresAfterMinutes": 20,
"payableUntilAt": "2026-04-29T10:20:00.000Z"
}Due-date timing:
{
"mode": "due_date",
"dueAfterDays": 7,
"gracePeriodDays": 14,
"dueAt": "2026-05-06T10:00:00.000Z",
"payableUntilAt": "2026-05-20T10:00:00.000Z"
}Due-date invoices require an enabled USDT or USDC payment method on Ethereum.
Payment Option Object
| Field | Type | Description |
|---|---|---|
id | string | Payment option ID. |
railType | wallet_contract or address_transfer | Payment rail used by this option. |
assetCode | string | Asset shown to the payer, such as USDT, USDC, or BTC. |
network | string | Network shown to the payer, such as ethereum or bitcoin. |
tokenContract | string or null | Token contract address for token-based options. |
quotedAmount | number | Amount due in the option asset. |
quoteRate | number | Rate used to quote the asset amount. |
destinationAddress | string or null | Destination address for address-transfer payment options. |
paymentUri | string or null | Payment URI for address-transfer payment options. |
qrCode | string or null | SVG QR code for the selected address-transfer option when requested. |
status | string | Payment option status. |
isDefault | boolean | Whether this is the default option on the hosted page. |
optionPayload | object or null | Executable payment data for custom wallet UI. |
For standard hosted checkout, redirect to paymentUrl and ignore paymentOptions[].
Payment Object
| Field | Type | Description |
|---|---|---|
id | string | Observed payment ID. |
paymentOptionId | string | Payment option matched by the observation. |
assetCode | string | Observed asset. |
network | string | Observed network. |
destinationAddress | string or null | Observed destination address when applicable. |
transactionHash | string or null | On-chain transaction hash when available. |
amountReceived | number | Amount counted from this observation. |
observedTotalAmount | number | Total amount observed for the matched payment evidence. |
confirmations | number | Confirmations observed for this payment. |
observedAt | string | ISO timestamp when payment was observed. |
confirmedAt | string or null | ISO timestamp when this payment was confirmed. |
invalidatedAt | string or null | ISO timestamp when previously observed evidence was invalidated, if applicable. |
invalidationReason | string or null | Reason a previously observed payment no longer counts toward the invoice payment, if applicable. |
Status Values
| Field | Values |
|---|---|
status | awaiting_payment, partially_paid, payment_detected, confirmed, paid_out_of_band, expired, voided |
paymentCoverage | no_payment, partial_payment, exact_payment, overpayment |
Use status for fulfillment decisions. paymentCoverage and paymentSummary explain underpayment and overpayment. A payment first observed at or before paymentTiming.payableUntilAt is on time; a payment first observed after that timestamp is late. Overpayment during the payable window does not open an exception; the invoice remains in its payment lifecycle state and exposes the excess amount in paymentSummary.overpaymentAmountUsd. A late payment never confirms an expired or voided invoice automatically. Late full payment opens a late_payment exception, and the invoice becomes confirmed only after the merchant closes it with accept_late_payment. confirmedAmountUsd shows how much USD has reached the confirmation threshold. Use payments[] for payment-level details such as transaction hash, observed asset amount, USD credit, confirmations, and confirmedAt.
Rate Limits
API-key-authenticated checkout requests are limited to 100 requests per minute from the same client. This limit applies to:
| Method | Path |
|---|---|
POST | /api/checkout/invoices |
GET | /api/checkout/invoices/:id |
GET | /api/checkout/invoices/:id/status |
POST | /api/checkout/invoices/:id/void |
POST | /api/checkout/invoices/:id/record-payment |
Requests over the limit return HTTP 429. Use the retry time in the error response before sending more requests.
Error Format
Errors use a JSON object with an error message:
{
"error": "Human-readable error message"
}Validation errors name the first invalid field and the relevant constraint:
{
"error": "productName must be at most 200 characters"
}HTTP Status Codes
| Code | Meaning |
|---|---|
200 | Success |
201 | Invoice created |
400 | Invalid request body, query, or invoice ID. The error message names the invalid field when validation fails. |
401 | Missing or invalid API key |
403 | Billing blocked invoice creation, or the API key cannot access the requested route |
404 | Checkout config or invoice not found |
409 | Incompatible invoice timing or unavailable payment method |
429 | Rate limit exceeded. API-key-authenticated checkout requests are limited to 100 requests per minute from the same client. |
502 | Payment-method or wallet backend unavailable |