Proposal: Payout Automation — award → paid → receipt
Owner: Guido · drafted with Fable. Depends on the shipped beneficiary-address collection in the contributor portal (2026-07-02: address capture, backfill banner, audited ops export — see Data Model). The award trigger is designed to be fed by the Reward Economy quests-pay-cash model once that ships; until then awards are entered by ops.
Problem
Paying a contributor is manual end to end. Who-is-owed-what lives outside any system; ops keys each recipient into Altitude by hand; nothing records that a payment was submitted, succeeded, or failed; no receipts are issued; and the €4,000/12-month operating cap plus the contributor's €5,000 prestazione-occasionale ceiling are enforced by memory, not by code.
Detail collection is already solved: the portal collects beneficiary name split
- full address with the IBAN, and
npm run ops:export-recipientsproduces an Altitude-ready list with full IBANs, missing-data flags, and per-call audit logging.
Verified current state (2026-07-04)
- 19 unique confirmed IBANs; address backfill in progress.
- The April 2026 schema already models the whole pipeline —
payout_requests,payment_batches,payments,receipts,cap_snapshots,exceptions— and every one of those tables is empty. The earn→milestone machinery (reward_milestones,playroll_time_ledger,contributor_milestone_unlocks) has never been written to; the Reward Economy proposal replaced the hours→cash ladder with quests-pay-cash, which is the future source of awards. - Rail: Altitude (Squads business banking). No public API. Team approval thresholds exist in-app.
- Wise Business API (verified against Wise docs, 2026-06 revision):
create recipients, create single/batch transfers, fund via API from a US
business account,
transfers#state-changewebhooks, sandbox. Their no-code batch tool takes a CSV of up to 1,000 payouts. This is the recommended Phase 2 executor;payment_batches.provideralready includes'wise'. - Grid (Squads developer platform): stablecoin accounts with fiat on-ramp. Third-party EUR SEPA payouts are unconfirmed — open question with Squads. Not on the critical path.
Design
One state machine over the existing tables. All transitions are service-role-only SECURITY DEFINER RPCs, each writing an audit row. Contributors gain no new write surface.
award (ops cmd; later: quest completion)
└─ compensation_items('available') + payout_requests('requested')
└─ no confirmed+complete payout method → 'needs_payout_method' + nudge
└─ contributor completes portal form → auto-heals to 'requested'
approve (ops cmd; €4k rolling-cap check; batch ceiling)
└─ payment_batches('approved') + payments('approved')
execute
├─ Phase 1: per-batch export in Altitude field order → ops keys in → mark-paid (requires bank reference)
└─ Phase 2: Wise API — recipient create → transfer create → fund → webhook flips paid
mark-paid / mark-failed
└─ cascades: compensation item, request, batch, receipt(draft), cap snapshot; failures → exceptions
Key properties: idempotent awards (unique key), one open request per
contributor, mark-paid always traces to a bank-side reference, receipts
generated per payment (held in draft until the ricevuta template is
approved), immutable audit log, "IBAN changed since last payment" flag in the
approval queue.
Phasing
- Phase 1 — no APIs, ~1–2 days: migration (RPCs + audit table +
'altitude'in the provider check) +payoutCLI (award/approve/export/mark-paid/mark-failed/status). Carries ~€100k of volume safely because Altitude remains the vault: the automation is bookkeeping and assist; money authority never leaves the bank UI. - Phase 1.5 — zero code: Wise Business account +
--wiseflag on the export emitting Wise's batch-CSV template. Upload, fund once, done. - Phase 2 — Wise API: executor + webhook reconciliation replace the paste step. Swappable for Grid later if Squads confirms third-party EUR SEPA payouts.
Open questions
- Source of truth for the current Pioneer amounts owed (seeds the first
award --csv). - Nudge/receipt email channel: manual DM now; SMTP-via-edge-function as the built path.
- Ricevuta template sign-off (Ryon) before receipts auto-send.
- Squads/Grid: third-party EUR SEPA payouts available? (Phase 2 alternative only.)