Use case

Instant creator withdrawals

A creator hits 'withdraw' and then watches the dashboard. On bank rails the answer is a payout file that clears next week; with halfin it is a payout you execute on-chain the moment your operator approves it. The withdrawal is one approved single payout to the creator's wallet — and when a queue of them piles up, the same payout API clears the whole queue as one idempotent run, so retrying never pays a creator twice.

01

The problem: 'withdraw' is a promise you have to keep fast

A creator's balance on your platform is money they have already earned. The withdrawal button is where your relationship with them is tested: they ask for their money, and the gap between the ask and the money landing is the part they remember. Bank rails make that gap multi-day and per-country — a payout file batched overnight, cross-border fees per recipient, and a clearing window that is opaque to the creator staring at a 'pending' label.

The other half of the problem is your own control. You cannot pay every withdrawal the instant it is requested — there is an approval step, sometimes a risk check, sometimes a hold. So withdrawals queue up: a list of approved-but-not-yet-paid requests that you need to clear in one pass without losing track of which ones already went out.

halfin splits the timing from the approval cleanly. Your platform owns the approval — eligibility, risk, holds, daily limits all stay in your stack. Once a withdrawal is approved, paying it is a single payout you execute on-chain, and settlement happens on the chain you send on rather than in a banking batch window. A creator who is approved is paid on a chain timescale, not a banking one.

02

One withdrawal is one approved single payout

The unit of an instant withdrawal is the single payout: one approved payment, one destination, one creator drawing down their available balance on demand. Your backend decides the withdrawal is good — the creator is eligible, the amount is within their balance, the wallet passed your checks — and then hands halfin the approved instruction to execute.

A payout line carries four things: the asset (`currency`), the `amount` as a string, the creator's `destination` wallet, and an `idempotency_key` that ties the payout to that specific withdrawal request. The key is what makes the approval-to-payment step safe to retry: if your approval handler fires twice, or a proxy replays the call, halfin recognises the key and the creator is paid exactly once.

Crediting on the receiving side is the chain's own business — reorg-aware, with the per-chain confirmation threshold applied — but the creator sees their withdrawal move from approved to sent as soon as you execute it. Most creator withdrawals settle in stablecoins on low-fee rails like Tron (TRC-20) or Solana, where the on-chain wait is short and the fee does not eat into a small balance.

  • Your platform approves the withdrawal — eligibility, balance, wallet checks, holds.
  • The approved withdrawal becomes one single payout to the creator's wallet.
  • The idempotency key ties the payout to the request, so approval retries don't double-pay.
  • Settlement is on-chain and reorg-aware, with the chain's confirmation threshold.
03

A withdrawal queue is one idempotent payout run

Most platforms do not pay each withdrawal the literal second it is approved. They batch: approvals accumulate through the day, and a scheduled pass — or an operator clicking 'pay approved' — clears the queue. That batch is where the dangerous ambiguity lives. A pass that dies halfway leaves you unsure which creators were paid, and a naive retry risks paying some of them a second time.

halfin's mass payout is exactly this queue-clearing run, and it is a fan-out over the same single-payout API — one call per approved withdrawal, each carrying its own idempotency key derived from the withdrawal request. There is no separate batch endpoint to learn; the run is N payouts, and the keys are what make the run safe. If the pass crashes and you re-run the whole queue, the colliding keys mean every creator is still paid exactly once. If one creator's wallet is bad, that one payout is a visible failure you re-issue without touching the lines that already paid.

So the same primitive covers both shapes of 'instant withdrawal': pay-on-approval is a single payout fired the moment your operator approves one request; clear-the-queue is the fan-out that pays every approved request in one safe pass. The table below is the decision you actually make.

Withdrawal shapehalfin primitiveWhen you reach for it
Pay one creator the moment it's approvedSingle payoutOn-demand draw-down; operator approves one request and it goes out now.
Clear the whole approved-withdrawal queueMass payouts (idempotent fan-out)Scheduled or operator-triggered pass over every approved request.
Re-issue one withdrawal that failedSingle payoutA bad destination or rejected line you fix and resend, run intact.
Pay in a different asset than the creator earnedBalance conversion + payoutCreator wants USDC; the platform holds another asset behind the balance.
04

What an on-approval withdrawal looks like

When your approval handler decides a withdrawal is good, it makes one authenticated call to the payout API with the creator's destination and an idempotency key tied to the withdrawal request id. You do not write per-chain wallet code or a confirmation watcher — you submit the approved instruction and read the payout's state back.

Below is a single on-approval withdrawal. The amount is a string — monetary values are strings end to end, never floats — and the idempotency key is derived from the withdrawal request so an accidental double-submit pays the creator once. The exact response shape is defined in the docs and the @halfin/sdk-merchant types; the point here is that one approved instruction becomes one on-chain payout.

# Fired from your withdrawal-approval handler. The idempotency key is
# derived from the withdrawal request id, so an accidental double-
# submit pays the creator exactly once.
curl -sS -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": "120.00",
    "destination": "TQ5...creatorWalletOnTron",
    "idempotency_key": "withdrawal-req-90431"
  }'

# Read the payout back to see its state, and confirm settlement from
# the payout.completed webhook your server receives — verify the HMAC
# signature first. See docs.thehalfin.com for the full response schema.
05

Confirm withdrawals from the signed event, not the request

The POST that submits a withdrawal tells you the payout was accepted; it does not tell you the creator's money has settled on-chain. The fact you should mark a withdrawal 'sent' on is the `payout.completed` webhook — the signed event halfin delivers when the payout reaches the completed state. Treat that event as the source of truth for your creator-facing status and your ledger, not the synchronous response and not a poll you happened to run.

Verify the HMAC signature on every webhook before you act on it. Only after the signature checks out should your code move the withdrawal to its final state, notify the creator, and debit their balance in your own ledger. A withdrawal you mark complete is then a withdrawal that actually completed on-chain — not one you assumed completed because a request returned 200.

Because the webhook carries the payout's identity, you can match it straight back to the withdrawal request and the creator it belongs to. Your reconciliation is the payouts' own state plus their completion events — not a guess assembled from request logs.

  • payout.completed is the canonical 'the creator was paid' signal — verify HMAC first.
  • Move the withdrawal to its final state and debit the creator's balance only after that.
  • Match the event back to the withdrawal request id you put in the idempotency key.
  • Reconcile from payout state + completion events, never from request logs.
06

Where instant withdrawals sit on the platform

Instant creator withdrawals are the out-bound half of the streamers and creator-economy flow. The in-bound half — tips, donations, and subscriptions through hosted checkout, credited reorg-aware to a balance — is what funds the balance creators later draw down. This page is narrower: it is only the moment a creator asks for their money and you pay it.

Approval and eligibility stay in your stack; that is your system of record for who may withdraw, how much, and to which wallet. halfin processes the on-chain rail and returns signed status. If a creator wants paying in an asset different from the one your platform holds, balance conversion sits between the held balance and the payout. For higher-risk niches, treat halfin as the payment layer and take licensing and compliance questions to your own counsel — this page does not give legal advice.