Payouts

Overview

Payouts send funds from merchant balances to external blockchain addresses.

A payout sends funds from your merchant balance to an external blockchain address. Payouts execute automatically as soon as they are created — a new payout enters queued and then moves through processing and confirming to completed (or failed). There is no approval or cancellation step in the API.

Payout object

FieldTypeDescription
iduuidUnique payout identifier
statusstringCurrent payout status (see table below)
currencystringCrypto currency code
networkstringBlockchain network
amountstringAmount to send (decimal string)
destinationstringDestination blockchain address
destination_tagstringMemo or tag (required by some chains)
tx_hashstringOn-chain transaction hash (set after broadcast)
idempotency_keystringYour idempotency key if provided
created_atdatetimeCreation timestamp

Statuses

StatusMeaning
queuedCreated — accepted and waiting to be picked up for broadcast
processingSubmitted to the blockchain
confirmingBroadcast, awaiting required confirmations
completedConfirmed on-chain
failedFailed — reserved funds released back to balance
cancelledReleased by the platform while still queued — only occurs when a merchant account is being closed; reserved funds are returned to your balance

Creating a payout

Required fields: currency, amount, destination. Optional: network, destination_tag, description, metadata, idempotency_key. network is required for multi-network currencies (e.g. USDT, USDC, ETH) and can be omitted when the currency has an unambiguous network.

curl -X POST https://api-sandbox.thehalfin.com/v1/payouts \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $HALFIN_API_KEY" \
  -d '{
    "currency": "BTC",
    "amount": "0.01000000",
    "destination": "bc1qexampleaddress000000000000000000000000",
    "idempotency_key": "payout-2024-001"
  }'
import { createHalfin, createPayout } from '@halfin/sdk-merchant';

const client = createHalfin({ apiKey: process.env.HALFIN_API_KEY! });
const { data } = await createPayout({
  client,
  body: {
    currency: 'BTC',
    amount: '0.01000000',
    destination: 'bc1qexampleaddress000000000000000000000000',
    idempotency_key: 'payout-2024-001',
  },
});

Create payouts from trusted server-side code only. Validate destination addresses before submitting. Payout API keys should have narrower scopes than invoice keys.

EventWhen it fires
payout.completedPayout confirmed on-chain
payout.failedPayout failed — reserved funds released

Methods

  • CreatePOST /v1/payouts
  • ListGET /v1/payouts
  • GetGET /v1/payouts/{payoutID}

Troubleshooting

403 Forbidden — the API key lacks the payouts:write permission.

insufficient_balance — the merchant balance is too low. Check /v1/balances first.

Payout stuck in processing — the transaction has been submitted but not yet confirmed on-chain. This usually clears once the network confirms; if it persists, contact support.