236 lines
8.8 KiB
Markdown
236 lines
8.8 KiB
Markdown
|
|
# Portal – Data Model & Mappings
|
|||
|
|
|
|||
|
|
This document lists the objects, custom fields, and mappings used across Salesforce, WHMCS, and the Portal BFF.
|
|||
|
|
|
|||
|
|
## Object inventory (what's standard vs custom)
|
|||
|
|
|
|||
|
|
- Salesforce standard objects
|
|||
|
|
- `Product2` (catalog)
|
|||
|
|
- `Pricebook2` / `PricebookEntry` (pricing)
|
|||
|
|
- `Order` (header)
|
|||
|
|
- `OrderItem` (line)
|
|||
|
|
|
|||
|
|
- Salesforce custom fields
|
|||
|
|
- Added on `Product2`, `Order`, and `OrderItem` only (listed below with proposed API names).
|
|||
|
|
|
|||
|
|
- WHMCS
|
|||
|
|
- Use native User (login identity), Client (billing profile), Order, Invoice, and Service (Product/Service) entities and API parameters. We do not create custom tables in WHMCS.
|
|||
|
|
|
|||
|
|
## Salesforce
|
|||
|
|
|
|||
|
|
### Product2 (catalog source of truth)
|
|||
|
|
|
|||
|
|
- Visibility & display
|
|||
|
|
- `Portal_Visible__c` (Checkbox)
|
|||
|
|
- `Portal_Category__c` (Picklist: Internet | eSIM | 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_Valid_From__c` (Date)
|
|||
|
|
- `Portal_Valid_Until__c` (Date)
|
|||
|
|
|
|||
|
|
- Eligibility (Internet)
|
|||
|
|
- `Portal_Eligibility_Dwelling__c` (Picklist: Home | Apartment | Any)
|
|||
|
|
- `Portal_Eligibility_Tier__c` (Picklist: 1G | 100Mb | Any)
|
|||
|
|
- `Portal_Eligibility_Region__c` (Text)
|
|||
|
|
|
|||
|
|
- Terms & options
|
|||
|
|
- `Portal_Billing_Cycle__c` (Picklist)
|
|||
|
|
- `Portal_Max_Quantity__c` (Number)
|
|||
|
|
- `Portal_Requires_Payment_Method__c` (Checkbox)
|
|||
|
|
- (Avoid using configurable options for pricing; see Replica Product Strategy below)
|
|||
|
|
|
|||
|
|
- WHMCS mapping
|
|||
|
|
- `WHMCS_Product_Id__c` (Number)
|
|||
|
|
- `WHMCS_Notes_Template__c` (Long Text)
|
|||
|
|
- `eSIM_Settings_JSON__c` (Long Text)
|
|||
|
|
|
|||
|
|
### PricebookEntry
|
|||
|
|
|
|||
|
|
- Use a dedicated “Portal” pricebook; ensure entries exist for all visible Product2 records
|
|||
|
|
|
|||
|
|
### Order (header)
|
|||
|
|
|
|||
|
|
- Required
|
|||
|
|
- `AccountId`
|
|||
|
|
- `EffectiveDate`
|
|||
|
|
- `Status` (Pending Review)
|
|||
|
|
- `Order_Type__c` (Picklist: Internet | eSIM | SIM | VPN | Other)
|
|||
|
|
|
|||
|
|
- Billing/Shipping snapshot (set on create; no ongoing sync)
|
|||
|
|
- `BillToContactId` (Lookup Contact)
|
|||
|
|
- `BillToStreet`
|
|||
|
|
- `BillToCity`
|
|||
|
|
- `BillToState`
|
|||
|
|
- `BillToPostalCode`
|
|||
|
|
- `BillToCountry`
|
|||
|
|
- `ShipToContactId` (Lookup Contact)
|
|||
|
|
- `ShipToStreet`
|
|||
|
|
- `ShipToCity`
|
|||
|
|
- `ShipToState`
|
|||
|
|
- `ShipToPostalCode`
|
|||
|
|
- `ShipToCountry`
|
|||
|
|
|
|||
|
|
- Service configuration (since one Order = one service)
|
|||
|
|
- Source category → `Order_Type__c` is auto-set from `Product2.Portal_Category__c` of the main service SKU at checkout.
|
|||
|
|
- eSIM/SIM
|
|||
|
|
- `SIM_Type__c` (Picklist: Physical SIM | eSIM)
|
|||
|
|
- `EID__c` (Text; masked; required when SIM_Type\_\_c = eSIM)
|
|||
|
|
- MNP (port-in)
|
|||
|
|
- `MNP_Application__c` (Checkbox)
|
|||
|
|
- `MNP_Reservation_Number__c` (Text, 10)
|
|||
|
|
- `MNP_Expiry_Date__c` (Date)
|
|||
|
|
- `MNP_Phone_Number__c` (Text, 11)
|
|||
|
|
- `Porting_LastName_Kanji__c` (Text)
|
|||
|
|
- `Porting_FirstName_Kanji__c` (Text)
|
|||
|
|
- `Porting_LastName_Katakana__c` (Text)
|
|||
|
|
- `Porting_FirstName_Katakana__c` (Text)
|
|||
|
|
- `Porting_Gender__c` (Picklist: Male | Female | Corporate/Other)
|
|||
|
|
- `Porting_DateOfBirth__c` (Date)
|
|||
|
|
- `MVNO_Account_Number__c` (Text)
|
|||
|
|
- Internet (service line config)
|
|||
|
|
- `Internet_Plan_Tier__c` (Picklist: Platinum_Gold | Silver)
|
|||
|
|
- `Access_Mode__c` (Picklist: IPoE‑HGW | IPoE‑BYOR | PPPoE)
|
|||
|
|
- `Service_Speed__c` (Text, e.g., "1Gbps")
|
|||
|
|
- Installation (separate line derived from these)
|
|||
|
|
- `Installment_Plan__c` (Picklist: One‑time | 12‑Month | 24‑Month)
|
|||
|
|
- `Installment_Months__c` (Number: 0 | 12 | 24)
|
|||
|
|
- `Weekend_Install__c` (Checkbox)
|
|||
|
|
|
|||
|
|
- Provisioning & results
|
|||
|
|
- `Activation_Status__c` (Not Started | Activating | Activated | Failed)
|
|||
|
|
- `Activation_Type__c` (Picklist: Immediate | Scheduled)
|
|||
|
|
- `Activation_Scheduled_At__c` (Date/Time; required when Activation_Type\_\_c = Scheduled)
|
|||
|
|
- `Activation_Error_Code__c` (Text)
|
|||
|
|
- `Activation_Error_Message__c` (Text)
|
|||
|
|
- `WHMCS_Order_ID__c` (Text/Number)
|
|||
|
|
- `Last_Activation_At__c` (Datetime)
|
|||
|
|
- `Activation_Attempt_Count__c` (Number)
|
|||
|
|
|
|||
|
|
### OrderItem (line)
|
|||
|
|
|
|||
|
|
- Standard
|
|||
|
|
- `OrderId`
|
|||
|
|
- `Product2Id`
|
|||
|
|
- `PricebookEntryId`
|
|||
|
|
- `Quantity`
|
|||
|
|
- `UnitPrice`
|
|||
|
|
|
|||
|
|
- Custom
|
|||
|
|
- `Billing_Cycle__c` (Picklist)
|
|||
|
|
- `ConfigOptions_JSON__c` (Long Text) (optional; not used for pricing)
|
|||
|
|
- `Item_Type__c` (Picklist: Service | Installation | Add‑on)
|
|||
|
|
|
|||
|
|
Notes
|
|||
|
|
|
|||
|
|
- Since one Order represents one service, all service configuration fields live on the Order header. OrderItems are generated from the header:
|
|||
|
|
- Item_Type = Service: Product2 = main service SKU; Billing_Cycle\_\_c typically Monthly.
|
|||
|
|
- Item_Type = Installation: Product2 = installation SKU selected from `Installment_Plan__c`/`Weekend_Install__c`; Billing_Cycle\_\_c = Onetime or Monthly (for installments).
|
|||
|
|
- Item_Type = Add‑on (e.g., Hikari Denwa): separate OrderItem with its own Product2.
|
|||
|
|
|
|||
|
|
## WHMCS
|
|||
|
|
|
|||
|
|
### Users & Clients (created on signup)
|
|||
|
|
|
|||
|
|
- Create WHMCS User (User-level identity and login)
|
|||
|
|
- `firstname` ← portal signup `firstName`
|
|||
|
|
- `lastname` ← portal signup `lastName`
|
|||
|
|
- `email` ← portal signup `email`
|
|||
|
|
- `password` ← portal signup `password`
|
|||
|
|
|
|||
|
|
- Create WHMCS Client (billing profile)
|
|||
|
|
- `firstname` ← portal signup `firstName`
|
|||
|
|
- `lastname` ← portal signup `lastName`
|
|||
|
|
- `email` ← portal signup `email`
|
|||
|
|
- `phonenumber?` ← portal signup `phone?`
|
|||
|
|
- `companyname?` ← portal signup `company?`
|
|||
|
|
|
|||
|
|
- Link User ↔ Client
|
|||
|
|
- `user_id` ← created User id
|
|||
|
|
- `client_id` ← created Client id
|
|||
|
|
|
|||
|
|
- Set Client address
|
|||
|
|
- `address1` ← portal address `street`
|
|||
|
|
- `address2` ← portal address `addressLine2`
|
|||
|
|
- `city` ← portal address `city`
|
|||
|
|
- `state` ← portal address `state`
|
|||
|
|
- `postcode` ← portal address `postalCode`
|
|||
|
|
- `country` (ISO 2-letter) ← portal address `country`
|
|||
|
|
|
|||
|
|
- Set Client custom field
|
|||
|
|
- `CustomerNumber` (id/name to confirm) ← Salesforce Account Customer Number (provided via SF Number)
|
|||
|
|
|
|||
|
|
- Payment methods
|
|||
|
|
- Managed in WHMCS UI; portal uses SSO and checks via `GetPayMethods`; no PAN stored in portal
|
|||
|
|
|
|||
|
|
### Orders & provisioning
|
|||
|
|
|
|||
|
|
- Replica Product Strategy (preferred)
|
|||
|
|
- Each sellable SKU is its own Product2 and WHMCS product (e.g., Internet Platinum vs Silver, IPoE‑HGW vs BYOR, Installment plan variants, Hikari Denwa, etc.).
|
|||
|
|
- Pricing and terms come from the chosen product; we avoid config option–based pricing.
|
|||
|
|
|
|||
|
|
- AddOrder (parameters used)
|
|||
|
|
- `clientid` ← portal mapping `sfAccountId` → `whmcsClientId`
|
|||
|
|
- `pid[]` ← for each OrderItem (Service/Installation/Add‑on) `Product2.WHMCS_Product_Id__c`
|
|||
|
|
- `billingcycle` ← OrderItem `Billing_Cycle__c`
|
|||
|
|
- `promocode?` ← Salesforce `Order.Promo_Code__c` or line-level
|
|||
|
|
- `notes` ← include `sfOrderId=<Salesforce Order Id>`
|
|||
|
|
- `noinvoice?` ← typically `0`
|
|||
|
|
- `noemail?` ← typically `0`
|
|||
|
|
- (Gateway) We do not pass `paymentmethod`; WHMCS uses the client's default gateway/payment method on file.
|
|||
|
|
|
|||
|
|
- AcceptOrder (no body fields; runs against created order)
|
|||
|
|
|
|||
|
|
- Results → Salesforce
|
|||
|
|
- `orderid` → `Order.WHMCS_Order_ID__c`
|
|||
|
|
|
|||
|
|
### Invoices & pay methods
|
|||
|
|
|
|||
|
|
- GetInvoices (surface in portal)
|
|||
|
|
- `clientid` ← portal mapping `whmcsClientId`
|
|||
|
|
- filters as needed (date/status)
|
|||
|
|
|
|||
|
|
- GetPayMethods (gate checkout)
|
|||
|
|
- `clientid` ← portal mapping `whmcsClientId`
|
|||
|
|
|
|||
|
|
- SSO links (open WHMCS UI)
|
|||
|
|
- invoice view/pay/download, payment methods screen
|
|||
|
|
|
|||
|
|
## Portal BFF
|
|||
|
|
|
|||
|
|
- Mappings table
|
|||
|
|
- `userId`, `whmcsClientId`, `sfAccountId`, timestamps
|
|||
|
|
|
|||
|
|
- Orchestration record (internal)
|
|||
|
|
- `sfOrderId`, `status`, `items/config`, `whmcsOrderId?`, `whmcsServiceIds?`, idempotency keys, timestamps
|
|||
|
|
|
|||
|
|
## Mappings Summary
|
|||
|
|
|
|||
|
|
- Order header → WHMCS
|
|||
|
|
- `sfOrderId` goes into WHMCS `notes` for idempotency tracing
|
|||
|
|
- `AccountId` resolves to `clientid` via mapping table
|
|||
|
|
|
|||
|
|
- OrderItem line → WHMCS
|
|||
|
|
- `Product2.WHMCS_Product_Id__c` → `pid[]`
|
|||
|
|
- `OrderItem.Billing_Cycle__c` → `billingcycle`
|
|||
|
|
- Identity/porting fields (EID, MNP, MVNO, etc.) live on Order and are used only for activation API, not stored in WHMCS
|
|||
|
|
- Price mapping: Product2 encodes plan tier/access mode/apt type in the SKU; we select the corresponding `PricebookEntry` in the Portal pricebook.
|
|||
|
|
|
|||
|
|
- Post-provisioning write-back
|
|||
|
|
- `WHMCS_Order_ID__c` on Order; `WHMCS_Service_ID__c` on each OrderItem
|
|||
|
|
|
|||
|
|
## Business Rules (data implications)
|
|||
|
|
|
|||
|
|
- Home Internet address
|
|||
|
|
- Billing address equals service address; no separate service address fields in portal.
|
|||
|
|
- Snapshot billing to Order BillTo\* at checkout; do not sync ongoing changes to Salesforce.
|
|||
|
|
|
|||
|
|
- Single Internet per account
|
|||
|
|
- Enforced in BFF: before creating an Order with Internet Product2, check WHMCS `GetClientsProducts` for existing Internet services (active/pending/suspended).
|
|||
|
|
- Optional SF guardrail: validation/Flow prevents OrderItem with Internet Product2 when account already has an Internet service (based on WHMCS write-backs or nightly sync).
|
|||
|
|
|
|||
|
|
- One fulfillment type per Order
|
|||
|
|
- BFF groups cart items by fulfillment type and creates separate Orders (e.g., one for eSIM, one for Home Internet) so Order-level activation fields remain consistent.
|