The checkout flow

Learn how to orchestrate a checkout flow using Composable Commerce, third-party services, and a resilient backend.

Copy for LLM
View as Markdown

After completing this page, you should be able to:

  • Describe the architecture of a checkout flow and the responsibilities of each component.

  • Outline the standard stages and lifecycle of a checkout flow within Composable Commerce.

A checkout flow involves converting a customer's cart into a finalized order and payment. A robust checkout flow must:

  • Handle guest and registered customers: Accommodate anonymous users and logged-in Customers.
  • Integrate multiple services: Orchestrate APIs from Composable Commerce, payment service providers (PSPs), shipping carriers, and fraud detectors.
  • Handle real-world complexities: Manage dynamic conditions like price changes, expiring discounts, inventory fluctuations, and payment delays. Provide clear feedback to the user.
  • Ensure reliability and security: Make each step idempotent (safe to retry) and secure; delegate sensitive operations like payment to compliant PSPs to minimize PCI scope.
  • Be extensible: Allow for future integrations, like loyalty programs or new delivery options, with minimal rework.

From an architect's perspective, a checkout flow orchestrates multiple services such as Composable Commerce, PSPs, tax and shipping calculators, and fraud detection. They work in sequence, with robust error handling at every potential failure point. The goal is to identify and resolve failures in one component without disrupting the entire process—for example, if a payment authorization fails, the system should handle it gracefully.

To build a robust checkout flow, you must first understand the high-level architecture and responsibilities of each component.

Architecture

A standard checkout involves coordination between a frontend client, a backend service (like a BFF), Composable Commerce, and various third-party services.

The interaction between these components follows several key principles to ensure security, reliability, and a clear separation of concerns:

  • Client-side tokenization: Payment data (for example, card numbers) is never sent to your backend. The client uses the PSP's SDK to tokenize sensitive data; only the resulting secure token is sent to your backend. This practice significantly reduces your PCI compliance scope.
  • Sequential orchestration: The backend coordinates the sequence of API calls—for example, it updates the Cart in Composable Commerce before calling a tax service. If any step fails, the backend handles the error; it either retries or returns an error to the client.
  • Single source of truth: All key state transitions are recorded in Composable Commerce—these include selected shipping method, applied discounts, and payment status. To allow other services (such as, email, ERP) to rely on a consistent data source, the Cart, Order, and Payment objects serve as the authoritative record for the checkout state.
  • PSP integration: A standard integration with a payment service provider (PSP) has two components—synchronous and asynchronous. The synchronous component initiates the payment by exchanging data; the asynchronous component receives payment-related notifications (like webhooks) from the PSP. Your backend orchestrates these interactions.

Frontend (client) responsibilities

  • Gather and validate user input: The client collects addresses, contact information, and payment details. It performs initial client-side validation (for example, email format) to improve the user experience.
  • Display real-time Cart and total calculations: The UI reflects the current Line Items, Prices, Shipping costs, and taxes. It updates these values as the user makes changes, such as selecting a different Shipping Method, by fetching the updated Cart from the backend.
  • Handle payment data via PSP SDKs: Payment details are collected using the PSP's secure UI components (for example, Stripe Elements). This ensures sensitive data never touches your servers. The frontend receives a secure token from the PSP to represent the payment details.
  • Drive the UI flow: The client guides the user through the checkout steps, manages user actions like "edit cart" or "retry payment," and displays confirmation or error messages.

Backend (BFF/server) responsibilities

  • Orchestrate API calls: The backend serves as the integration layer, calling Composable Commerce APIs and third-party services in the correct sequence. It contains the business logic for the checkout flow.
  • Maintain idempotency and state: The backend ensures that critical operations, like creating a Payment or Order, are not accidentally duplicated if a request is retried. Idempotency means an operation can be safely repeated without causing unintended side effects. Using the Cart's version for Order creation is a key part of this, as the Composable Commerce API will reject a second attempt with the same version.
  • Secure server-side communication: The backend securely stores and uses credentials to authenticate with Composable Commerce and other services. It uses privileged API scopes that are never exposed to the client.
  • Handle asynchronous events: The backend listens for webhooks from services like PSPs (for example, payment success or failure notifications) and updates the Payment state in Composable Commerce accordingly. It can also use Subscriptions to react to events within Composable Commerce.
  • Enforce business rules: The backend is the final authority for enforcing custom business logic, such as minimum order values, stock availability checks, or customer-specific purchase limits, before creating an Order.

Third-party services

  • PSPs: Handle payment processing. The checkout flow interacts with the PSP's API to create payment intents or authorizations. The PSP typically notifies your backend of the payment result via webhooks.
  • Tax calculation services: For regions with complex tax rules, an external service can be used to calculate taxes based on order data. While Composable Commerce can store tax rates, many businesses use specialized third-party engines for compliance.
  • Shipping rate providers: To get real-time shipping costs or integrate with carriers for label generation, the backend calls external shipping APIs based on the Cart's address and items.
  • Fraud detection systems: The flow may include sending order and payment information to a fraud detection service (for example, Signifyd) for risk assessment before finalizing the order.

Now that you understand the components and their roles, let's look at how they interact to move a checkout from an active Cart to a completed Order.

High-level lifecycle in Composable Commerce

From the perspective of Composable Commerce, a typical checkout lifecycle is as follows:

  1. An active Cart exists: The system contains an active Cart. It is associated with either an anonymous session (anonymousId) or a registered Customer (customerId).
  2. Addresses and Shipping Method are set: The Shipping and billing addresses are set on the Cart. A Shipping Method is selected. Composable Commerce uses this information to calculate applicable Shipping rates and taxes, updating the Cart totals.
  3. A Payment object is created and linked to the Cart: A Payment resource is created to represent the financial transaction. It holds details like the Payment method and amount. It is linked to the Cart via its paymentInfo field. Creating a Payment object is a best practice for recording PSP interactions and Payment status.
  4. An Order is created from the Cart: Using the Cart's latest version, the backend creates an Order. This operation converts the Cart into an Order. It makes the Cart immutable by setting the Cart's state to Ordered.
  5. Post-Order processes are triggered: After Order creation, subsequent processes are initiated. These are typically triggered via Subscriptions to Composable Commerce Messages—for example, an OrderCreated message can trigger a confirmation email, an update to an ERP, and an inventory decrement.

Throughout this lifecycle, Composable Commerce acts as the single source of truth for Cart and Order data. Every change to the Cart creates a new version—for example, adding a Line Item or an address increments the version. You must use the latest version for subsequent updates to prevent conflicts.

This system-level lifecycle maps directly to the stages a user experiences in the frontend.

Standard stages of a checkout flow

Most checkout processes follow a standard sequence of stages. While businesses may customize or combine steps, the general flow includes:

StagePurposeKey commercetools resources
Cart reviewUser reviews and confirms items, quantities, discountsCart (Line Items, Custom Line Items, Product and Cart Discounts)
ShippingCollect shipping address, choose shipping methodCart (shipping address, shipping method)
BillingCollect billing address (if different from shipping address)Cart (billing address)
PaymentCapture payment details; authorize/capture funds via PSPPayment (and Cart Payment information)
Order confirmationCreate and finalize the order, show confirmation, trigger post-purchase actionsOrder (created from Cart), Subscription (for post-order events)
Each stage corresponds to specific API calls and data objects in Composable Commerce—for example, during the shipping stage, you set the shippingAddress and select a shippingMethod on the Cart. This action prompts Composable Commerce to recalculate taxes and shipping costs. By the Order confirmation stage, an Order is created from the Cart, and subsequent processes (like sending a confirmation email or syncing to an ERP) are triggered via Subscriptions.

To see how these concepts come together, let's walk through a complete example.

Example lifecycle

This example walks through the checkout flow for Zen Electron, a high-end electronics retailer, highlighting how each step maps to Composable Commerce actions and integrations with third-party services.

  1. Cart creation and Product addition: A guest user adds a "ZenBook Pro" laptop to their Cart. The backend creates an anonymous Cart in Composable Commerce, identified by an anonymousId. The laptop is added as a Line Item.
  2. Cart review: The frontend retrieves the current Cart data (Line Items, Prices, totals) to display an Order summary.
  3. Shipping address and Method: The user enters their shipping address.
    1. The backend sets the address on the Cart using the setShippingAddress update action.
    2. It then calls the 3rd-party ShipEngine API with the address and item details to get real-time shipping rates.
    3. Available rates are displayed.
    4. The user selects "Express Air," and the backend calls the setShippingMethod update action on the Cart.
  4. Tax calculation: With the address and Shipping Method set, the backend calls the 3rd-party Avalara tax service with the Cart details. Avalara returns the tax amount, which the backend adds to the Cart.
  5. Payment details: The frontend renders the PSP's secure Payment component, tokenizes sensitive data, and sends the token to the backend.
  6. Create Payment and fraud check:
    1. The backend creates a Payment object with the Cart's totalPrice and links it to the Cart.
    2. It sends Order and Payment context to a fraud service for risk assessment.
  7. Payment authorization: The backend calls the PSP API to authorize using the token, then records the transaction with its type as Authorization. This step is only possible for PSPs that allow the authorization and capture steps to be done separately. For PSPs where authorize and capture steps are atomic—for example, done in a single step—authorize and capture happens at this point.
  8. Place Order and post-Order processes: If the fraud check passes, the backend calls the 'Create Order from Cart' endpoint with the current Cart version. Composable Commerce creates an Order and sets the Cart state to Ordered. An OrderCreated Message triggers a Subscription (ERP sync, email).

    The timing of Order creation affects customer experience, stock management, and revenue tracking. You can create the Order before or after successful payment.

    • Creating an Order after successful payment is often preferred. It offers a more streamlined operational flow and simplifies edge case handling. If payment fails, no Order exists that needs to be canceled. This approach reduces cleanup logic.
    • Creating the Order before payment capture allows you to reserve inventory immediately. However, you must handle payment failures by canceling or updating the Order state.
    For detailed analysis of both approaches, see the Checkout best practices.
  9. Payment capturing: Later, usually just before the package is sent out, a backend system like the fulfillment system calls the PSP API to capture using the token, the backend then records the transaction with its type as Pending (on success, the transaction is updated to Charged, usually, via a webhook call from the PSP).
When updating the Cart or creating an Order, the latest Cart version is always used; every update action increments the Cart version. If you attempt to use an old version, Composable Commerce rejects the request with a concurrent modification error.

The standard pattern is to always query the Cart version before making updates—this is called "read before write."

If any step fails (for example, createOrderFromCart returns an error), implement a retry strategy. Use exponential backoff for transient errors. If the issue is not recoverable, return a descriptive error to the client.

Key takeaways

  • Checkout orchestration relies on the backend coordinating Cart, Payment, and Order interactions plus third-party services.
  • Composable Commerce is the single source of truth: Cart, Order, Payment, and related transactions capture state transitions.
  • Cart version enforces optimistic concurrency; always use the latest version for updates and Order creation.
  • Use tokens, single-use (for example nonces) or reusable, for sensitive Payment data client-side to reduce PCI scope.
  • Design every step (Payment creation, Order creation, external service calls) for idempotency and safe retries.

Next, we will dive into each of these checkout stages in more detail. First up, we will discuss Cart preparation and review, where we will do a deep-dive into retrieving and managing the active Cart, applying promotions, and performing pre-checkout validations.

Test your knowledge