Ward Integration Guide
Integrate FTM with Ward to fetch LTL rates and transit days from a Lane Quote and show them inside Salesforce.
Overview
The Ward integration lets FTM users:
- Request LTL rate quotes from Ward’s rate endpoint
- Parse Net Charge and Transit Days from the XML response
- Display a friendly net charge string (or “No service availability”)
This integration uses a simple XML POST (not SOAP) to Ward’s ratequote endpoint.
1️⃣ User Information
Purpose
Pull a quick Ward LTL rate and transit estimate from a Lane Quote.
Workflow (User Perspective)
- Open a Lane Quote in Salesforce.
- Click “Get Rates (Ward)” on the VF/LWC action.
- The system returns a Net Charge and Transit Days (if available).
Booking is not implemented in this class; this is a rate-only integration.
What You’ll See
- netCharge (string) → e.g., “432.15” or “No service availability”
- transitDays (number) when present in Ward’s response
Prerequisites
- Credentials on User (CreatedBy of Lane Quote):
- Ward_User_Name__c
- Ward_Password__c
- Ward_Customer_Number__c (used in the request <Customer>)
- Lane Quote fields populated:
- Pickup/Delivery City, State, Zip
- Freight Class, Weight (Value), Pieces, Handling Units
- PaymentMethod__c (mapped to Ward billing terms)
- Remote Site Setting for:
- https://wardtlctools.com
- Apex Class Access:
- WardInteg
- (Recommended) Move credentials to Protected Custom Metadata/Setting.
2️⃣ Developer Information
Apex Components
| Component | Purpose |
| WardInteg | Controller that builds XML, posts to Ward, parses Net Charge & Transit Days |
Endpoint & Operation
| Purpose | Method | URL |
| Get Rate Quote | POST | https://wardtlctools.com/wardtrucking/webservices/ratequote |
HTTP Headers
- Content-Type: text/xml
- Accept: */*
Authentication & Billing
- Auth in body: <User><UserName>…</UserName><Password>…</Password></User>
- Billing terms mapping (from Lane Quote PaymentMethod__c):
- PrePaid → PPD
- Collect → COD
Field Mapping (Lane Quote → Ward XML)
| Source (Salesforce) | Ward Field | Notes |
| CreatedBy.Ward_User_Name__c | User.UserName | Auth |
| CreatedBy.Ward_Password__c | User.Password | Auth |
| CreatedBy.Ward_Customer_Number__c | Customer | Required |
| PaymentMethod__c | BillingTerms | Mapped to PPD/COD |
| FreightTM__Pickup_City__c | OriginCity | – |
| FreightTM__Pickup_State__c | OriginState | – |
| FreightTM__Pickup_Zip_Code__c | OriginZipcode | – |
| FreightTM__Delivery_City__c | DestinationCity | – |
| FreightTM__Delivery_State__c | DestinationState | – |
| FreightTM__Delivery_Zip_Code__c | DestinationZipcode | – |
| Handling_Units__c | PalletCount | Decimal accepted |
| Pieces__c | Details.DetailItem.Pieces | Integer |
| Weight_Value__c | Details.DetailItem.Weight | Integer (lbs) |
| Freight_Class__c | Details.DetailItem.Class | Mapped (below) |
Freight Class Mapping (as used in code)
CLASS_050→50, 55→55, 60→60, 65→65, 70→70, 77.5→77.5,
85→85, 92.5→92.5, 100→100, 110→110, 125→125,
150→150, 175→175, 200→200, 250→250, 300→300,
400→400, 500→500
How It Works
- Controller loads Lane Quote and the CreatedBy Ward credentials.
- Maps class and billing terms; builds minimal XML request body.
- POST XML to Ward ratequote.
- Parses:
- <NetCharge> → netCharge (string, or “No service availability”)
- <TransitDays> → transitDays (Integer, when present)
If NetCharge is 0, missing, or unparsable → returns “No service availability.”
Sample Request Body (Trimmed)
<Body>
<request>
<User>
<UserName>WARD_USERNAME</UserName>
<Password>WARD_PASSWORD</Password>
</User>
<Details>
<DetailItem>
<Pieces>3</Pieces>
<Weight>1200</Weight>
<Class>85</Class>
</DetailItem>
</Details>
<Accessorials>
<AccessorialItem>
<Code>IDC</Code>
</AccessorialItem>
</Accessorials>
<BillingTerms>PPD</BillingTerms>
<OriginCity>Glen Mills</OriginCity>
<OriginState>PA</OriginState>
<OriginZipcode>19342</OriginZipcode>
<DestinationCity>Seattle</DestinationCity>
<DestinationState>WA</DestinationState>
<DestinationZipcode>98101</DestinationZipcode>
<PalletCount>3</PalletCount>
<Customer>0932997</Customer>
</request>
</Body>
Note: The code sets Accessorials to a single hard-coded item: <Code>IDC</Code>. Add dynamic mapping when needed.
Sample Response Snippet (Trimmed)
<RateQuoteResponse>
<NetCharge>432.15</NetCharge>
<TransitDays>3</TransitDays>
</RateQuoteResponse>
Parsing Logic
- Net Charge
- Extract substring between <NetCharge> and </NetCharge>
- Parse as Decimal; if 0 or error → netCharge = ‘No service availability’
- Else → netCharge = String.valueOf(value)
- Transit Days
- Extract substring between <TransitDays> and </TransitDays>
- Parse to Integer → transitDays
Error Handling
| Condition | Outcome |
| Non-200 HTTP | netCharge = ‘No service availability’ (logs retained) |
| Missing <NetCharge> | netCharge = ‘No service availability’ |
| NetCharge unparsable or equals 0 | netCharge = ‘No service availability’ |
| Missing/invalid <TransitDays> | transitDays = null |
| Exceptions | Caught; safe fallbacks; debug logs for diagnosis |
Security Recommendations
- Move Ward creds to Protected Custom Metadata/Setting (e.g., Ward_Config__mdt with Username__c, Password__c, Customer_Number__c).
- Do not commit credentials to source control.
- Add Remote Site Setting or use a Named Credential for outbound allowlisting.
Testing
Anonymous Apex
WardInteg.makeRequest('a0HXXXXXXXXXXXX'); // Lane Quote Id
System.debug(WardInteg.netCharge);
System.debug(WardInteg.transitDays);
From UI
- Add a button/quick action bound to controller getData() on WardInteg.
Deployment Checklist
✅ Remote Site Setting: https://wardtlctools.com
✅ Apex class access: WardInteg
✅ Lane Quote fields populated (origin/destination, weight, pieces, class, handling units)
✅ User has Ward credentials & customer number (or Protected CMDT)
✅ (Optional) Extend accessorials mapping beyond hard-coded IDC
Limitations
- Rates only (no booking)
- Accessorials are static (IDC) in current implementation
- Assumes US domestic data (ZIP-driven)
- Parses the first <NetCharge> found; response schema must remain consistent
FAQ
Q: Can we send multiple line items?
A: Current code sends one DetailItem. Extend Details to support multiple.
Q: Where does the rate show up?
A: As the controller static netCharge string. Bind to VF/LWC or persist to a field (e.g., Ward_Net_Charge__c) if you need history.
Q: How do we change billing terms?
A: Set PaymentMethod__c on Lane Quote: PrePaid → PPD, Collect → COD.
Support
📧 FTM Integration Support: [email protected]
