Coinfat

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_with set to a wallet_network_id. The response's active_payment already carries the deposit address and expected_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

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.

Node
// 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".
}