Payouts

Single crypto payouts with operator approval

A single payout is one approved withdrawal to one destination address. You create it from the dashboard or with one API call, an operator approves it before anything moves on-chain, and the whole sequence lands in an audit trail your finance team can reconcile. It is the primitive behind trader withdrawals, vendor settlements, and the ad-hoc transfers that never fit a batch.

01

The problem: one-off payments leak time and accountability

Most crypto payments out of a business are not batches. A trader requests a withdrawal, a supplier sends an invoice, a partner is owed a one-time settlement. Each is a single transfer to a single address, and each one tends to escape the system that should record it. The amount gets pasted into a wallet UI, someone screenshots the confirmation, and the only record that the money moved lives in a chat thread.

That informality is where the cost hides. A wrong address is irreversible on-chain. An unapproved transfer is a control gap an auditor will flag. A payout with no link back to the request it satisfied turns month-end reconciliation into archaeology. The work is not the transfer itself; it is proving, after the fact, who authorized it, against what, and that it went where it was supposed to.

halfin's single payout treats a one-off transfer as a first-class operation rather than a manual wallet action. The request, the approval, the on-chain execution, and the final state are one tracked object with a stable ID. Nothing leaves your balance until an operator approves it, and every step is recorded against that ID.

02

How a single payout works

You create a payout against your merchant balance by naming the currency, the amount, and the destination address. halfin validates the address for the chain you chose and reserves the funds, but does not broadcast anything yet. The payout enters pending_approval — it is recorded, visible, and inert.

An operator with payout permissions reviews and approves it in the dashboard. Approval is the gate: it separates the act of requesting a payment from the act of authorizing one, so the person who drafts a withdrawal is not necessarily the person who releases it. Only after approval does halfin sign and submit the transaction to the network.

From there the payout follows the chain. halfin waits for the per-chain confirmation threshold and crediting is reorg-aware, so a transaction that gets dropped in a short reorg does not leave you with a false completed state. The dashboard, the API, and a signed webhook all carry the same lifecycle, so your back office never has to guess where a withdrawal stands.

  • Create — name currency, amount, and destination; halfin validates the address and reserves the funds.
  • Approve — an operator with payout permissions authorizes it; nothing moves on-chain before this.
  • Execute — halfin signs and broadcasts to the destination network.
  • Confirm — crediting waits for the per-chain confirmation threshold and is reorg-aware.
  • Reconcile — final state lands in the dashboard, the API, and a signed webhook.
03

Payout lifecycle and what each state means

A single payout moves through an explicit set of states. Because the same lifecycle is exposed in the dashboard, the API, and webhooks, your CRM or ledger can mirror it exactly instead of inferring status from a block explorer.

The state that matters most operationally is pending_approval. It is a deliberate hold, not a delay — it is the window in which an operator confirms the destination and the amount before the transfer becomes irreversible. A payout can be cancelled while it is still pending_approval or approved but not yet executed; once it is on-chain, it is final.

StateMeaningCan cancel?
pending_approvalCreated and funds reserved; waiting for an operator to authorize.Yes
approvedAuthorized by an operator; queued for on-chain execution.Yes, until executed
processingSigned and broadcast to the network; awaiting confirmations.No
completedConfirmed on-chain to the per-chain threshold; reconciled.No
failedRejected before or during execution; reserved funds returned to balance.n/a
cancelledStopped by an operator before execution; nothing left the balance.n/a
04

Create a payout from the API

A single payout is one POST to the payouts endpoint. You authenticate with an API key scoped to payout permissions, pass the currency, amount, and destination, and include an idempotency key so a retried request after a network hiccup never creates a second withdrawal. The response comes back in pending_approval; the actual release still happens behind operator approval.

The amount is a decimal string, not a floating-point number — money crosses the API boundary as a string so no precision is lost in a JSON parser. The same request shape works for any supported asset; you change the currency and the destination address to match the chain.

curl -X POST https://api.thehalfin.com/api/v1/payouts \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $HALFIN_API_KEY" \
  -d '{
    "currency": "USDT_TRC20",
    "amount": "250.00",
    "destination": "TExampleTronAddress0000000000000000000",
    "idempotency_key": "withdrawal-9a3f"
  }'

# 201 Created — the payout is recorded in "pending_approval".
# Funds are reserved but nothing is broadcast until an operator approves it.
05

Supported assets and networks

A single payout can be denominated in any asset halfin settles. Stablecoins are the common case for withdrawals and vendor payments because the recipient gets a predictable amount, but native-asset payouts work the same way. You pick the chain the recipient wants to receive on; the payout primitive does not change.

halfin validates the destination address against the chosen network before reserving funds, so a TRC-20 address pasted into an ERC-20 payout is caught at creation rather than lost on-chain.

AssetNetworks for payout
USDTTron (TRC-20), Ethereum (ERC-20), Solana
USDCEthereum (ERC-20), Solana, Base
BTCBitcoin
ETHEthereum, plus L2s Base, Arbitrum, Polygon
Native L1/L2BNB Smart Chain, Tron, XRP Ledger, Solana
06

Approval, permissions, and the audit trail

Single payouts are built around the assumption that moving money is a controlled action. API keys carry scoped permissions, so an integration that only needs to read balances never holds the ability to draft a payout, and a payouts key can be issued separately from the key your accounting export uses. The operator approval step then sits on top of that, as a human authorization that on-chain finality demands.

Every transition is recorded against the payout ID: who created it, who approved it, when it executed, and the on-chain transaction it produced. That record is what makes a one-off payout reconcilable. When finance closes the month, each withdrawal points back to the request it satisfied and forward to the transaction that settled it, with no chat-thread reconstruction in between.

Each transition also emits a webhook so your systems learn about it without polling. halfin signs every event with HMAC, and your handler should verify that signature before it acts — credit a trader account, mark a vendor invoice paid, or notify a customer. Treat the webhook as a prompt to read the authoritative state, not as the source of truth itself: an unverified or replayed payload should never move money on your side.

  • Scoped API keys — a payouts:write key is separate from a read-only accounting key.
  • Operator approval — a human authorizes the release before anything is broadcast.
  • Address validation — the destination is checked against the chosen chain at creation.
  • Idempotency keys — a retried create request never produces a duplicate payout.
  • Full history — creator, approver, timestamps, and the on-chain tx are stored against the ID.
07

Paying out an asset you do not hold

A payout draws from your merchant balance, so the asset and network you want to send have to be funded. Settlement rarely lines up perfectly: you might collect mostly USDT on Tron but owe a vendor USDC on Base, or hold native ETH while a trader wants to withdraw a stablecoin. A single payout does not invent the funds — it moves what your balance holds.

When the balance is in the wrong asset, balance conversion is the step in front of the payout. You convert part of your balance into the asset and network the recipient expects, then create the payout against the converted funds. Conversion can run automatically as a treasury rule or manually when you want to time it, and because both share the same merchant balance, the two operations chain without leaving halfin. The payout itself stays unchanged: name the currency, the amount, and the destination, and let an operator approve it.

08

When to use single vs. mass payouts

Reach for a single payout when each transfer is its own decision: a trader withdrawal that an operator reviews, a supplier settlement tied to a specific invoice, a one-time partner payment. The value is the per-payout approval and the clean record attached to one request.

When you are paying many recipients on a schedule — marketplace sellers, affiliate runs, contractor payroll — the unit of work is the run, not the individual line. That is what mass payouts handle: one idempotent batch with one approval, instead of dozens of separate authorizations. Both share the same balance, the same reorg-aware crediting, and the same webhook envelope, so you can move a flow from one to the other without re-plumbing your reconciliation.