Notes from the
payments edge.
What we learn shipping crypto money-movement at scale: postmortems, network deep-dives, compliance notes, and field lessons.
The halfin journal is where our payments and engineering teams write down what actually happens when crypto money moves at scale: invoice lifecycles and underpayment handling, mass-payout idempotency, confirmation timing across chains, settlement-currency choices, and the compliance boundaries that gate going live. Each post is a field note, not a press release — concrete patterns you can apply to your own integration. For step-by-step walkthroughs see the guides, short operational answers in the FAQ, and term definitions in the glossary.
Instant player withdrawals: a retention metric
For casinos and sportsbooks, a withdrawal that lands in two minutes beats the bonus you paid to acquire the player — and crypto delivers it.
Kill the Friday CSV: idempotent affiliate payouts
Pay an affiliate network from an idempotent fan-out over the single-payout API, with operator approval and an audit trail, so retrying the file is always safe.
USDT vs USDC for prop firm deposits
Stablecoin choice is not a brand preference. It changes trader adoption, treasury controls, network cost, and the support path when a deposit gets stuck.
Mass payouts to traders: a technical guide
Trader withdrawals, IB commissions, rebates, and profit splits need the same basics: approval IDs, wallet checks, batch state, and reconciliation.
Compliance for FX brokers accepting crypto
Crypto payment acceptance does not remove broker obligations. The safer design keeps trader controls in the broker stack and payment controls in the rail.
How crypto cuts trader funding time
A trader deposit is slow when payment, proof, review, and crediting live in separate queues. Stablecoin rails only help when the broker removes the handoffs.
Recurring crypto billing without a saved card
There is no card to vault and no instrument to auto-charge, so stop pretending. The honest pattern is an invoice per cycle with a fresh rate lock, and entitlements driven off the verified webhook.
The chargeback math of a stablecoin checkout
What an online store actually changes when settlement happens on-chain instead of on a card rail — disputes, refunds, and who eats the loss.
Collecting cross-border tuition without losing the dollar
A playbook for schools and bootcamps that price in USD but get paid from forty countries — fiat-anchored invoices that don't drift, instructor payouts, and refunds that aren't chargebacks.
Creator payouts and donations at scale: money in, money out, on the same rails
A working blueprint for a creator platform that takes crypto tips at the checkout and pays thousands of creators back out, without two reconciliations that disagree.
Verify the signature before you act on a webhook
An unsigned webhook is an anonymous HTTP request that knows your invoice IDs — here is how to handle a halfin event so a forged one can't ship a customer their order.
USDC on Base vs Ethereum: the same dollar, a different rail
Why the network you steer a USDC payer toward matters more than the asset itself, and why a fiat-anchored invoice lets you stop choosing.
Why a confirmation on Bitcoin isn't a confirmation on Solana
Per-chain thresholds aren't arbitrary caution — they're the price of reorg-aware crediting, and the reason a paid event reflects value that actually held.
Reorg-aware crediting: why we don't mark you paid the instant we see the money
A transaction in the latest block is the least safe transaction on the chain. Here is what a reorg actually does, and why halfin waits before it tells you to ship.
Designing an idempotent payout runner
A payout run is a loop over POST /api/v1/payouts, not a batch call — so the runner you write is the batch. Here is how we build one that survives a crash mid-file.
The deferred invoice: bill in fiat, let the payer pick the asset
How a fiat-anchored deferred invoice moves the asset choice and the rate lock to activation time, and when you should reach for it over a fixed-asset invoice.
From sandbox to production: the checklist we actually use
Six gates to clear before you flip from test keys to live keys, in the order that catches the most bugs while it's still free to find them.
When the card processor says no: a high-risk crypto playbook
A concrete playbook for businesses that get declined, throttled, or have funds held by card processors — what changes when settlement moves on-chain, and what doesn't.
Mass payouts vs single payouts: the same endpoint, a different mindset
Both go through POST /api/v1/payouts and both land in pending-approval — so the choice isn't an API decision, it's about who owns the loop and the ledger.
Static deposit addresses vs invoices: pick the right primitive
One is a mailbox that never closes; the other is a question with a deadline. The choice is not stylistic — it changes how you credit money and which webhooks you wait for.
The travel rule for crypto merchants, explained
What it actually is — passing originator and beneficiary information above a threshold between regulated providers — why it exists, and why it's a process you may run, not a badge a payment provider wears.
What to expect from KYB: business verification as a process, not a wall
KYB is the gate at the start of a payment relationship, not a certificate and not an API flag. Here is what it establishes, why it runs in parallel with your build, and the language to be precise about.
When the deposit isn't the amount: handling underpaid and overpaid invoices
The amount that lands on-chain is the customer's decision, not yours — so invoice.underpaid and invoice.overpaid aren't errors to catch, they're outcomes to design for. Here's the policy code that turns a support fire-drill into a switch statement.
A treasury playbook for the crypto you didn't ask to hold
Accepting crypto leaves you holding a dozen assets across seven networks. Here is how we use balance conversion to collapse that into a stablecoin position you can actually manage.
XRP and Solana for fast settlement: two rails, two definitions of 'done'
Both confirm in seconds, but they get there by different mechanics — and that difference decides where each one earns a place in your acceptance and payout flows.

Changelog: Q2 2026 SPL settlements, batch v2, EU MiCA notes
Solana SPL is now a first-class settlement rail, batch payouts get idempotent re-submission, and MiCA Phase 2 affects our roadmap.
A crypto checkout that doesn't lose payments
The browser redirect is a courtesy, not a fact. The webhook is the source of truth — verify the HMAC, fulfil on invoice.paid, and reconcile through the API after every outage.
Accepting crypto on Shopify, the honest way
There is no official halfin Shopify plugin. The real path is a hosted-checkout link and webhook-driven order reconciliation. Here is exactly what you wire up, and what nobody tells you about the order edge cases.
The redirect_url is a UI. The webhook is the truth.
The browser return is a courtesy to the customer. Fulfilment runs off the verified invoice.paid webhook, or it doesn't run at all. Here's why, and what breaks when you confuse the two.
Choosing a settlement currency: hold, convert, or rebalance
Three honest options for what your balance does after an invoice is paid — hold the asset you were paid in, auto-convert toward a stablecoin, or rebalance treasury by hand. None of them is a bank wire.

A stablecoin payroll playbook for distributed teams
How three remote-first companies replaced SWIFT and EOR fees with USDC payouts, including the tax and accounting plumbing nobody tells you about.
XRP destination tags: the integer that decides who gets paid
On the XRP Ledger the address is shared and the destination tag is the routing detail. Drop the tag and the money lands, but in the wrong ledger row. Here is why, and how it shapes acceptance.
The pending-approval gate: why every payout waits
Every payout you create sits inert until someone releases it from the dashboard. Teams read that pause as friction. It is the opposite — it is the one place a wrong address gets caught before the chain makes it permanent.
Why on-chain payments have no chargebacks
A confirmed crypto payment is final, with no card network to claw it back. Here is what that actually changes for disputes, fraud reserves, and the refund flow that replaces the chargeback button.

Designing webhooks that survive everything
Idempotency keys, signed envelopes, exponential backoff with jitter, and the moment your queue catches fire at 03:14 UTC. Lessons from the halfin event bus.
Multi-currency invoices in practice: one bill, the coin they brought
One fiat-anchored invoice can present USDT, USDC, BTC, ETH, SOL, and XRP at once. The customer settles in whatever they hold, and the fiat figure you billed never moves. Here is how that plays out at the checkout and in your books.
Building a crypto subscription system without a card on file
Invoice-per-cycle, a fresh rate lock every period, entitlement granted off the verified invoice.paid webhook, and dunning that doesn't lock people out on the first miss. The architecture, not the marketing.
Accepting USDT on three chains: let the payer pick
The same dollar of USDT settles on Tron, Ethereum, and Solana with wildly different fees and confirmation times. Here is how to expose all three and why TRC-20 keeps winning high-volume acceptance.
Reconciling mass payouts without tears
A payout run of 5,000 lines will time out, double-fire, and lie to you at least once. Per-line idempotency_key, the payout webhooks as truth, and the recovery query that closes the books.

MiCA Phase 2, in plain English
The CASP licence track, stablecoin reserve rules, and what changes for merchants accepting EUR-denominated crypto invoices in the EU.
KYB and going live: how verification gates the live key
Business verification isn't a hurdle you clear before you start — it's the one thing standing between a sandbox key and a live one. Here is what the process looks like and how to run it so going live is a credential swap, not a scramble.
Account funding: give each customer one address, not one invoice per top-up
When a customer adds money to a balance again and again, an invoice per charge is the wrong tool. A persistent per-customer deposit address credits reorg-aware with a webhook and keeps your reconciliation flat.
Crypto for prop firms: funding challenges in, paying winners out
How to take stablecoin deposits for challenge fees with a fiat-anchored, rate-locked invoice, and how to release trader profits through approved payouts without leaking treasury control.
After the window closes: late deposits, reversals, and the handler that doesn't double-credit
An invoice that already expired can still receive money, and a credit you already booked can still be unwound by a reorg. invoice.late_deposit and invoice.deposit_reversed are the two events that make those facts arrive as data instead of as a finance ticket — if your handler is idempotent enough to trust them.

How fiat-anchored invoices actually price themselves
A look under the hood at the rate window, settlement tolerance, and why a 90-second TTL is the right answer for almost everyone.
Base vs Arbitrum for merchant settlement: how to actually choose
Two Ethereum L2s, both EVM, both cheap, both reorg-aware. The decision is not throughput benchmarks — it's which assets settle on each rail and where your customers' funds already sit.
Accepting crypto donations for creators: whose tip is this?
A tip is a payment with a name on it. The hard part isn't taking the money — it's knowing which creator it belongs to when the signed webhook arrives, and paying them all back out without a reconciliation that disagrees with itself.
A sandbox-first testing playbook: prove the lifecycle before you flip to live
Simulate the full invoice and payout lifecycle with test keys, drive the real webhook events, assert idempotency under replay, then promote. What we want green before a single mainnet cent moves.

Closing 4,000 sellers a week without losing your mind
A marketplace finance lead walks through their batch-payout reconciliation, dispute window, and the single Postgres view they wish they'd built sooner.
Selling across borders when the card declines anyway
The order is real, the customer is real, and the card still gets rejected for being in the wrong country. Here's how to price in your own fiat and settle in USDT or USDC without the card network getting a vote.
Webhook idempotency and replays: build the handler that ships nothing twice
A webhook can arrive more than once. Verify the HMAC, dedupe on the event id, and make the side effect itself idempotent — so a redelivery is a no-op instead of a second shipment.
Orderbook vs AMM: where your conversion price actually comes from
When you convert one asset to another, a price has to come from somewhere. Two machines produce it differently — a matched book of resting orders, or a pool with a formula. Knowing which is answering decides how you read the number you get.

Your first hour in the halfin sandbox
A guided tour: create a key, fire an invoice, simulate a confirmation, replay a webhook. Everything you need to demo a flow before standup.
