Intégration Stripe (paiements & caution)
Statut : non implémenté. Cette page documente comment l'intégration
Stripe sera câblée (acompte 30% + caution pré-autorisée, cf.
docs/plateforme-conciergerie-deployment-plan.md). Aucun code Stripe n'existe encore dans
ce dépôt — c'est une référence pour le futur développement, pas un mode d'emploi d'une fonctionnalité
déjà en ligne.
1. Obtenir les clés API Stripe
Dans le Dashboard Stripe, aller dans Developers > API keys. Stripe fournit deux jeux de clés :
- Mode test (clés préfixées
sk_test_.../pk_test_...) : aucun mouvement d'argent réel, à utiliser pour tout le développement et les tests de recette. - Mode live (clés préfixées
sk_live_.../pk_live_...) : mouvements réels, à activer seulement une fois l'intégration validée en test.
La clé secrète (sk_...) ne doit jamais être exposée côté client ni
committée dans le dépôt ; seule la clé publique (pk_...) est destinée au
navigateur/formulaire de paiement.
2. Variables d'environnement prévues
Une fois l'intégration codée, l'app lirait ces variables (même schéma que
BEDS24_API_TOKEN aujourd'hui — via le service app de
docker-compose.yml, jamais en clair dans le dépôt) :
STRIPE_SECRET_KEY— clé secrète utilisée côté serveur pour créer les PaymentIntents et interroger l'API Stripe.STRIPE_PUBLISHABLE_KEY— clé publique injectée dans la page de paiement (formulaire Stripe Elements/Payment Element) côté navigateur.STRIPE_WEBHOOK_SECRET— secret de signature utilisé pour vérifier l'authenticité des événements webhook reçus (voir section 5).
3. Flux de l'acompte (30%) — capture automatique
Selon le plan de déploiement, à la réservation directe le client verse un
acompte de 30% du montant du séjour. Ce flux correspond à un
PaymentIntent Stripe standard, en capture automatique (capture_method:
automatic, la valeur par défaut) : le montant est débité immédiatement à la confirmation
du paiement. Une fois implémenté, chaque paiement d'acompte réussi serait enregistré comme une
ligne dans payments avec kind = 'deposit' et
stripe_payment_intent renseigné avec l'identifiant du PaymentIntent Stripe
correspondant.
4. Flux de la caution (dépôt de garantie) — capture manuelle
La caution fonctionne différemment : c'est une autorisation, pas un débit.
Le mécanisme Stripe adapté est un PaymentIntent en capture manuelle
(capture_method: manual) :
- À l'arrivée (ou à la réservation, selon la politique retenue), on crée un PaymentIntent en capture manuelle : la carte du client est autorisée (les fonds sont bloqués) mais pas débitée.
- Si un dégât est constaté au départ, on capture tout ou partie du montant
autorisé (
PaymentIntent.capture) — c'est à ce moment que l'argent est effectivement prélevé. - Si tout est en ordre, on annule l'autorisation
(
PaymentIntent.cancel) après le départ et un délai de grâce (le temps de l'inspection du logement) — les fonds sont alors libérés sans qu'aucun débit n'ait lieu.
Différence clé avec l'acompte : l'acompte débite tout de suite (capture automatique), la caution ne fait qu'autoriser puis capture ou annule plus tard (capture manuelle). Une autorisation Stripe non capturée expire au bout de 7 jours (cartes) — le délai de grâce doit rester dans cette fenêtre, ou prévoir une nouvelle autorisation.
Une fois implémenté, ces paiements seraient enregistrés dans payments avec
kind = 'security_hold' (cf. contrainte CHECK (kind IN ('deposit',
'security_hold', 'balance')) du schéma), et stripe_payment_intent pointant
vers le PaymentIntent d'autorisation.
5. Webhooks
Stripe notifie l'application de manière asynchrone via des webhooks signés. Les événements pertinents pour ce flux seraient :
payment_intent.succeeded— l'acompte (capture auto) a été débité avec succès, ou une caution a été capturée suite à un dégât.payment_intent.canceled— l'autorisation de caution a été annulée (libération des fonds sans débit).charge.dispute.created— un client conteste un prélèvement (utile en particulier pour un débit de caution suite à dégât, pour suivre les litiges).
STRIPE_WEBHOOK_SECRET sert à vérifier la signature de chaque requête webhook
reçue (en-tête Stripe-Signature) afin de s'assurer qu'elle provient bien de Stripe
et n'a pas été forgée.
6. Étapes pour passer en production
- Développer et tester intégralement en mode test, avec les cartes de test Stripe (succès, refus, 3-D Secure, etc.) pour valider les deux flux (acompte capture auto, caution capture manuelle + annulation).
- Tester le webhook en local avec le CLI Stripe (
stripe listen --forward-to) puis en environnement de recette avec une URL publique. - Une fois la recette validée, basculer
STRIPE_SECRET_KEY,STRIPE_PUBLISHABLE_KEYetSTRIPE_WEBHOOK_SECRETvers les valeurs live dans la configuration du serviceapp.