SF DeFacto #1 — Salesforce Headless Commerce Checkout with Saved Payment Method

The views and opinions expressed here are my own and do not represent those of my employer, Salesforce.

Photo by SumUp on Unsplash

Context

This article showcases how to implement Commerce Checkout (Cart-to-Order) in a headless context using a combination of B2B and D2C Commerce, Salesforce Payments, and Salesforce Commerce Payments APIs.

This niche use case may be necessary if the following business requirements apply:

  • Implement a headless checkout process (not relying on store managed checkout).
  • Use a saved payment method instead of capturing payment details during checkout.

Notes

  • A fully headless checkout with Salesforce Payments is not yet officially supported by Salesforce. This implementation presents a suggested solution based on personal experience with the Salesforce Payments capabilities.

Prerequisites

  • Watch Salesforce Mojo’s video about Headless Commerce Checkout.
  • Salesforce Payments must be configured in the org with a valid Merchant Account and associated Payment Method Sets.
  • Set up Postman with the required authentication details for the external store user.
  • This process assumes that an active cart with existing Cart Item records already exists.

Postman Collection

Import the following collection to access the APIs mentioned in this solution: Headless Commerce APIs.postman_collection.json.

Headless Commerce Checkout Process with Saved Payment Method (Salesforce Payments)

The following flow outlines the sequence of processes and API calls required to create an order from a cart. As mentioned in the notes section, the flow is not fully API-driven. Custom logic is introduced as a workaround after authorizing payment. This is necessary because the checkouts/active/payments API does not yet support Saved Payment Method records.

Headless checkout flow with saved payment method: sequence of API calls from active cart to placed order

  1. Get Active CartGET Commerce Webstore Cart
  2. Start CheckoutPOST Commerce Webstore Checkouts
  3. Check Asynchronous Checkout StatusGET Commerce Webstore Checkout
    • During the asynchronous checkout process (e.g., calculating shipping, taxes, promotions), GET requests return a 202 status. When processing is complete, requests return a 200 status with up-to-date data.
  4. Update Checkout DetailsPATCH Commerce Webstore Checkout
    • Must include data for only one sub-resource per call, such as contact information, shipping details, or delivery method.
  5. Get Store Application ContextGET Commerce Webstore Application Context
    • Goal is to retrieve the paymentMethodSetDevName.
  6. Retrieve Payment Method Sets InformationGET Get Payment Method Sets By Dev Or MerchantAccountId
    • Extra permissions: Authenticated Payer permission set.
    • Goal is to retrieve the gatewayId.
  7. Authorize PaymentPOST Authorize Payment
    • paymentGroup.sourceObjectId can be empty, as it will be populated after the order is placed. paymentMethod.id references the Saved Payment Method ID.
  8. Update Checkout Payment Information — custom logic
    • Extra permissions: custom WebCart permissions.
    • Custom logic updates WebCart.PaymentMethodId and WebCart.PaymentGroupId. These fields may not be updatable by external users due to license/sharing restrictions. Options for implementation include Composite API, Flows, or Apex.
  9. Place OrderPOST Commerce Webstore Checkout Orders

Additional Resources

This article is also available on Medium — this page is the canonical, updated version.