Aller au contenu

Paiements

Chaque échéance a sa ligne de paiement, créée quand le client ouvre le paiement, puis à l’arrivée des factures. Le client paie par carte ou SEPA (Single Euro Payments Area, prélèvement européen) sur une page de paiement Stripe (mode abonnement). Stripe encaisse lui-même les paiements récurrents via ses abonnements (mensuel, trimestriel, annuel) : aucune tâche planifiée d’Inqase ne débite le client. Les notifications automatiques de Stripe sont la seule source de vérité : le clic sur « payer » met la demande en attente de paiement, jamais en acceptée.

Le déroulé complet, avec les emails envoyés à chaque étape, est dans le flux Du clic au paiement. Les avertissements de prélèvement et de mandat SEPA sont dans Échecs de paiement et relances.

Notification de Stripe Effet
Le client a validé la page de paiement Abonnement : le paiement passe en cours. Changement de carte : applique la nouvelle carte et relance la facture. Toute notification traitée est marquée comme telle, y compris celles qui sont ignorées, donc un rejeu ne s’exécute pas deux fois.
L’abonnement est créé Lie l’abonnement et la facture au paiement, ouvre l’accès au portail.
La facture est payée Le paiement passe à payé, la demande à paiement confirmé, puis la création de la police démarre. Une facture inconnue crée un paiement de renouvellement.
Prochain prélèvement annoncé, mandat SEPA modifié Email de préavis (lien de connexion de 14 jours). Mandat invalide : alerte Slack et email pour signer à nouveau. L’identifiant d’abonnement est lu de façon à fonctionner avec l’ancien et le nouveau format de message de Stripe (la production reçoit la version la plus récente).
  • Offre acceptée seulement au paiement. Quand Stripe signale la facture payée, la demande passe à paiement confirmé ; l’offre est alors acceptée et les autres offres du produit sont rejetées. Avant le paiement, la demande désigne l’offre à payer. Pourquoi : accepter au clic laissait des demandes impayées avec une commission.
  • Un même message n’a d’effet qu’une fois. Chaque notification de Stripe est enregistrée une seule fois : une notification traitée est ignorée, une notification inachevée est reprise. Le traitement verrouille la ligne de paiement pendant qu’il agit. La création de l’abonnement et le remboursement depuis Stripe n’ont pas cet enregistrement : leurs propres contrôles les rendent sans effet au rejeu.
  • Tolérance au désordre. Stripe peut annoncer la facture payée avant la création de l’abonnement. Le paiement est alors retrouvé par la facture, puis par l’abonnement, puis (premières échéances seulement) par l’abonnement mémorisé à l’ouverture du paiement. Une validation de page de paiement tardive ne fait jamais reculer un paiement déjà réglé (payé, remboursé, partiellement remboursé, annulé, contesté) ; un échec tardif ne touche jamais un paiement payé. Si une information manque, le traitement échoue, la notification reste non traitée et Stripe réessaie. Voir Webhooks Stripe tolérants à l’ordre.
  • Après l’enregistrement. L’annonce « paiement réussi » part après l’enregistrement en base, donc les traitements en file d’attente ne tournent jamais avant que la ligne de paiement existe. Un premier paiement lance la création de la police et un rapport d’analyse (GA4). Un paiement de renouvellement envoie l’email « paiement reçu » aux contacts de la police.
  • Signature. La réception des notifications de Stripe n’est pas soumise au jeton de formulaire. En production, si le secret de signature manque, elle répond par une erreur 500 au lieu d’accepter des notifications non signées.
  • Un seul paiement ouvert par demande. Ouvrir un paiement annule les paiements en attente des autres offres et fait expirer leur page Stripe ; si une page ne peut pas expirer, l’opération est abandonnée. Un paiement en cours n’est jamais touché. La page de paiement est réutilisée tant qu’elle vit et que méthode, fréquence et langue n’ont pas changé (la demande est verrouillée pendant l’opération) : deux clics ne créent jamais deux abonnements.
  • Un paiement Stripe n’est jamais modifié, supprimé ni marqué payé à la main ; seuls les paiements manuels (virement) le sont.
  • Un paiement sur une offre déjà rejetée ne crée aucune police : alerte critique dans les logs, remboursement manuel. Une facture payée sur une police annulée ou expirée n’est pas rattachée : alerte Slack, le remboursement est une décision humaine.
  • Le montant initial du paiement est la prime annuelle, remplacée par le montant réellement payé à l’encaissement.
  • app/Http/Controllers/StripeWebhookController.php, app/Models/StripeWebhookEvent.php
  • app/Services/PaymentService.php
  • app/Observers/QuoteRequestOfferAcceptanceObserver.php, routes/console.php (relances)
Terme de la page Identifiant technique
Validation de la page de paiement checkout.session.completed
Abonnement créé customer.subscription.created
Facture payée invoice.paid
Prochain prélèvement annoncé invoice.upcoming
Mandat SEPA modifié mandate.updated
Remboursement depuis Stripe charge.refunded
Paiement en attente, en cours, payé pending, processing, paid
Paiement remboursé, partiellement remboursé, annulé, contesté refunded, partially_refunded, cancelled, disputed
Demande : paiement en attente, paiement confirmé payment_pending, payment_confirmed
Annonce « paiement réussi » PaymentSucceeded
Désigner l’offre à payer QuoteRequest::payableQuote()
Enregistrement unique d’une notification StripeWebhookEvent::claim
Notification traitée processed_at
Lecture de l’abonnement, formats ancien et récent InvoicePayload::subscriptionId
  • Les notifications activées côté Stripe se règlent dans le Dashboard Stripe, pas dans le dépôt.
  • Le comportement réel du SEPA en production (délais, rejets) n’est pas dans le code, qui suit seulement les notifications de Stripe.
  • La prime recalculée d’un renouvellement n’est pas poussée vers Stripe : l’abonnement continue de facturer l’ancien montant, voir Polices et renouvellements.