Payouts
Overview
Payouts are batch payments to partners that cover one or more approved commissions. The provider controls when payouts are generated and how partners are paid.
Payout lifecycle
Commissions approved
│
▼
Generate payouts (by date range)
│
▼
Payout created (status: pending)
│
├── Pay via Stripe Connect → status: paid
├── Mark as paid manually → status: paid
└── Cancel → status: cancelledStatus values
| Status | Description |
|---|---|
pending |
Payout created, not yet paid |
requested |
Partner requested a payout (self-service) |
paid |
Payment completed |
cancelled |
Payout cancelled by provider |
Generating payouts
Providers generate payouts by specifying a date range. Affihub sums all approved commissions for each partner within that period:
curl -X POST "https://api.affihub.com/api/v1/payouts/generate" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"period_start": "2026-03-01",
"period_end": "2026-03-31"
}'This will:
- Query all approved commissions in the date range, grouped by partner
- Skip partners whose total is below the program's
min_payout_centsthreshold - Create a payout record for each qualifying partner
- Update the related commissions to
processingstatus
Dry run
Preview what payouts would be generated without creating them:
curl -X POST "https://api.affihub.com/api/v1/payouts/generate" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"period_start": "2026-03-01",
"period_end": "2026-03-31",
"dry_run": true
}'Minimum payout threshold
Programs can set a minimum payout amount (min_payout_cents). Partners whose approved commissions total less than this amount will not receive a payout in that period — their commissions roll over to the next cycle.
Set via the API:
curl -X PATCH "https://api.affihub.com/api/v1/programs/me" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"min_payout_cents": 5000}'This sets a $50.00 minimum.
Payout methods
Partners configure their preferred payout method in their portal settings:
| Method | Description |
|---|---|
stripe |
Direct bank transfer via Stripe Connect |
paypal |
PayPal transfer (manual) |
bank_transfer |
Wire transfer (manual) |
crypto |
Crypto payment (manual) |
Stripe Connect payouts
For Stripe Connect, Affihub can execute the transfer automatically:
curl -X POST "https://api.affihub.com/api/v1/payouts/pay_abc123/pay" \
-H "Authorization: Bearer YOUR_API_KEY"This creates a Stripe Transfer to the partner's connected account. The partner must have completed Stripe Connect onboarding (see below).
Manual payouts
For PayPal, bank transfer, or crypto, you pay the partner outside of Affihub and then mark the payout as paid:
curl -X PATCH "https://api.affihub.com/api/v1/payouts/pay_abc123" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"status": "paid", "payout_ref": "paypal-txn-123"}'Stripe Connect onboarding
Partners who want direct bank payouts can onboard via Stripe Connect:
- Partner clicks "Connect Stripe" in their portal
- Affihub creates a Stripe Express account and generates an onboarding link
- Partner completes Stripe's identity verification and bank account setup
- Once verified, their
stripe_account_idis stored and payouts can be executed automatically
Partners can check their Stripe Connect status in their portal under Settings.
Partner-requested payouts
Partners can request payouts from their portal if their approved commission balance meets the minimum threshold:
- Partner goes to Payouts in their portal
- Clicks Request Payout
- A payout with status
requestedis created - The provider reviews and either approves (pays) or cancels it
Payout term
Programs can configure a payout_term (e.g., NET-15, NET-30) that defines the payment schedule. This is informational — it sets expectations but doesn't automatically trigger payouts.
When commissions become "paid"
When a payout status changes to paid:
- All commissions included in that payout are updated to
paidstatus - The
paid_attimestamp is set on the payout - A
payout.paidwebhook event is fired