Skip to content

Express Checkout PR 3: Shipping & Totals Endpoint#94

Open
daniellzl wants to merge 4 commits intodl260302/express-checkout-pr2-checkout-objectfrom
dl260302/express-checkout-pr3-shipping-totals
Open

Express Checkout PR 3: Shipping & Totals Endpoint#94
daniellzl wants to merge 4 commits intodl260302/express-checkout-pr2-checkout-objectfrom
dl260302/express-checkout-pr3-shipping-totals

Conversation

@daniellzl
Copy link
Copy Markdown
Collaborator

@daniellzl daniellzl commented Mar 18, 2026

Tech Spec

Summary

  • ShippingTotals POST route: server-to-server endpoint called by Affirm backend
  • HMAC-SHA512 signature verification (affirmUtils.verifyHMAC)
  • Calculates shipping options with tax and totals for each method
  • Extensibility hooks: validateAddress, calculateTotals, filterShippingMethods
  • Error codes: ORDER_NOT_FOUND, CURRENCY_MISMATCH, UNSUPPORTED_SHIPPING_ZONE, etc.

PR Stack (3 of 4)

  1. PR 1: Infrastructure & Configuration
  2. PR 2: UUID Generation + Checkout Object + UI
  3. PR 3 (this): Shipping & Totals Endpoint
  4. PR 4: Order Confirmation & Placement

Implements Step 3 of the Affirm Express Checkout Integration Guide.

Known issues

  • Debug HMAC logs expose sensitive data at ERROR level (marked for removal)
  • ShippingTotals uses BasketMgr.getCurrentOrNewBasket() in sessionless context

Test plan

  • Verify HMAC signature validation works with valid/invalid signatures
  • Verify shipping options are returned correctly for valid addresses
  • Verify appropriate error codes for invalid requests (bad currency, missing cart, etc.)
  • Verify extensibility hooks are called when registered

Implements Step 3 of the Affirm Express Checkout Integration Guide:
- ShippingTotals POST route: server-to-server endpoint called by Affirm
  backend to get shipping options and order totals
- HMAC-SHA512 signature verification (affirmUtils.verifyHMAC)
- Extensibility hooks: validateAddress, calculateTotals, filterShippingMethods

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
var tempBasket = BasketMgr.getCurrentOrNewBasket();

// Populate basket with products from the cart snapshot
Transaction.wrap(function () {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want 1 transaction block between this line and the Transaction.begin() on line 490?

// Note: getApplicableShippingMethods() requires a plain JS object, not an SFCC OrderAddress
var tempShipment = tempBasket.getDefaultShipment();
var applicableShippingMethods = ShippingMgr.getShipmentShippingModel(tempShipment)
.getApplicableShippingMethods(addressObj);
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is addressObj being passed in here? Shouldn't tempShipment have the saved cart address?

}

// Validate currency
if (currency !== 'USD') {
Copy link
Copy Markdown
Collaborator Author

@daniellzl daniellzl Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Express checkout only supports the United States and USD for initial launch.

// Validate address via hook or default validation
if (HookMgr.hasHook('app.affirm.express.validateAddress')) {
var cartData = JSON.parse(expressCart.custom.cartData);
var addressValidation = HookMgr.callHook('app.affirm.express.validateAddress', 'validateAddress', shippingAddress, cartData);
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Custom merchant-defined validation hook called here, otherwise default to simple validation on line 415.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants