Use case

Developer payouts: pay your ecosystem from the same balance

A SaaS platform with a marketplace owes money outward, not just inward. Plugin authors earn a revenue share, bounty hunters claim a posted reward, integration partners take a cut of referred revenue. These are recipients you do not control — wallets on chains they chose, in countries where a bank transfer is slow or impossible — and the payout run repeats every cycle. halfin pays that ecosystem from the same balance your subscriptions collected: each recipient is one idempotent payout, the whole run is a fan-out you can retry from the top, and a treasurer still approves before funds move.

01

Paying a developer ecosystem is a different problem than paying a payroll

Payroll is a short, stable list you have onboarded and verified, paid through a banking rail you already hold. A developer ecosystem is the opposite: a long tail of recipients you did not hire, who joined a marketplace or claimed a bounty, who hold a wallet on whichever chain they prefer, and who turn over from one cycle to the next. The list is never the same twice, and a meaningful fraction of it is unreachable by traditional payment rails at all.

The amounts are messy too. A revenue share is a percentage of what a plugin earned this period — a number your billing system computes, rarely a round figure. A bounty is a fixed reward attached to a specific piece of work. A referral commission is a cut of a partner's referred subscriptions. Each line has its own amount, its own destination, and its own reason, and the run has to reconcile back to your ledger afterward so an author can see why they were paid what they were paid.

That shape — many destinations, varying amounts, a recurring cadence, recipients on chains they chose — is exactly what halfin's payout primitives are built for. You stage the run programmatically from your own marketplace ledger, halfin executes each approved line and validates each destination for its chosen network, and the result comes back per-recipient so reconciliation is mechanical rather than a spreadsheet reconstruction.

  • Recipients are a changing long tail, not a fixed onboarded payroll.
  • Amounts are computed (revenue share) or posted (bounty), rarely round.
  • Each recipient holds a wallet on a chain they chose, in a country of their choosing.
  • The run repeats every cycle and must reconcile back to your marketplace ledger.
02

One balance, two directions: subscriptions in, ecosystem out

Most SaaS platforms that accept crypto eventually pay in crypto too, and the natural place for that money to live is the same halfin balance the subscriptions accrued to. A marketplace collects platform fees and subscription revenue on one side; it owes plugin authors, bounty hunters, and partners on the other. Running both off one balance means you are not bridging funds between a collection rail and a separate payout rail every cycle.

Sitting between collection and payout is balance conversion. The assets your customers paid in are rarely the exact assets your ecosystem wants to receive. A plugin author may want USDC on Base; a bounty hunter may have claimed the reward in USDT on Tron; you may have collected a mix of native assets and stablecoins across several chains. Automatic and manual conversion let you consolidate into the payout asset before a run — without moving funds off-platform — so the payout step works from a known, settled treasury position.

The division of responsibility is the same one a careful finance team would draw. Your marketplace decides who earned what and computes the line amounts; halfin executes the approved instruction, validates each destination, and reports the result through signed webhooks you reconcile against. halfin makes no custody guarantee beyond signing, scoped permissions, and an audit trail — the platform is payment infrastructure, and the earning logic stays inside your stack as the source of record.

03

Each payout line is the unit; idempotency makes the run safe

A developer payout run is a set of single payouts you submit together and reason about as one event. Every recipient line carries the same small set of fields, and the field that does the real work is the idempotency key. Derive it deterministically from your own ledger — typically the recipient's account id joined with the payout period or the bounty id — so that re-submitting the same run reproduces the same keys and halfin matches each one to the payout it already created instead of issuing a second.

That property is what turns a fragile loop into a safe one. Network calls to any payment API time out ambiguously: the request may have landed even though your worker never saw the response. Without idempotency, a retry is a second payment; with it, a retry is a no-op for every line that already succeeded. You can re-run the entire file after a crash, a rate limit, or a restart and converge on exactly one payout per recipient — the guarantee a hand-rolled marketplace payout script never has.

Amounts are always strings, never floating-point numbers, so a revenue-share value computed to many decimal places is transported exactly with no binary-rounding drift between your books and the chain. Each line also picks its own currency and network, so one run can pay an author in USDC on Base, a bounty hunter in USDT on Tron, and a partner in native SOL — without forcing everyone onto a chain they cannot receive on.

FieldTypeWhat it carries
currencystringAsset + network: USDT (TRC-20 / ERC-20 / Solana), USDC (ERC-20 / Solana / Base), BTC, ETH, SOL.
amountstringDecimal as a string. A revenue-share figure stays exact end to end — never a JS number.
destinationstringThe author's or partner's wallet, validated for the chosen network before the payout is accepted.
idempotency_keystringCaller-supplied, deterministic per recipient + run (e.g. account id + period). Re-submitting returns the original payout.
04

Submitting a payout run from your marketplace ledger

There is no separate batch endpoint to learn: a mass payout is a fan-out over the single-payout API, and the idempotency key on each line is what makes the loop safe to interrupt and re-run. Your marketplace already knows, for a given cycle, which authors earned what — that table is the run. Walk it, submit one payout per row with a key derived from your own records, and a retry after a timeout or a crash re-runs the whole thing without paying anyone twice.

The request below walks a recipient list and submits each line with its own deterministic key. Because each call is idempotent, wrapping the entire run in a retry is correct rather than dangerous. Each payout enters a pending-approval state rather than moving funds the instant you call — so the run you POST is a proposal staged unattended, and a treasurer releases it from the dashboard before anything leaves the balance. The exact request and response shapes are defined at docs.thehalfin.com.

  • Compute the cycle's amounts in your marketplace ledger — that table is the run.
  • Fan out over POST /api/v1/payouts, one line per recipient, no batch endpoint.
  • Key each line deterministically (account id + period) so the run is safe to retry.
  • Payouts stage as pending approval; a treasurer releases the run from the dashboard.
  • Reconcile per-recipient against signed payout.completed webhooks, not against a guess.
# Fan out a developer revenue-share run from your marketplace ledger.
# Each line is idempotent, so re-running after a crash pays no one twice.
while IFS=, read -r account currency amount destination; do
  curl -sS -X POST https://api.thehalfin.com/api/v1/payouts \
    -H "Content-Type: application/json" \
    -H "X-API-Key: $HALFIN_API_KEY" \
    -d "{
      \"currency\": \"$currency\",
      \"amount\": \"$amount\",
      \"destination\": \"$destination\",
      \"idempotency_key\": \"revshare-2026-06-$account\"
    }"
done < marketplace-payouts.csv
# Re-run the same file after a restart: keys collide, nobody is paid twice.
05

Bounties, revenue share, and partner commissions on one rail

The three ways a SaaS platform owes its developer ecosystem look different to the people earning, but they collapse into the same payout primitive. A bounty is a fixed reward posted against a task: the moment the work is accepted, you owe one wallet a known amount — a single payout to one destination after your own approval. A revenue share is a percentage of what a plugin or integration earned over a period: a computed amount paid per cycle, which is the recurring fan-out run above. A partner or reseller commission is a cut of referred subscriptions: same cadence, same run, a different line in the same ledger.

Because all three settle from the same balance with the same fields, you do not maintain three payout integrations. A one-off bounty is a single payout; a monthly revenue-share and commission run is a mass payout over the same API. The distinction is operational, not architectural — single payouts and mass payouts are the same guarantees applied to one destination versus the whole list at once.

What you oweHow it is earnedhalfin primitive
Bounty rewardA fixed amount posted against a task, owed once the work is accepted.Single payout to one destination after your approval.
Plugin revenue shareA percentage of a plugin's earnings, computed per billing cycle.Mass payout: a fan-out keyed per author + period.
Partner / reseller commissionA cut of subscriptions referred by an integration partner.Mass payout in the same cycle run, a different ledger line.
Correcting a missed or wrong lineA recipient was skipped or under-credited in a prior run.Single payout, or re-submit the run — keyed lines are no-ops.
06

Reconciling the run and where this leads

A payout run is not done when you POST it — it is done when each line has settled and you have matched the result back to your ledger. halfin credits and settles reorg-aware, using each chain's confirmation threshold, so a payout reported complete has actually settled to the depth that chain requires rather than merely being broadcast. That matters most at the tail of a large revenue-share run, where you want each author's status to mean paid, not submitted.

Drive that reconciliation off the payout.completed webhook rather than a polling loop. Verify the HMAC signature on every webhook before you act on it, then mark that author's cycle as settled in your own records and surface it in their earnings view. Because each payout carries the idempotency key you derived, matching a completion back to the exact ledger row is deterministic — no fuzzy amount-and-time matching against an unmatched-deposit pile.

The cleanest place to go deeper is the payout primitives themselves: mass payouts for the recurring revenue-share and commission run, and single payouts for one-off bounties and corrections. Both draw on the SaaS balance your subscriptions collected, and the SaaS hub covers the collection side — invoicing per cycle, the rate lock, and the confirmation webhook — that funds the balance these payouts spend.