Native SOL on Solana — what you are actually taking
When a customer pays this invoice in SOL, the network's native coin moves on the Solana blockchain. There is no SPL token contract to verify and no wrapped representation standing in — SOL is the coin Solana itself runs on, paid straight from the customer's main wallet balance. halfin's Solana gate watches that chain for the transfer, matches it to your invoice, and tracks it through to settlement. For a payer who keeps value in SOL, that is the most direct path: no token-account setup, no bridging, no detour through another asset.
SOL is a volatile asset, which is the one thing that shapes how you bill it. Unlike a dollar-denominated stablecoin, the SOL price moves against your fiat figure between the moment you present the invoice and the moment the customer sends. halfin handles that with an activation-time rate lock: the payable SOL amount is pinned for the life of the invoice, so the customer settles the exact figure they were shown and the dollar amount that reconciles to your ledger is the one you billed. The volatility is absorbed by the lock, not pushed onto either side mid-payment.
If your customers also hold USDC or USDT on Solana, those SPL stablecoins are a separate rail on the same chain — and on the same invoice. This page stays narrow on purpose: accepting native SOL, on the network it is native to. The stablecoin path lives on the Solana asset hub.
- Native SOL — Solana's own coin, paid from the customer's main wallet balance.
- No token contract — SOL is not an SPL token, so there is nothing to verify or whitelist.
- Volatile asset — the activation-time rate lock pins the payable SOL amount for the invoice's life.
- Same gate, same chain as Solana USDC and USDT — SOL is one rail among them, not a separate integration.
Fast, low-fee settlement — and why it helps the checkout
Speed and fee are properties of the Solana network, not a halfin rate — but they change how the payment feels for your customer. A Solana transfer confirms quickly and costs a fraction of a cent in network fee, so the payer is not watching a spinner for ten minutes or weighing whether the gas is worth a small purchase. For a checkout, that lands as fewer abandoned payments: the window between "I clicked send" and "the invoice says paid" is short.
The low fee matters most on small-ticket sales. On a high-fee chain, a few-dollar invoice can carry a network cost the customer resents; on Solana that friction largely disappears, which makes SOL a sensible rail to offer for low-value top-ups, micro-purchases, and pay-per-use flows. None of this is a claim about what halfin charges — pricing is separate and qualitative. It is a claim about the chain your customer is paying on.
halfin does not turn that speed into a shortcut on safety. A fast confirmation is still a confirmation: crediting waits for Solana's per-chain threshold before an invoice is marked paid, and the crediting is reorg-aware. You get the perceived speed without crediting money that has not actually settled.
Confirmations and reorg-aware crediting
A Solana transfer is not final the instant a wallet broadcasts it. It is seen on the network, then accumulates confirmations toward the per-chain threshold halfin applies before it marks the payment paid. Early on, the network can still reorganize and unwind a transaction that looked settled — crediting too eagerly on that early signal is how a merchant ends up releasing goods against a payment that later disappears.
halfin's crediting is reorg-aware on the Solana gate as it is on every gate: if the network reorganizes and undoes a transaction halfin was tracking, that is reflected rather than left as a phantom credit on your books. You do not implement confirmation counting or reorg handling yourself; that logic lives in the gate. The number you see as settled is one that actually held. The table below is the shape of a single SOL payment as your integration observes it — through the dashboard, the REST API, or a signed webhook.
| State | What is happening on Solana | What you should do |
|---|---|---|
| Awaiting payment | Invoice is live, the rate is locked, and the gate is watching for an incoming SOL transfer before the invoice expires. | Show the SOL address, the exact amount, the network, and the countdown. |
| Confirming | A matching SOL transfer has been seen and confirmations are accumulating toward the Solana threshold. | Tell the customer the payment is in flight. Do not release goods yet. |
| Paid | The confirmation threshold is met; the billed amount settles to your balance. | Fulfil the order and reconcile against the fiat figure you billed. |
| Underpaid / overpaid | The transfer cleared but the amount differs from the expected SOL figure. | Request a top-up, settle partially, or account for the excess under your own policy. |
| Expired | The invoice window elapsed before a sufficient payment arrived. | Re-issue at the current rate if the customer still wants to pay. |
Bill in fiat, let the customer settle in SOL
You price in dollars; the customer pays in the SOL they hold. A halfin invoice carries the fiat amount you actually care about and the payable SOL amount derived from it, and the rate locks when the invoice activates — not when you draft it. A customer who pays inside the payment window settles the exact SOL amount they were shown, and the dollar figure that reconciles to your ledger is the one you billed. Because SOL is volatile, this lock is where the model earns its keep: neither you nor the customer is exposed to a price move between presentation and payment.
Underpaid and overpaid amounts are first-class outcomes, not silent failures. If a customer sends slightly less SOL than quoted — a stale wallet quote, an exchange withdrawal fee deducted from the send — the invoice records the shortfall so you can request a top-up or settle partially under your own policy. An overpayment is recorded too, visible and accountable instead of disappearing into an unmatched-deposit pile. The invoice always tracks the expected SOL amount against what actually arrived on-chain.
- Rate locks at activation — the payable SOL amount is fixed, not recalculated mid-payment.
- Bounded expiry — every invoice has a payment window, so a stale SOL quote never settles.
- Underpaid / overpaid amounts are recorded against the invoice, never stranded.
- Settled SOL accrues to a balance you can convert to a stablecoin, pay out, or hold.
Three ways to take a SOL payment
How you collect SOL depends on the 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 Solana gate underneath three surfaces, so you pick the one that fits instead of rebuilding the on-chain plumbing each time. Each option produces a Solana address and an expected amount — the difference is lifecycle.
Hosted checkout renders the SOL invoice — address, scannable QR, exact amount, network, and a live countdown — with nothing for you to build. If you render your own UI with self-hosted checkout, you read the same fields off the same API. A static deposit address is a persistent place to receive SOL that does not expire, for top-ups and deposits rather than a single priced order. Most businesses use invoices for sales and a static address for everything that is not one.
- Invoicing — bill in your own currency (USD, EUR) and let the customer pay the equivalent in SOL. The rate locks at activation, so the amount you book never drifts while the customer fetches their wallet.
- Hosted checkout — hand the customer a halfin-hosted link that shows the SOL address, a QR, the exact amount, the network, and a live status. Nothing to render yourself.
- Static deposit addresses — a persistent per-merchant Solana address that does not expire, for deposits and top-ups. Funds arriving on it are credited the same reorg-aware way.
Create a SOL-payable invoice
SOL acceptance runs on the same spec-first REST API as every other asset. Authenticate with a scoped API key via the X-API-Key header, post the fiat amount and currency, and halfin locks the rate at activation, computes the payable SOL amount, and returns an invoice you can present through hosted checkout or render yourself. Send idempotency_key in the request body so a retried request never creates a duplicate invoice.
The call below is the minimal create. The amount is 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 SOL here; the customer chooses Solana 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": "25.00",
"fiat_currency": "USD",
"deferred": true,
"description": "Wallet top-up",
"idempotency_key": "00000000-0000-4000-8000-000000000001"
}'
# The customer chooses Solana and pays in native SOL at pay time.
# halfin locks the rate at activation, pins the payable SOL amount,
# and credits the deposit reorg-aware once it meets the Solana
# confirmation threshold. Track it via signed webhook events.
# See docs.thehalfin.com for the full request/response schema.