- Added '*.tar.gz.sha256' to .gitignore to exclude SHA256 checksum files from version control. - Updated SHA256 checksums for the latest portal backend and frontend tar.gz files to reflect new builds. - Enhanced address handling in `useAddressEdit`, `useProfileData`, and `AddressConfirmation` components to invalidate catalog queries upon address updates, ensuring accurate server-personalized results. - Introduced new query key for catalog queries in the API to streamline cache management.
465 lines
25 KiB
Markdown
465 lines
25 KiB
Markdown
# Portal Ordering & Provisioning – Complete Reference
|
||
|
||
_This document consolidates the complete ordering and provisioning specification, integrating architecture, flows, and implementation details._
|
||
|
||
**Related Documents:**
|
||
|
||
- `ORDER-FULFILLMENT-COMPLETE-GUIDE.md` – **Complete implementation guide with examples**
|
||
- `SALESFORCE-WHMCS-MAPPING-REFERENCE.md` – **Comprehensive field mapping reference**
|
||
- `PORTAL-DATA-MODEL.md` – Field mappings and data structures
|
||
- `PRODUCT-CATALOG-ARCHITECTURE.md` – SKU architecture and catalog implementation
|
||
- `SALESFORCE-PRODUCTS.md` – Complete product setup guide
|
||
|
||
> **📖 For complete implementation details, see `ORDER-FULFILLMENT-COMPLETE-GUIDE.md`**
|
||
|
||
- Backend: NestJS BFF (`apps/bff`) with existing integrations: WHMCS, Salesforce
|
||
- Frontend: Next.js portal (`apps/portal`)
|
||
- Billing: WHMCS (invoices, payment methods, subscriptions)
|
||
- Control plane: Salesforce (review/approval, provisioning trigger)
|
||
- Logging: centralized logger "dino" – do not introduce alternate loggers
|
||
|
||
We require a Customer Number (SF Number) at signup and gate checkout on the presence of a WHMCS payment method. Orchestration runs in the BFF; Salesforce reviews and triggers provisioning.
|
||
|
||
## 0) Architecture at a Glance
|
||
|
||
- Source of truth
|
||
- Salesforce: Catalog (Product2 + PricebookEntry with portal fields), eligibility, order review/trigger, reporting
|
||
- WHMCS: Customer profile, payment methods, invoices, subscriptions (authoritative)
|
||
- Portal BFF: Orchestration + ID mappings (no customer data authority)
|
||
- Salesforce data model (three-object pattern)
|
||
- `Product2` (+ `PricebookEntry`) with portal fields (catalog + WHMCS mapping)
|
||
- `Order` (header; one per checkout)
|
||
- `OrderItem` (child; one per selected product) → references `Product2` (and PricebookEntry)
|
||
- Provisioning
|
||
- Operator approves in Salesforce → Record‑Triggered Flow publishes Platform Event → BFF reads Order + OrderItems, dereferences `Product2` portal fields, calls WHMCS `AddOrder` → `AcceptOrder`, then writes back WHMCS IDs to Order/OrderItems
|
||
|
||
## 1) Customer Experience
|
||
|
||
1. Signup (Customer Number required)
|
||
- User provides: Email, Confirm Email, Password, Confirm Password, First/Last Name, optional Company/Phone, and Customer Number (SF Number).
|
||
- Portal validates and links to the existing Salesforce Account using the SF Number; if email differs, proceed and auto-create a Salesforce Case for CS (details in data model doc).
|
||
- WHMCS client is always created on signup (no pre-existing clients expected). WHMCS custom field for Customer Number must be set to the SF Number.
|
||
- Mapping is stored: `portalUserId ↔ whmcsClientId ↔ sfAccountId`.
|
||
|
||
2. Add payment method (required before checkout)
|
||
- Portal shows an “Add payment method” CTA that opens WHMCS payment methods via SSO (`POST /api/auth/sso-link` → `index.php?rp=/account/paymentmethods`).
|
||
- Portal checks `GET /billing/payment-methods/summary` to confirm presence before enabling checkout.
|
||
|
||
3. Browse catalog and configure
|
||
- `/catalog` lists products from BFF `GET /catalog` (reads Salesforce Product2 via BFF).
|
||
- Product detail pages collect configurable options; checkout button disabled until payment method exists.
|
||
|
||
4. Place order
|
||
- `POST /orders` creates a Salesforce Order (Pending Review) and stores orchestration state in BFF. Portal shows “Awaiting review”.
|
||
|
||
5. Review & Provision (operator in Salesforce)
|
||
|
||
- Recommended (async): Operator reviews/approves. A Record-Triggered Flow publishes Platform Event `OrderProvisionRequested__e`.
|
||
- BFF subscribes to the event and enqueues a provisioning job. Worker validates payment method, (for eSIM) calls activation API, then `AddOrder` and `AcceptOrder` in WHMCS, updates Salesforce Order fields/status.
|
||
- Legacy (webhook): previously called `POST /orders/{sfOrderId}/fulfill`. This path has been removed.
|
||
|
||
6. Completion
|
||
- Subscriptions and invoices appear in portal (`/subscriptions`, `/billing/invoices`). Pay via WHMCS SSO links.
|
||
|
||
## 1.1 Email Notifications
|
||
|
||
We will send operational emails at key events (no email validation step required at signup):
|
||
|
||
- Signup success: send Welcome email to customer; CC support.
|
||
- eSIM activation: send Activation email to customer; CC support.
|
||
- Order activated: send Activated/Next steps email to customer.
|
||
|
||
Implementation notes:
|
||
|
||
- Reuse centralized logger; no sensitive data in logs.
|
||
- Add a lightweight `EmailService` abstraction in BFF using existing modules style; queue via BullMQ jobs for reliability (Jobs module already present). Transport to be configured (SMTP/SendGrid) via env.
|
||
- Templates stored server-side; configurable CC list via env.
|
||
|
||
## 2) Backend Contracts (BFF)
|
||
|
||
### 2.1 Auth & Identity
|
||
|
||
- Modify `POST /auth/signup` (exists) to require `sfNumber: string` (Customer Number).
|
||
- Steps:
|
||
- Validate request; check portal user exists by email; if exists → error (prompt login/reset).
|
||
- Salesforce: find Account by Customer Number (SF Number). If not found → error.
|
||
- WHMCS: create client unconditionally for this flow. Set Customer Number custom field to SF Number.
|
||
- Create portal user and store mapping.
|
||
- Send Welcome email (to customer) with support on CC.
|
||
- If email mismatch is detected between inputs/systems (e.g., SF Account email vs signup email), automatically create a Salesforce Case to notify CS team and include both emails and Account reference.
|
||
- Security: sanitize errors; never log passwords; use centralized logger.
|
||
|
||
- `POST /auth/claim` (optional future): If we ever separate claim flow from signup.
|
||
|
||
### 2.2 Identity & Data Mapping (Portal ↔ Salesforce ↔ WHMCS)
|
||
|
||
- Systems of Record
|
||
- Salesforce: Catalog (Product2/PricebookEntry) and process control (Order approvals/status), account eligibility fields. Read-only from portal at runtime except Order creations/updates.
|
||
- WHMCS: Customer details, payment methods, invoices, subscriptions, provisioning outcomes. Source of truth for customer contact/billing data.
|
||
- Portal (BFF): Orchestration state and ID mappings only.
|
||
|
||
- Mapping Records (existing):
|
||
- `portalUserId ↔ whmcsClientId ↔ sfAccountId` stored in BFF mappings service.
|
||
- Customer Number (SF Number) is provided once at signup to create the mapping; we do not ask again.
|
||
|
||
- Portal User → Salesforce Account (lookup only)
|
||
- Authoritative lookup key: Customer Number on Account (provided via SF Number at signup).
|
||
- We do not sync profile/address changes from portal to Salesforce.
|
||
|
||
- Portal User → WHMCS Client (authoritative for customer profile)
|
||
- Email → `email`
|
||
- First/Last Name → `firstname`, `lastname`
|
||
- Company → `companyname` (optional)
|
||
- Phone → `phonenumber`
|
||
- Address: `address1`, `address2`, `city`, `state`, `postcode`, `country` (ISO 2-letter)
|
||
- Custom Field (Customer Number) → set to SF Number (id/name TBD; currently used in mapping)
|
||
- Notes (optional) → include correlation IDs / SF refs
|
||
|
||
- Discrepancy handling
|
||
- If SF Account email differs from signup email, proceed and auto-create a Salesforce Case for CS with both emails and Account reference (for review). No sync/write to SF.
|
||
|
||
### 2.3 Address Capture (WHMCS only)
|
||
|
||
- Capture Requirements
|
||
- Required: `street`, `city`, `state`, `postalCode`, `country`
|
||
- Optional: `addressLine2`, `buildingName`, `roomNumber`, `phone`
|
||
- Validation: client-side + server-side; normalize country to ISO code.
|
||
|
||
- UX Flow
|
||
- After signup, prompt to complete Address before catalog/checkout.
|
||
- Dashboard banner if address incomplete.
|
||
|
||
- API Usage
|
||
- Use `PATCH /api/me/address` to update address fields only. No write to Salesforce from portal.
|
||
- Centralized logging; redact PII.
|
||
|
||
### 2.4 Billing
|
||
|
||
- `GET /billing/payment-methods/summary` (new)
|
||
- Returns `{ hasPaymentMethod: boolean }` using WHMCS `GetPayMethods` for mapped client.
|
||
|
||
- `POST /api/auth/sso-link` (exists)
|
||
- Used to open WHMCS payment methods and invoice/pay pages.
|
||
|
||
### 2.5 Catalog (Salesforce Product2 as Source of Truth)
|
||
|
||
We will not expose WHMCS catalog directly. Instead, Salesforce `Product2` (with `PricebookEntry`) will be the catalog, augmented with a small set of custom fields used by the portal and BFF.
|
||
|
||
Custom fields on `Product2` (proposal; confirm API names):
|
||
|
||
- Identity & Display
|
||
- `Product2Categories1__c` (Picklist): Internet | SIM | VPN | Other
|
||
- `Portal_Description__c` (Long Text)
|
||
- `Portal_Feature_Bullets__c` (Long Text)
|
||
- `Portal_Hero_Image_URL__c` (URL)
|
||
- `Portal_Tags__c` (Text)
|
||
- `Portal_Sort_Order__c` (Number)
|
||
- `Portal_Catalog__c` (Checkbox, default false)
|
||
- `Portal_Valid_From__c` / `Portal_Valid_Until__c` (Date)
|
||
- Terms/Options
|
||
- `Portal_Billing_Cycle__c` (Picklist): Monthly | Onetime (default)
|
||
- `Portal_Max_Quantity__c` (Number, default 1)
|
||
- `Portal_Requires_Payment_Method__c` (Checkbox, default true)
|
||
- `Portal_ConfigOptions_JSON__c` (Long Text) – defaults and allowed values
|
||
- Eligibility (Internet personalization)
|
||
- `Portal_Eligibility_Dwelling__c` (Picklist): Home | Apartment | Any
|
||
- `Portal_Eligibility_Tier__c` (Picklist): 1G | 100Mb | Any
|
||
- `Portal_Eligibility_Region__c` (Text) (optional)
|
||
- WHMCS Mapping
|
||
- `WHMCS_Product_Id__c` (Number)
|
||
- `WHMCS_Notes_Template__c` (Long Text)
|
||
- `eSIM_Settings_JSON__c` (Long Text)
|
||
|
||
Endpoints (BFF)
|
||
|
||
- `GET /catalog` (exists): return public offerings from `Product2` where `Portal_Catalog__c = true` and within validity dates; price via `PricebookEntry` for the portal pricebook.
|
||
- `GET /catalog/personalized` (new):
|
||
- Authenticated: infer `sfAccountId` from mapping. We only check the SF Number once during signup to create the mapping.
|
||
- Query `Product2` filtered by `Portal_Catalog__c` and validity, then apply eligibility filters using Account fields (e.g., dwelling/tier). eSIM/VPN are always included.
|
||
|
||
- Caching & Invalidation
|
||
- Cache global catalog 15m; cache personalized results per `sfAccountId` 5m.
|
||
- Optional Salesforce CDC/Platform Event to bust cache on `Product_Offering__c` changes.
|
||
|
||
### 2.6 Orders & Provisioning
|
||
|
||
- `POST /orders` (new)
|
||
- Body: `{ items: { productId, billingCycle, configOptions?, notes? }[], promoCode?, notes? }`
|
||
- Server-side checks: require WHMCS mapping; require `hasPaymentMethod=true`.
|
||
- Actions: Create Salesforce Order (Pending Review), persist orchestration record (sfOrderId, items/config, status=Pending Review, idempotency), return `{ sfOrderId, status }`.
|
||
|
||
- `GET /orders/:sfOrderId` (new)
|
||
- Returns orchestration status and relevant IDs; portal polls for updates.
|
||
|
||
- Async Provisioning (Platform Events)
|
||
- Event: `OrderProvisionRequested__e` with `{ OrderId__c, IdemKey__c?, CorrelationId__c? }`
|
||
- BFF autosubscribes when `SF_EVENTS_ENABLED=true`; enqueues provisioning job; returns 202 immediately (no inbound SF call).
|
||
- Worker performs the same steps as above and updates Salesforce.
|
||
|
||
## 3) Salesforce
|
||
|
||
### 3.1 Account matching
|
||
|
||
- Personalization Fields (Internet Eligibility)
|
||
- Use the Account’s serviceability/plan eligibility field(s) to decide which Internet product variants to show.
|
||
- Examples (to confirm API names and values):
|
||
- `Dwelling_Type__c`: `Home` | `Apartment`
|
||
- `Internet_Tier__c`: `1G` | `100Mb`
|
||
- The BFF personalization endpoint maps these to curated catalog SKUs.
|
||
|
||
- Customer Number (SF Number) is authoritative. Signup requires it. We find Account by that number.
|
||
- Mirror SF Number to WHMCS client custom field.
|
||
- If a discrepancy is found (e.g., Account has a different email than signup), create a Salesforce Case automatically with context so CS can triage; proceed with signup (no hard block), but flag the portal user for review.
|
||
|
||
### 3.2 Order fields
|
||
|
||
- Add the following fields to `Order`:
|
||
- `Activation_Status__c` (Pending Review, Activating, Provisioned, Failed)
|
||
- `WHMCS_Order_ID__c`
|
||
- Optional (if needed): `ESIM_ICCID__c`
|
||
|
||
#### 3.2.1 Salesforce Order API & Required Fields (to confirm)
|
||
|
||
- Object: `Order`
|
||
- Required fields for creation (proposal):
|
||
- `AccountId` (from SF Number lookup)
|
||
- `EffectiveDate` (today)
|
||
- `Status` (org-specific; code currently sets "Pending Review" — use your org's draft/review value)
|
||
- `Description` (optional: include product summary)
|
||
- Custom: `Activation_Status__c = Not Started`
|
||
- Optional link: `OpportunityId` (if created/available)
|
||
- On updates during provisioning:
|
||
- Set `Activation_Status__c` → Activating → Activated/Failed
|
||
- Store `WHMCS_Order_ID__c`
|
||
- For eSIM: masked `ESIM_ICCID__c`
|
||
|
||
#### 3.2.2 Order Line Representation (Salesforce-side, to confirm)
|
||
|
||
Options (pick one):
|
||
|
||
1. Use standard `OrderItem` with `Product2` and Pricebooks (recommended)
|
||
- Pros: native SF pricing and reporting; clean standard model
|
||
- Cons: maintain `Product2` and `PricebookEntry` for all offerings
|
||
- Fields per `OrderItem` (standard):
|
||
- `OrderId`, `Product2Id`, `PricebookEntryId`, `Quantity`, `UnitPrice`
|
||
- Custom fields to add on `OrderItem`:
|
||
- (Derived billing cycle from SKU class; no custom field)
|
||
- `ConfigOptions_JSON__c` (Long Text)
|
||
|
||
2. Custom child object `Order_Offering__c`
|
||
- Not used; we standardize on `OrderItem`.
|
||
|
||
Decision: Use standard `OrderItem` with `Product2` and portal fields for mapping.
|
||
|
||
We will build the BFF payload for WHMCS from these line records plus the Order header.
|
||
|
||
#### 3.2.3 Salesforce ↔ WHMCS Order Mapping
|
||
|
||
- Header mapping
|
||
- SF `Order.Id` → included in WHMCS `notes` as `sfOrderId=<Id>`
|
||
- SF `AccountId` → via portal mapping to `whmcsClientId` → `AddOrder.clientid`
|
||
- SF `Promo_Code__c` (if on header) → `AddOrder.promocode`
|
||
- SF `Activation_Status__c` controls operator flow; not sent to WHMCS
|
||
|
||
- Line mapping (per OrderItem)
|
||
- Product2 `WHMCS_Product_Id__c` → `AddOrder.pid[]`
|
||
- Derived billing cycle (Service=Monthly, Activation/Install=Onetime) → `AddOrder.billingcycle`
|
||
- SF `ConfigOptions_JSON__c` → `AddOrder.configoptions`
|
||
- Quantity → replicate product ID in `pid[]` or use config option/quantity if applicable
|
||
|
||
- After `AddOrder`:
|
||
- Call `AcceptOrder` to provision; capture `orderid` from response
|
||
- Update SF `WHMCS_Order_ID__c`; set `Activation_Status__c = Activated` on success
|
||
- On error, set `Activation_Status__c = Failed`
|
||
|
||
### 3.3 Flow (Provisioning Trigger)
|
||
|
||
- Record‑Triggered Flow publishes `OrderProvisionRequested__e` on Order approval.
|
||
|
||
### 3.4 UI
|
||
|
||
### 3.5 Catalog → Order → Provisioning Linkage (Clean Mapping)
|
||
|
||
- Single source of mapping truth: Product2 portal fields
|
||
- `WHMCS_Product_Id__c`, `Portal_ConfigOptions_JSON__c`, and `Provisioning_Flow__c` live on Product2.
|
||
- Do not duplicate these fields on `OrderItem`; each line references Product2 and price from PricebookEntry.
|
||
- Snapshot only what can change over time: `UnitPrice` and `Quantity` on the line.
|
||
|
||
- Order construction (by portal at checkout)
|
||
- Create `Order` header with `Activation_Status__c = Not Started`.
|
||
- For each cart item, create a line (either `OrderItem` with custom fields or `Order_Offering__c`) that includes:
|
||
- `Product2Id` and `PricebookEntryId`
|
||
- `Quantity`, `UnitPrice__c`
|
||
- Item type is inferred from SKU class (Service vs Activation/Install); no custom field needed.
|
||
- Optional overrides in `ConfigOptions_JSON__c` (e.g., size, add-ons) based on user selection
|
||
|
||
- Provisioning (triggered from Salesforce)
|
||
- BFF receives `sfOrderId`, loads `Order` and its lines.
|
||
- For each line, dereference Product2 to fetch `WHMCS_Product_Id__c` and default config options, then merge with any line-level overrides in `ConfigOptions_JSON__c`.
|
||
- Build `AddOrder` payload using the mapping above; place `sfOrderId` in WHMCS `notes`.
|
||
- After `AcceptOrder`, write back:
|
||
- Header: `WHMCS_Order_ID__c`
|
||
- Header: `Activation_Status__c = Activated` on success
|
||
|
||
- Subscriptions linkage
|
||
- The authoritative subscription record lives in WHMCS.
|
||
|
||
This keeps the mapping clean and centralized in Product2 portal fields, while Orders/OrderItems act as a snapshot of the customer’s selection and price at time of checkout.
|
||
|
||
## 3.5 Flow Sanity Check
|
||
|
||
1. Catalog comes from Salesforce Product2 (filtered/personalized by Account eligibility).
|
||
2. Customer signs up with SF Number; portal creates WHMCS client and mapping; address/profile managed in WHMCS.
|
||
3. Checkout creates an SF `Order` and child lines (no provisioning yet).
|
||
4. Operator approves in SF; Flow publishes Platform Event.
|
||
5. BFF subscriber enqueues job and provisions: recheck payment method (WHMCS), handle eSIM activation if needed, then `AddOrder` + `AcceptOrder` in WHMCS using mappings from Product2 portal fields referenced by the OrderItems.
|
||
6. BFF updates SF Order fields (`WHMCS_Order_ID__c`, etc.) and status; emails are sent as required.
|
||
7. Customer sees completed order; subscriptions/invoices appear from WHMCS data in the portal.
|
||
|
||
- LWC on `Order` to display provisioning status, errors, WHMCS IDs, and a Retry button.
|
||
|
||
## 4) Frontend (Portal)
|
||
|
||
- Signup page: add `sfNumber` field; validation and error messages for missing/invalid SF Number.
|
||
- Payment banner: dashboard shows CTA to add a payment method if none.
|
||
- Catalog: `/catalog` page using existing BFF endpoint.
|
||
- Product detail + Checkout:
|
||
- Checkout button disabled until `hasPaymentMethod=true` (via `GET /billing/payment-methods/summary`).
|
||
- On submit, call `POST /orders` and redirect to order status page with polling.
|
||
- Order status page: shows statuses (Not Started → Activating → Activated/Failed), with links to Subscriptions and Invoices.
|
||
|
||
### 4.1 eSIM Self-service Actions (Service Detail)
|
||
|
||
- Actions available on an active eSIM subscription:
|
||
- Reissue eSIM: triggers BFF endpoint to call activation provider for a new profile, updates WHMCS notes/custom fields, sends email to customer.
|
||
- Top-up: triggers BFF to call provider top-up API; invoice/charges handled via WHMCS (AddOrder for add-on or gateway charge depending on implementation), sends email confirmation.
|
||
- UI: buttons gated by subscription status; confirmations and progress states.
|
||
|
||
## 5) Security, Idempotency, Observability
|
||
|
||
- Secrets in env/KMS, HTTPS-only, strict timeouts and retries with backoff in BFF external calls.
|
||
- Signed Salesforce → BFF requests with short TTL; IP allowlisting of Salesforce egress ranges.
|
||
- Idempotency keys for order creation and provisioning; include `sfOrderId` marker in WHMCS order notes.
|
||
- Logging: use centralized logger "dino" only; redact sensitive values; no payment data.
|
||
- Metrics: activation latency, WHMCS API error rates, provisioning success/failure, retries; alerts on anomalies.
|
||
|
||
## 6) Data Storage (minimal in BFF)
|
||
|
||
- Orchestration record: `sfOrderId`, items/config, status, masked eSIM identifiers, WHMCS order/service IDs, timestamps, idempotency keys.
|
||
- Mappings: `userId ↔ whmcsClientId ↔ sfAccountId`.
|
||
- No PANs, CVVs, or gateway tokens stored.
|
||
|
||
## 7) Work Items
|
||
|
||
Prerequisites for WHMCS provisioning
|
||
|
||
- Each Salesforce Product2 used by the portal must map to a WHMCS Product (pid): set `Product2.WHMCS_Product_Id__c` accordingly for:
|
||
- Main service SKUs (Internet, SIM/eSIM, VPN)
|
||
- Installation/activation SKUs (Internet install variants, VPN activation)
|
||
- BFF uses `Product2.StockKeepingUnit` to select PricebookEntry and `Product2.WHMCS_Product_Id__c` to build the `pid[]` list for WHMCS AddOrder.
|
||
|
||
1. Auth: require `sfNumber` in `SignupDto` and signup flow; lookup SF Account by Customer Number; align WHMCS custom field.
|
||
2. Billing: add `GET /billing/payment-methods/summary` and frontend gating.
|
||
3. Catalog UI: `/catalog` + product details pages.
|
||
4. Orders API: implement `POST /orders`, `GET /orders/:sfOrderId`.
|
||
5. Salesforce: fields, Record‑Triggered Flow to publish `OrderProvisionRequested__e`; LWC for status.
|
||
6. WHMCS: add wrappers for `AddOrder`, `AcceptOrder`, `GetPayMethods` (if not already exposed).
|
||
7. Observability: correlation IDs, metrics, alerts; CDC or Platform Events for cache busting (optional).
|
||
8. Email: implement `EmailService` with provider; add BullMQ jobs for async sending; add templates for Signup, eSIM Activation, Activated.
|
||
9. eSIM Actions: implement `POST /subscriptions/:id/reissue-esim` and `POST /subscriptions/:id/topup` endpoints with BFF provider calls and WHMCS updates.
|
||
10. Future: Cancellations form → Salesforce Cancellations object submission (no immediate service cancel by customer).
|
||
|
||
## 8) Acceptance Criteria
|
||
|
||
- Signup requires Customer Number (SF Number) and links to the correct Salesforce Account and WHMCS client.
|
||
- Portal blocks checkout until a WHMCS payment method exists; SSO to WHMCS to add card.
|
||
- Orders are created in Salesforce and provisioned via BFF after operator trigger; idempotent and retriable.
|
||
- Customer sees clear order status and resulting subscriptions/invoices; sensitive details are not exposed.
|
||
|
||
## 9) WHMCS Field Mapping (Order Creation)
|
||
|
||
- `AddOrder` parameters to use:
|
||
- `clientid`: from user mapping
|
||
- `pid[]`: array of WHMCS product IDs (map from our catalog selection)
|
||
- `billingcycle`: `monthly` | `quarterly` | `semiannually` | `annually` | etc.
|
||
- `configoptions`: key/value for configurable options (from product detail form)
|
||
- `customfields`: include Customer Number (SF Number) and any order-specific data
|
||
- `paymentmethod`: WHMCS gateway system name (optional if default)
|
||
- `promocode`: if provided
|
||
- `notes`: include `sfOrderId=<Salesforce Order Id>` for idempotency tracing
|
||
- `noinvoice` / `noemail`: set to 0 to allow normal invoice + emails unless we handle emails ourselves
|
||
- After creation, call `AcceptOrder` to provision services and generate invoice/subscription as per WHMCS settings.
|
||
|
||
### 9.1 WHMCS Updates for eSIM Actions
|
||
|
||
- On Reissue:
|
||
- Update service custom fields (store masked new ICCID/EID if applicable), append to service notes with correlation ID and SF Order/Case references if any.
|
||
- Optionally create a zero-priced order for traceability or a billable add-on as business rules dictate.
|
||
- On Top-up:
|
||
- Create an add-on order or billable item/invoice through WHMCS; capture payment via existing payment method.
|
||
- Record top-up details in notes/custom fields.
|
||
|
||
## 10) Endpoint DTOs (Proposed)
|
||
|
||
- `POST /auth/signup`
|
||
- Request: `{ email, password, firstName, lastName, company?, phone?, sfNumber }`
|
||
- Response: `{ user, accessToken, refreshToken }`
|
||
|
||
- `GET /billing/payment-methods/summary`
|
||
- Response: `{ hasPaymentMethod: boolean }`
|
||
|
||
- `POST /orders`
|
||
- Request: `{ items: { productId: number; billingCycle: string; configOptions?: Record<string,string>; notes?: string }[]; promoCode?: string; notes?: string }`
|
||
- Response: `{ sfOrderId: string; status: 'Pending Review' }`
|
||
|
||
- `GET /orders/:sfOrderId`
|
||
- Response: `{ sfOrderId, status, whmcsOrderId?, whmcsServiceIds?: number[], lastUpdatedAt }`
|
||
|
||
// No SF → portal endpoint is required; provisioning is triggered via Platform Events.
|
||
|
||
- `POST /subscriptions/:id/reissue-esim`
|
||
- Request: `{ reason?: string }`
|
||
- Response: `{ status: 'InProgress' | 'Completed' | 'Failed', activationRef?, maskedIccid?, errorMessage? }`
|
||
|
||
- `POST /subscriptions/:id/topup`
|
||
- Request: `{ amount?: number; packageCode?: string }`
|
||
- Response: `{ status: 'Completed' | 'Failed', invoiceId?, errorMessage? }`
|
||
|
||
## 11) Email Requirements
|
||
|
||
- Transport: configurable (SMTP/SendGrid) via env; no secrets logged.
|
||
- Events & templates (to be provided):
|
||
- Signup Welcome (customer, CC support)
|
||
- eSIM Activation (customer, CC support)
|
||
- Order Provisioned (customer)
|
||
- Include correlation ID and minimal order/service context; no sensitive values.
|
||
|
||
### 11.1 Email Provider Recommendation
|
||
|
||
- Primary: SendGrid API (robust deliverability, templates, analytics). Use API key via env; send via BullMQ job for resiliency.
|
||
- Fallback: SMTP (e.g., SES SMTP or company SMTP relay) for environments without SendGrid.
|
||
- Rationale: SendGrid simplifies templating and CC/BCC handling; API-based sending reduces SMTP variability. Keep centralized logging without leaking PII.
|
||
|
||
## 12) Open Questions (to confirm)
|
||
|
||
1. Salesforce
|
||
- Confirm the Customer Number field API name on `Account` used for lookup.
|
||
- Confirm the exact custom field API names on `Order` (`Provisioning_Status__c`, etc.).
|
||
- Should `OpportunityId` be mandatory for Orders we create?
|
||
2. WHMCS
|
||
- Confirm the custom field id/name for Customer Number (currently used in mapping; assumed id 198).
|
||
- Provide product ID mapping for Home Internet/eSIM/VPN and their configurable options keys.
|
||
- Preferred default `paymentmethod` gateway system name.
|
||
3. Email
|
||
- Preferred provider (SMTP vs SendGrid) and from/reply-to addresses.
|
||
- Support CC distribution list for ops; any BCC requirements?
|
||
- Provide or approve email templates (copy + branding).
|
||
4. eSIM Activation API
|
||
- Endpoint(s), auth scheme, required payload, success/failed response shapes.
|
||
- Which identifiers to store/mask (ICCID, EID, MSISDN) and masking rules.
|
||
5. Provisioning Trigger
|
||
- Trigger via Flow on status change to Approved; optional manual retry publishes event again.
|
||
- Retry/backoff limits expected from SF side?
|
||
6. Cancellations
|
||
- Cancellation object API name in Salesforce; required fields; desired intake fields in portal form; who should be notified.
|