Embedded Checkout
Embedded checkout
Render the whole payment experience inside your own product instead of redirecting the payer to the hosted page.
The flow
There are two ways to reach a payable state:
- One request: create the invoice with
pay_withset to awallet_network_id. The response'sactive_paymentalready carries the depositaddressandexpected_value. - Let the payer choose: create the invoice without
pay_with, call List payable coins to render the coin picker, then Select a coin to get the deposit address.
Then show the payer the address and expected_value.amount, and poll the invoice (or use webhooks) until it is completed or expired.
Quotes & polling
There is no requote endpoint. When rate_expires_at passes, the server automatically re-quotes the held (undetected) payment. Simply re-read the invoice to pick up the refreshed expected_value and rate_expires_at.
Track status by re-reading the invoice, or through the invoice webhooks: invoice.created, invoice.completed, invoice.expired, and invoice.canceled.
Constraints
Memo / destination-tag networks are not supported. Only offer tag-free chains. A deposit is a bare address string; there is no memo or tag field.
For the deposit QR, each payment carries a deposit_uri (a chain-correct URI pre-filled with the address and amount) and a hosted qr_code_url image. Prefer encoding deposit_uri into your own QR; use qr_code_url as a zero-effort fallback.
// 1. Create the invoice and select the coin in one request.const res = await fetch("https://api.coinfat.com/api/invoices", {method: "POST",headers: {Authorization: `Bearer ${process.env.COINFAT_API_KEY}`,"Content-Type": "application/json","Idempotency-Key": crypto.randomUUID()},body: JSON.stringify({amount: "49.99",duration: "1h",supported_wallets: ["usdt"],pay_with: "tron"})});const invoice = await res.json();const { address, expected_value } = invoice.active_payment;// 2. Show address + expected_value.amount to the payer (build the QR yourself).// 3. Poll until the invoice settles — or rely on webhooks.async function poll(id) {const r = await fetch(`https://api.coinfat.com/api/invoices/${id}`, {headers: { Authorization: `Bearer ${process.env.COINFAT_API_KEY}` }});const inv = await r.json();if (inv.status === "pending") return setTimeout(() => poll(id), 5000);// inv.status is now "completed", "expired", or "canceled".}