Communitygithub.com

timerise-ai/stripe-connect-subscriptions

Agent Skill: build Stripe Connect marketplace settlement and platform subscription billing — separate charges and transfers, connected-account onboarding, escrow and rolling reserves, idempotent webhooks, transfer retry and reversals, off-session dunning, ledger reconciliation — in Next.js App Router

Was ist stripe-connect-subscriptions?

stripe-connect-subscriptions is a Claude Code agent skill that agent Skill: build Stripe Connect marketplace settlement and platform subscription billing — separate charges and transfers, connected-account onboarding, escrow and rolling reserves, idempotent webhooks, transfer retry and reversals, off-session dunning, ledger reconciliation — in Next.js App Router.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add timerise-ai/stripe-connect-subscriptions

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Stripe Connect & Subscription Billing

Two money flows on one Stripe account. A marketplace charges the buyer once and fans the proceeds out to many merchants (Connect, separate charges and transfers). A platform subscription charges those merchants a recurring fee off-session (Billing). They share a client, a webhook pair and a money type.

The insight that shapes everything: the buyer's charge and the merchants' payouts fail independently. By the time settlement runs the money has already moved, so a rejected transfer must never fail the charge or the webhook, and must stay re-drivable later without paying anyone twice.

When to use

  • One payment splits across several sellers, with the platform taking a cut.
  • Sellers onboard to Connect and are paid on a delay (escrow, reserves, KYC).
  • The platform bills its own sellers a recurring fee on a saved card.
  • A connected account looks healthy but has never received any money.

When NOT to use

Not thisUse instead
Single-seller checkout, no splitStripe Checkout / Payment Element directly
PayPal Marketplace onboarding + payoutsA PayPal skill; only the seams are shared
Card UI, Payment Element stylingYour design system; this skill is server-side

Architecture

buyer ──charge (platform account, transfer_group = orderId)──▶ platform balance
                │  settlement fan-out (webhook OR read-path sync; leased claim)
   ┌────────────┴──┬────────────────────────┬────────────────┐
   ▼               ▼                        ▼                ▼
transfer:merchant  transfer:partner    escrow hold     rolling reserve
(source_transaction = the charge)      (release_at)    (% withheld)
   │                                        │  release-escrow cron
   ▼                                        ▼
connected balance ◀── retry-transfers  payable balance ──▶ payout (KYC/risk gated)
                      (unfunded legs)

platform ──off_session PaymentIntent (customer + saved PM)──▶ subscription invoice
             dunning: 3 attempts, 3 days apart, then suspend

Critical facts

  1. Separate charges and transfers, never destination charges. A charge takes one destination; a multi-vendor cart needs N transfers under one transfer_group, so application_fee_amount is unusable.
  2. A transfer without source_transaction draws on the available balance and is rejected while the charge is still settling; on a young platform account, that is every transfer. This one flag is what lets a split fund while the charge is still settling.
  3. Stripe transfers cross-border only inside US/CA/UK/EEA/CH. A platform elsewhere pays connected accounts in its own country only. Stripe enforces this at transfer time, not onboarding time, so the templates apply the region rule at onboarding.
  4. Connect events carry a different signing secret than platform events. Two endpoints, two secrets, one URL — verify against both.
  5. A connected account's country is immutable — wrong country means re-onboarding, not a patch.
  6. Money is never a floatnumeric(19,4) strings end to end, bigint math, minor units only at the SDK edge.

Hard rules

Never let a failed transfer fail the settlement. Record the leg unfunded and continue. The charge has already succeeded, so the webhook must succeed too; the retry cron funds the leg later.

Never treat a duplicate webhook insert as "already handled". The insert is a claim; the retry after a delivery crashed mid-handling re-runs the handlers, so every event runs to completion exactly once.

Never re-send a transfer without asking Stripe whether it already exists. A leg recorded unfunded because the response was lost pays twice once Stripe's 24h idempotency window passes.

Never derive settlement exclusivity from a status flag written at the end. Two callers reach settlement routinely; an atomic leased claim is what makes inventory and transfers happen once.

Never reverse more than a transfer's remaining headroom. Stacked reversals (gateway fee, then a refund) are rejected past the original amount.

Quick start

  1. Model the money — money.md, data-model.md, store.md.
  2. Client, dual webhook secrets, env — stripe-adapter.md.
  3. Onboard accounts; check the region rule firstconnect-accounts.md.
  4. Receive events idempotently — webhooks.md.
  5. Settle: claim, fan out, escrow, reserve — settlement.md.
  6. Converge: retry legs, reconcile fees — reconciliation.md.
  7. Bill tenants — subscriptions.md; run it with operations.md.

Fit it to your app with adaptation.md; the record of the audit is in provenance.md.

Adaptation Contract

SeamThe skill shipsThe host supplies
Domain entitiesTenant (seller org), Order, VendorOrder, PartnerIts own vocabulary
Tenant scopeOne server-derived tenantIdorg / workspace / seller
Auth guardAn adapter signature per routeClerk, NextAuth, Supabase, custom
Data accessA PaymentsStore contract + SQLIts ORM or SDK
Audit + notificationsCall sites, event names, payload shapesIts audit table / outbox
Background workFour crons and their cadenceIts scheduler
ValidationA schema shape per route bodyzod / valibot / yup
UINothing — this skill is server-sideAll of it

Reference directory

ScenarioTrigger keywordsReference
Why this money modelseparate charges and transfers, destination charge, application_fee_amount, transfer_group, ledgerarchitecture.md
Tables, columns, RLSschema, migration, payment_intents, transfers, escrow_holds, webhook_eventsdata-model.md
The data-access contractstore, repository, atomic claim, conditional update, ORMstore.md
Amounts and roundingnumeric, bigint, minor units, distribute, largest remainder, centsmoney.md
Client and adapter codestripeClient, apiVersion, constructEvent, whsec_, PaymentIntent, refund, payoutstripe-adapter.md
Onboarding, account stateExpress, Accounts v2, account.updated, charges_enabled, acct_, country, regionconnect-accounts.md
Receiving events safelyidempotency, duplicate, replay, raw body, signature, invalid_signaturewebhooks.md
Splitting a paid ordersettlement, fan-out, source_transaction, escrow, reserve, single-flightsettlement.md
Fixing what didn't landretry, unfunded, backoff, adopt, gateway fee, clawback, reversal, headroomreconciliation.md
Recurring platform feesSetupIntent, off_session, saved card, dunning, invoice, past_due, suspendsubscriptions.md
Setup, env, crons, debuggingSTRIPE_SECRET_KEY, webhook endpoint, stripe listen, cron, "merchant never paid"operations.md
Fitting it to this appadapt, host probe, rename, ORM, auth guard, portadaptation.md
The audit recordprovenance, deviation, kept, added, unverifiedprovenance.md

Verwandte Skills