How to Approve Creator Payouts to Collaborators with Stripe and Multi-Slot Sign-Off
Build a Spojit workflow that runs on a schedule, tallies each collaborator's share of your Stripe revenue, pauses for the creator and a finance partner to both approve, then raises a Stripe invoice and confirms every payout in Slack.
What This Integration Does
If you split revenue with editors, co-hosts, designers, or guest contributors, doing the math by hand every pay cycle is slow and error-prone. This tutorial builds a payout-prep workflow in Spojit that pulls your recent Stripe charges, applies each collaborator's agreed percentage, and hands you a clean payout summary. Nothing moves money until two people sign off, so you keep a clear paper trail and never release a payout the creator or finance partner has not seen.
The workflow runs on a Schedule trigger (for example, the first business day of each month). On each run it calls list-charges to gather paid charges, a Transform node computes the per-collaborator splits, and a Human node with two approval slots blocks the workflow until both the creator and a finance partner approve. Once both slots are satisfied, the workflow calls create-invoice for each collaborator and posts a confirmation to Slack with send-message. If either approver rejects or the request times out, the workflow halts before any invoice is raised, so re-runs always start from a fresh tally rather than acting on stale numbers.
Prerequisites
- A Stripe connection added in Spojit (Connections → Add connection → Stripe) with permission to read charges and create invoices.
- A Slack connection with permission to post messages to the channel where you confirm payouts.
- A Stripe
customerID for each collaborator you intend to invoice (collaborators must already exist as customers in your Stripe account, or be created withcreate-customerbeforehand). - A simple split table you can paste into the workflow: each collaborator's name, Stripe
customerID, and percentage share (the shares should total 100, or less if you keep a house cut). - The Spojit users (or a Role/Team) you want as approvers: the creator and a finance partner.
Step 1: Start the workflow on a Schedule trigger
On a new workflow canvas, add a Trigger node and set its type to Schedule. Enter a 5-field cron expression and an IANA timezone. To run at 9am on the first day of every month, use:
0 9 1 * *
Australia/Sydney
The Schedule trigger outputs { scheduledAt }, which you can reference downstream as {{ trigger.scheduledAt }} to stamp the payout period. A single trigger can hold multiple schedules if you want, for example, both a monthly run and an on-demand cron you toggle during testing.
Step 2: Pull recent Stripe charges
Add a Connector node in Direct mode, choose the Stripe connector, and select the list-charges tool. Direct mode is the right choice here because this is a single, predictable call with no AI cost. Set limit to the maximum of 100 to capture as many charges as possible in one page:
{
"limit": 100
}
The tool returns a list of charges. If your charge volume exceeds 100 per period, use the returned cursor with starting_after inside a Loop node (While mode) to page through the rest, collecting each page before you tally. Bind the node's output to a variable such as charges so later steps can read {{ charges }}.
Step 3: Tally collaborator splits in a Transform node
Add a Transform node to reshape the raw charges into a per-collaborator payout list. Sum the amounts of the paid charges (Stripe amounts are in the smallest currency unit, for example cents), then apply each collaborator's percentage. Your split table lives here as a small constant. The Transform node should produce an array your invoice loop can iterate, for example:
{
"period": "{{ trigger.scheduledAt }}",
"grossCents": 482350,
"payouts": [
{ "name": "Editor", "customer": "cus_AbC123", "pct": 30, "amountCents": 144705 },
{ "name": "Co-host", "customer": "cus_XyZ789", "pct": 20, "amountCents": 96470 }
]
}
Bind the output to a variable such as tally. Keep amounts in the smallest currency unit so they map cleanly onto Stripe later. If you prefer to format human-readable dollar figures for the approval message, the math connector's currency tool and the json connector can help shape a display string without changing the underlying cents.
Step 4: Require sign-off in a Human node with two approval slots
Add a Human node so no money moves without explicit approval. The only required field is Approval slots: create two slots so approval completes only when both are satisfied (slots use AND semantics across the whole node). Put the creator into the first slot and the finance partner into the second. Each slot can hold a User, a Role, or a Team as an atom; any atom in a slot satisfies that slot, so you could make slot two a finance Role if more than one person can sign off there.
Fill in the supporting fields so approvers see what they are approving. Set a Message summarizing the tally, a Notification title and body (both support {{ variables }}), and an Urgency of Normal. Optionally enable Email approvers and set a Timeout (minutes) so a stalled cycle does not block forever. A useful notification body:
Payout tally for {{ tally.period }} is ready: {{ tally.payouts.length }} collaborators, gross {{ tally.grossCents }} cents. Approve to raise invoices.
Approvers act in the Approvals inbox at /approvals (also surfaced on the dashboard widget and the menu badge). On approval the node outputs { approved: true, approvalId, outcome: "APPROVED" }; bind that output to a variable such as approval so later steps can reference {{ approval.approvalId }}, and the workflow continues. A rejection or timeout halts the workflow before any invoice is created; note that "on reject do X" branching is not supported, so a halt is the safe stop.
Step 5: Raise a Stripe invoice for each collaborator
Add a Loop node in ForEach mode over {{ tally.payouts }}. Inside the loop, add a Connector node in Direct mode on the Stripe connector and select create-invoice. Map the loop item's collaborator to the required customer field and write a clear description so the invoice is self-documenting:
{
"customer": "{{ item.customer }}",
"collection_method": "send_invoice",
"description": "Collaborator payout for {{ tally.period }}: {{ item.pct }}% share ({{ item.amountCents }} cents)"
}
By default create-invoice auto-finalizes the invoice (auto_advance defaults to true). Choose the collection_method that matches how you settle: send_invoice emails the collaborator a payable invoice, while charge_automatically suits a stored payment method. Bind each result so the next step can confirm exactly what was raised.
Step 6: Confirm each payout in Slack
Still inside the loop (or in a follow-up Loop over the invoice results), add a Connector node in Direct mode on the Slack connector and select send-message. Post one confirmation line per collaborator to your payouts channel:
{
"channel": "#creator-payouts",
"text": "Payout invoice raised for {{ item.name }} ({{ item.pct }}%): {{ item.amountCents }} cents for {{ tally.period }}. Approved by {{ approval.approvalId }}."
}
Reference the channel by name or by its channel ID. If you prefer an at-a-glance summary instead of per-collaborator lines, post a single message after the loop with a rolled-up total. For a separate email receipt to the creator, add a Send Email node (which uses Spojit's built-in mail service, no connection required) with the recipient, subject, and a templated body summarizing the run; remember external recipients must be on the org allowlist under Settings → General → Email recipients.
Tips
- Keep the split table in one place. Storing the percentages and Stripe
customerIDs in the single Transform node makes rate changes a one-line edit each cycle. - Work in the smallest currency unit (cents) end to end and only format to dollars for display. This avoids rounding drift between the tally and the invoices.
- Set a sensible Timeout (minutes) on the Human node so a forgotten approval does not leave the run paused indefinitely; a timeout is treated as a reject and halts safely.
- Scaffold the canvas fast with Miraxa, the intelligent layer across your automation, then fine-tune fields in the properties panel. For example: "Add a Schedule trigger, a Stripe Connector node in Direct mode using list-charges, a Transform node, then a Human node with two approval slots."
Common Pitfalls
- Missing charges from pagination.
list-chargesreturns at most 100 per page. If a busy period exceeds that, you will undercount unless you page through withstarting_after. - Counting unpaid or refunded charges. A returned charge is not always settled revenue. Filter to genuinely captured charges in the Transform node before applying splits, or you will over-pay collaborators.
- Only one approval slot. If you put both approvers as atoms in a single slot, either one alone can approve. To require both people, use two separate slots so the AND semantics apply.
- Timezone surprises on the schedule. The cron is evaluated in the IANA timezone you set. A blank or wrong timezone can fire the payout run a day early or late around month boundaries.
Testing
Before scheduling it live, validate on a small scope. Temporarily set list-charges limit to a low number and point the send-message step at a private test channel. Add yourself to both approval slots so you can drive the Human node end to end from the Approvals inbox, approving once to confirm invoices are raised, then on a second test run rejecting to confirm the workflow halts before create-invoice. In Stripe, raise invoices against a test collaborator with collection_method set to send_invoice so nothing is auto-charged while you check the amounts. Once the tally, the two-slot sign-off, and the Slack confirmations all look right, restore the real limit, channel, and approvers, then enable the Schedule trigger.