frontend phase 11
This commit is contained in:
@@ -12,6 +12,32 @@ for awareness.
|
||||
- **Requests filed:** frontend/requests/for-backend.md (yes/no)
|
||||
-->
|
||||
|
||||
## frontend-phase-11-b12 — BNPL installment checkout (D1–D5) — 2026-07-10
|
||||
- **Shipped:** the **alternate checkout branch** off C6 — a **new `services/bnpl` domain** (types/keys/
|
||||
constants/invalidations/apis[client+mock]/7 hooks + barrel) and the five wireframe screens under the
|
||||
customer shell, terracotta-financial: **D1 روش پرداخت** (provider chooser off `useBnplOptions`, full-card
|
||||
fall-back), **D2 انتخاب طرح** (single-select plan), **D3 اعتبارسنجی** (کد ملی + prefilled موبایل +
|
||||
consent-gated → approved-with-ceiling / declined+ceiling-exceeded → **card fall-back**), **D4 تایید طرح و
|
||||
قرارداد** (served repayment table + ownership note + contract-gated final action → provider handoff), and
|
||||
**D5 پیگیری اقساط** in the **کیفپول** tab (provider-reported outstanding balance + due list + early-pay
|
||||
**provider hand-off**). The handoff (gateway harness → return) settles the down-payment and **routes to the
|
||||
reused f9 confirmation** (`?method=bnpl`), so the booking confirms exactly as the card path. Two shared
|
||||
tested composites: `BnplPlanCard`, `InstallmentScheduleRow` (reused D4+D5). C6's «پرداخت اقساطی» is enabled;
|
||||
the `installments` icon + the `bnpl` i18n namespace (87 keys, both locales in sync) added.
|
||||
- **Consumes:** dev/contracts/domains/bnpl.md (backend phase b12) — `eligibility`/`initiate`/order-by-id map
|
||||
1:1; options/schedule/wallet-status/by-request-order/D3-KYC are contract gaps.
|
||||
- **Mocked client-side:** `services/bnpl` via `bnplMockApi` (`USE_BNPL_MOCK=true`) — the settle bridge reuses
|
||||
the f9 conversion (a settled BNPL order = a card payment net-of-fee) + seeds a provider-reported Wallet
|
||||
plan. See mocks-registry. Money = served IRR digit-strings end-to-end (mock computes with BigInt; components
|
||||
only format). **D5 is provider-reported status, NOT a Balinyaar ledger; early-pay hands off to the provider.**
|
||||
- **Reviewed:** 6-dimension adversarial multi-agent review + verify pass — 5 confirmed findings, all fixed
|
||||
(return-page window-expired copy/CTA, real getBnplOrder order-id keying, a needless poll fetch, dead `col_*`
|
||||
keys + surfacing `ownership_note` at D1, a dark-mode glyph-contrast token).
|
||||
- **Gate:** npm run check green · npm run test:ci green (223 tests, +9) · npm run build green with
|
||||
NEXT_PUBLIC_API_URL set.
|
||||
- **Requests filed:** frontend/requests/for-backend.md — yes (REQ-022 options+schedule, REQ-023 eligibility
|
||||
KYC inputs, REQ-024 wallet status + customer bookingId + by-request order lookup).
|
||||
|
||||
## frontend-phase-10-b11 — Cancellation & refund status (customer) — 2026-07-10
|
||||
- **Shipped:** the trust-first **exit** — a **new `services/refunds` domain** (types/constants/keys/
|
||||
invalidations/apis[client+mock]/3 hooks + barrel) and two customer screens: the **cancellation flow**
|
||||
|
||||
@@ -323,3 +323,59 @@ delivers fixes in its own change. **Frontend never edits backend code to "fix" a
|
||||
the b12 `IBnplProvider` mock echoes it as nullable and the client treats any provider-commission figure
|
||||
as opaque/never customer-facing.
|
||||
- **Status:** open
|
||||
|
||||
## REQ-022 — BNPL provider/plan options + repayment schedule (D1/D2/D4) — filed by frontend-phase-11-b12 — 2026-07-10
|
||||
- **Need:** Two customer-facing reads the installment checkout renders that b12 serves **nothing** for:
|
||||
1. **Provider + plan options** — proposed `GET api/v1/checkout_bnpl/options/{bookingRequestId}` (owner-scoped) →
|
||||
`{ bookingRequestId, requestStatus, orderAmountIrr, bnplEligible, providers: [{ providerCode, tagline?,
|
||||
plans: [{ planId, termMonths?, installmentCount, feePercent, downPaymentPercent, monthlyAmountIrr,
|
||||
downPaymentIrr, totalIrr }] }] }` — the payable amount plus the provider set (دیجیپی/اسنپپی/اقساط
|
||||
بالینیار) and, **per plan, the served monthly amount / down-payment / total** (all IRR digit-strings).
|
||||
2. **Repayment schedule** — proposed `GET api/v1/checkout_bnpl/schedule/{bookingRequestId}?provider=&plan=`
|
||||
→ `{ bookingRequestId, providerCode, planId, totalIrr, downPaymentIrr, installmentCount,
|
||||
rows: [{ sequence, kind: 'down_payment'|'installment', dueDate, amountIrr }] }` — the D4 پیشپرداخت +
|
||||
قسط ۱…N table.
|
||||
- **Why:** b12 is order-centric (`eligibility` / `initiate` / status / webhook) and the contract **explicitly
|
||||
does not model the customer's repayment schedule** (`installment_count` is informational). But D1–D4 must
|
||||
show a provider list, per-plan monthly/down-payment figures, and a due-dated repayment table — and the
|
||||
client is forbidden from computing any money figure. Today the whole D1/D2/D4 money surface is mocked
|
||||
(`services/bnpl` mock computes the plan split + schedule with BigInt at the configured provider fees).
|
||||
When these land, the swap is a single `USE_BNPL_MOCK=false` flip.
|
||||
- **Note on provider set:** the wireframe includes an **in-house `balinyaar`** plan not in the b12
|
||||
`provider_code` enum (`snapppay|digipay|tara|torobpay`). Please add `balinyaar` (or state how the in-house
|
||||
plan is modelled) so `providerCode` stays a closed set.
|
||||
- **Status:** open
|
||||
|
||||
## REQ-023 — BNPL eligibility should accept the D3 credit-check inputs (national ID / mobile / consent) — filed by frontend-phase-11-b12 — 2026-07-10
|
||||
- **Need:** Either extend `POST api/v1/checkout_bnpl/eligibility` to accept `{ nationalId, mobile, consent }`
|
||||
alongside `{ bookingRequestId, providerCode }`, or define a separate provider-KYC step that captures them.
|
||||
- **Why:** D3 (اعتبارسنجی) collects کد ملی + موبایل + a consent checkbox and submits them for the provider
|
||||
credit inquiry, but the b12 eligibility body is only `{ bookingRequestId, providerCode }`. The client sends
|
||||
the extra fields today (ignored server-side until the KYC step exists) and the mock uses them for the
|
||||
deterministic declined-path demo. The response already carries `eligibilityStatus` + `creditCeilingIrr`,
|
||||
which D3 renders — only the request inputs are the gap.
|
||||
- **Status:** open
|
||||
|
||||
## REQ-024 — BNPL provider-reported installment status for the Wallet (D5) + customer bookingId link — filed by frontend-phase-11-b12 — 2026-07-10
|
||||
- **Need:** Two additions for the Wallet installment view and the confirmation deep-link:
|
||||
1. **Provider-reported installment status** — proposed `GET api/v1/checkout_bnpl/wallet_installments`
|
||||
(owner-scoped) → `[{ bnplTransactionId, bookingId?, providerCode, status, serviceLabel,
|
||||
outstandingBalanceIrr, installmentCount, nextDueDate?, nextAmountIrr?, earlyPayUrl?,
|
||||
installments: [{ sequence, kind, dueDate, amountIrr, status: 'paid'|'due_soon'|'upcoming'|'overdue' }] }]`
|
||||
— the مانده بدهی + per-installment due list D5 renders. This is **provider-reported status Balinyaar
|
||||
proxies, not a Balinyaar-managed ledger** (the repayment schedule is out of the b12 contract's scope);
|
||||
`earlyPayUrl` is a hand-off link to the provider (early-pay is a provider action, never a Balinyaar
|
||||
transaction).
|
||||
2. **Customer-readable `bookingId`** on the settled BNPL order (`BnplOrderStatus` sets it at settle) so the
|
||||
return surface can deep-link the reused f9 confirmation → booking detail + invoice (same gap as REQ-017
|
||||
on the card path).
|
||||
3. **A customer by-request order lookup** — proposed `GET api/v1/checkout_bnpl/by_request/{bookingRequestId}`
|
||||
→ `BnplOrderStatus`. The b12 `GET checkout_bnpl/{id}` is keyed by the **order id**, but the return-poll
|
||||
surface holds the **request id** (from the C6 handoff), not the order id. (The settle-on-return path
|
||||
reads the order **by its own id** via the `transaction_id` carried through the handoff, which is already
|
||||
contract-correct — only the standalone poll needs a by-request read.)
|
||||
- **Why:** D5 (پیگیری اقساط) is the load-bearing "provider owns the schedule, Balinyaar only displays it"
|
||||
surface, and b12 models none of the per-installment schedule/status. The client mocks the whole D5 read
|
||||
behind the `services/bnpl` seam (seeded plan + a plan pushed on each settled checkout). When it lands the
|
||||
swap is one config flip.
|
||||
- **Status:** open
|
||||
|
||||
Reference in New Issue
Block a user