Payouts
How money reaches each account, on Stripe Connect. Your share of each charge transfers to your connected account and pays out to your bank; members' pay transfers on the Pool's schedule and each account pays out daily; every deposit reconciles back to its jobs, and an account that can't be paid keeps its pay.
Payouts answer where the money goes once a charge releases. Every account is a Stripe Connect account: yours, which receives what your brand sells, and each member's, which receives their pay. services.dev holds only held dollars waiting for their fact, each tagged to its job (flow of funds).
You connect one account per brand, once, before the first live order:
npx services.dev payoutsapi.forsale · payouts · Stripe Connect
account acct_…F0r5 · api.forsale · verified · bank …6789
receives your share of each charge, one transfer when it releases · services.dev's take stays on its account, its own entry
held outcome money waits under its own job, outside your balance, until its window closes
pays you to your bank daily, two days after a charge collects
members pay transfers on the Pool's schedule, from each job's charge, or by a debit from your balance before any charge · each account pays out daily
closers weekly, on Fridays · a new closer's first 5 gigs wait 7 days (hold_first)
health median 2.4 days from act to bank · p90 4.1 days · 0 failed this month| What lands there | When |
|---|---|
| Your share of each charge your brand sells | one transfer when the charge releases |
| Held outcome money | when its window closes; until then it waits under its job, outside your balance |
| Refunds and chargebacks | debited from it: refunds and disputes |
| services.dev's take | stays on services.dev's account when your share transfers, as its own entry, and returns pro rata with a refund |
A fee sold on a member's own rail lands on the member's account, never on yours. Until your account is connected, a live order answers BLOCKED with the cure, and test mode pays out on the simulated rail:
→ POST /deals {"account":{"name":"Northwind Freight"},"value":80000,"offer":"https://seller.example/offer","max_usd":12000,"key":"northwind"} # live, before the account is connected
{
"type": "BLOCKED",
"category": "unavailable",
"code": "payouts_unconfigured",
"reason": "Live orders need api.forsale's payout account: its charges land there, and its members are paid from it.",
A member connects one payout account at the last step of /join, and the same account serves every Pool and brand they work for. The Pool's schedule sets when pay transfers to it: from the job's charge, or, for pay that comes before any charge, such as a setter's, by a debit from your balance (money outside a charge). The account pays out to the member's bank daily, on Stripe's timing:
grep -n "payouts" pools/closers.ts22: payouts: { schedule: 'weekly', hold_first: { tasks: 5, for: '7d' } },payouts | Paid |
|---|---|
| left out | transferred every Friday, pay payable two days after the act |
'same-day' | each evening, once payable |
'weekly' | every Friday |
{ schedule, hold_first: { tasks: 5, for: '7d' } } | a new member's first five Tasks wait seven days, then the schedule |
{ schedule, instant_fee: 'brand' | 'member' } | at once when the member asks; you pay the fee unless it's 'member', and then it is Stripe's cost, shown before they choose |
Pay in the Pool has each schedule's dates and the member's view of every act.
Each run carries a line per brand, so a member who works for three brands gets one deposit. Held share pay stays out of it until its window closes:
→ GET /owner/pools/closers/payouts?week=2026-W47 # the owner: one week's run, Fri 20 Nov pyo_7Hq4 mbr_7Hq4 $900.00 4 gigs setter $750.00 · nurturer $150.00
pyo_7Hq9 mbr_7Hs1 $250.00 1 gig setter, tsk_7Hs5, held 7 days: gig 2 of the first 5
held $7,400.00 · tsk_7Hw6 · the closer's share, to 12 Jan 2027 (outcome.window)Every payout reconciles to the entries it paid, each to its job and its Stripe transfer, ending on the bank deposit:
npx services.dev payouts reconcile pyo_7Hq4 # as mbr_7Hq4: from the bank deposit back to each jobpyo_7Hq4 · $900.00 to bank …1182 · arrived Fri 20 Nov 2026 16:41 · Stripe po_…7Hq4
le_7Hr9p +$250.00 setter · tsk_7Hr9 · tr_…Hr9, after py_…Hr9 debited api.forsale: a held meeting comes before any charge
le_7Hr1p +$250.00 setter · tsk_7Hr1 · tr_…Hr1, after py_…Hr1
le_7Hr3p +$250.00 setter · tsk_7Hr3 · tr_…Hr3, after py_…Hr3
le_7Hr6p +$150.00 nurturer · tsk_7Hr6 · tr_…Hr6, after py_…Hr6
fees $0.00 weekly schedule, no instant payout
deposit $900.00 bank …1182, 20 Nov · difference $0.00Your own payouts reconcile the same way, with each transfer, the take and each debit as its own entry. GET /owner/payouts/:id/entries returns them, and npx services.dev jobs ledger --month 2026-11 --csv exports the month for your books.
A payout the bank returns comes back to the member's own balance, tells them with the cure, and goes out with the next payout; nothing is lost, and nothing is charged for the failure. An account Stripe restricts, waiting on a document or a tax ID, keeps accruing pay, shows pay.waiting with the cure in the delivery portal, and is paid once the account clears:
→ GET /me/payouts # as mbr_7Hs1, whose bank returned the payout pay back in your balance · nothing is lost, and nothing is charged for the failure
cure add a bank account in the delivery portal · it goes out with the next payoutEach member gives a tax ID at onboarding. Pay on your rail is reported under your brand, as its payments to the member, and a fee sold on the member's own rail is reported as the member's own sales. Each year's forms are in the delivery portal.
The time from an accepted act to the member's bank is measured, never claimed: the median and p90 per Pool, in Pool health and on the door's demand board, where members choose where to work.
→ GET /payouts/pyo_7Hq4 # as mbr_7Hq4
{
"id": "pyo_7Hq4",
"object": "payout",
"member": "mbr_7Hq4",
"amount": 90000,
"currency": "usd",
| Event | Audience | Says |
|---|---|---|
pay.accrued | member, owner | pay for an accepted act |
pay.payable | member, owner | the pay is due on the next payout |
pay.waiting | member, owner | the account can't be paid yet; the pay waits, with the cure |
pay.paid | member, owner | the pay transferred to the member's account, on the Pool's run, a line per brand |
payout.paid | member, owner | the account paid out to the bank |
payout.failed | member, owner | the bank returned the payout; it is back in the member's balance and goes out with the next one |
Worked in: closing on closers.deals, one share from won to Friday's payout.
| App | What it shows |
|---|---|
| Customer portal | Nothing: a buyer never sees how a member is paid |
| Delivery portal | Accrued, held, payable and paid, the next payout's date, the account it lands in, each payout's entries and the year's tax forms |
| Owner console | Your account's balance and payouts, each payout's entries, each Pool's next run, and its act-to-bank median |
| Key | Written | Left out | Does |
|---|---|---|---|
Brand.payouts | { rail: 'stripe'; schedule?: 'same-day' | 'weekly' } | rail: 'stripe', daily | Your account's rail, and how often it pays you |
Pool.payouts | { at: 'act'; after?: Within } | 'same-day' | 'weekly' | { schedule; hold_first?; instant_fee? } | Fridays, two days after the act | When members' pay is payable and transferred |
Paying yourself runs on every plan; a Pool's schedule and hold_first run live on Launch.