UseCheckoutComponent Interface

On the checkout page for a B2B or B2C store created with an LWR template, child checkout components implement the useCheckoutComponent mixin interface.

The component API is used to create custom components that integrate with the checkout process of form validation and the synchronization of external API validations.

/**
 * Applies mixin for base class for any checkout dedicated building block.
 *
 * example:
 * export default class MyCheckoutInput extends useCheckoutComponent(LightningElement) {
 *     setAspect(newAspect: CheckoutContainerAspect): void {
 *         console.log(`dbb newAspect`, JSON.stringify(newAspect));
 *     }
 *     private handleButton(): void {
 *         this.dispatchCommit();
 *     }
 * }
 */
 export function useCheckoutComponent(
    superclass: Constructor<LightningElement>
): Constructor<LightningElement & CheckoutComponent>;

This component API adds these helper methods to a LightningElement.

/**
 * interface implemented by CheckoutComponentMixin
 * and required to exist for CheckoutContainerMixin
 */
export interface CheckoutComponent extends CheckoutComponentHandlers {
  /**
   * notify the container the child component has modified data to put in the form store
   * the container should start 'dirty form' processing:
   * - optionally stageAction on this and other components
   * - save form store data to the server
   * - report errors
   */
  dispatchCommit(): void;
  /**
   * notify the DataProvider to update the form with the supplied changes.
   * the DataProvider catches updateForm errors so components do not need to.
   * unlike most dispatch functions this one is awaitable.
   */
  dispatchUpdateAsync(formRequest: CheckoutFormRequest): Promise<void>;
  /**
   * specialized version of dispatchUpdateAsync for setting client side errors.
   * note: this will never reject or throw, so it's safe not to await if circumstances permit
   */
  dispatchUpdateErrorAsync(errorRequest: CheckoutException): Promise<void>;
  /**
   * notify the DataProvider to start 'final' processing (the place order button pressed)
   * returns a Promise to facilitate advanced payment integrations.
   */
  dispatchFinalizeAsync(): Promise<void>;
  /**
   * notify the DataProvider to call place order API
   * unlike most dispatch fns this one is awaitable.
   */
  dispatchPlaceOrderAsync(): Promise<OrderConfirmation>;
  /**
   * ask our container to change our display such as put us in summary mode
   */
  dispatchRequestAspect(desiredAspect: CheckoutContainerAspectRequest): void;
}

The component API also adds these default implementations for container-initiated actions. The component designer can override these implementations as needed.

/**
 * ComponentRegistration delegates CheckoutContainerSubscriptionPayload to these handlers in the derived component implementation
 */
export interface CheckoutComponentHandlers {
    /**
     * called on connect. derived classes should expose this key the DOM
     * if DOM ordering of container children is needed.
     * container classes combine a DOM query with sortSubscribers to break
     * through the otherwise opaque CheckoutComponentReference.
     * e.g. this.setAttribute('data-checkout-domkey', suggestedDomKey)
     */
    setDomKey(suggestedDomKey: string): string;
    /**
     * display hints from container such as summary mode, stencil, etc.
     * @param newAspect update checkout mode and stage
     */
    setAspect(newAspect: CheckoutContainerAspect): void;
    /**
     * derived class must implement REPORT_VALIDITY_SAVE calls reportValidity if defined.
     * derived class must implement CHECK_VALIDITY_UPDATE or do equivalent before dispatchCommit.
     * unsummarize if an error encountered to ensure it is seen
     *
     * aside: this subsumes all of CheckoutSavable's reportValidity, checkValidity, checkoutSave, placeOrder
     *
     * @param _checkoutStage used to synchronize processing and responses across components
     * @returns a Promise that resolves false if processing should be blocked
     *          should always return true if uninterested in a stage.
     */
    stageAction(checkoutStage: CheckoutStage): Promise<boolean>;

Checkout Stages

These are the currently defined checkout stages.

/**
 * where in the linear steps of checkout process, affects stageAction/reportValidity responses
 * note: these are unordered, stageAction should only use equality checks.
 */
export enum CheckoutStage {
    // commit (user edit) stages that lead to form save (checkout API update)
    //
    // CHECK_VALIDITY_UPDATE may skip update if component updates itself on each change before dispatchCommit
    CHECK_VALIDITY_UPDATE = 'CHECK_VALIDITY_UPDATE',
    REPORT_VALIDITY_SAVE = 'REPORT_VALIDITY_SAVE',
    // finalize stages that lead to place order
    BEFORE_PAYMENT = 'BEFORE_PAYMENT',
    PAYMENT = 'PAYMENT',
    BEFORE_PLACE_ORDER = 'BEFORE_PLACE_ORDER',
    PLACE_ORDER = 'PLACE_ORDER',
}

Aspect Type Definitions

These aspect type definitions are referenced by the helper methods.

/**
 * Used for nested checkout containers to specify how they are displayed
 */
export type CheckoutContainerAspect = {
  /**
   * truthy indicates DP is initializing, preparing for the place order step,
   * or reached an unrecoverable error.
   * input controls should render as readonly
   *
   * WARNING! when disabled or readonly lightning-input.reportValidity always
   *          returns true; therefore, defer setting controls to read-only
   *          unless they pass checkValidity.
   *          Otherwise they break stageAction(REPORT_VALIDITY_SAVE)
   */
  readOnlyIfValid: boolean,
  /**
   * truthy indicates expandable child sections should show as collapsed
   * typically this indicates the section is in a future accordion step, or in
   * a past or future subway step.
   */
  collapse: boolean,
  /**
   * truthy indicates summarizable components should render as summarized
   *
   * component may ignore summary: true requests, and if needed respond
   * with dispatchRequestAspect(false) to ask their containers to become unsummarized;
   * useful because errors are not typically rendered nor fixable in
   * summarized components.
   */
  summary: boolean,
};
/**
 * Used by components to ask their container to change how they are displayed
 */
export type CheckoutContainerAspectRequest = {
  /**
   * true container should enter summary mode, false should leave it
   * Children inform containers they can be summarized.
   */
  summarizable: boolean,
  /**
   * if truthy there are no options and summarized container can hide edit button
   */
  uneditable?: boolean,
};

Checkout Data Provider with Form Data

The checkout data provider is used to access checkout session API data and local, not-yet-persisted form changes. The data provider Checkout.Details publishes an object of type CheckoutFormOverlay.

/**
 * holds current state of checkout from the checkout api overlayed with
 * with unpersisted client side changes and related meta-data.
 */
export type CheckoutFormOverlay = CheckoutInformation & {
  /**
   * captured billing details
   */
  billingInfo?: CheckoutBillingInfo,
  /**
   * captured client side exceptions
   */
  notifications?: FormNotification[],
  /**
   * computed meta information about the overlay
   */
  formStatus?: CheckoutFormStatus,
};
/**
 * billing information that is not necessarily represented
 * in the checkout session
 */
export type CheckoutBillingInfo = {
  address?: Address,
  email?: string,
};
/**
 * computed meta information about the form like is
 * there data that should be saved
 */
export type CheckoutFormStatus = CheckoutFormActivity & {
  /**
   * true if persistForm should be called
   * does not  account for inconguent data, billing info, etc.
   * cleared by persistForm (sometimes) and revertForm
   */
  dirty: boolean,
  /**
   * true if some data typically saved by persistForm is incomplete
   * for example only some of the fields required to save
   * contactInfo have been set.
   * promoted (cleared) to dirty (set) when updateform gets missing data.
   * cleared by revertForm
   */
  incongruent: boolean,
  /**
   * indicates if billingInfo.address explicitly set
   */
  useShippingAddressForBilling: boolean,
};
/**
 * used to add and remove client side notifications returned in the overlay.
 * note: overlay's server side errors are not affected by adding or removing these.
 * note: new client side notifications are appended to the overlay array
 */
export type FormNotification = {
  /**
   * unique ID used to clear all client notifications added in previous requests that
   * had the same groupId.
   */
  groupId: string,
  /**
   * pass a unique type that can control where in the UI the exception renders.
   */
  type?: RequestErrorType,
  /**
   * the l10n string to display in the UI as the notification body.
   * when detail falsey clear all client side set exceptions of this groupId.
   */
  detail?: string,
  /**
   * optional unique error class identifier which can be used to further customize
   * the notification.
   *
   * Examples are the Error.name (PaymentAuthorizationError)
   * or Error.message (CheckoutError.NO_DELIVERY_ADDRESSES)
   */
  code?: string,
};

Updating Checkout Form Data

The checkout data provider published data is updated using the provided component API dispatchUpdateAsync. It accepts an object of type CheckoutFormRequest with the list of fields to update.

/**
 * used by components to update the unpersisted client side data.
 * assumes all contents are "validated" with checkValidity
 */
export type CheckoutFormRequest = {
  /**
   * caller short hand for deliveryGroups.items[0]
   */
  defaultDeliveryGroup?: CheckoutFormRequestDeliveryGroup,
  contactInfo?: ContactInfo,
  billingInfo?: {
    /**
     * in FormRequest send null to revert to useShippingAddressForBilling
     */
    address?: Address | null,
    email?: string,
  },
  notifications?: FormNotification[],
};
/**
 * selectable fields of a DeliveryGroup
 */
export type CheckoutFormRequestDeliveryGroup = {
  /**
   * notice changing the deliveryAddress results in all existing
   * availableDeliveryMethods and any selectedDeliveryMethod (even
   * an explictly set one) to be removed from the overlay until the
   * new deliveryAddress is saved.
   */
  deliveryAddress?: Address,
  desiredDeliveryDate?: string,
  shippingInstructions?: string,
  /**
   * in FormRequest send null to revert to existing selection
   *
   * notice an invalid (or no longer valid) delivery method selection
   * is ignored (the xisting selection (if any) shows in the overlay
   *
   * notice that by default changing the deliveryAddress will not
   * clear any explicitly set selectedDeliveryMethodId.  if a caller
   * wants to reset to the default (cheapest) delivery method when
   * changing addresses they must also explicitly clear any previous
   * selectedDeliveryMethodId setting.
   */
  selectedDeliveryMethodId?: string | null,
};