29 KiB
Portal – Data Model & Mappings
This document consolidates all required/used fields across Salesforce and WHMCS, plus how the portal consumes them.
Quick Reference: Required Fields Summary
Product2 (7 core + service-specific fields)
Core: SKU__c, Product2Categories1__c, Portal_Catalog__c, Portal_Accessible__c, Item_Class__c, Billing_Cycle__c, WH_Product_ID__c, WH_Product_Name__c
Internet: Internet_Plan_Tier__c, Internet_Offering_Type__c, Internet_Monthly_Price__c, Internet_Display_Order__c
SIM: SIM_Data_Size__c, SIM_Plan_Type__c, SIM_Has_Family_Discount__c
VPN: VPN_Display_Order__c
Order (6 core + service-specific independent fields)
Core: AccountId, EffectiveDate, Status, Pricebook2Id, Order_Type__c
Activation: Activation_Type__c, Activation_Scheduled_At__c, Activation_Status__c
Internet: Internet_Plan_Tier__c, Installation_Type__c, Weekend_Install__c, Access_Mode__c, Hikari_Denwa__c
VPN: VPN_Region__c
SIM: SIM_Type__c, EID__c, SIM_Voice_Mail__c, SIM_Call_Waiting__c + MNP fields
WHMCS: WHMCS_Order_ID__c
OrderItem (2 core + 2 integration fields)
Core: OrderId, PricebookEntryId, Quantity, UnitPrice
WHMCS: WHMCS_Service_ID__c, Billing_Cycle__c
Order with Add-ons Example
When a customer orders "Internet Gold + Hikari Denwa + Weekend Installation":
-- Order Header
Order_Type__c: "Internet"
Internet_Plan_Tier__c: "Gold"
Installation_Type__c: "Single"
Weekend_Install__c: true -- Synced from add-on OrderItem
-- OrderItems (5 separate items)
1. Internet Gold Service → SKU: "INTERNET-GOLD" → WH: 188 (monthly)
2. Internet Installation → SKU: "INTERNET-INSTALL-SINGLE" → WH: 242 (one-time)
3. Weekend Installation Fee → SKU: "INTERNET-INSTALL-WEEKEND" → WH: 245 (one-time ¥3000)
4. Hikari Denwa Service → SKU: "INTERNET-ADDON-HOME-PHONE" → WH: 246 (monthly ¥450)
5. Hikari Denwa Installation → SKU: "INTERNET-ADDON-DENWA-INSTALL" → WH: 247 (one-time)
Complete Product Structure Needed:
-- Main Services (Portal_Visible = true)
"Internet Gold Plan" → Item_Class: "Service" → Monthly billing
"Single Installation" → Item_Class: "Installation" → One-time billing
-- Add-on Services (Portal_Visible = false, shown as checkboxes)
"Hikari Denwa (Home Phone)" → Item_Class: "Add-on" → Monthly billing
"Weekend Installation" → Item_Class: "Add-on" → One-time billing
"Hikari Denwa Installation" → Item_Class: "Add-on" → One-time billing (auto-added when Denwa selected)
Key Points:
- 5 OrderItems total - each service/fee is separate
- Automatic dependencies - selecting Hikari Denwa auto-adds its installation fee
- Mixed billing cycles - services are monthly, installations are one-time
- Independent WHMCS products - each OrderItem maps to different WHMCS Product ID
Object inventory (what's standard vs custom)
-
Salesforce standard
Product2(catalog)Pricebook2/PricebookEntry(pricing)Order(header)OrderItem(line)Account(customer profile and eligibility)
-
WHMCS
- Use native User, Client, Order, Invoice, Product (Service). No custom tables.
Salesforce fields (by object)
Account (eligibility and mapping)
-
Eligibility (used for personalized Internet catalog)
Internet_Eligibility__c(Picklist)- Values (Label = API Name):
Home 1GHome 10GApartment 1GApartment 100M
- Default behavior: if the field is missing/blank/invalid, the portal treats eligibility as
Home 1G.
- Values (Label = API Name):
- Environment variable mapping (so code doesn’t hardcode field API names):
ELIGIBILITY_INTERNET_FIELD(default:Internet_Eligibility__c)
-
Mapping key
SF_Account_No__c(Text) used to link portal user ↔ Account (via WHMCS link/signup)
Product2 (clean field structure)
Core Fields (Required for all products)
StockKeepingUnit Text(255) -- Product identifier (standard Salesforce field)
Product2Categories1__c Picklist -- "Internet", "SIM", "VPN", "Other"
Portal_Catalog__c Checkbox -- Show in main catalog (GET /catalog)
Portal_Accessible__c Checkbox -- Can be used in orders/OrderItems
Item_Class__c Picklist -- "Service", "Installation", "Add-on", "Activation"
Billing_Cycle__c Picklist -- "Monthly", "Onetime"
WH_Product_ID__c Number(18,0) -- WHMCS Product ID (operator can change on OrderItem)
WH_Product_Name__c Text(255) -- WHMCS Product Name for reference
Internet Product Fields
Internet_Plan_Tier__c Picklist -- "Silver", "Gold", "Platinum"
Internet_Offering_Type__c Picklist -- "Home 1G", "Home 10G", "Apartment 1G", "Apartment 100M"
-- UI sorting (1, 2, 3)
Pricing (from PricebookEntry)
-- Pricing comes from PricebookEntry.UnitPrice where Pricebook2Id = '01sTL000008eLVlYAM' (Portal Price Book)
-- Portal Price Book ID is configurable via PORTAL_PRICEBOOK_ID environment variable
UnitPrice Currency -- Display price (¥4800, ¥4900, ¥5300)
SIM Product Fields
SIM_Data_Size__c Text(50) -- "5GB", "10GB", "25GB", "30GB", "50GB", "Voice-Only"
SIM_Plan_Type__c Picklist -- "DataOnly", "DataSmsVoice", "VoiceOnly" (only for Service items)
SIM_Has_Family_Discount__c Checkbox -- Family discount eligibility
Note: Display order is determined by data size, plan type, and offering type - no separate display order fields needed.
VPN Product Fields
-- UI sorting
Note: VPN type is typically "Remote Access" for all portal products, no separate field needed.
Add-on Products
Add-ons are separate products that customers can select alongside main services. They use the existing product structure with Item_Class__c = "Add-on", Portal_Catalog__c = false (hidden from catalog), and Portal_Accessible__c = true (can be ordered).
How Add-ons Work:
- Customer Selection: Optional add-ons appear as checkboxes (e.g., Hikari Denwa)
- Frontend Logic: Auto-add dependencies (e.g., Hikari Denwa adds installation fee)
- Salesforce Logic: Auto-detect conditions and add OrderItems (e.g., weekend installation dates)
- Order Creation: Each selected/detected add-on creates a separate OrderItem
- Provisioning: Each add-on provisions as separate WHMCS product
- Billing: Add-ons have their own pricing and billing cycles
Internet Add-ons:
- Weekend Installation: Salesforce auto-adds (¥3000) -
INTERNET-INSTALL-WEEKEND(when installation date is weekend) - Hikari Denwa Service: Customer checkbox (¥450/month) -
INTERNET-ADDON-HOME-PHONE - Hikari Denwa Installation: Frontend auto-adds (one-time) -
INTERNET-ADDON-DENWA-INSTALL
SIM Add-ons:
- Voice Mail: Monthly service -
SIM-ADDON-VOICE-MAIL - Call Waiting: Monthly service -
SIM-ADDON-CALL-WAITING - Unlimited Calling: Monthly service -
SIM-ADDON-UNLIMITED-CALLING
Product Structure Examples:
-- Main Service Plans (Portal_Catalog = true, Portal_Accessible = true)
"Internet Silver Plan" → SKU: "INTERNET-SILVER" → WH_Product_ID__c: 184
"Internet Gold Plan" → SKU: "INTERNET-GOLD" → WH_Product_ID__c: 188 (default, operator can change)
"Internet Platinum Plan" → SKU: "INTERNET-PLATINUM" → WH_Product_ID__c: 183 (default, operator can change)
-- Installation Options (Portal_Catalog = true, Portal_Accessible = true)
"Single Installation" → SKU: "INTERNET-INSTALL-SINGLE" → WH_Product_ID__c: 242
"12-Month Installation" → SKU: "INTERNET-INSTALL-12M" → WH_Product_ID__c: 243
"24-Month Installation" → SKU: "INTERNET-INSTALL-24M" → WH_Product_ID__c: 244
-- Add-on Services (Portal_Catalog = false, Portal_Accessible = true)
"Weekend Installation" → SKU: "INTERNET-INSTALL-WEEKEND" → WH_Product_ID__c: 245
"Hikari Denwa (Home Phone)" → SKU: "INTERNET-ADDON-HOME-PHONE" → WH_Product_ID__c: 246
"Hikari Denwa Installation" → SKU: "INTERNET-ADDON-DENWA-INSTALL" → WH_Product_ID__c: 247
-- Customer sees clear messaging:
Silver: Standard pricing, customer configures access mode
Gold: Premium pricing, operator reviews and may adjust configuration
Platinum: Premium pricing + additional fees, operator reviews and may adjust configuration
Order (clean field structure)
Core Fields (Required for all orders)
-- Salesforce Standard Fields
AccountId Lookup(Account) -- Customer account
EffectiveDate Date -- Order date
Status Picklist -- "Pending Review", "Approved", "Completed", "Cancelled"
Pricebook2Id Lookup(Pricebook2) -- Portal pricebook
OpportunityId Lookup(Opportunity) -- Optional, created by BFF
-- Order Classification
Order_Type__c Picklist -- "Internet", "SIM", "VPN", "Other"
Activation Fields (All order types)
Activation_Type__c Picklist -- "Immediate", "Scheduled"
Activation_Scheduled_At__c Datetime -- When Status = Scheduled
Activation_Status__c Picklist -- "Not Started", "Activating", "Activated", "Failed"
Internet Order Fields (Independent fields synced with OrderItems)
-- Customer/Operator Selections (Independent fields)
Internet_Plan_Tier__c Picklist -- "Silver", "Gold", "Platinum" (syncs with OrderItems)
Installation_Type__c Picklist -- "Single", "12-Month", "24-Month" (syncs with OrderItems)
Weekend_Install__c Checkbox -- Weekend installation add-on (syncs with OrderItems)
Access_Mode__c Picklist -- "IPoE-BYOR", "IPoE-HGW", "PPPoE" (operator configures)
-- Add-on Selections (Customer choices, syncs with OrderItems)
Hikari_Denwa__c Checkbox -- Customer selected Hikari Denwa service
VPN Order Fields (Customer selections)
-- Customer Selections
VPN_Region__c Picklist -- "USA-SF", "UK-London" (customer chooses region)
SIM Order Fields (Customer choices + MNP data)
-- SIM Configuration (plan type and data size come from selected Product2)
SIM_Type__c Picklist -- "eSIM", "Physical SIM" (customer choice)
EID__c Text(255) -- Required when SIM_Type__c = "eSIM"
-- Add-on Selections (Customer choices, syncs with OrderItems)
SIM_Voice_Mail__c Checkbox -- Customer selected Voice Mail add-on
SIM_Call_Waiting__c Checkbox -- Customer selected Call Waiting add-on
-- MNP/Porting (when MNP_Application__c = true)
MNP_Application__c Checkbox -- Customer wants to port number
MNP_Reservation_Number__c Text(10) -- 10 digits numeric
MNP_Expiry_Date__c Date -- MNP expiry date
MNP_Phone_Number__c Text(11) -- 11 digits, no hyphens
MVNO_Account_Number__c Text(255) -- Optional
Porting_LastName__c Text(255) -- Kanji/Alphabet
Porting_FirstName__c Text(255) -- Kanji/Alphabet
Porting_LastName_Katakana__c Text(255) -- Katakana
Porting_FirstName_Katakana__c Text(255) -- Katakana
Porting_Gender__c Picklist -- "Male", "Female", "Corporate/Other"
Porting_DateOfBirth__c Date -- YYYY/MM/DD
WHMCS Integration Fields
WHMCS_Order_ID__c Number(18,0) -- Set after provisioning
Billing/Shipping Snapshot (Set on create, not synced)
-- Billing Address
BillToContactId Lookup(Contact)
BillToStreet Text(255)
BillToCity Text(40)
BillToState Text(80)
BillToPostalCode Text(20)
BillToCountry Text(80)
-- Shipping Address
ShipToContactId Lookup(Contact)
ShipToStreet Text(255)
ShipToCity Text(40)
ShipToState Text(80)
ShipToPostalCode Text(20)
ShipToCountry Text(80)
OrderItem (clean field structure)
Core Fields (Required for all order items)
-- Salesforce Standard Fields
OrderId Lookup(Order) -- Parent order
PricebookEntryId Lookup(PricebookEntry) -- Product + pricing
Quantity Number(18,2) -- Usually 1
UnitPrice Currency -- Price at time of order
WHMCS Integration Fields
-- Provisioning
WHMCS_Service_ID__c Number(18,0) -- Set after provisioning
Billing_Cycle__c Picklist -- "Monthly", "Annually", "One-time"
Note: WH_Product_ID__c is stored on Product2, but operator can override it on OrderItem during review for Gold/Platinum plans.
Salesforce Setup Checklist
Custom Fields to Create
Product2 Object
-- Core Fields (All Products)
StockKeepingUnit Text(255) External ID, Unique (standard Salesforce field)
Product2Categories1__c Picklist Values: Internet, SIM, VPN, Other
Portal_Catalog__c Checkbox Default: false
Portal_Accessible__c Checkbox Default: true
Item_Class__c Picklist Values: Service, Installation, Add-on, Activation
WH_Product_ID__c Number(18,0)
-- Internet Fields
Internet_Plan_Tier__c Picklist Values: Silver, Gold, Platinum
Internet_Offering_Type__c Picklist Values: Home 1G, Home 10G, Apartment 1G, Apartment 100M
Internet_Monthly_Price__c Currency
-- SIM Fields
SIM_Data_Size__c Text(50)
SIM_Plan_Type__c Picklist Values: DataOnly, DataSmsVoice, VoiceOnly
SIM_Has_Family_Discount__c Checkbox Default: false
-- VPN Fields
Order Object
-- Core Fields
Order_Type__c Picklist Values: Internet, SIM, VPN, Other
-- Activation Fields
Activation_Type__c Picklist Values: Immediate, Scheduled
Activation_Scheduled_At__c Datetime
Activation_Status__c Picklist Values: Not Started, Activating, Activated, Failed
-- Internet Fields (Independent fields synced with OrderItems)
Internet_Plan_Tier__c Picklist Values: Silver, Gold, Platinum
Installation_Type__c Picklist Values: Single, 12-Month, 24-Month
Weekend_Install__c Checkbox Weekend installation add-on
Access_Mode__c Picklist Values: IPoE-BYOR, IPoE-HGW, PPPoE (operator sets)
-- VPN Fields (Independent fields)
VPN_Region__c Picklist Values: USA-SF, UK-London (customer chooses)
-- SIM Fields (Customer choices only - plan details come from Product2)
SIM_Type__c Picklist Values: eSIM, Physical SIM (customer chooses format)
EID__c Text(255) Required for eSIM activation
-- MNP Fields (when applicable)
MNP_Application__c Checkbox
MNP_Reservation_Number__c Text(10)
MNP_Expiry_Date__c Date
MNP_Phone_Number__c Text(11)
MVNO_Account_Number__c Text(255)
Porting_LastName__c Text(255)
Porting_FirstName__c Text(255)
Porting_LastName_Katakana__c Text(255)
Porting_FirstName_Katakana__c Text(255)
Porting_Gender__c Picklist Values: Male, Female, Corporate/Other
Porting_DateOfBirth__c Date
-- WHMCS Integration
WHMCS_Order_ID__c Number(18,0)
OrderItem Object
-- WHMCS Integration Fields
WHMCS_Service_ID__c Number(18,0) Set after provisioning
Billing_Cycle__c Picklist Values: Monthly, Annually, One-time
Account Object
-- Portal Integration Fields
Internet_Eligibility__c Picklist Values: Home 1G, Home 10G, Apartment 1G, Apartment 100M
SF_Account_No__c Text(255) External ID, Unique (Customer Number)
Salesforce Sync Flow: Order Fields ↔ OrderItems
Overview
Independent fields on Order are synced with OrderItems using Salesforce Flow. When operators change Order fields, Flow automatically adds/removes/updates OrderItems. When OrderItems change, Flow updates Order fields.
Weekend Installation Auto-Detection
// Trigger: After Insert, After Update on Order
// When: Installation_Scheduled_Date__c changes
Date installDate = order.Installation_Scheduled_Date__c;
String dayOfWeek = installDate.format('E'); // 'Sat' or 'Sun' for weekends
if (dayOfWeek == 'Sat' || dayOfWeek == 'Sun') {
// Add weekend installation fee if not exists
List<OrderItem> existing = [SELECT Id FROM OrderItem
WHERE OrderId = :order.Id
AND Product2.SKU__c = 'INTERNET-INSTALL-WEEKEND'];
if (existing.isEmpty()) {
Product2 product = [SELECT Id FROM Product2 WHERE SKU__c = 'INTERNET-INSTALL-WEEKEND'];
PricebookEntry pbe = [SELECT Id, UnitPrice FROM PricebookEntry
WHERE Product2Id = :product.Id AND Pricebook2.Name = 'Portal'];
INSERT new OrderItem(
OrderId = order.Id,
PricebookEntryId = pbe.Id,
Quantity = 1,
UnitPrice = pbe.UnitPrice
);
order.Weekend_Install__c = true;
UPDATE order;
}
} else {
// Remove weekend fee if date changed to weekday
DELETE [SELECT Id FROM OrderItem WHERE OrderId = :order.Id
AND Product2.SKU__c = 'INTERNET-INSTALL-WEEKEND'];
order.Weekend_Install__c = false;
UPDATE order;
}
Flow 1: Order Fields → OrderItems (When operator changes Order fields)
Internet Plan Tier Change
// Trigger: After Update on Order
// When: Internet_Plan_Tier__c changes
// 1. Remove old Internet service OrderItem
DELETE [SELECT Id FROM OrderItem
WHERE OrderId = :order.Id
AND Product2.Product2Categories1__c = 'Internet'
AND Product2.Item_Class__c = 'Service'];
// 2. Add new Internet service OrderItem
String newSku = 'INTERNET-' + order.Internet_Plan_Tier__c.toUpperCase();
Product2 newProduct = [SELECT Id FROM Product2 WHERE SKU__c = :newSku LIMIT 1];
PricebookEntry pbe = [SELECT Id, UnitPrice FROM PricebookEntry
WHERE Product2Id = :newProduct.Id AND Pricebook2.Name = 'Portal' LIMIT 1];
OrderItem newItem = new OrderItem(
OrderId = order.Id,
PricebookEntryId = pbe.Id,
Quantity = 1,
UnitPrice = pbe.UnitPrice
);
INSERT newItem;
Installation Type Change
// When: Installation_Type__c changes
// 1. Remove old installation OrderItem
DELETE [SELECT Id FROM OrderItem
WHERE OrderId = :order.Id
AND Product2.Product2Categories1__c = 'Internet'
AND Product2.Item_Class__c = 'Install'];
// 2. Add new installation OrderItem if not null
if (order.Installation_Type__c != null) {
String installSku = 'INTERNET-INSTALL-' +
(order.Installation_Type__c == 'Single' ? 'SINGLE' :
order.Installation_Type__c == '12-Month' ? '12M' : '24M');
// Create new installation OrderItem with installSku
}
Weekend Install Toggle
// When: Weekend_Install__c changes
if (order.Weekend_Install__c == true && oldOrder.Weekend_Install__c == false) {
// Add weekend installation OrderItem
// SKU: 'INTERNET-INSTALL-WEEKEND'
} else if (order.Weekend_Install__c == false && oldOrder.Weekend_Install__c == true) {
// Remove weekend installation OrderItem
DELETE [SELECT Id FROM OrderItem
WHERE OrderId = :order.Id
AND Product2.SKU__c = 'INTERNET-INSTALL-WEEKEND'];
}
Add-on Field Changes
// When: Hikari_Denwa__c changes
if (order.Hikari_Denwa__c == true && oldOrder.Hikari_Denwa__c == false) {
// Add Hikari Denwa service and installation OrderItems
INSERT new OrderItem(Product2.SKU__c = 'INTERNET-ADDON-HOME-PHONE');
INSERT new OrderItem(Product2.SKU__c = 'INTERNET-ADDON-DENWA-INSTALL');
} else if (order.Hikari_Denwa__c == false && oldOrder.Hikari_Denwa__c == true) {
// Remove Hikari Denwa OrderItems
DELETE [SELECT Id FROM OrderItem WHERE OrderId = :order.Id
AND Product2.SKU__c IN ('INTERNET-ADDON-HOME-PHONE', 'INTERNET-ADDON-DENWA-INSTALL')];
}
// When: SIM add-on fields change
if (order.SIM_Voice_Mail__c != oldOrder.SIM_Voice_Mail__c) {
if (order.SIM_Voice_Mail__c) {
INSERT new OrderItem(Product2.SKU__c = 'SIM-ADDON-VOICE-MAIL');
} else {
DELETE [SELECT Id FROM OrderItem WHERE OrderId = :order.Id
AND Product2.SKU__c = 'SIM-ADDON-VOICE-MAIL'];
}
}
// Similar logic for SIM_Call_Waiting__c
Flow 2: OrderItems → Order Fields (When OrderItems change)
Sync Order Fields from OrderItems
// Trigger: After Insert, After Update, After Delete on OrderItem
// Purpose: Keep Order fields in sync with OrderItems
// Get all OrderItems for this Order
List<OrderItem> items = [SELECT Product2.Internet_Plan_Tier__c, Product2.SKU__c,
Product2.Item_Class__c, Product2.Product2Categories1__c
FROM OrderItem WHERE OrderId = :orderId];
Order orderToUpdate = new Order(Id = orderId);
// Sync Internet fields
for (OrderItem item : items) {
if (item.Product2.Product2Categories1__c == 'Internet' && item.Product2.Item_Class__c == 'Service') {
orderToUpdate.Internet_Plan_Tier__c = item.Product2.Internet_Plan_Tier__c;
}
if (item.Product2.Product2Categories1__c == 'Internet' && item.Product2.Item_Class__c == 'Installation') {
if (item.Product2.SKU__c.contains('SINGLE')) orderToUpdate.Installation_Type__c = 'Single';
else if (item.Product2.SKU__c.contains('12M')) orderToUpdate.Installation_Type__c = '12-Month';
else if (item.Product2.SKU__c.contains('24M')) orderToUpdate.Installation_Type__c = '24-Month';
}
if (item.Product2.SKU__c == 'INTERNET-INSTALL-WEEKEND') {
orderToUpdate.Weekend_Install__c = true;
}
if (item.Product2.SKU__c == 'INTERNET-ADDON-HOME-PHONE') {
orderToUpdate.Hikari_Denwa__c = true;
}
// SIM add-on sync
if (item.Product2.SKU__c == 'SIM-ADDON-VOICE-MAIL') {
orderToUpdate.SIM_Voice_Mail__c = true;
}
if (item.Product2.SKU__c == 'SIM-ADDON-CALL-WAITING') {
orderToUpdate.SIM_Call_Waiting__c = true;
}
// VPN fields: Only VPN_Region__c is stored on Order (customer selection)
}
// Set defaults if no items found
if (noInternetService) orderToUpdate.Internet_Plan_Tier__c = null;
if (noInstallation) orderToUpdate.Installation_Type__c = null;
if (noWeekendInstall) orderToUpdate.Weekend_Install__c = false;
if (noHikariDenwa) orderToUpdate.Hikari_Denwa__c = false;
if (noSIMVoiceMail) orderToUpdate.SIM_Voice_Mail__c = false;
if (noSIMCallWaiting) orderToUpdate.SIM_Call_Waiting__c = false;
UPDATE orderToUpdate;
WHMCS fields/IDs used
-
Users & Clients (created/linked at signup)
- User:
firstname,lastname,email,password - Client:
firstname,lastname,email, optionalphonenumber,companyname - Address:
address1,address2,city,state,postcode,country - Custom field:
CustomerNumber(maps to Salesforce AccountSF_Account_No__c) - Link: User ↔ Client recorded in portal mapping table
- User:
-
Invoices & PayMethods
- GetInvoices (by
clientid) surfaced in portal - GetPayMethods used to gate checkout (must have a method on file)
- SSO links used to open invoice/payment-methods UI in WHMCS
- GetInvoices (by
-
Client linking in portal
- Portal mapping stores:
userId,whmcsClientId,sfAccountId
- Portal mapping stores:
-
Product IDs (pid) used in AddOrder:
- Internet (by dwelling/speed): Home 1G SILV=181, GOLD=182, PLAT=183; APT 1G SILV=184, GOLD=185, PLAT=186; APT 100M SILV=187, GOLD=188, PLAT=189
- Installation: Single=242, 12M=243, 24M=244
- VPN: USA=33, UK=54, Activation=37
- SIM/eSIM: see mapping table above (e.g., Data-only 5GB=97, Data+Voice 10GB=216, Voice-only=142)
AddOrder request fields (reference)
clientid(Number) – required – resolved fromOrder.AccountIdvia portal mapping to WHMCS clientpid[](Array) – required – service and install Product2 →WH_Product_ID__cbillingcycle(derived) – sent to WHMCS based on the SKU type (Onetime for activation/install SKUs; Monthly for service SKUs)promocode(Text) – optionalnotes(Text) – should includesfOrderId=<Salesforce Order Id>(templated viaProduct2.WHMCS_Notes_Template__c)noinvoice(Boolean) – optionalnoemail(Boolean) – optional
Catalog requirements
- Pricebook: create a
Portalprice book; ensure activePricebookEntryfor each visible Product2 - API dependencies:
GET /catalogqueriesProduct2fields: Id, Name, SKU__c, Product2Categories1__c, Portal_Catalog__c, Portal_Accessible__c - Personalized catalog:
GET /catalog/personalized(planned)- Filters by consolidated offering: include Product2 where
Portal_Internet_Offering_Type__cequalsAccount.Internet_Eligibility__c(fallback to Home 1G when Account field missing/invalid)
- Filters by consolidated offering: include Product2 where
Enablement & permissions (Salesforce)
- Enable Products and Price Books in the org (Setup → Product Settings)
- Integration user (Named Credential/Connected App user) minimum permissions:
- Objects (Read):
Product2,Pricebook2,PricebookEntry,Order,OrderItem,Account - Fields (Readable):
Product2.SKU__c,Product2.Portal_Catalog__c,Product2.Portal_Accessible__c,Product2.Product2Categories1__c- Optional display:
Product2.Portal_Description__c,Product2.Portal_Feature_Bullets__c,Product2.Portal_Hero_Image_URL__c,Product2.Portal_Tags__c,Product2.Portal_Sort_Order__c,Product2.Portal_Valid_From__c,Product2.Portal_Valid_Until__c - Optional eligibility:
Product2.Portal_Eligibility_Dwelling__c,Product2.Portal_Eligibility_Speed__c,Product2.Portal_Eligibility_Region__c
- Account eligibility fields per env: dwelling/speed
- Order custom fields listed above (Type/Activation/Internet/SIM/MNP)
- OrderItem custom fields:
ConfigOptions_JSON__c
- Objects (Read):
Portal field mapping reference (source-of-truth → target)
Activation (Portal → Salesforce)
activationType(Immediate | Scheduled) →Order.Activation_Type__cactivationScheduledAt(Datetime) →Order.Activation_Scheduled_At__c
Address (Portal → WHMCS/Order snapshot)
street→WHMCS.Client.address1;Order.BillToStreetaddressLine2→WHMCS.Client.address2city→WHMCS.Client.city;Order.BillToCitystate→WHMCS.Client.state;Order.BillToStatepostalCode→WHMCS.Client.postcode;Order.BillToPostalCodecountry(ISO 2) →WHMCS.Client.country;Order.BillToCountry
Checkout (Portal → Salesforce/WHMCS)
billingCycle(UI concept only) → derived server-side from SKU class; WHMCSbillingcycleproductSKU(Text) →Product2.SKU__c(PBE lookup)promoCode(Text) → WHMCSpromocodequantity(Number) →OrderItem.Quantity(validated againstProduct2.Portal_Max_Quantity__c)
Internet (Portal → Salesforce)
accessMode(IPoE‑HGW | IPoE‑BYOR | PPPoE) →Order.Access_Mode__cinstallmentPlan(One-time | 12-Month | 24-Month) →Order.Installment_Plan__cplanTier(Platinum | Gold | Silver) →Order.Internet_Plan_Tier__c(derived from SKU)serviceSpeed(Text) →Order.Service_Speed__cweekendInstall(Checkbox) →Order.Weekend_Install__cinternetOffering(Picklist) →Order.Internet_Offering_Type__c(defaults from Account when not provided)- Also set from product on selection:
Order.Internet_Offering_Type__c = Product2.Portal_Internet_Offering_Type__c
- Also set from product on selection:
VPN (Portal → Salesforce)
vpnRegion(Picklist) →Order.VPN_Region__c- (optional)
vpnType(Picklist) →Order.VPN_Type__c
SIM / eSIM (Portal → Salesforce)
simType(eSIM | Physical SIM) →Order.SIM_Type__ceid(Text) →Order.EID__c(required whenSIM_Type__c = eSIM)- Porting (all optional unless flow requires):
mnpApplication→Order.MNP_Application__cmnpReservationNumber→Order.MNP_Reservation_Number__cmnpExpiryDate→Order.MNP_Expiry_Date__cmnpPhoneNumber→Order.MNP_Phone_Number__cmvnoAccountNumber→Order.MVNO_Account_Number__cportingDob→Order.Porting_DateOfBirth__cportingFirstNameKanji→Order.Porting_FirstName_Kanji__cportingLastNameKanji→Order.Porting_LastName_Kanji__cportingFirstNameKatakana→Order.Porting_FirstName_Katakana__cportingLastNameKatakana→Order.Porting_LastName_Katakana__cportingGender(Male | Female | Corporate/Other) →Order.Porting_Gender__c
Signup (Portal → WHMCS; plus SF mapping)
email,firstName,lastName,password→ WHMCS User + Clientcompany→WHMCS.Client.companyname(optional)phone→WHMCS.Client.phonenumber(optional)customerNumber(Salesforce Account number) →WHMCS.Client.customfields.CustomerNumber→ BFF links to SalesforceAccount.SF_Account_No__c
Notes
- BFF resolves pricing by
Product2.SKU__c→PricebookEntryand provisioning byProduct2.WH_Product_ID__c→ WHMCSpid[] - Use
SIMas the sole Product2 category for both eSIM and Physical SIM;Order_Type__cretains SIM vs eSIM - All Product2 visible in portal must have
SKU__c,Portal_Catalog__c = true, and aPricebookEntry