Withdrawal speed is a retention number, not a finance chore
Acquisition and deposits get the marketing budget, but withdrawals are where a player decides whether to come back. The first cashout is a trust test: a player deposits, plays, wins, and then watches to see whether the money actually arrives. If it does, quickly and without a support ticket, they reload and keep playing. If it stalls, that player is gone — and they tell other players why.
Card and bank rails make this test hard to pass. Gaming merchant categories are treated as high-risk, so a refund or push-to-card cashout can be declined by the player's issuer for reasons the operator can neither see nor fix. Bank transfers settle on banking-hours timelines, not play timelines. A manual payout queue adds human latency on top, and every hour in that queue is an hour the player spends doubting they will ever see the funds.
A low withdrawal approval rate is not a neutral cost — it actively burns the players you paid to acquire and the affiliates who referred them. Affiliates watch their referred players' experience closely; a network that hears "this operator is slow to pay" quietly redirects traffic elsewhere. Speeding up withdrawals is one of the few payment changes that shows up in retention and in acquisition at the same time.
A withdrawal is a payout you push, not a transfer you wait on
On crypto rails the shape of the problem changes. There is no issuer sitting between the operator and the player to decline an outbound payment, and a transfer to a valid address either confirms on-chain or it does not. Once your back office approves a cashout, the withdrawal becomes a payout: name the asset, the amount, and the player's wallet, and halfin executes it on the network you already accept deposits on.
The clean division of labor is the whole point. Your platform owns the decision — KYC status, bonus wagering completion, fraud and bonus-abuse checks, jurisdiction rules — and halfin owns the execution. halfin never decides whether a player may withdraw; it processes the instruction you send after your own controls have cleared. That keeps regulatory and responsible-gaming judgment inside your system, where it belongs, and keeps the rail itself a mechanical, fast, auditable step.
Because deposits and withdrawals run on the same chains, a player can cash out to the wallet they deposited from. A USDT-on-Tron depositor withdraws in USDT on Tron; a USDC-on-Solana player gets USDC on Solana. No currency surprise, no "we can only pay you back a different way," and the address is often one the player has already used with you.
Why the approval rate is structurally high
"High approval rate" on crypto rails is not a feature you toggle or a risk score you tune — it falls out of how the rail works. The reasons a card cashout fails simply are not present.
| Why card cashouts fail | What happens on a halfin payout |
|---|---|
| Issuer declines a push-to-card to a gaming MCC | No issuer in the loop — the payout goes straight to the player's wallet |
| Bank settles on banking-hours, not play-hours | Settles as fast as the chain confirms, any hour of any day |
| Refund/reversal limits cap how much can go back | No reversal mechanism — a payout is a fresh outbound transfer |
| Cross-border card rules block the corridor | Same chain worldwide; the corridor is the network, not a bank |
| Manual queue adds human latency on top | Approve once, then execution is programmatic and immediate |
The two ways operators pay cashouts
Player withdrawals come in two shapes, and halfin covers both with the same payout primitive. A single payout handles the one-off cashout a player just requested. A batch run handles the cashouts and rebates you settle on a cadence — end-of-day clears, weekly loyalty payouts, tournament prize distributions. Both share the same per-line shape and the same operator-approval control point.
The batch path is where the operational safety matters. Each payout line carries its own idempotency key, derived from your own ledger — for example the cashout id joined with the run. If a request times out, your worker restarts, or someone re-runs the file, re-submitting the same key returns the payout halfin already created instead of paying the player a second time. A double-paid winner is one of the worst outcomes in a gaming back office; idempotency keys are what take that failure mode off the table so you can retry a run from the top without fear.
Neither path moves funds the instant you call the API. Every payout enters a pending-approval state and is released after operator review, so a staged batch is a proposal until a treasurer signs it off. Your integration can queue thousands of cashouts unattended; a human still authorizes the money leaving the balance.
- Single payout — the immediate cashout a player just requested, to their own wallet.
- Batch payout — end-of-day, weekly loyalty, and tournament-prize runs in one idempotent submission.
- Per-line idempotency key — a retried run never pays a winner twice.
- Pending approval — every payout is reviewed and released before funds move on-chain.
- payout.completed webhook — the signed event that updates the player balance and your treasury.
Execute an approved cashout
Once your back office has approved a cashout, the withdrawal is a single API call. Name the currency and network the player withdraws on, the amount as a string, the player's destination address, and an idempotency key derived from your own cashout record so a retry resolves to the same payout. The full request and response schema lives at docs.thehalfin.com — the call below shows the line shape and the one header that authenticates it.
Treat the payout.completed webhook as the source of truth, not the API response. The POST stages the payout; an operator releases it; halfin broadcasts and tracks confirmations reorg-aware at the chain's threshold. When the transfer has actually settled to the required depth, your server receives an HMAC-signed payout.completed event — verify the signature, then mark the cashout paid and reconcile the player balance against it. A batch cashout run is the same call in a loop, one idempotent line per player.
# Execute one approved player cashout. amount is a string; the
# idempotency_key is derived from your own cashout record so a retry
# resolves to the same payout instead of paying the winner twice.
curl -X POST https://api.thehalfin.com/api/v1/payouts \
-H "X-API-Key: $HALFIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"currency": "USDT",
"amount": "240.00",
"destination": "TPlayerWalletAddressForUsdtOnTron",
"idempotency_key": "cashout-player-8821-00417"
}'
# The payout enters pending approval. After an operator releases it and
# the chain confirms, your server receives a signed payout.completed
# webhook — verify its signature before marking the cashout paid.What stays yours, and what irreversibility means for cashouts
halfin does not become your withdrawal logic. Whether a player has cleared wagering, passed KYC, triggered a fraud rule, or is allowed to withdraw in their jurisdiction is your platform's call. halfin receives the approved instruction, validates the destination address for the chosen chain, executes the payout under operator review, and returns a signed status your finance team can reconcile. Player identity stays your system of record; the payout record attaches to your player and cashout ids.
An outbound crypto payout is final once it confirms — there is no chargeback or recall on a settled transfer. That is a feature for deposits and a discipline for withdrawals: the address you send to must be the address you meant. This is exactly why the pending-approval step exists, and why address validation runs before a payout is accepted. The speed comes from removing the issuer, not from removing the human; an operator still reviews before the money leaves, so "instant" means instant once approved, not unattended.