To accept Bitcoin on a website with CryptoLike, create a payment for the order with POST /v1/invoices and the BTC coin_id, send the customer to the payment page, and ship when the payment becomes paid. What makes Bitcoin different from other assets is time: blocks come every 10 minutes on average, the payer's fee decides how soon their transfer gets into one, and your deadline has to allow for both. This guide goes step by step, with the Bitcoin-specific decisions at each step.
Bitcoin payments at a glance
CryptoLike accepts native bitcoin on the Bitcoin network, on-chain. Every payment gets its own address, the status moves from new to pending when the transfer is in a block and to paid at the confirmation threshold of the asset, and a signed webhook reports each change.
| Fact | Bitcoin on CryptoLike |
|---|---|
| Asset · network | BTC · Bitcoin; network in the API is btc |
| Precision | 8 decimals (1 satoshi = 0.00000001 BTC) |
| Payment address | Native SegWit, starts with bc1q, new for every payment, never reused |
| Payment URI and QR | bitcoin:<address>?amount=<BTC> — the payer's wallet fills in the amount |
When pending appears |
When the transfer is in a block (its first confirmation) |
When paid |
At the confirmation threshold of the asset: confirmations in GET /v1/currencies, shown on the Bitcoin page |
| Block interval | 10 minutes on average, by the network's design |
| Payout destinations | Addresses starting with 1, 3, bc1q or bc1p |
| Not supported | Lightning payments; bitcoin-pegged tokens on other networks |
Checked against CryptoLike and the Bitcoin developer documentation on 2026-09-24.
Before you start
You need a CryptoLike account with Bitcoin enabled, an API key with create_invoice and read, and a webhook endpoint on your server that verifies signatures. If your site runs WooCommerce, OpenCart, PrestaShop or Magento, the plugin does steps 2–5 for you — see integrations — and only the deadline advice below applies.
Signing requests is shown in the Node.js guide, the PHP guide and the Python guide. The examples here reuse the cryptolike() helper from the Node.js guide.
1. Choose how you price and how long the customer has
CryptoLike can price a Bitcoin payment in BTC or in a fiat currency. In BTC, the amount is what you type. In USD or EUR, the rate is locked when the payment is created with the BTC coin_id and holds until the deadline, so the BTC amount on the page does not move while the customer pays. How that works: pricing in USD, getting paid in crypto.
The deadline matters more for Bitcoin than for faster networks. A payment that is new or pending at its deadline becomes expired, even if the transfer is already in a block. Money that confirms later is still credited, as a late payment — but the order no longer moves to paid on its own. Size the deadline for three things:
- The customer's time to open a wallet and send, often longer when they buy bitcoin on an exchange first.
- The first block. 10 minutes on average, but single blocks can take much longer, and a transfer with a low fee can wait for several blocks.
- The confirmations. The threshold from
GET /v1/currenciestimes about 10 minutes.
With ttl_seconds you set it per payment, from 60 seconds to 30 days; without it your account default applies, 30 minutes unless changed. For Bitcoin, a deadline of a few hours avoids most late payments; for a price in USD, remember that a longer deadline means a longer rate lock.
2. Find Bitcoin in the catalogue
Take the entry with ticker BTC and network btc from GET /v1/currencies. Its id is the coin_id for payments and payouts, confirmations is the threshold for crediting, and maintenance: true means the asset temporarily cannot be chosen for new payments.
const { currencies } = await cryptolike("GET", "/v1/currencies");
const btc = currencies.find((c: any) => c.ticker === "BTC" && c.network === "btc");
if (!btc || btc.maintenance) throw new Error("Bitcoin is not available right now");If the entry is missing, Bitcoin is switched off for your account: turn it on in the cabinet on the Coins page. Ask support only if Bitcoin is not offered there at all; until then, offer the customer another asset.
3. Create the payment for the order
Create one payment per order, with the order number as order_id and as the idempotency key, so a double click or a retry never opens a second payment. This example prices the order in US dollars, gives the customer three hours, and fixes the asset to Bitcoin.
const payment = await cryptolike("POST", "/v1/invoices", {
amount: "129.00",
currency: "USD",
coin_id: btc.id,
order_id: "A-1003",
idempotency_by_order_id: true,
ttl_seconds: 3 * 3600,
return_url: "https://shop.example/orders/A-1003",
}, "order-A-1003");
// payment.address → bc1q…
// payment.payer_amount → the exact BTC amount to send
// payment.checkout_url → the payment page for the customerStore payment.id with the order. A 503 unavailable means no fresh BTC rate was available: retry with the same key, or price the payment in BTC. Leave coin_id out if the customer may choose between Bitcoin and other assets on the payment page.
4. Send the customer to the payment page
Redirect the customer to checkout_url, or embed the same page with the checkout widget. The page shows the BTC amount, the network, the bc1q address with a QR code, a warning to send only on the Bitcoin network and the time left. The QR code and the "open in wallet" link carry a bitcoin: URI with the amount, so most wallets fill in both the address and the amount.
Two things the payer should know, and your support should repeat if asked:
- Send the exact amount, on the Bitcoin network. If a wallet or exchange takes its fee out of the amount, the payment arrives short; a shortfall of more than 0.5 % of the amount makes it
underpaid, a smaller one still counts aspaid. The payer can top up to the same address before the deadline. - The network fee is on top. The payer's wallet chooses the fee in satoshis per virtual byte; a higher fee usually gets the transfer into a block sooner. CryptoLike does not set it and does not receive it.
5. Wait for confirmations and ship on paid
CryptoLike watches the Bitcoin blockchain block by block. When a block includes the transfer, the payment becomes pending — "Payment detected. Waiting for confirmation." — and your endpoint receives invoice.pending. Each new block adds a confirmation; at the threshold the payment is paid, the funds are credited, and invoice.paid arrives. Ship on invoice.paid, not before.
Transfers that are only in the mempool — broadcast but not yet in a block — are not shown as pending. This is deliberate: until a transfer is in a block it can still be replaced, and showing it would promise a payment that may never arrive. The customer sees the page update as soon as the first block includes the transfer. Why the threshold differs between networks is explained in how many confirmations a crypto payment needs.
If a block reorganisation removes a confirmed transfer from the chain, CryptoLike reverses the credit and sends invoice.reverted. Stop fulfilment until a new invoice.paid arrives. More about reorgs.
6. Handle slow, replaced and late transfers
Bitcoin transfers can be slow or can change before they confirm, and your order logic needs an answer for each case. None of them needs special code on your side: the payment's status and webhooks already express them.
| What happened | What CryptoLike does | What you do |
|---|---|---|
| Transfer with a low fee waits for a block | Nothing is shown until it is in a block | Nothing; if the deadline passes first, see "late" below |
| The payer replaced the transfer (replace-by-fee) before a block | Only the transfer that reaches a block counts | Nothing: the replacement is credited if it pays the address |
| The replacement sends the coins elsewhere | Nothing arrives at the payment | The payment expires; the customer pays again with a new payment |
| Transfer confirmed after the deadline | Credited to your balance, late_payment: true, invoice.late_payment |
Decide with the customer: fulfil or refund |
| More than 0.5 % less than the amount | underpaid; the payer can top up until the deadline |
Wait, then ship for less, ask for the rest or refund |
The last two rows are covered in detail in underpaid, overpaid and late payments.
7. Pay out bitcoin
Payouts in BTC go from your available balance with POST /v1/withdrawals, to standard Bitcoin addresses: legacy (1…), script (3…), native SegWit (bc1q…) or Taproot (bc1p…). Call POST /v1/withdrawals/estimate first: it returns the platform fee, the reserved network fee, the total debit and the minimum amount, all in BTC, before anything is created.
The network fee of a Bitcoin payout is based on the fee rate the network currently needs for confirmation within a few blocks. The estimate reserves it with a safety margin; depending on the mode the platform sets for your account, you pay the reserve, or the fee actually paid with the rest returned. Send your own payout_id so a retried request never pays twice, and protect regular destinations with the payout whitelist and second approval. The fee schedule is on the pricing page.
Errors and what to do
| HTTP · code | What happened | What to do |
|---|---|---|
400 validation_error, field amount |
More than 8 decimals, or not a positive number | Round to satoshis and resend |
409 conflict, order_invoice_mismatch |
The order has an open payment with another amount | Reuse it, or cancel it while it is still new and create a new one |
503 unavailable |
No fresh BTC rate for a fiat-priced payment | Retry with the same Idempotency-Key, or price in BTC |
422 address_refused on a payout |
The destination is not accepted | Use another address |
403 kyb_required on a payout |
Payouts need a verified account | Complete account verification in the cabinet |
All codes are listed in the API reference.
FAQ
How long does a Bitcoin payment take to confirm?
Bitcoin produces a block every 10 minutes on average, and CryptoLike credits BTC at the confirmation threshold of the asset, published in GET /v1/currencies. The payment becomes pending when the first block includes the transfer. A low network fee can delay that first block.
Why doesn't the payment page show my transfer right away?
CryptoLike shows a Bitcoin transfer once a block includes it. A transfer that is only broadcast can still be replaced or dropped, so it is not shown as pending. If the payer set a low fee, the first block may take longer; the page updates as soon as it arrives.
What deadline should I set for Bitcoin payments?
Allow time for the customer to send, for the first block and for the confirmations. A payment that is still new or pending at its deadline expires, and money that confirms later arrives as a late payment. A deadline of a few hours avoids most late payments.
Can customers pay with Lightning?
No. CryptoLike accepts on-chain bitcoin on the Bitcoin network only. Lightning payments and bitcoin-pegged tokens on other networks do not reach the payment. Customers who hold stablecoins can pay in USDT on TRON or Ethereum instead.
Are Bitcoin payment addresses reused?
No. Every payment gets a new native SegWit address starting with bc1q, and an address index is never reused. That is how a transfer is matched to exactly one payment without asking the payer for a reference.