Skip to content

Integration modes

The Shipping Protection (SP) integration mode controls two things: when the fee line is written to the cart, and which SDK method your checkout button calls. Your account manager (AM) configures the integration mode in the back office. Your code can read it, but cannot modify it:

window.xcotton.sp.getMode() // 'cart' | 'checkout' | 'checkoutPlus'

All three modes share the exact same init, syncCart, and adapter setup. Changing the mode changes when the fee line is written, how the first sync cleans the cart, and which call your checkout buttons make. Everything from the Quick start stays unchanged.

Aspectcartcheckoutcheckout+
getMode() return value'cart''checkout''checkoutPlus'
Panel UI (back-office setting)Includes a toggle switchIncludes a toggle switchPrice display only (no switch)
When the switch is toggledImmediately adds or removes the fee lineRecords the customer’s choice and updates the price. Cart is untouched—
When the fee line is writtenOn switch toggle. The first sync and any sync whose SP inputs changed also align itAt checkout, resolveSP() follows the switch intentaddSpFee() on “Checkout with protection”.declineSpFee() on “Checkout without protection”
Checkout button behaviorawait resolveSP(), then navigateSame as cartButtons call await addSpFee() / await declineSpFee()
Additional code requiredCall resolveSP() from checkout, block on failure, retry while busyOne checkout click handlerTwo checkout buttons and their click handlers

In cart mode, toggle-triggered fee writes are asynchronous. The SDK does not intercept native checkout links or make browser navigation wait for a write. Your storefront must call resolveSP() at the checkout boundary. When the intent is on, it re-quotes and aligns the fee line. When the intent is off, it removes the fee line or confirms that none exists (added / removed / skipped). It rejects if adding or removing the fee line fails. resolveSP() does not queue behind a switch write. While a toggle-triggered write is still running, it rejects with OPERATION_IN_PROGRESS. Wait for the write to settle and retry. Navigate only after it resolves. For any other rejection, stay on the page and show the error.

Waiting only for storefront cart requests, observing onCartChange, or seeing a successful recovery read does not prove that the toggle write you just triggered succeeded: a recovery read after a failed write can also trigger onCartChange. The pre-checkout resolveSP() (or addSpFee() / declineSpFee() in checkout+) is the public entry point that observes the write result.

On the initial syncCart(cartId) call (or init({ cartId })), and whenever you switch to a different cart ID, the SDK applies the mode’s entry handling. checkout and checkout+ remove leftover fee lines before refreshing the quote.cart refreshes the quote first, then aligns the fee line with the switch intent:

cart mode. The switch intent is resolved as follows:

  1. Fee line and a main product in cart: keep the fee line and set the switch to on. Exception: if this browser saved an off intent and the cache has not expired, remove the fee line as saved.
  2. No fee line in cart: add the fee line or leave it out according to the switch intent saved in this browser. If nothing was saved, apply the default state configured by your account manager (AM). Apply that default as well on the first visit to the /cart page when the cart has a main product and this browser saved an intent.

The intent cache expires 2 hours after each write. Expiry does not reset every intent to the back-office default. It affects only rule 1: when the cache has expired and the cart has a fee line and a main product, the switch is forced on.

In cart mode, the SDK aligns the fee line with both intent and current eligibility. When the switch intent is on and the cart is eligible, the SDK keeps exactly one fee line with quantity 1. Otherwise, it removes every fee line.

checkout and checkout+ modes. The SDK removes any leftover fee line from the cart regardless of switch state. In both modes, the fee line is written strictly at checkout time. In checkout+ the switch intent is only a generic-model placeholder (initially fixed to on): the SDK never reads, writes, or renews the switch cache.

After the initial sync, syncCart(cart.id) compares the cart facts before and after the sync and re-quotes only when an SP input changes, such as a main product line, a discount code, or a cart-level attribute. Adding or removing a PP protection line does not trigger an SP quote. Switching to another cart runs the mode’s initial handling again. In cart mode, the SDK also removes the fee line whenever the cart becomes empty or the order subtotal falls outside the eligible range. In checkout and checkout+ modes, it updates the quote only and defers fee line changes until checkout.

The SP selector discovers storefront containers and excludes SDK panel and modal subtrees. A container keeps its panel after its first match until the node leaves the document or the configured selector changes. Changing attributes such as its class after mounting does not release the panel. This prevents selectors such as :empty from repeatedly mounting and removing their own content. Remove the container node to dispose of its panel.

The SDK renders only the panel inside your container. It never replaces your checkout button or injects a secondary “without protection” button. Your account manager (AM) configures the panel style to match the integration mode, while your storefront renders the container and checkout buttons:

Elementcartcheckoutcheckout+
Panel styleWith a switchWith a switchUse the price-only panel without a switch
Checkout buttonAdd resolveSP() to the existing button’s click handler. Block on failureExisting button whose click handler calls resolveSP()Two buttons calling addSpFee() and declineSpFee()

checkout+ has no switch intent. If the back office still pairs this mode with a switch panel, the switch only changes the placeholder intent. It writes no cart line and checkout never reads it. The customer’s choice is therefore expressed only by the two checkout buttons, so the page must provide the “without protection” button as well. Do not call resolveSP() (it rejects and points you to the two write entries), and the modal does not show the intent button. You provide both the panel container and the button handlers.

  • cart: the Quick start covers the basic setup. Also implement the checkout call, failure blocking, and busy retry described above.
  • checkout: continue to Checkout mode.
  • checkout+: continue to Checkout+ mode.