ACH payouts to creators
ACH payouts with KYC gates, eligibility checks, and signed lifecycle webhooks.
Answers the question
How do I add creator payouts to my app?
Summary
Creator payouts involve identity state, tax profile state, bank instrument state, ledger state, rail execution, and lifecycle events. Soledgic presents that workflow as one API surface. A payout request goes through KYC + tax-profile + bank-instrument gates, posts an atomic ledger entry, starts the payout, and fires signed webhooks at every state transition. Indeterminate rail outcomes remain in a reconciliation lane until confirmation arrives.
Primitives in play
- request_payout
Idempotent payout request. Routes through the org daily-cap advisory lock if a cap is set.
- KYC gates
Three independent layers: edge function, reservation RPC, DB trigger. Defense in depth.
- process_payout_atomic
Debit creator_balance, credit cash, optionally credit tax_withholding — all atomic.
- payout.executed webhook
Fires when the payout rail confirms the ACH was sent.
How it fits together
- Creator completes KYC. Hosted KYB/KYC flow. Result lands on `connected_accounts.kyc_status`.
- Creator certifies tax profile. W-9 style certification stored in `shared_tax_profiles`. Required for live payouts.
- Creator adds a bank account. Bank instrument linked to `default_bank_account_id` on the connected account.
- Request the payout. Single SDK call. Soledgic gates, posts the ledger entry, fires the ACH, and emits webhooks.
Code
Request a payout
await soledgic.payouts.request({
participantId: 'creator_maya',
amount: 4750, // $47.50 in cents
referenceId: 'payout_2026_05_01', // idempotency key
})Handle the lifecycle webhook
// app/api/webhooks/soledgic/route.ts
const event = soledgic.webhooks.parseEvent(rawBody)
if (event.type === 'payout.executed') {
await notifyCreator(event.data.participant_id, event.data.amount)
}When it fits
- You're paying creators in USD to US bank accounts via ACH.
- You need KYC + tax + bank gates enforced consistently across API and database layers.
- You want lifecycle webhooks for request, approval, processing, completion, and failure states.
FAQ
What happens if a payout rail times out mid-transfer?
Soledgic leaves the request as `processing` with `requires_reconciliation: true`. The processor-inbox worker resolves it to `completed` or `failed` when the payout rail confirms.
Can I enforce a manual review step?
Yes. Set `capabilities.requires_payout_review = true` at the org level. Direct payout calls are rejected; only payouts that came through the admin-reviewed `payout_request` flow proceed.
Try it in sandbox
Sandbox keys are issued instantly. The full flow runs end-to-end against simulated rails — no real money required.