Payment Page
Each invoice has a public payment page that customers can use to complete their payment. No authentication is required.
Payment page URL
https://fincobra.com/pay/:idWhere :id is the invoice UUID returned when you create an invoice.
Payment page API
The payment page frontend fetches invoice data from a public endpoint:
GET /api/checkout/pay/:idIt then polls a lightweight status endpoint while the invoice is active:
GET /api/checkout/pay/:id/statusThis endpoint requires no authentication and returns:
{
"id": "a1b2c3d4-...",
"amountUsd": 49.99,
"status": "pending",
"confirmations": 0,
"productName": "Pro Plan - Monthly",
"redirectUrl": "https://yoursite.com/thank-you",
"paymentSummary": {
"paymentState": "unpaid",
"receivedAmount": 0,
"remainingAmount": 49.99,
"overpaidAmount": 0
},
"selectedPaymentOptionId": "payment-option-1",
"paymentOptions": [
{
"id": "payment-option-1",
"railType": "wallet_contract",
"assetCode": "USDT",
"network": "ethereum",
"quotedAmount": 49.99,
"quoteRate": 1,
"destinationAddress": null,
"paymentUri": null,
"qrCode": null,
"isDefault": true,
"optionPayload": {
"railType": "wallet_contract",
"chainId": 1,
"contractAddress": "0x...",
"tokenContract": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
"recipient": "0x1111111111111111111111111111111111111111",
"decimals": 6,
"requiredConfirmations": 14,
"merchantIdHash": "0x...",
"invoiceIdHash": "0x...",
"paymentIdHash": "0x...",
"paymentAmountAtomic": "49990000",
"paymentCall": {
"merchantId": "0x...",
"invoiceId": "0x...",
"paymentId": "0x...",
"token": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
"recipient": "0x1111111111111111111111111111111111111111",
"amount": "49990000"
}
}
}
],
"payments": [],
"paidAt": null,
"confirmedAt": null,
"paymentTiming": {
"mode": "immediate",
"expiresAfterMinutes": 20,
"payableUntilAt": "2025-01-15T10:50:00.000Z"
},
"lastPaymentObservedAt": null
}Features
The hosted payment page includes:
- Rail-aware rendering — direct-transfer rails show amount, address, and QR; wallet rails show connect-wallet actions and the executable wallet-call payload
- Invoice identity — optional
billToandissuedByvalues appear on the hosted invoice when set - Timing-aware rendering — immediate invoices show a live countdown; due-date invoices show their due date instead
- Copy buttons — one-click copy for the active address-transfer destination and amount
- Real-time status — polls for payment updates and shows progress (partial payments, confirmations, exceptions)
- Return navigation — customers can go back to the previous page in their browser without affecting the configured
redirectUrl - Auto-redirect — when the payer-facing flow completes, the page redirects to the configured
redirectUrl(if set). Deterministic address-transfer payments can redirect after on-chain receipt even though merchant withdrawal is a separate later action.
Linking customers to the page
You can link customers directly to the payment page:
<a href="https://fincobra.com/pay/a1b2c3d4-..."> Pay now </a>The hosted page is intended to open directly in the browser. It is not designed for iframe embedding.
Polling behavior
The payment page loads GET /api/checkout/pay/:id once, then polls GET /api/checkout/pay/:id/status every few seconds while the invoice is pending or paid. Polling stops when the payer-facing flow is complete or the invoice reaches a terminal state (confirmed, expired, or underpaid).
Building a custom payment page
If you prefer a custom UI, use GET /api/checkout/pay/:id for the initial invoice payload and GET /api/checkout/pay/:id/status for polling.
For wallet-contract rails, after the payer transaction is mined you must also call:
POST /api/checkout/pay/:id/sync-wallet-paymentwith:
{
"paymentOptionId": "payment-option-1",
"transactionHash": "0x..."
}This records the on-chain PaymentAccepted event against the invoice so the hosted status and merchant views move forward correctly.
Public responses intentionally exclude operator-only fields such as reconciliation references, merchant withdrawal details, metadata, and exception resolution notes. Customer-facing invoice identity fields such as billTo and issuedBy remain part of the public payload.