Skip to main content
Commerce Engine provides two checkout paths:

Hosted Checkout

Recommended. Pre-built cart, authentication, addresses, fulfilment, discounts, payment, and order confirmation inside an embeddable checkout.

Custom checkout

Advanced. Use the Storefront SDK when the business requires complete control over the checkout UI and payment experience.
Do not build custom checkout only to change colours, typography, layout direction, login methods, or feature flags. Configure those through Checkout Studio.

Hosted Checkout path

Install the checkout package and use the framework-specific integration.
When the application also uses @commercengine/storefront, use authMode: "provided" and two-way token synchronization. This preserves one user, cart, and analytics journey. Hosted Checkout handles:
  • cart review and quantity updates
  • OTP login/registration
  • saved and new addresses
  • delivery and collect-in-store options where configured
  • coupons, promotions, loyalty, and credit features
  • payment-provider UI
  • order completion and callbacks
The host application should handle onReady, onError, onSessionError, and onComplete, and keep cart/checkout controls disabled until checkout is ready.

Custom checkout prerequisites

A custom checkout requires:
  • an active cart with at least one item
  • a logged-in customer session
  • billing and shipping addresses as applicable
  • a valid fulfilment preference for physical goods
  • an available payment method unless to_be_paid is zero
Recommended journey:
Authentication before address/payment verifies the contact channel and reduces delivery failures. Use register_if_not_exists: true for a single login/register path.

1. Review the current cart

Before continuing:
  • ensure the cart is active and not expired
  • revalidate item availability
  • display to_be_paid as the final payable amount
  • show promotions, coupons, loyalty, credit, tax, and shipping separately

2. Authenticate

If sdk.isLoggedIn() is false, complete OTP or password authentication before entering the protected checkout steps.
After login, refetch the cart. Commerce Engine merges the active anonymous cart; do not create a replacement cart.

3. Create or select an address

For a custom checkout, create addresses on the customer profile and link their IDs to the cart. This preserves them for later orders.
Confirm the exact current createAddress body type from the LLM-first reference. Address fields can vary by country and operation version. Link the selected addresses:
Use the returned cart because shipping and tax totals may change.

Pincode lookup

For supported countries, use the helper operation to suggest city/state after the customer enters a valid-length pincode. Debounce the lookup and allow manual correction if no result is found. Do not treat an address lookup as a deliverability check.

4. Check deliverability

Use unserviceable_items where returned to explain whether the whole cart or only specific items cannot be delivered. Do not use legacy shipment serviceability endpoints or guess a path; retrieve the exact current operation contract.

5. Retrieve fulfilment options

The response can include:
  • summary availability and recommendation
  • delivery shipments and shipping methods
  • courier options for an aggregator method
  • collect-in-store locations
A cart can produce multiple shipments. The UI must choose a valid method for every shipment rather than assuming one shipping option covers the order.

6. Set fulfilment preference

Delivery example:
Collect-in-store example:
Restore the cart’s existing preference after refresh instead of automatically replacing the customer’s previous selection. If the product requirements allow automatic delivery selection, choose using an explicit rule—for example, lowest cost then shortest delivery estimate—and show the selection to the customer.

Address, deliverability, and fulfilment

7. Apply discounts

Coupons, loyalty points, and credit balance update the cart. Use the returned cart after every operation and display the new to_be_paid. A 100% discount or sufficient credit can produce to_be_paid: 0; order creation may then complete without a payment redirect.

8. Discover and validate payment methods

For a custom payment UI, retrieve the store’s available methods rather than hardcoding cards, UPI, banks, or wallets.
Payment method availability and payload fields are provider- and integration-specific. Use the exact slug returned by payment-method discovery; the current Juspay contract examples use lowercase juspay. Retrieve the exact method and schema contracts from the LLM-first reference. For express payment UIs:
  • use card BIN lookup before declaring a network supported
  • validate UPI VPA before submission where applicable
  • do not store or log raw card/OTP data
  • prefer provider-hosted surfaces when PCI scope and complexity are not justified

9. Create the order

Hyper Checkout example:
Use the exact provider slug, action, and payload casing returned/documented for the configured integration. Do not copy placeholder gateway IDs into production. Persist the returned order number before redirecting.
Handle both outcomes:
Confirm the payment-info shape for the selected provider before accessing a link.

10. Verify payment status

Do not trust redirect query parameters as the authoritative payment result. Commerce Engine processes provider callbacks asynchronously. Poll the order status after the customer returns:
If the poll times out, show a processing state and link to order history. Do not declare failure or success prematurely.

11. Retry a failed payment

Only show Retry when is_retry_available is true.
Use the new payment information and repeat the authoritative status check. Prevent duplicate clicks while retry creation is in flight.

Order creation, payment verification, and retry

Payment-return resilience

The return page should recover from:
  • missing query parameters
  • browser refresh
  • a new tab
  • delayed provider callback
  • network failure during polling
  • customer navigating away and returning through order history
Persist the order number before redirecting and verify that it belongs to the current authenticated session before displaying sensitive details.

Error handling

Do not blindly retry order creation. An ambiguous response can still mean an order was created.

Accessibility and UX

  • preserve checkout step state after recoverable errors
  • focus the first invalid field
  • announce total and fulfilment changes
  • prevent accidental double submission
  • show progress without trapping keyboard focus
  • provide clear processing, success, failed, and pending states
  • keep order confirmation accessible after refresh through account history
Hosted Checkout supplies these screens; custom checkout teams must build and test them.

Analytics in a custom checkout

@commercengine/analytics is not tied to Hosted Checkout. A custom checkout built with the Storefront SDK or direct REST can map the same canonical Commerce Engine Cart, CartItem, Order, and user entities into Segment/RudderStack-compatible events. The application owns the semantic trigger—for example, emit Checkout Started when the customer actually begins checkout—while the package owns the event schema and entity normalization.

Commerce analytics

Use the vendor-neutral mapper package with Hosted Checkout, custom SDK checkout, direct REST, any compatible CDP, or a custom analytics pipeline.

Production checklist

Custom checkout skills

The cart-checkout skill contains detailed cart queues, address/fulfilment selection, payment discovery, payload, polling, and retry references.