agmission/Development/client/docs/SUBSCRIPTION-DISPLAY.md

577 lines
30 KiB
Markdown

# Subscription Display Reference
Quick overview of how subscriptions, pricing, and promos are displayed across the entire flow — from checkout through confirmation and the account management page.
---
## Table of Contents
1. [At a Glance — Full User Journey](#1-at-a-glance--full-user-journey)
2. [Page Structure Overview](#2-page-structure-overview)
3. [Checkout Flow (3 Stages)](#3-checkout-flow--3-stages)
- [Stage 1 — Enter Payment](#stage-1--enter-payment-checkoutcomponent)
- [Stage 2 — Review & Submit](#stage-2--review--submit-checkout-reviewcomponent)
- [Stage 3 — Confirmation](#stage-3--confirmation-checkout-confirmcomponent)
4. [Manage Subscription Page](#4-manage-subscription-page-myservices)
- [Subscription State Decision Tree](#subscription-state-decision-tree)
- [Case-by-Case Pricing Display](#case-by-case-pricing-display)
5. [Shared Pricing Components](#5-shared-pricing-components)
- [`<payment-amount>` Template Guide](#payment-amount-template-guide)
- [`<payment-summary>` Mode Guide](#payment-summary-mode-guide)
6. [Canada Tax Logic](#6-canada-tax-logic)
7. [Conditional Label Reference](#7-conditional-label-reference)
---
## 1. At a Glance — Full User Journey
```
User selects a plan
┌───────────────────┐ ┌─────────────────────┐
│ Regular Purchase │ │ Trial Signup │
│ /checkout │ │ /checkout (isTrial) │
└────────┬──────────┘ └──────────┬───────────┘
│ │
│ ┌─────────────┴─────────────┐
│ │ │
│ Trial only Trial + "continue
│ (no card yet) after trial" checked
│ │ │
▼ ▼ ▼
Stage 1: Stage 1: Stage 1:
Payment form $0.00 total After-trial price
(Templates 1) (Template 5) (Template 7)
│ │ │
└──────────────┴───────────────────────────┘
Stage 2: Review
payment-summary REGULAR
(Template 2 — tax/discount/total)
┌───────────────┼───────────────┐
│ │ │
TRIALING CONTINUE_TRIAL REGULAR
Stage 3: Stage 3: Stage 3:
Template 5 Template 7 Template 2
($0 confirm) (after-trial (full receipt)
confirm)
/myservices (manage-subscription)
Displays live subscription state
for all owned packages/addons
```
---
## 2. Page Structure Overview
### `/checkout` — Stage 1
```
┌──────────────────────────────────────────────────────┐
│ CHECKOUT │
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ [Regular purchase — no refund] │ │
│ │ │ │
│ │ payment-info (new line items) │ │
│ │ ┌──────────────────────────────────────────┐ │ │
│ │ │ [IF promo active] → Template 1 │ │ │
│ │ │ [ELSE] → coupon input field │ │ │
│ │ └──────────────────────────────────────────┘ │ │
│ │ ── Credit card form ── │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────┬─────────────────────────────┐ │
│ │ [With refund] │ │ │
│ │ Payment column │ Refund column │ │
│ │ payment-info │ payment-info (refund items)│ │
│ │ Template 1 / │ Template 1 │ │
│ │ coupon input │ │ │
│ └──────────────────┴─────────────────────────────┘ │
│ ── Credit card form ── │
└──────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────┐
│ CHECKOUT (trial — start only, isTrial=true) │
│ │
│ Trial Information │
│ payment-info (trial items) │
│ │
│ [IF promo]: 🎁 Total Promo Savings: -$X.XX │
│ After Trial Total: $X.XX ← * │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ Template 5: "Free trial until DATE" │ │
│ │ Total: $0.00 US │ │
│ └──────────────────────────────────────────────┘ │
│ │
│ ☐ I want to continue the service after trial end │
│ └─(checked)→ credit card form appears │
└──────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────┐
│ CHECKOUT (trial → continuing, isContAftTrialEnd) │
│ │
│ ⚠ Your trial is active until [DATE]. You will be │
│ charged on that date. │
│ │
│ Your Subscription After Trial Ends │
│ payment-info (trial items) │
│ │
│ [IF promo]: 🎁 Total Promo Savings: -$X.XX │
│ After Trial Total *: $X.XX │
│ │
│ Total *: $X.XX │
│ [Canada only]: Plus Applicable Tax │
│ │
│ ── Credit card form ── │
│ │
│ * label changes in Canada (see §6) │
└──────────────────────────────────────────────────────┘
```
### `/checkout-review` — Stage 2
```
┌──────────────────────────────────────────────────────┐
│ REVIEW AND SUBMIT │
│ │
│ ✓ (success icon) │
│ │
│ payment-summary [mode]="REGULAR" │
│ ┌────────────────────────┬───────────────────────┐ │
│ │ Payment Information │ Card Info │ │
│ │ ───────────────── │ ───────────────── │ │
│ │ Template 2: │ •••• 4242 │ │
│ │ Total Excl. Tax $X.XX │ Visa Exp 12/27 │ │
│ │ Tax $X.XX │ │ │
│ │ [Discount] -$X.XX │ [Edit button] │ │
│ │ [Plan Refund]-$X.XX │ │ │
│ │ ────── │ │ │
│ │ Total $X.XX │ │ │
│ └────────────────────────┴───────────────────────┘ │
│ │
│ [Error states: PAST_DUE / CARD_DECLINED / etc. │
│ → error banner above payment-summary] │
│ │
│ [ SUBMIT ] │
└──────────────────────────────────────────────────────┘
```
### `/checkout-confirm` — Stage 3
```
┌──────────────────────────┐
│ mode = TRIALING │
├──────────────────────────┤
│ ✓ Trial subscription │
│ is active │
│ │
│ payment-summary TRIALING │
│ Trial Information │
│ payment-info (items) │
│ Template 5: $0.00 │
└──────────────────────────┘
┌──────────────────────────┐
│ mode = CONTINUE_TRIAL │
├──────────────────────────┤
│ ✓ Continuation setup │
│ complete │
│ │
│ payment-summary │
│ CONTINUE_TRIAL │
│ [showApplicableTax= │
│ authSvc.isCanada] │
│ ───────────────────── │
│ Trial Information │
│ ⚠ constraint-message │
│ payment-info (items) │
│ Template 7: │
│ 🎁 Promo Savings $X │
│ Total (Before Tax) * │
│ Plus Applicable Tax * │
│ Card: •••• 4242 │
└──────────────────────────┘
┌──────────────────────────┐
│ mode = REGULAR │
├──────────────────────────┤
│ ✓ Subscription active │
│ [promo note if promo] │
│ │
│ Template 2: │
│ Total Excl. Tax $X.XX │
│ Tax $X.XX │
│ [Discount] -$X.XX │
│ [Plan Refund] -$X.XX │
│ Total $X.XX │
│ │
│ Card: •••• 4242 Visa │
└──────────────────────────┘
* label changes in Canada (see §6)
```
---
## 3. Checkout Flow — 3 Stages
### Stage 1 — Enter Payment (`checkout.component`)
#### Decision tree
```
checkout.component
├─[isTrial = false]────────────────── Regular purchase
│ │
│ ├─[hasRefund = false]─────── Single column
│ │ payment-info (items)
│ │ [promo?] Template 1 : coupon input
│ │ credit card form
│ │
│ └─[hasRefund = true]──────── Two columns
│ Payment col │ Refund col
│ items+T1 │ items+T1
│ credit card form below
└─[isTrial = true]─────────────────── Trial purchase
├─[isContAftTrialEnd = false]── Trial-start only
│ Trial info + items
│ [promo?] 🎁 savings + After Trial Total *
│ Template 5 ($0.00)
│ Checkbox: continue after trial?
│ └─(checked) → isContAftTrialEnd = true
└─[isContAftTrialEnd = true]─── Trial + continue
Constraint banner
After-trial items
[promo?] 🎁 savings + After Trial Total *
Total * / Plus Applicable Tax (CA)
Credit card form
* = "After Trial Total (Before Tax)" / "Total (Before Tax)" in Canada
```
---
### Stage 2 — Review & Submit (`checkout-review.component`)
Always renders `<payment-summary [mode]="REGULAR">`**Template 2** inside.
```
Template 2 layout:
┌─[IF promoSavings > 0]────────────────────────────────┐
│ 🎁 Total Promo Savings: -$X.XX │
│ [IF creditAmount > 0] │
│ 🔄 Plan Refund: -$X.XX │
│ Tax: $X.XX │
│ Total: $X.XX │
└──────────────────────────────────────────────────────┘
┌─[ELSE — no promo]────────────────────────────────────┐
│ Total Excluding Tax: $X.XX │
│ Tax: $X.XX │
│ [IF discount.amountOff] │
│ (Discount): -$X.XX │
│ [IF creditAmount > 0] │
│ 🔄 Plan Refund: -$X.XX │
│ Total: $X.XX │
└──────────────────────────────────────────────────────┘
```
---
### Stage 3 — Confirmation (`checkout-confirm.component`)
```
Mode selection:
TRIALING ──────────────────→ payment-summary TRIALING
→ Template 5 ($0.00 + trial msg)
CONTINUE_TRIAL ────────────→ payment-summary CONTINUE_TRIAL
[showApplicableTax]="isCanada"
→ Template 7 (after-trial totals)
REGULAR (default) ─────────→ Template 2 (full tax + total receipt)
```
---
## 4. Manage Subscription Page (`/myservices`)
### Subscription State Decision Tree
```
manage-subscription: for each pkg in subscriptions
├─[TRIALING]───────────────────────────────────────────────────
│ Trial Ends: [DATE]
│ │
│ ├─[No promo — Case 2A]
│ │ After Trial: $X.XX/year
│ │
│ ├─[Promo + will continue — Case 2C]
│ │ Regular Price: $X.XX/year ← context
│ │ Paid Price: $X.XX + (save $X.XX)
│ │ [IF time-limited] After Promo Ends: $X.XX/year
│ │
│ └─[Promo + cancel at end — Case 2D]
│ Regular Price: $X.XX/year
│ (no paid price shown — trial will cancel)
├─[ACTIVE + hasActivePromo(pkg)]─────────────────────────────
│ │
│ ├─[isRenewalPromo — Case 2B]
│ │ 🏷 Discount badge
│ │ getRenewalPromoMessage() (e.g. "Renew by X and save!")
│ │
│ └─[existingPromo — Case 3]
│ Regular Price: $X.XX/year ← context
│ Paid Price: $X.XX + (save $X.XX)
│ [IF time-limited] After Promo Ends: $X.XX/year
├─[ACTIVE — no promo]────────────────────────────────────────
│ Paid Price: $X.XX/year
├─[CANCELED]─────────────────────────────────────────────────
│ Ended On: [DATE]
│ Previous Price: $X.XX/year
└─[PAST_DUE / INCOMPLETE]────────────────────────────────────
Paid Price: $X.XX/year
Next Bill Date: [DATE]
```
### Case-by-Case Pricing Display
Each subscription card shows a **Pricing Section** and a **Details Section**:
```
┌─────────────────────────────────────────────────┐
│ 📦 Package Name [STATUS BADGE] │
│ ───────────────────────────────────────────── │
│ PRICING SECTION (varies by case — see below) │
│ ───────────────────────────────────────────── │
│ DETAILS SECTION (always shown): │
│ Max Vehicles: N Aircraft │
│ Max Acres: N,000 / Unlimited │
│ Billing Cycle: Yearly │
│ Payment Method: Visa •••• 4242 │
│ Next Bill Date: Jan 1, 2027 ─┐ ACTIVE / │
│ Next Bill Amt: $X.XX ┘ TRIALING │
│ ───────────────────────────────────────────── │
│ [Promo section if applicable — see below] │
│ ───────────────────────────────────────────── │
│ [ MANAGE ] [ CANCEL / REACTIVATE ] │
└─────────────────────────────────────────────────┘
```
#### Pricing section — by case
```
CASE 2A — Trial, no promo
Trial Ends: Jan 10, 2026
After Trial: $995.00/year
CASE 2B — Active, renewal incentive promo (cancel_at_period_end)
🏷 [badge] "Renew by Jan 10, 2026 and save 50%!"
CASE 2C — Trial, promo applied, will continue after trial
Trial Ends: Jan 10, 2026
Regular Price: $995.00/year ← full price for context
Paid Price: $497.50/year (save $497.50)
After Promo Ends: $995.00/year ← only if time-limited promo
CASE 2D — Trial, promo applied, cancel at end
Trial Ends: Jan 10, 2026
Regular Price: $995.00/year
CASE 3 — Active, promo applied on subscription
Regular Price: $995.00/year ← full price for context
Paid Price: $497.50/year (save $497.50)
After Promo Ends: $995.00/year ← only if time-limited promo
ACTIVE (no promo)
Paid Price: $995.00/year
CANCELED
Ended On: Dec 31, 2025
Previous Price: $995.00/year
PAST_DUE / INCOMPLETE
Paid Price: $995.00/year
Next Bill Date: Jan 10, 2026
```
#### Promo details block (ACTIVE non-renewal promos)
```
─────────────────────────────────────────────────
🏷 Percentage Off | Amount Off | Forever
Discount: 50% off or $497.50 off
Duration: For N months | One time | Forever
[IF expires]: Promo Expires: Dec 31, 2026 (N days left)
─────────────────────────────────────────────────
[IF pendingPromo]:
⏳ Pending Promo (from next billing cycle):
Discount / Duration / Savings
─────────────────────────────────────────────────
```
---
## 5. Shared Pricing Components
### `<payment-amount>` Template Guide
The component is template-switched via `[template]="N"`.
```
Template Used In Renders
───────── ─────────────────────────────────── ──────────────────────────────────────────────
1 checkout (with active promo) Tax + discount + promo savings + Total
2 checkout-review, checkout-confirm Full grid: Excl.Tax / Tax / Discount / Total
3 (reserved) Subtotal ─── Tax ─── Discount ─── Total
4 (reserved) Coupon/discount line only
5 trial start confirm, TRIALING mode Trial msg + Total: $0.00
6 (reserved) "Will be charged after trial" note + Total
7 CONTINUE_TRIAL confirm, isContAftTrial Promo savings + Total (Before Tax)* + Tax note
```
#### Template 1 layout
```
Tax: $X.XX US
[IF %off] 50% off: ($X.XX) US
[IF $off] ($ off): ($X.XX) US
[IF promo] 🎁 Total Promo Savings: -$X.XX US
Total: $X.XX US
```
#### Template 2 layout
```
┌─[IF promoSavings > 0]───────────────────────────────┐
│ 🎁 Total Promo Savings: -$X.XX │
│ [Plan Refund]: -$X.XX (if > 0) │
│ Tax: $X.XX │
│ Total: $X.XX │
└─────────────────────────────────────────────────────┘
┌─[ELSE]──────────────────────────────────────────────┐
│ Total Excluding Tax: $X.XX │
│ Tax: $X.XX │
│ [(Discount)]: ($X.XX) (if $off) │
│ [Plan Refund]: -$X.XX (if > 0) │
│ Total: $X.XX │
└─────────────────────────────────────────────────────┘
```
#### Template 5 layout
```
[msg] "Free trial until Jan 10, 2026"
Total: $0.00 US
```
#### Template 7 layout
```
[IF promoSavings > 0]
🎁 Total Promo Savings: -$X.XX US
[!Canada] Total: $X.XX US
[Canada] Total (Before Tax): $X.XX US
Plus Applicable Tax ← only when totalAmount > 0
```
---
### `<payment-summary>` Mode Guide
A mode-driven wrapper that picks the layout and calls `<payment-amount>` with the right template.
```
Mode Template Used Shows Card? showApplicableTax driven by
─────────────── ───────────── ─────────── ──────────────────────────────
REGULAR 2 yes N/A (Template 2 has no tax toggle)
TRIALING 5 no N/A
CONTINUE_TRIAL 7 yes [showApplicableTax] input → isCanada
```
**Inputs:**
| Input | Type | Purpose |
|---|---|---|
| `mode` | `Mode` | `REGULAR`, `TRIALING`, or `CONTINUE_TRIAL` |
| `card` | `Card` | Credit card info for display |
| `payment` | `PaidAmount` | `{ total, totalTax, totalExcludingTax, discount, refundAmount }` |
| `trialItems` | `TrialItem[]` | Line items for trial subscriptions |
| `promoSavings` | `number` | Total promo discount |
| `showApplicableTax` | `boolean` | Passed down to `<payment-amount>` (Template 7) |
| `editable` | `boolean` | Shows Edit button in REGULAR mode |
| `promos` | `Map<string, any>` | Promo badge data for `<payment-info>` |
---
## 6. Canada Tax Logic
```typescript
// auth.service.ts
get isCanada(): boolean {
return this.user?.country === 'CA'; // populated from login response
}
```
### Where `isCanada` propagates
```
AuthService.isCanada
├── checkout.component (readonly authSvc exposed to template)
│ ├── "Total (Before Tax):" label [isContAftTrialEnd block]
│ ├── "After Trial Total (Before Tax):" label
│ └── "Plus Applicable Tax" div
└── checkout-confirm.component (readonly authSvc)
└── <payment-summary [showApplicableTax]="authSvc.isCanada">
└── <payment-amount [showApplicableTax]="showApplicableTax">
└── Template 7 tax toggle + "Plus Applicable Tax" note
```
### Label changes by country
```
Non-Canada Canada
───────────────────── ─────────────────────────────
Total label Total: Total (Before Tax):
After-trial total label After Trial Total: After Trial Total (Before Tax):
Tax line (hidden) Plus Applicable Tax
```
---
## 7. Conditional Label Reference
| Label | Component | Renders when |
|---|---|---|
| **Total:** | All templates, default | `!showApplicableTax` |
| **Total (Before Tax):** | Template 7, `checkout.html` | Canada (`showApplicableTax = true`) |
| **Total Excluding Tax:** | Template 2, no-promo branch | Non-promo path (always) |
| **Tax:** | Templates 1, 2, 3 | Tax data available |
| **Plus Applicable Tax** | Template 7, `checkout.html` | Canada + `totalAmount > 0` |
| **After Trial Total:** | `payment-summary #trial`, `checkout.html` | `!showApplicableTax` + `promoSavings > 0` |
| **After Trial Total (Before Tax):** | `payment-summary #trial`, `checkout.html` | Canada + `promoSavings > 0` |
| **🎁 Total Promo Savings:** | Templates 2, 7; inline in checkout | `promoSavings > 0` |
| **🔄 Plan Refund:** | Template 2 | `creditAmount > 0` |
| **Regular Price:** | manage-subscription Cases 2C, 2D, 3 | Has promo applied |
| **Paid Price:** | manage-subscription Cases 2C, 3, ACTIVE, PAST_DUE | Active promo or non-promo active |
| **After Promo Ends:** | manage-subscription Cases 2C, 3 | `showAfterPromoEnds(pkg)` — time-limited promo |
| **Next Period Amount:** | manage-subscription | `nextBillAmounts[key]` loaded |