Paiements
Comment le paiement encaisse, comment connecter Stripe ou PayPal, et ce qui arrive à une commande à chaque étape.
Pour le pack Full Stack
Comment le paiement est encaissé
Le client paie sur la page du prestataire, Stripe Checkout ou PayPal, donc le site et l'API ne voient jamais de numéro de carte. L'API calcule elle-même le prix de la commande, à partir de son propre menu, de ses frais et de ses remises, jamais à partir des prix envoyés par le navigateur.
| Méthode | Proposé quand | Ce qui se passe |
|---|---|---|
| Paiement par carte (Stripe) | STRIPE_SECRET_KEY est défini | La commande est enregistrée comme impayée et le navigateur va sur la page de Stripe. La commande devient payée une fois que l'API a demandé à Stripe ce qui s'est passé et que le montant correspond. |
| PayPal | PAYPAL_CLIENT_ID et PAYPAL_CLIENT_SECRET sont définis | La même chose, sur la page de PayPal : l'API capture le paiement approuvé avant que la commande compte comme payée. |
| Paiement de démonstration | Aucun prestataire n'est configuré | Marque la commande comme payée sans déplacer d'argent, pour pouvoir essayer tout le parcours en local. Il n'est jamais proposé à côté d'un prestataire configuré. |
Les invités peuvent passer commande avec leur nom et leur e-mail ; les clients connectés voient la commande dans leur compte. Une commande payée passe dans la file d'attente de la cuisine ; une commande impayée ne peut pas être confirmée par le personnel.
Les prix sont en dollars américains. Dans les paramètres de démonstration, la livraison coûte $2.99 et le retrait sur place est gratuit, avec un minimum de livraison de $10.00. Il n'y a pas de ligne de taxe séparée : le client paie les prix du menu plus les frais, moins une éventuelle remise. Le personnel modifie les frais dans le tableau de bord, sous Settings, Restaurant, qui liste aussi les moyens de paiement proposés par ce build et indique si chacun fonctionne en mode test ou en production.
Connecter Stripe
Ajoutez votre clé secrète
Depuis la page des clés API du tableau de bord Stripe, placez la clé secrète dans le
.envde l'API. Utilisez une clé de test (sk_test_…) jusqu'à ce que vous soyez prêt à encaisser de l'argent réel : elle n'en déplace aucun.Le .env de l'APISTRIPE_SECRET_KEY=sk_test_…Abonnez le webhook
Dans Stripe, ajoutez un endpoint de webhook à l'adresse de votre API suivie de
/api/payments/webhooks/stripe, abonné àcheckout.session.completed,checkout.session.expired,charge.refundedetcharge.dispute.created. Copiez son secret de signature dans le.envde l'API.Le .env de l'APISTRIPE_WEBHOOK_SECRET=whsec_…Vérifiez les adresses de retour
Stripe renvoie le navigateur vers
API_PUBLIC_URL, et l'API le renvoie ensuite vers le site surSTOREFRONT_URL. En local, les deux valeurs par défaut fonctionnent. Sur vos propres domaines, définissez les deux avec les vraies adresses.Redémarrez l'API
Résultat attendu: Le paiement propose « Pay by card », et Settings, Restaurant, Payments l'indique comme proposé, en mode test.
La clé publiable n'est pas nécessaire : le paiement a lieu sur la page de Stripe. Pour tester le webhook sur votre propre machine, la CLI Stripe peut transférer les événements vers http://localhost:8000/api/payments/webhooks/stripe et affiche le secret de signature à utiliser pendant qu'elle tourne.
Connecter PayPal
Ajoutez les identifiants de votre application
Depuis le tableau de bord développeur de PayPal, copiez le client id et le secret de votre application dans le
.envde l'API.PAYPAL_ENVvautsandboxpar défaut, ce qui ne déplace aucun argent ;liveencaisse de vrais paiements.Le .env de l'APIPAYPAL_CLIENT_ID=your-paypal-sandbox-client-id PAYPAL_CLIENT_SECRET=your-paypal-sandbox-client-secret PAYPAL_ENV=sandboxAbonnez le webhook
Ajoutez un webhook à l'adresse de votre API suivie de
/api/payments/webhooks/paypal, avec les événements de capture de paiement : terminé, refusé, remboursé et annulé. Copiez l'id du webhook dans le.envde l'API : l'API vérifie chaque appel par rapport à lui.Le .env de l'APIPAYPAL_WEBHOOK_ID=your-paypal-webhook-idRedémarrez l'API
Résultat attendu: Le paiement propose PayPal.
Ce qui arrive à une commande
| Événement | La commande |
|---|---|
| Le client la passe | Enregistrée comme en attente et impayée. Elle réserve son stock et les points de fidélité que le client a utilisés. |
| Le prestataire confirme le paiement | Payée, au retour du client ou par le webhook, selon ce qui arrive en premier. Le retour du navigateur seul ne marque jamais une commande comme payée : l'API interroge d'abord le prestataire. |
| Le client quitte la page de paiement | Vérifiée auprès du prestataire au bout de 35 minutes pour Stripe et de 3 heures pour PayPal, puis annulée comme paiement échoué, avec restitution de son stock et de ses points. |
| Le prestataire signale un remboursement complet | Remboursée, et les points qu'elle avait rapportés sont retirés. Un remboursement partiel Stripe est consigné dans le journal et laisse la commande telle quelle. |
Un paiement qui arrive pour une commande déjà annulée est consigné comme devant être remboursé et ne rétablit jamais la commande. Le personnel ne peut pas passer une commande en remboursée à la main : les remboursements se font dans Stripe ou PayPal, et le webhook met à jour la commande.
Le paiement de démonstration
- Sans prestataire configuré, le paiement affiche « Demo payment » et « Place demo order ». La commande est payée immédiatement, sans déplacer d'argent, pour pouvoir essayer de bout en bout la file d'attente de la cuisine et la page de suivi.
- Dès que Stripe ou PayPal est configuré, le paiement de démonstration disparaît, et une commande qui le demande est refusée.
- Le webhook propre au paiement de démonstration,
POST /api/payments/webhooks/demo, refuse chaque appel sauf siPAYMENT_WEBHOOK_SECRETest défini et envoyé dans l'en-têtex-webhook-secret.
Encaisser de vrais paiements
- Passez aux clés de production (
sk_live_…, ou l'application de production de PayPal avecPAYPAL_ENV=live) et à un webhook créé en mode production, qui a son propre secret de signature ou son propre id. - Définissez
API_PUBLIC_URLetSTOREFRONT_URLavec vos vraies adresses, et ajoutez le site àCORS_ORIGIN: une adresse de retour en dehors de cette liste est refusée. - Settings, Restaurant, Payments affiche chaque moyen comme « Live, real money » dès qu'il fonctionne avec des identifiants de production.
- Les montants sont partout en dollars américains : l'API facture dans la
CURRENCYdeback-end/src/common/constants/ordering.constants.ts, et les deux frontends affichent les prix en dollars. Une autre devise demande une modification du code dans l'API et les frontends, avecNEXT_PUBLIC_ANALYTICS_CURRENCYdéfini en conséquence.