All checks were successful
CI / secret-scan (pull_request) Successful in 17s
CI / js-tests (pull_request) Successful in 25s
CI / secret-scan (push) Successful in 9s
CI / php-lint (push) Successful in 22s
CI / static-tests (push) Successful in 50s
CI / php-lint (pull_request) Successful in 23s
CI / static-tests (pull_request) Successful in 48s
CI / js-tests (push) Successful in 27s
La borne POSTe desormais une vraie commande a l'API (avant : payment.html simulait
une redirection). Au paiement : le panier est traduit vers le contrat /api/orders,
la commande est creee puis encaissee (pay -> decrement stock RG-T20).
- checkout.js : traduction PURE panier -> contrat (produit/menu, format normal/maxi,
selections [{menu_slot_id, product_id}] reconstruites depuis la composition + les
slots re-fetches ; service_mode dine_in/takeaway ; service_tag chevalet). submitOrder
fait create puis pay. Cle d'idempotence STABLE en sessionStorage : un retry reutilise
la meme cle -> pas de commande doublon (RG-T19) ; effacee au succes.
- page-payment.js : recap + flux ; modale chevalet (sur-place, saisie du numero de
table, maquette ecran 9) avec focus-trap/ESC ; verrou anti double-clic ; messages
d'erreur. Cle d'idempotence fraiche a chaque visite paiement.
- page-confirmation.js : numero de commande REEL (via sessionStorage) au lieu d'un
numero genere ; repli si visite directe.
- tests : checkout.test.js (traduction + submitOrder mocke). 64/64 verts.
Verifie e2e contre l'API reelle : commande creee + payee, stock decremente exactement
(Menu Le 280 + Big Mac x2 -> -5 Steak hache). Revue adversariale (9 findings) :
CRITIQUE (migration service_tag dupliquee) ecarte -- la colonne est livree par
0003_order_service_tag.sql (#55), juste non appliquee sur la stack dev (reconcilie
dans schema_migrations) ; MEDIUM idempotency + double-clic corriges ; aria-live
imbrique + commentaires obsoletes nettoyes. Differes (LOW notes) : format deduit du
supplement (theorique, le seed met toujours +150), selection sans slot silencieuse.
91 lines
3.5 KiB
HTML
91 lines
3.5 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta name="robots" content="noindex, nofollow">
|
|
<meta name="description" content="Wakdo - Choisissez votre mode de paiement">
|
|
<title>Wakdo - Paiement</title>
|
|
<link rel="stylesheet" href="assets/css/style.css">
|
|
</head>
|
|
<body class="payment-page">
|
|
|
|
<!--
|
|
payment.html — Payment method selection.
|
|
MVP: both buttons simulate payment and redirect to confirmation.html.
|
|
No real payment integration (kiosk demo — out of scope permanently).
|
|
-->
|
|
|
|
<header class="site-header">
|
|
<a
|
|
class="site-header__back"
|
|
href="cart.html"
|
|
aria-label="Retour au panier"
|
|
>
|
|
← Panier
|
|
</a>
|
|
<img
|
|
class="site-header__logo"
|
|
src="assets/images/ui/logo.png"
|
|
alt="Wakdo"
|
|
>
|
|
<span class="mode-badge site-header__mode" data-mode-badge aria-label="Mode de consommation">Sur place</span>
|
|
</header>
|
|
|
|
<main class="payment-main" aria-label="Choix du mode de paiement">
|
|
|
|
<h1 class="payment-main__heading">Comment souhaitez-vous payer ?</h1>
|
|
|
|
<!-- Mini order recap injected by inline script using localStorage -->
|
|
<div class="payment-recap" id="payment-recap" aria-label="Recapitulatif de commande">
|
|
<!-- Filled by page-payment.js -->
|
|
</div>
|
|
|
|
<p class="payment-error" id="payment-error" role="alert" hidden></p>
|
|
|
|
<div class="payment-methods" role="group" aria-label="Modes de paiement">
|
|
|
|
<!--
|
|
Carte bancaire. Paiement simule (pas de PSP), mais la commande est
|
|
REELLEMENT creee + encaissee : page-payment.js -> checkout.submitOrder.
|
|
-->
|
|
<button
|
|
class="payment-choice"
|
|
id="pay-card"
|
|
type="button"
|
|
aria-label="Payer par carte bancaire"
|
|
>
|
|
<!-- Card SVG icon (inline, no external dependency) -->
|
|
<svg class="payment-choice__icon" viewBox="0 0 64 64" aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg">
|
|
<rect x="4" y="14" width="56" height="36" rx="6" ry="6" fill="#FFC72C"/>
|
|
<rect x="4" y="24" width="56" height="8" fill="#1A1A1A"/>
|
|
<rect x="12" y="36" width="16" height="6" rx="2" fill="#fff"/>
|
|
</svg>
|
|
<span class="payment-choice__label">Carte bancaire</span>
|
|
</button>
|
|
|
|
<!-- Especes -->
|
|
<button
|
|
class="payment-choice"
|
|
id="pay-cash"
|
|
type="button"
|
|
aria-label="Payer en especes"
|
|
>
|
|
<!-- Cash SVG icon (inline) -->
|
|
<svg class="payment-choice__icon" viewBox="0 0 64 64" aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg">
|
|
<rect x="4" y="20" width="56" height="32" rx="4" ry="4" fill="#FFC72C"/>
|
|
<circle cx="32" cy="36" r="8" fill="#fff"/>
|
|
<circle cx="32" cy="36" r="4" fill="#FFC72C"/>
|
|
<rect x="8" y="12" width="48" height="6" rx="2" fill="#E6A800"/>
|
|
</svg>
|
|
<span class="payment-choice__label">Especes</span>
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</main>
|
|
|
|
<script type="module" src="assets/js/page-payment.js"></script>
|
|
<script type="module" src="assets/js/nav.js"></script>
|
|
</body>
|
|
</html>
|