Path C
Office Hours — seat or waitlist
The visitor browses Office Hours listings, opens a session or tier detail, and either joins a waitlist or buys a payable tier.
What the visitor is trying to do
“I want to join an Office Hours session or buy a membership — and I need to know the price and availability before committing.”
Entry points
| Element | Destination |
|---|---|
| Resources “Voir le format et les accès” | /ressources/office-hours/ |
| Nav indirect via resources | /ressources/office-hours/ |
| Qualification group format note | /ressources/office-hours/ |
| Session detail cohort link | /ressources/office-hours/cohortes/<slug>/ |
Flow
flowchart LR
LAND["Landing page"] --> OH["/ressources/office-hours/"]
OH --> SESSION["Session / tier detail"]
SESSION --> DECISION{"Payable tier?"}
DECISION -- Yes --> FORM["Checkout form"]
FORM --> POST["POST /paiement/produit/<slug>"]
POST --> SESSION2["Stripe Checkout session"]
SESSION2 --> RETURN["/paiement/<ref>/retour/"]
SESSION2 --> CANCEL["/paiement/<ref>/annule/"]
RETURN --> WEBHOOK["Webhook confirms PAID"]
WEBHOOK --> ENTITLE["Entitlement + delivery link"]
DECISION -- No --> WAITLIST["Waitlist registration
(no payment)"]
Screen inventory
| ID | Screen | User task |
|---|---|---|
| P0 | Landing | Choose an entry point |
| P8 | Office Hours listing | Compare tiers and sessions |
| P9 | Session / tier detail | Join waitlist or buy seat |
| P3 | Checkout form | Select plan, enter identity, accept terms |
| P11 | Stripe hosted checkout | Enter card and confirm |
| P12 | Return / cancelled | See confirmation or backing-out notice |
| P13 | Webhook (machine) | Settle payment and grant entitlement |
| P14 | Entitlement / delivery | Download file or see access instructions |
Flow scenario
Scenario C1
Buy an Office Hours membership
Trigger
- Visitor clicks “Office Hours” in the footer
- Compares the three tiers
- Selects a payable tier
Experience
- The Office Hours listing shows tiers, prices, and cohort status.
- The tier detail includes the checkout organism if the tier has a payable price.
- The visitor chooses a plan, enters identity, and posts to
/paiement/produit/<slug>/. - Stripe Checkout handles the card entry.
- The return page grants access to the session or opens the next instalment.
Trust and safety rules
- The amount charged is always read from a
ProductPrice— never from a browser field. - The terms version is frozen at payment creation time; later CGV updates do not retroactively change an open payment.
- The return page never declares a payment settled: it shows “confirmation en cours” until the signed webhook arrives.
- No card data touches the server. Stripe hosts the checkout page and returns the buyer via HTTPS.
- Pending checkouts are throttled per email address to prevent probing.
- Payment pages are blocked by
robots.txtand carry no editorial SEO value.
Interaction rules
- A product with no payable price shows no checkout form; the page keeps its existing CTAs only.
- A visitor cannot start a second pending payment from the same email address more than ten times per hour.
- The office-hours waitlist records a request, not a payment; the checkout form appears only on payable tiers.
- Mobile fields use 16 px text to avoid browser zoom; choice targets are at least 44×44 px.
- Reduced-motion preferences disable nonessential transitions.
Result states
| State | What the visitor sees | What happens next |
|---|---|---|
| Pending | Checkout form, “continuer vers le paiement sécurisé” | Redirect to Stripe |
| Processing | Return page: “confirmation en cours” | Webhook settles the row |
| Paid | Return page: access granted, entitlements, next instalment if any | Buyer attends session or downloads |
| Cancelled | “Vous avez annulé le paiement” — nothing was charged | Buyer may restart |
| Failed | Error message, no charge | Buyer retries or contacts support |