Overview
Balances show per-currency available funds. Transactions is the operations feed — one row per settled money event with gross, fee, and net amounts.
Balances show the current available and pending funds per currency in your merchant account. The transactions feed records every settled money event — invoice payments, payouts, refunds, conversions — with a breakdown of gross amount, fees, and net amount credited or debited.
Balance object
| Field | Type | Description |
|---|---|---|
currency | string | Crypto currency code |
network | string | Blockchain network |
available | string | Spendable balance (decimal string) |
pending | string | Funds held for in-flight payouts or refunds |
Transaction object
Each transaction row is one settled money event:
| Field | Type | Description |
|---|---|---|
id | uuid | Operation UUID |
kind | string | Event kind: invoice_payment, payout, refund, recovery, conversion |
money_status | string | pending, posted, or reversed |
currency | string | Primary currency of the operation |
gross_amount | string | Full amount moved before fees (decimal string) |
fee_total | string | Total fees across the operation (decimal string) |
net_amount | string | Amount after fees (decimal string) |
invoice_id | uuid | null | Linked invoice UUID for payment events; null otherwise |
source_type | string | Domain entity type the event was recorded for |
source_id | uuid | Domain entity UUID |
counter_currency | string | null | Counter currency for conversions; null for single-currency events |
counter_amount | string | null | Counter amount for conversions (decimal string) |
rate | string | null | Conversion rate (decimal string); null for single-currency events |
amount_usd | string | null | USD equivalent at event time |
created_at | datetime | Event timestamp |
Postings (drill-down)
Fetching a single transaction via GET /v1/transactions/{operationID} returns the same fields plus a postings array — the individual accounting lines that make up the event:
| Field | Type | Description |
|---|---|---|
entry_type | string | Accounting entry type (e.g. invoice_credit, invoice_service_fee, conversion_out, conversion_in, payout_reserve) |
amount | string | Positive decimal-string amount |
direction | string | credit or debit |
currency | string | Posting currency |
payer | string | null | Fee payer on fee lines: merchant, payer, or halfin. null on non-fee postings |
Example: invoice payment postings
entry_type amount direction payer
invoice_credit 100.00 credit —
invoice_service_fee 0.49 debit merchantExample: conversion postings
entry_type amount currency direction payer
conversion_out 100.00 USDT debit —
conversion_in 92.00 EUR credit —
conversion_fee 0.50 EUR debit merchantWhen to use each surface
| Surface | Use |
|---|---|
GET /v1/balances | Check current spendable funds before creating a payout |
GET /v1/transactions | Reconcile your ledger — keyset-paginated feed of all events |
GET /v1/transactions/{operationID} | Drill down into one event to see per-fee accounting lines |
The balance.credited webhook
Use balance.credited as the fulfillment signal when you need to confirm that spendable balance is available — not just that an invoice payment was confirmed. A confirmed invoice payment credits the merchant balance after platform fees are deducted. The webhook payload includes gross_amount, fee_amount, and net_amount.
import { createHalfin, listBalances, listTransactions } from '@halfin/sdk-merchant';
const client = createHalfin({ apiKey: process.env.HALFIN_API_KEY! });
const { data: balances } = await listBalances({ client });
const { data: txns } = await listTransactions({ client, query: { limit: 50 } });Reconciliation notes
The transactions feed uses keyset pagination. Pass the previous response's next_cursor back as the cursor parameter to page forward. Do not use offset pagination for reconciliation — it can produce gaps or duplicates during concurrent inserts.
- Do not calculate spendable funds from webhook totals alone — fees, reversals, and late payments affect the balance independently.
- Treat
invoice.paidas payment confirmation; usebalance.creditedwhen fulfillment depends on spendable balance availability. - Reversals and late payments are reconciliation events that adjust balance after the fact — they appear as separate transaction rows with
money_status: reversedor as newinvoice_paymentrows. - Each transaction's
gross_amount,fee_total, andnet_amountare always consistent with its postings — use the postings drill-down for per-fee attribution.
Methods
- List Balances —
GET /v1/balances - List Transactions —
GET /v1/transactions - Get Transaction —
GET /v1/transactions/{operationID}