Native BTC, on the Bitcoin network
This is real bitcoin moving on the Bitcoin blockchain — not a wrapped token, not BTC riding on another chain. The customer sends from whatever wallet they already use, the transaction lands in a block, and halfin watches that block. Because it is the base layer, the payer is never asked to bridge, swap, or trust a representation of bitcoin issued somewhere else.
That matters for who actually pays you. The people most likely to reach for BTC are the ones who treat it as a long-term holding: they run a hardware wallet, they self-custody, and a card or a bank transfer is genuinely inconvenient for them. Bitcoin is the asset they can send without leaving the tools they trust. Accepting it natively removes the one step that would otherwise lose the sale.
Bitcoin is also the asset with the least ambiguity about what it is. There is one BTC and one Bitcoin network, so there is no token-contract to verify and no second issuer to vet. The trade-off is throughput: blocks are mined roughly every ten minutes, so a Bitcoin payment is deliberate rather than instant. halfin's job is to make that wait observable instead of a black box — you and the customer both see the payment move from seen, to confirming, to settled.
Confirmations and reorg-aware crediting
A Bitcoin transaction is not final the instant it broadcasts. It sits in the mempool, gets mined into a block, and then accumulates confirmations as more blocks stack on top. Early on, the chain can still reorganize — a competing block wins and a transaction that looked settled is unwound. Crediting too eagerly is how merchants get burned.
halfin waits for the per-chain confirmation threshold before it marks a Bitcoin payment as paid, and crediting is reorg-aware: if the chain reorganizes and undoes a transaction halfin was tracking, that is reflected rather than ignored. The number you see as settled is a number that actually held on the canonical chain. You do not have to implement confirmation counting, mempool watching, or reorg handling yourself — that logic lives in halfin's Bitcoin gate.
Practically, that means you should treat the early states as in-flight, not done. The table below is the shape of a Bitcoin payment as your integration observes it. Each transition is something you can react to through the dashboard, the REST API, or a signed webhook — and the only state that should trigger fulfilment is the settled one.
| State | What is happening on-chain | What you should do |
|---|---|---|
| Awaiting payment | Invoice is live, the rate is locked, and halfin is watching for an incoming BTC transaction before the invoice expires. | Show the customer the BTC address, the exact amount, and the countdown. |
| Payment seen | A matching transaction has appeared but is not yet mined or not yet sufficiently confirmed. | Tell the customer the payment is in flight. Do not release goods. |
| Confirming | The transaction is mined and confirmations are accumulating toward the Bitcoin threshold. | Keep waiting — crediting is reorg-aware and not yet final. |
| Paid | The confirmation threshold is met; the billed amount is settled to your balance. | Fulfil the order and reconcile against the fiat figure you billed. |
| Expired | The invoice window elapsed before a sufficient payment arrived. | Re-issue at the current rate if the customer still wants to pay. |
Where Bitcoin sits among the assets you can take
Bitcoin is one rail among several. A customer who holds BTC pays in BTC; another who lives in stablecoins reaches for USDT or USDC on a faster chain. You do not have to choose — a single fiat-anchored invoice can offer the networks your customers actually use, and each settles back to the same booked amount. The matrix below places Bitcoin against the other supported assets so you can see where its strengths and trade-offs land.
The point of showing it side by side is honesty about fit. Bitcoin is unmatched for self-custody payers and for sums where the payer wants base-layer settlement, and it carries no chargeback risk once confirmed. It is not the rail you would steer someone toward for a small, time-sensitive checkout where a stablecoin on Solana or an L2 confirms in seconds. Offer both and let the customer pick the one they already hold.
| Asset | Network | Finality feel | Best for |
|---|---|---|---|
| BTC | Bitcoin | Deliberate — confirmations over minutes | Self-custody and BTC-only payers; base-layer settlement |
| USDT | Tron (TRC-20), Ethereum (ERC-20), Solana | Fast on Tron and Solana | Low-friction stablecoin billing |
| USDC | Ethereum (ERC-20), Base, Solana | Fast on Base and Solana | Dollar-denominated billing for EVM-native and Solana payers |
| ETH | Ethereum (+ ERC-20) | Minutes | EVM-native payers and token settlement |
| SOL | Solana (+ SPL) | Seconds | Fast, low-fee settlement |
| XRP | XRP Ledger | Seconds | Fast finality on the XRP Ledger |
Three ways to take a Bitcoin payment
How you collect BTC depends on your flow: billing a known customer for a known amount is one shape, needing a standing place for value to land is another. halfin gives you the same Bitcoin gate underneath three different surfaces, so you can pick the one that matches rather than rebuilding the on-chain plumbing each time.
Each option below produces a Bitcoin address and an expected amount. The difference is in lifecycle: an invoice is a one-time, rate-locked request with an expiry; a static deposit address is a persistent place to receive bitcoin that does not expire. Most businesses use invoices for sales and a static address for top-ups, deposits, or anything that is not a single priced order.
- Invoicing — bill in your own currency (USD, EUR), let the customer pay the equivalent in BTC. The rate locks when the invoice activates, so the amount you book never drifts while the customer fetches their wallet.
- Hosted checkout — present a halfin-hosted page that shows the BTC address, a scannable QR, the exact amount, the network, and a live status. Nothing to render yourself; you hand the customer a link.
- Static deposit addresses — a persistent per-merchant Bitcoin address that does not expire, for deposits and top-ups rather than a single priced sale. Funds arriving on it are credited the same reorg-aware way.
No chargebacks, settled to your balance
A confirmed Bitcoin payment is final in a way a card payment is not. There is no issuer to reverse it weeks later and no chargeback window hanging over the sale. Once the transaction has the confirmations the network requires, the value is yours — your fraud exposure on the payment itself is the wait for confirmations, which halfin manages, not a months-long reversal risk. That is precisely why high-risk and chargeback-prone merchants reach for crypto rails in the first place.
Settled BTC accrues to a balance you control. From there it behaves like any other settled value on the platform: convert it to a stablecoin if you would rather not hold price exposure, pay it out to a destination, or leave it as bitcoin. If you ever need to return funds to a customer, that flows through refunds as a deliberate, recorded action — there is no automatic reversal, because on-chain there is nothing to automatically reverse.
Create a BTC-payable invoice
Bitcoin acceptance runs on the same spec-first REST API as every other asset. You authenticate with a scoped API key and post the fiat amount and currency; halfin locks the rate at activation, computes the BTC amount, and returns an invoice you can present through hosted checkout or render yourself. Send an idempotency key so a retried request never creates a duplicate invoice.
The call below is the minimal create. The amount is sent as a string — monetary values are strings end to end, never floats — and the currency is your fiat anchor, not the asset. You do not name the asset here; the customer chooses BTC at pay time from the networks you support. The exact request and response fields are defined in the docs and the @halfin/sdk-merchant types.
curl -X POST https://api.thehalfin.com/api/v1/invoices \
-H "X-API-Key: $HALFIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount_fiat": "120.00",
"fiat_currency": "USD",
"deferred": true,
"description": "Order #4471",
"idempotency_key": "00000000-0000-4000-8000-000000000001"
}'
# The customer chooses BTC at pay time. halfin locks the rate at
# activation, pins the payable bitcoin amount, and credits the
# deposit reorg-aware once it meets the Bitcoin confirmation
# threshold. See docs.thehalfin.com for the full request/response schema.