Class Name: CheckoutDeliveryIntegration¶
Last Updated: 2025-10-22 Source Code: https://github.com/AANP-IT/I2C.Salesforce.Metadata/blob/STAGING/force-app/main/default/classes/CheckoutDeliveryIntegration.cls
API Name: CheckoutDeliveryIntegration Type: Commerce Cloud Cart Extension (Shipping Calculator) Test Coverage: To be determined Created: 06/26/2024 Author: Ecaterina Popa
Business Purpose¶
This class extends Salesforce Commerce Cloud's shipping calculator framework to implement zero-cost digital delivery for products that don't require physical shipping. It automates the checkout process for digital products (online courses, certifications, digital downloads) by automatically applying a "Digital Delivery" shipping method with $0.00 cost, eliminating shipping cost confusion and streamlining the member experience for digital purchases. This is critical for AANP's digital product offerings where physical shipping is not applicable.
Class Overview¶
Scope and Sharing¶
- Sharing Model: Inherited from CartExtension.ShippingCartCalculator (system context)
- Access Modifier: public
- Interfaces Implemented: None (extends CartExtension.ShippingCartCalculator)
Key Responsibilities¶
- Override Commerce Cloud shipping calculation for digital products
- Clean up existing shipping validation outputs
- Remove previous delivery group methods
- Query and reference "Shipping Charge" product for Commerce Cloud compatibility
- Create "Digital Delivery" shipping method with $0.00 cost
- Set USPS carrier and "Digital Shipping" class of service
- Auto-select the created delivery method
- Validate cart delivery group existence
- Integrate seamlessly with Commerce Cloud checkout flow
Public Methods¶
calculate¶
Purpose: CartExtension framework callback method that executes during cart calculation to determine and apply shipping methods. Overrides base class to implement digital delivery logic.
Parameters:
- request (CartExtension.CartCalculateCalculatorRequest): Commerce Cloud request object containing cart context and calculation state
Returns: - void (modifies cart state via CartExtension API)
Throws: - QueryException: If Product2 query for "Shipping Charge" fails (not handled) - NullPointerException: If shippingProducts list is empty and [0] accessed (not handled) - CartExtension exceptions: Various Commerce Cloud exceptions (not explicitly handled)
Usage Example:
// Called automatically by Commerce Cloud during cart calculation
// Configured in Commerce Setup:
// Setup → Commerce → Checkout → Shipping Calculator
// Extension Point: Commerce_Domain_Checkout_ShippingCalculator
// Implementation: CheckoutDeliveryIntegration
Business Logic:
- Get Cart Context:
- Extracts cart from request
-
Cart contains all delivery groups, items, validation outputs
-
Clean Up Shipping Validation Outputs:
- Gets CartValidationOutputList from cart
- Iterates backwards through list (to safely remove during iteration)
- Removes all CartValidationOutput items of type SHIPPING
-
Clears any previous shipping errors/warnings
-
Get Cart Delivery Groups:
- Retrieves CartDeliveryGroupList from cart
- Checks if size == 0 (no delivery groups defined)
- If empty: Creates ERROR validation output "No Cart Delivery Groups have been defined"
-
Returns early if validation fails
-
Get Cart Items:
- Retrieves CartItemList to get unique item count
- Count used for tracking/debugging (stored in numberOfUniqueItems)
-
Not actively used in current logic
-
Get First Delivery Group:
- Gets cartDeliveryGroups.get(0) (assumes single delivery group)
-
Retrieves existing CartDeliveryGroupMethodList
-
Clean Up Existing Delivery Methods:
- Iterates backwards through CartDeliveryGroupMethods
- Removes all existing methods
-
Clears selected method:
cartDeliveryGroup.setSelectedCartDeliveryGroupMethod(null) -
Query Shipping Product:
- Looks for product named exactly "Shipping Charge"
- Excludes variation parents
-
Converts to String ID
-
Create Digital Delivery Method:
-
Add Method and Set as Selected:
- Adds method to CartDeliveryGroupMethodList
- Sets as delivery method:
cartDeliveryGroup.setDeliveryMethodId(...)
Cart Extension API Usage:
- cart.getCartValidationOutputs(): Get/modify validation messages
- cart.getCartDeliveryGroups(): Access delivery groups
- cart.getCartItems(): Access cart items
- CartExtension.CartValidationOutput: Create validation messages
- CartExtension.CartDeliveryGroupMethod: Create shipping methods
Commerce Cloud Integration: - Runs during cart calculation phase - Must be registered as shipping calculator extension - Affects order summary shipping cost - Integrated with tax and pricing calculators
Private/Helper Methods¶
None - All logic in single calculate method. Could benefit from extraction:
- cleanupValidationOutputs(cart)
- validateDeliveryGroups(cart)
- getShippingProduct()
- createDigitalDeliveryMethod(shippingProductId)
Dependencies¶
Apex Classes¶
- CartExtension.ShippingCartCalculator (base class): Commerce Cloud framework class
- No other Apex dependencies
- Must be configured in Commerce Cloud settings
Salesforce Objects¶
Product2 (Standard) - Fields accessed: Id, Name, ProductClass - Query for: "Shipping Charge" product - Purpose: Reference product for shipping method
CartExtension Framework Objects (Commerce Cloud) - Cart: Main cart container - CartDeliveryGroup: Delivery group configuration - CartDeliveryGroupMethod: Shipping method options - CartValidationOutput: Error/warning messages - CartItem: Items in cart
Custom Settings/Metadata¶
- None identified - Consider adding:
- Shipping_Config__mdt: Configurable product name, carrier, class of service
- Commerce_Settings__mdt: Enable/disable digital delivery
External Services¶
- None - Pure internal Commerce Cloud processing
- No callouts or external integrations
Commerce Cloud Configuration¶
- Required Setup:
- Product2 record with Name = 'Shipping Charge' must exist
- Extension registered at: Commerce_Domain_Checkout_ShippingCalculator
- Commerce store must have delivery groups configured
- Integration must be activated in Commerce setup
Design Patterns¶
- Extension Pattern: Extends CartExtension.ShippingCartCalculator
- Strategy Pattern: Implements shipping calculation strategy for digital products
- Template Method Pattern: Overrides calculate() to provide custom behavior
- Commerce Cloud Pattern: Follows CartExtension framework conventions
Why These Patterns: - Extension pattern required by Commerce Cloud framework - Strategy pattern allows different shipping logic per calculator - Template method provides hook into cart calculation lifecycle - Commerce Cloud pattern ensures compatibility with platform
Governor Limits Considerations¶
SOQL Queries: 1 (Product2 query for shipping product) DML Operations: 0 (all changes via CartExtension API, not direct DML) CPU Time: Low (simple logic, minimal processing) Heap Size: Low (small objects, minimal data)
Bulkification: N/A (processes single cart per invocation) Async Processing: No (synchronous calculator)
Governor Limit Risks: - LOW: Single SOQL query well within limits - LOW: No DML operations - LOW: CartExtension API calls are framework-managed - NONE: No loops over large data sets
Performance Considerations: - Called during every cart calculation/recalculation - Should execute quickly (<100ms ideal) - Product query could be cached if performance becomes issue - CartExtension framework manages transaction boundaries
Recommendations: - Current implementation is efficient - Consider caching shipping product ID if called frequently - Monitor Commerce Cloud performance dashboards
Error Handling¶
Strategy: No explicit error handling - relies on Commerce Cloud framework
Logging: - None - No custom logging - Commerce Cloud framework logs errors - No debug statements for troubleshooting
User Notifications: - CartValidationOutput used for "No Cart Delivery Groups" error - Other errors surface as generic Commerce Cloud errors - No custom user-friendly messages
Validation: - Checks for empty cart delivery groups - Creates ERROR level validation output if no delivery groups - No validation for: - Missing shipping product - Empty shippingProducts list - Null cart items
Rollback Behavior: - Commerce Cloud manages transaction rollback - CartExtension state changes rolled back on error - Cart returns to previous valid state
Recommended Improvements: - Add try-catch around Product2 query - Validate shippingProducts not empty before accessing [0] - Add validation output if shipping product not found - Log calculation steps for troubleshooting - Add null checks for cart objects
Security Considerations¶
Sharing Rules: SYSTEM CONTEXT - CartExtension runs as system - No sharing declaration (inherits from framework) - Runs with system privileges - Appropriate for checkout automation
Field-Level Security: NOT ENFORCED - CartExtension framework bypasses FLS - Appropriate for checkout process - Products must be accessible to cart
CRUD Permissions: NOT ENFORCED - System context allows all operations - Appropriate for automated checkout
Input Validation: MINIMAL - Validates delivery groups exist - No validation of cart state - No validation of product existence - No validation of cart items
Security Risks: - LOW: System context appropriate for checkout - MEDIUM: Hardcoded product name could be exploited if product deleted/renamed - LOW: No input from users (framework-driven)
Commerce Security: - Cart belongs to authenticated user - Commerce Cloud enforces user permissions - Extension operates on user's cart only
Mitigation Recommendations: 1. Add validation that shipping product exists 2. Log security-relevant events (cart modifications) 3. Consider using custom metadata for configuration 4. Regular audits of shipping product configuration
Test Class¶
Test Class: CheckoutDeliveryIntegrationTest.cls (assumed - verify in codebase) Coverage: To be determined
Test Scenarios That Should Be Covered: - ✓ Cart with delivery group applies digital delivery successfully - ✓ Cart without delivery groups shows error validation - ✓ Shipping product "Shipping Charge" exists and is used - ✓ Existing delivery methods are cleaned up - ✓ Existing validation outputs are cleaned up - ✓ Digital delivery method created with $0.00 cost - ✓ Carrier set to 'USPS' - ✓ Class of service set to 'Digital Shipping' - ✓ Delivery method automatically selected - ✓ Multiple cart items handled correctly - ✓ Empty cart handling - ✓ Missing shipping product (should fail gracefully) - ✓ Multiple delivery groups (only first processed)
Testing Challenges: - Commerce Cloud CartExtension mocking is complex - Requires Commerce Cloud test data setup - Must configure test store and products - CartExtension.Cart object difficult to mock - Framework behavior testing requires integration tests
Test Data Requirements: - Product2 record named "Shipping Charge" - WebCart with Status = 'Active' - CartDeliveryGroup configured - CartItems in cart - Commerce store configuration
Mock Patterns:
// Create test cart
WebCart testCart = new WebCart(/*...*/);
CartDeliveryGroup testGroup = new CartDeliveryGroup(/*...*/);
// Mock CartExtension request
CartExtension.CartCalculateCalculatorRequest mockRequest = /*...*/;
// Call calculator
CheckoutDeliveryIntegration calculator = new CheckoutDeliveryIntegration();
calculator.calculate(mockRequest);
// Assert delivery method created
// Assert validation outputs correct
Changes & History¶
- Created: 06/26/2024
- Author: Ecaterina Popa
- Purpose: Digital delivery shipping calculation for Commerce Cloud
- Last Modified: Check git log
Related Changes: - Part of Commerce Cloud checkout implementation - Supports digital product strategy - Integrates with pricing and tax calculators
⚠️ Pre-Go-Live Concerns¶
CRITICAL - Fix Before Go-Live¶
- Hardcoded Product Dependency: Class relies on exact product name "Shipping Charge" - if product doesn't exist, rename, or is deleted, checkout BREAKS. Add existence check and error handling.
- No Error Handling on Query: Line 52-60 queries Product2 without try-catch - query exceptions will break checkout with cryptic errors.
- Array Index Risk:
shippingProducts[0]accessed without checking list size - will throw NullPointerException if no products found. - No Product Validation: If "Shipping Charge" product is deactivated or wrong ProductClass, checkout silently fails or breaks.
HIGH - Address Soon After Go-Live¶
- No Logging: Zero logging makes troubleshooting checkout issues impossible. Can't determine why delivery methods fail.
- Single Delivery Group Assumption: Only processes first delivery group (
.get(0)) - multi-shipment orders will fail. - No Configuration: All values hardcoded ('USPS', 'Digital Shipping', product name) - requires code deployment to change.
- Missing Validation Outputs: Should add validation output if shipping product not found (user sees generic error).
MEDIUM - Future Enhancement¶
- Hardcoded Carrier/Service: 'USPS' and 'Digital Shipping' should be configurable via custom metadata.
- Product Name Dependency: Use Product Code or custom metadata instead of Name for better reliability.
- No Caching: Queries shipping product every time - could cache for performance.
- Limited Error Messages: Generic Commerce Cloud errors don't help users understand issues.
- Unused Variable:
numberOfUniqueItemscaptured but never used - remove or implement logic.
LOW - Monitor¶
- Code Organization: Single 77-line method should be refactored into smaller methods.
- Virtual Override: Method is virtual but no subclasses exist - remove virtual if not needed.
- Documentation: Inline comments are good but could be more detailed for complex Cart Extension API.
- Test Coverage: Verify comprehensive test coverage exists for all scenarios.
Maintenance Notes¶
Complexity: Medium (Commerce Cloud framework complexity) Recommended Review Schedule: Quarterly, before Commerce Cloud upgrades
Key Maintainer Notes:
🛒 COMMERCE CLOUD CRITICALITY: - This class is REQUIRED for checkout to function - Failures block all digital product purchases - Must be tested in full Commerce Cloud sandbox - Changes require Commerce Cloud expertise - Test with actual products and checkout flow
📋 Usage Patterns:
- Called automatically during cart calculation
- Runs every time cart is modified
- Runs during checkout flow
- Must be registered in Commerce Cloud settings: Setup → Commerce → Checkout
- Extension point: Commerce_Domain_Checkout_ShippingCalculator
🧪 Testing Requirements: - Test in Commerce Cloud sandbox with real products - Test complete checkout flow end-to-end - Verify "Shipping Charge" product exists and is configured correctly - Test with multiple cart items - Test with different product types - Verify $0.00 shipping cost appears correctly - Test in mobile and desktop checkout
🔧 Commerce Cloud Configuration: - Product2 with Name = 'Shipping Charge' MUST exist - Product must have ProductClass != 'VariationParent' - Extension must be activated in Commerce setup - Must be associated with correct store - Delivery groups must be configured in store
⚠️ Gotchas and Warnings: - Renaming "Shipping Charge" product breaks checkout immediately - Deleting shipping product breaks checkout immediately - Only first delivery group processed - multi-shipment not supported - CartExtension errors are cryptic - add detailed logging - Changes require Commerce Cloud redeployment - Must test in full Commerce environment (not just unit tests)
📅 When to Review This Class: - Before any Commerce Cloud upgrades - When adding new product types - If checkout failures reported - When modifying shipping logic - During annual Commerce Cloud reviews - If "Shipping Charge" product changes - When implementing physical shipping
🛑 Emergency Deactivation:
If digital delivery needs to be disabled:
// Option 1: Deactivate extension in Commerce setup
// Setup → Commerce → Checkout → Shipping Calculator
// Deactivate CheckoutDeliveryIntegration
// Option 2: Add metadata check at start of calculate():
public virtual override void calculate(CartExtension.CartCalculateCalculatorRequest request) {
Commerce_Settings__mdt settings = Commerce_Settings__mdt.getInstance('Shipping');
if (settings != null && !settings.Digital_Delivery_Enabled__c) {
// Fall back to default shipping calculator
super.calculate(request);
return;
}
// ... rest of method
}
🔍 Debugging Tips: - Enable Commerce Cloud debug logs - Check Setup → Commerce → Checkout configuration - Verify extension is active and associated with store - Query for "Shipping Charge" product directly - Check cart delivery groups are configured - Review Commerce Cloud transaction logs - Test in scratch org or full sandbox
📊 Monitoring Checklist: - Daily: Checkout success rate - Weekly: Shipping calculation errors - Monthly: "Shipping Charge" product configuration validation - Monitor: Commerce Cloud performance dashboards - Alert: Any CartExtension exceptions
🔗 Related Components: - Product2: "Shipping Charge" product (CRITICAL dependency) - Commerce Cloud Store: Store configuration - Cart Delivery Groups: Must be configured - Commerce pricing calculator: Works alongside this - Commerce tax calculator: Works alongside this - Order creation: Uses shipping method from this class
💡 Future Enhancements: - Make shipping product configurable via metadata - Support multiple delivery groups - Add detailed logging - Implement product caching - Add comprehensive validation - Support mixed physical/digital shipments
Business Owner¶
Primary: E-Commerce / Digital Products Team Secondary: IT Operations / Commerce Cloud Admin Stakeholders: Product Management, Customer Experience, Development Team, Member Services