Communitygithub.com

timerise-ai/stripe-connect-subscriptions

Compétence d'agent : construire la facturation de place de marché Stripe Connect et la gestion des abonnements de plateforme — séparation des paiements et des transferts, intégration des comptes connectés, séquestre et réserves renouvelables, webhooks idempotents, reprise et annulation de transferts, relance hors session, rapprochement comptable — dans Next.js App Router.

Qu'est-ce que stripe-connect-subscriptions ?

Cette compétence d'agent permet de développer une architecture de paiement complexe mêlant deux flux monétaires sur un même compte Stripe : une place de marché qui facture l'acheteur une fois et répartit les recettes entre plusieurs vendeurs (via Stripe Connect avec des paiements et transferts séparés), et un abonnement de plateforme qui facture ces vendeurs de manière récurrente hors session. Elle gère également l'intégration des comptes connectés, les mécanismes de séquestre et de réserves renouvelables, les webhooks idempotents, la reprise des transferts échoués, les annulations, et le rapprochement comptable. C'est une compétence purement serveur, conçue pour Next.js App Router, qui fournit des références détaillées pour chaque aspect (modèle de données, argent, transport, webhooks, règlement, réconciliation, abonnements, opérations) et un contrat d'adaptation pour l'intégrer dans votre application existante. Elle est utile aux développeurs qui souhaitent implémenter une place de marché multi-vendeurs avec des paiements Stripe avancés, sans avoir à recréer toute la logique complexe de gestion des fonds, des risques et de la comptabilité.

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

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Stripe Connect & Facturation d'Abonnements

Deux flux monétaires sur un seul compte Stripe. Une place de marché facture l'acheteur une fois et répartit le produit entre plusieurs vendeurs (Connect, paiements et transferts séparés). Un abonnement de plateforme facture ces vendeurs de façon récurrente hors session (Billing). Ils partagent un client, une paire de webhooks et un type de monnaie.

L'idée directrice qui structure tout : le paiement de l'acheteur et les reversements aux vendeurs échouent indépendamment. Au moment où le règlement s'exécute, l'argent a déjà été déplacé, donc un transfert rejeté ne doit jamais faire échouer le paiement ou le webhook, et doit pouvoir être relancé plus tard sans payer personne deux fois.

Quand l'utiliser

  • Un paiement est réparti entre plusieurs vendeurs, la plateforme prélevant une commission.
  • Les vendeurs intègrent Connect et sont payés avec un délai (séquestre, réserves, KYC).
  • La plateforme facture ses propres vendeurs de manière récurrente sur une carte enregistrée.
  • Un compte connecté semble sain mais n'a jamais reçu d'argent.

Quand NE PAS l'utiliser

Pas celaUtilisez plutôt
Paiement unique, pas de répartitionStripe Checkout / Payment Element directement
Intégration PayPal Marketplace + paiementsUne compétence PayPal ; seules les interfaces sont partagées
Interface de carte, style Payment ElementVotre système de design ; cette compétence est côté serveur

Architecture

acheteur ──paiement (compte plateforme, transfer_group = orderId)──▶ solde plateforme
                │  répartition règlement (webhook OU lecture synchrone avec revendication louée)
   ┌────────────┴──┬────────────────────────┬────────────────┐
   ▼               ▼                        ▼                ▼
transfert:commerçant transfert:partenaire  séquestre     réserve renouvelable
(source_transaction = le paiement)      (release_at)    (% retenu)
   │                                        │  cron de libération du séquestre
   ▼                                        ▼
solde connecté ◀── reprise des transferts  solde payable ──▶ paiement (KYC/risque)
                      (jambes non financées)

plateforme ──PaymentIntent off_session (client + PM enregistré)──▶ facture d'abonnement
             relance : 3 tentatives, 3 jours d'écart, puis suspension

Faits essentiels

  1. Paiements et transferts séparés, jamais de destination unique. Un paiement prend une seule destination ; un panier multi-vendeurs a besoin de N transferts sous un seul transfer_group, donc application_fee_amount est inutilisable.
  2. Un transfert sans source_transaction puise dans le solde disponible et est rejeté tant que le paiement est en cours de règlement ; sur un compte plateforme récent, c'est le cas de chaque transfert. Ce seul indicateur permet de financer une part alors que le paiement est encore en cours de règlement.
  3. Les transferts Stripe transfrontaliers ne fonctionnent qu'entre US/CA/UK/EEA/CH. Une plateforme ailleurs ne paie les comptes connectés que dans son propre pays. Stripe applique cette règle au moment du transfert, pas de l'intégration, donc les modèles appliquent la règle de région lors de l'intégration.
  4. Les événements Connect portent un secret de signature différent des événements de plateforme. Deux endpoints, deux secrets, une URL — vérifiez avec les deux.
  5. Le pays d'un compte connecté est immuable — un mauvais pays signifie une ré-intégration, pas une correction.
  6. L'argent n'est jamais un nombre à virgule flottante — chaînes numeric(19,4) bout en bout, calcul en bigint, unités mineures uniquement à la limite du SDK.

Règles strictes

Ne laissez jamais un transfert échoué faire échouer le règlement. Enregistrez la jambe comme non financée et continuez. Le paiement a déjà réussi, donc le webhook doit aussi réussir ; la cron de reprise finance la jambe plus tard.

Ne traitez jamais une insertion de webhook en double comme "déjà traitée". L'insertion est une revendication ; la reprise après un crash de livraison en cours de traitement réexécute les gestionnaires, donc chaque événement s'exécute à son terme exactement une fois.

Ne renvoyez jamais un transfert sans demander à Stripe s'il existe déjà. Une jambe enregistrée comme non financée parce que la réponse a été perdue paie deux fois une fois que la fenêtre d'idempotence de 24h de Stripe est passée.

Ne dérivez jamais l'exclusivité du règlement d'un indicateur de statut écrit à la fin. Deux appelants atteignent régulièrement le règlement ; une revendication atomique louée est ce qui rend les inventaires et les transferts uniques.

Ne reversez jamais plus que la marge restante d'un transfert. Des reversements empilés (frais de passerelle, puis un remboursement) sont rejetés au-delà du montant d'origine.

Démarrage rapide

  1. Modélisez l'argent — money.md, data-model.md, store.md.
  2. Client, secrets de webhook doubles, variables d'environnement — stripe-adapter.md.
  3. Intégrez les comptes ; vérifiez d'abord la règle de région — connect-accounts.md.
  4. Recevez les événements de manière idempotente — webhooks.md.
  5. Réglez : revendiquer, répartir, séquestre, réserve — settlement.md.
  6. Convergez : reprise des jambes, rapprochement des frais — reconciliation.md.
  7. Facturez les locataires — subscriptions.md ; exécutez-le avec operations.md.

Adaptez-le à votre application avec adaptation.md ; l'archive de l'audit se trouve dans provenance.md.

Contrat d'Adaptation

Point d'extensionLa compétence fournitL'hôte fournit
Entités métierTenant (org. vendeur), Order, VendorOrder, PartnerSon propre vocabulaire
Périmètre locataireUn tenantId dérivé du serveurorg / espace de travail / vendeur
Garde d'authentificationUne signature d'adaptateur par routeClerk, NextAuth, Supabase, personnalisé
Accès aux donnéesUn contrat PaymentsStore + SQLSon ORM ou SDK
Audit + notificationsSites d'appel, noms d'événements, formes de payloadSa table d'audit / boîte de sortie
Travail en arrière-planQuatre crons et leur cadenceSon planificateur
ValidationUne forme de schéma par corps de routezod / valibot / yup
UIRien — cette compétence est côté serveurTout

Répertoire des références

ScénarioMots-clés déclencheursRéférence
Pourquoi ce modèle monétairepaiements et transferts séparés, destination unique, application_fee_amount, transfer_group, registrearchitecture.md
Tables, colonnes, RLSschéma, migration, payment_intents, transfers, escrow_holds, webhook_eventsdata-model.md
Le contrat d'accès aux donnéesstore, repository, revendication atomique, mise à jour conditionnelle, ORMstore.md
Montants et arrondisnumeric, bigint, unités mineures, distribuer, plus grand reste, centimesmoney.md
Code client et adaptateurstripeClient, apiVersion, constructEvent, whsec_, PaymentIntent, refund, payoutstripe-adapter.md
Intégration, état du compteExpress, Accounts v2, account.updated, charges_enabled, acct_, country, regionconnect-accounts.md
Réception sécurisée des événementsidempotence, duplication, rejeu, corps brut, signature, invalid_signaturewebhooks.md
Répartition d'une commande payéerèglement, répartition, source_transaction, séquestre, réserve, single-flightsettlement.md
Correction de ce qui n'a pas aboutireprise, non financé, backoff, adopter, frais de passerelle, récupération, reversement, margereconciliation.md
Frais de plateforme récurrentsSetupIntent, off_session, carte enregistrée, relance, invoice, past_due, suspendsubscriptions.md
Configuration, environnement, crons, débogageSTRIPE_SECRET_KEY, endpoint webhook, stripe listen, cron, "le vendeur n'a jamais payé"operations.md
Adaptation à cette applicationadapter, sonde hôte, renommer, ORM, garde d'authentification, portadaptation.md
L'archive d'auditprovenance, déviation, conservé, ajouté, non vérifiéprovenance.md

Skills associés