# Salesforce ↔ WHMCS Mapping Reference

_Complete field mapping and data transformation reference for order fulfillment workflow._

## 🗺️ Overview

This document provides the authoritative mapping between Salesforce Order/OrderItem data and WHMCS API parameters for the order fulfillment process.

### Data Flow

```
Salesforce Order/OrderItems → BFF Transformation → WHMCS AddOrder API → WHMCS Services
```

## 📊 Complete Field Mapping

### Order Header Mapping

| Salesforce Field  | WHMCS Parameter | Example Value                    | Type   | Notes                                    |
| ----------------- | --------------- | -------------------------------- | ------ | ---------------------------------------- |
| `Order.AccountId` | `clientid`      | `1`                              | int    | Resolved via portal mapping table        |
| N/A (System)      | `paymentmethod` | `"mailin"`                       | string | **Required by WHMCS API**                |
| N/A (System)      | `noinvoice`     | `true`                           | bool   | Don't create invoice during provisioning |
| N/A (System)      | `noemail`       | `true`                           | bool   | Don't send emails during provisioning    |
| `Order.Id`        | Added to notes  | `"sfOrderId=8014x000000ABCDXYZ"` | string | For tracking purposes                    |

### OrderItem Array Mapping

| Salesforce Source           | WHMCS Parameter  | Example                             | Type     | Transformation           |
| --------------------------- | ---------------- | ----------------------------------- | -------- | ------------------------ |
| `Product2.WH_Product_ID__c` | `pid[]`          | `["185", "242", "246"]`             | string[] | Convert number to string |
| `Product2.Billing_Cycle__c` | `billingcycle[]` | `["monthly", "onetime", "monthly"]` | string[] | Lowercase transformation |
| `OrderItem.Quantity`        | `qty[]`          | `[1, 1, 1]`                         | int[]    | Direct mapping           |

### Optional Parameters

| Salesforce Source | WHMCS Parameter   | Default Value  | Notes                    |
| ----------------- | ----------------- | -------------- | ------------------------ |
| N/A               | `promocode`       | `""`           | Not used in provisioning |
| N/A               | `configoptions[]` | `["", "", ""]` | Base64 encoded if needed |
| N/A               | `customfields[]`  | `["", "", ""]` | Base64 encoded if needed |

## 🏷️ Product Mapping Examples

### Internet Products

| Product Name                     | Salesforce SKU              | WH_Product_ID\_\_c | WHMCS pid | Billing_Cycle\_\_c | WHMCS billingcycle |
| -------------------------------- | --------------------------- | ------------------ | --------- | ------------------ | ------------------ |
| Internet Silver (Home 1G)        | `INTERNET-SILVER-HOME-1G`   | 181                | "181"     | "Monthly"          | "monthly"          |
| Internet Gold (Home 1G)          | `INTERNET-GOLD-HOME-1G`     | 182                | "182"     | "Monthly"          | "monthly"          |
| Internet Platinum (Home 1G)      | `INTERNET-PLATINUM-HOME-1G` | 183                | "183"     | "Monthly"          | "monthly"          |
| Internet Silver (Apartment 1G)   | `INTERNET-SILVER-APT-1G`    | 184                | "184"     | "Monthly"          | "monthly"          |
| Internet Gold (Apartment 1G)     | `INTERNET-GOLD-APT-1G`      | 185                | "185"     | "Monthly"          | "monthly"          |
| Internet Platinum (Apartment 1G) | `INTERNET-PLATINUM-APT-1G`  | 186                | "186"     | "Monthly"          | "monthly"          |

### Installation Products

| Product Name             | Salesforce SKU             | WH_Product_ID\_\_c | WHMCS pid | Billing_Cycle\_\_c | WHMCS billingcycle |
| ------------------------ | -------------------------- | ------------------ | --------- | ------------------ | ------------------ |
| Single Installation      | `INTERNET-INSTALL-SINGLE`  | 242                | "242"     | "One-time"         | "onetime"          |
| 12-Month Installation    | `INTERNET-INSTALL-12M`     | 243                | "243"     | "One-time"         | "onetime"          |
| 24-Month Installation    | `INTERNET-INSTALL-24M`     | 244                | "244"     | "One-time"         | "onetime"          |
| Weekend Installation Fee | `INTERNET-INSTALL-WEEKEND` | 245                | "245"     | "One-time"         | "onetime"          |

### Add-on Products

| Product Name              | Salesforce SKU                 | WH_Product_ID\_\_c | WHMCS pid | Billing_Cycle\_\_c | WHMCS billingcycle |
| ------------------------- | ------------------------------ | ------------------ | --------- | ------------------ | ------------------ |
| Hikari Denwa Service      | `INTERNET-ADDON-HOME-PHONE`    | 246                | "246"     | "Monthly"          | "monthly"          |
| Hikari Denwa Installation | `INTERNET-ADDON-DENWA-INSTALL` | 247                | "247"     | "One-time"         | "onetime"          |

### VPN Products

| Product Name            | Salesforce SKU   | WH_Product_ID\_\_c | WHMCS pid | Billing_Cycle\_\_c | WHMCS billingcycle |
| ----------------------- | ---------------- | ------------------ | --------- | ------------------ | ------------------ |
| VPN USA (San Francisco) | `VPN-USA-SF`     | 33                 | "33"      | "Monthly"          | "monthly"          |
| VPN UK (London)         | `VPN-UK-LONDON`  | 54                 | "54"      | "Monthly"          | "monthly"          |
| VPN Activation Fee      | `VPN-ACTIVATION` | 37                 | "37"      | "One-time"         | "onetime"          |

## 📋 Complete Order Example

### Salesforce Order Structure

```sql
Order {
  Id: "8014x000000ABCDXYZ",
  AccountId: "001xx000004TmiQAAS",
  Status: "Pending Review",
  Order_Type__c: "Internet"
}

OrderItems [
  {
    Id: "8024x000000DEFGABC",
    Product2: {
      WH_Product_ID__c: 185,
      Billing_Cycle__c: "Monthly",
      SKU: "INTERNET-GOLD-APT-1G"
    },
    Quantity: 1
  },
  {
    Id: "8024x000000HIJKLMN",
    Product2: {
      WH_Product_ID__c: 242,
      Billing_Cycle__c: "One-time",
      SKU: "INTERNET-INSTALL-SINGLE"
    },
    Quantity: 1
  },
  {
    Id: "8024x000000OPQRSTU",
    Product2: {
      WH_Product_ID__c: 246,
      Billing_Cycle__c: "Monthly",
      SKU: "INTERNET-ADDON-HOME-PHONE"
    },
    Quantity: 1
  }
]
```

### Transformed WHMCS AddOrder Request

```json
{
  "action": "AddOrder",
  "clientid": 1,
  "paymentmethod": "mailin",
  "pid": ["185", "242", "246"],
  "billingcycle": ["monthly", "onetime", "monthly"],
  "qty": [1, 1, 1],
  "noinvoice": true,
  "noemail": true,
  "promocode": "",
  "configoptions": ["", "", ""],
  "customfields": ["", "", ""]
}
```

### WHMCS AddOrder Response

```json
{
  "result": "success",
  "orderid": 12345,
  "serviceids": "67890,67891,67892",
  "addonids": "",
  "domainids": "",
  "invoiceid": 0
}
```

## 🔄 Status Update Mapping

### Salesforce Order Status Updates

#### During Fulfillment

| Step            | Order.Status     | Provisioning_Status\_\_c | WHMCS_Order_ID\_\_c | Notes                 |
| --------------- | ---------------- | ------------------------ | ------------------- | --------------------- |
| Initial         | "Pending Review" | null                     | null                | Customer placed order |
| CS Approval     | "Activating"     | "In Progress"            | null                | CS clicked provision  |
| WHMCS Created   | "Activating"     | "In Progress"            | "12345"             | AddOrder completed    |
| Services Active | "Activated"      | "Fulfilled"              | "12345"             | AcceptOrder completed |

#### On Failure

| Step               | Order.Status | Provisioning_Status\_\_c | Error Fields                    | Notes           |
| ------------------ | ------------ | ------------------------ | ------------------------------- | --------------- |
| Validation Failure | "Draft"      | "Failed"                 | Error_Code**c, Error_Message**c | Revert to draft |
| WHMCS API Failure  | "Draft"      | "Failed"                 | Error_Code**c, Error_Message**c | Rollback status |

### OrderItem Status Updates

| Field                 | Source               | Example   | Notes                        |
| --------------------- | -------------------- | --------- | ---------------------------- |
| `WHMCS_Service_ID__c` | AddOrder response (`serviceids`) | "67890"   | Individual service ID        |
| `Billing_Cycle__c`    | Already set          | "Monthly" | No change during fulfillment |

## 🔧 Data Transformation Rules

### Billing Cycle Transformation

```typescript
// Salesforce → WHMCS transformation
const billingCycleMap = {
  Monthly: "monthly",
  Quarterly: "quarterly",
  Semiannually: "semiannually",
  Annually: "annually",
  "One-time": "onetime",
  Onetime: "onetime",
};

// Implementation
billingCycle: product.billingCycle.toLowerCase();
```

### Product ID Transformation

```typescript
// Salesforce WH_Product_ID__c (number) → WHMCS pid (string)
productId: product.whmcsProductId.toString();
```

### Client ID Resolution

```typescript
// Order.AccountId → WHMCS clientid via mapping table
const mapping = await mappingsService.findBySfAccountId(order.AccountId);
clientId: mapping.whmcsClientId;
```

## 🛡️ Validation Rules

### Required Field Validation

```typescript
// Before WHMCS API call
✅ clientid must be valid WHMCS client
✅ paymentmethod must be valid WHMCS payment method
✅ pid[] must contain valid WHMCS product IDs
✅ billingcycle[] must match WHMCS billing cycles
✅ qty[] must be positive integers
```

### Business Rule Validation

```typescript
// Before provisioning
✅ Order.Status must be "Pending Review" or "Activating"
✅ Order must not already have WHMCS_Order_ID__c
✅ Client must have valid payment method in WHMCS
✅ All products must have WH_Product_ID__c mapping
```

## 📝 Implementation Notes

### Array Handling

- **WHMCS expects arrays**: Use `pid[]`, `billingcycle[]`, `qty[]` format
- **Order matters**: Arrays must be in same order (pid[0] matches billingcycle[0])
- **Empty values**: Use empty strings `""` for optional array elements

### Serialization (Advanced)

```typescript
// For configoptions[] and customfields[] if needed
function serializeForWhmcs(data: Record<string, string>): string {
  const serialized = phpSerialize(data);
  return Buffer.from(serialized).toString("base64");
}

// PHP serialize format: a:2:{s:3:"key";s:5:"value";}
```

### Error Handling

```typescript
// WHMCS API error responses
{
  "result": "error",
  "message": "Client ID Not Found"
}

// Map to structured error codes
WHMCS_CLIENT_NOT_FOUND → ORDER_NOT_FOUND
WHMCS_PRODUCT_INVALID → MAPPING_ERROR
WHMCS_API_ERROR → WHMCS_ERROR
```

This mapping reference ensures consistent data transformation and provides the complete picture for troubleshooting and maintenance.
