# Cart page widget

The Captain Insure App is a tool for creating self-funded shipping protection plans for your customers, where we take the lead to the merchants themselves, offsetting the cost of claims for damaged, lost, or stolen packages. The premium set by the merchant is deposited entirely into the merchant's account, we are not an insurance company and do not underwrite the program.

### Cart page widget

#### 1. A clean and safe install

Since the Captain Shipping Protection widget is embedded in the theme using Shopify's latest technical approach to ensure a clean, secure installation, you'll need to head over to the theme editor to **enable app embedding** first.

<figure><img src="/files/hExFF8VXmzRLxhqdeU1T" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/ZdKdH1Ri21XVvyGCOBiq" alt=""><figcaption></figcaption></figure>

Please note that it is important to remember to click **Save** to complete the application embedding. Please be assured that although the app embed is saved, the widget will not yet appear in your store cart and will not affect the normal functioning of your store cart. You will also need to publish the widget in the next step of our app before applying the widget.

#### 2. Setting up the widget

<figure><img src="/files/mdKQphCeOMcd6mVvqmm0" alt=""><figcaption></figcaption></figure>

Go to the **Protection widget - Cart page** to **publish** the widget and set the shipping protection price and appearance.

Once the insurance widget is published, the widget will start working in your store cart. You can add a product and check the widget effect in the store cart.

<mark style="color:green;">**Please note:**</mark> Different store themes have different shopping cart styles, if the widget does not display and work properly in your store shopping cart, please turn off the publish switch in this step only, but do not turn off the switch for the App embedding in **step 1** (This way the widget will not appear in your store cart, while our technical experts will be able to check it and adapt it to your store theme) .

Then please contact support via **Live Chat** in the App or email **<support@shipwill.org>** and we will check your theme and adapt it to ensure the widget displays and works perfectly in your store cart.

#### 3. Customer Purchase Shipping Protection

<figure><img src="/files/GqGKEk5B97DPpjJcFSiH" alt="" width="563"><figcaption></figcaption></figure>

**Shipping protection exists in your store in the form of a digital product.**

When the widget is enabled, the app automatically creates a shipping protection product for you, the customer places the order with shipping protection enabled, and then at checkout, the system adds the shipping protection item to the order.

#### 4. Merchants keep all profits

We are not an insurance company and do not underwrite the program. Merchants keep all profits from shipping protection products and use a portion of those profits to offset claim costs as needed in the event of an individual claim, and the rest is all yours.


# About store theme compatibility

Different store themes have different shopping cart styles, if the widget fails to display and work properly in your store shopping cart, please contact support via **Live Chat** in the app or email **<support@shipwill.org>**, we will check your theme and adapt it to ensure the widget displays and works perfectly in your store shopping cart.

If you are using a third-party theme or the developer has modified your shopping cart style, these situations may cause the insurance widget to display abnormally. Please feel free to contact us via Live Chat in the app and we will check your theme and adapt it.

We are highly concerned about template compatibility, we guarantee that the insurance widget embedding is seamless and perfect, and will not add any extra code to your theme and uninstall without any residual code.

We are currently fully compatible with **209** Shopify templates, and we will keep updating to be perfectly compatible with more templates. We value your feedback and you can always contact us at **<support@shipwill.org>**


# Shipping protection pricing

### Overview

Captain Insure allows you to set your shipping protection price with 2 methods: by fixed price or by percentage price based on the cart value.

### Percentage price method

When the shipping protection widget is enabled, the app automatically creates a **shipping protection product** for you. The default pricing method is percentage pricing. Within the product details, you will find 100 SKUs. The first SKU, priced at 3.00\*, represents the **default fixed price**, which you can modify under the fixed price method. In addition to the first variant for fixed pricing, the other 99 variants are for percentage pricing. These variants start from a minimum price of $1 and increase in increments of $1.01, with the maximum price capped at $99.98.

The widget calculates the estimated shipping protection price based on the total price of the items in the shopping cart or checkout page, using the percentage you set. It then selects the **closest price variant upwards** from the shipping protection product list.

For example, if the total price of the items in the shopping cart is $220 and the percentage you set is 2%, the calculated estimated price is $4.40. The two adjacent variants of the shipping protection product are $4.03 and $5.04, respectively. In this case, the final widget display price will be $5.04.

<figure><img src="/files/O9KPoq0wR2vZotrRf3Li" alt="" width="563"><figcaption></figcaption></figure>

### Advanced setting for percentage-based shipping protection fee

If you don't like the default variants, such as needing a minimum charge under the percentage method, you can modify the variants using advanced settings.

<figure><img src="/files/9zyPiuXOa0fJ8MuZYgsl" alt=""><figcaption></figcaption></figure>

After clicking 'Advanced settings', you will see a popup that initially displays a minimum charge of $1 and an increment amount of $1.01, which corresponds to the default of 99 SKUs. You can change these values if needed. The minimum charge is the lowest fee you will charge your customers under the percentage method, regardless of the cart value. The increment amount represents the difference between two adjacent variants.

<figure><img src="/files/llJmr3FsrWXuBfT1YsrH" alt=""><figcaption></figcaption></figure>

For example in the below case, If you set the minimum charge to be $3.99 and the increment amount to be $1. Variants used for percentage pricing would be $3.99, $4.99, $5.99...$101.99. If you set your shipping protection charged for 2% of the total cart value, when the cart value equals $50, the price will still be $3.99 since the calculated price is smaller than $3.99. When the cart value equals $500, the calculated price is $10. The two adjacent variants of the shipping protection product are $9.99 and $10.99 respectively. Then the final widget display and order checkout variant price will be $10.99.&#x20;

<figure><img src="/files/oxfLgDcQC7lFedOmkaVp" alt=""><figcaption></figcaption></figure>

### Fixed price

If you prefer to set a single shipping protection fee, you can switch to the fixed-price method. A new shipping protection product will then be created. The price you set below will be the **universal price** applied to all carts and checkouts, regardless of the cart value, unless you have set other tier pricing rules

<figure><img src="/files/JiwjtqmzyWUVMHbRNjdw" alt=""><figcaption></figcaption></figure>

### Create custom tier pricing rules

Under the fixed pricing method, you can also set fees based on cart value tiers by clicking **'Add custom rules'** below the universal price. This allows you to charge different prices based on specific cart value ranges. For example, as shown in the image below, if the cart value is between $0 and $60, the shipping protection fee is $0. If the cart value is between $60 and $100, the fee is $0.99. If the cart value is between $100 and $10,000, the fee is $7.99. If the cart value does not match any custom rules, the **universal price** will be applied. If the cart value meets more than one rule, the **higher shipping price** will be applied.

<figure><img src="/files/TwQlBk4NkltpogpSmyfY" alt=""><figcaption></figcaption></figure>


# Checkout page widget

### Overview

Shopify currently only opens up the ability to customize checkout pages for **Shopify Plus stores**, so you need a Shopify Plus store to load the widget.

### Quick Setup

**Step 1.** Go to **Protection widget - Checkout page,** **publish** the widget at checkout page, and then click **Go to checkout editor**

<figure><img src="/files/Nbzq8OB7fXXmNlcDTsH1" alt=""><figcaption></figcaption></figure>

**Step 2.** In the Shopify checkout editor: click the **Add app block** button > click to add the "**Captain Shipping Protection**" app block > Click Add to **Checkout,** check the displayed insurance style and amount, and finally remember to **Save**!

<figure><img src="/files/ojSvv1go97QRb9ln3YRN" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/v7t1yAEhN5wS3fh2AdYU" alt=""><figcaption></figcaption></figure>

**Step 3.** After the addition is completed, you can also click the arrow in the upper left corner to return to the editing page and adjust the position of the widget you want.

<figure><img src="/files/jREJUXK5U6V5aykeKWQk" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/RpSHT9o79GvX9P540yc6" alt=""><figcaption></figcaption></figure>

**Finally**, remember to go to the actual checkout page of your store to review the widget styles to make sure they appear and function properly.

<figure><img src="/files/kClONA6XVLVSX0DFxNVZ" alt=""><figcaption></figcaption></figure>

If there are any problems, please turn off the widget switch in the App, but there is no need to remove the App block of the checkout page editor, so that the widget will no longer be displayed on your checkout page. Then please contact support via **Live Chat** in Our App or email **<support@shipwill.org>** and we will check your theme and adapt it to ensure the widget displays and works perfectly on your store's checkout page.

### **Our Shopify Plus user**

<figure><img src="/files/qYpltq0cveqI5FjVy7lb" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/NFnAT2U1LrNzRiN5VB28" alt=""><figcaption></figcaption></figure>

**imjoyshoes.myshopify.com**

<figure><img src="/files/EgqtzkwU3AsbPR5onxnF" alt=""><figcaption></figcaption></figure>

And more...


# Claim portal setting

### How to add Captain claim portal to the storefront?

Captain Shipping Protection provides your customers with a seamless experience, from purchasing protection to filing a claim in just a few clicks. Adding a claim portal allows customers who have purchased protection to submit claims at any time. Merchants can manage claims easily, and customers will see updates directly in the portal.

In the Captain Protection app, go to **Claim Portal > Claim Portal Editor**, click **Add Portal**, and then choose the menu and location where you want to place the claim portal.

### How the claim process works

You can also help customers file a claim if needed. Just head to the **Orders** page, find the protected order, and click **File claim**. Once submitted, the customer can still track the status and details of the claim in the portal, just like if they had done it themselves.

### Set a time limit for claim submissions

If you'd like to set a deadline for when customers can submit claims, go to **Settings** > **Claim portal preference**. There, you can choose how many days after the order date a claim can be filed. It's a simple way to keep your policy clear.

### Customize claim resolution options

Want to control whether customers can request a refund, reorder, or both? Go to **Settings** > **Claim portal preference**, and under **Resolution options**, choose what you'd like to offer. You decide what makes sense for your store.

### Customize Claim Reasons

You can create your own claim reasons that best reflect your business. Go to **Settings > Claim portal > Claim reasons** to add or edit them. You can also define the follow-up tasks that will be triggered when a reason is selected. This helps you better track and manage claim control.


# Auto-translation feature

#### What is Auto-translation?

Auto-translation is a useful feature for international stores that operate in multiple languages. When enabled, this feature automatically translates the Shipping Protection widget content to match the languages supported by your store. The translated widgets will appear in the designated languages based on the customer's visiting site.

<figure><img src="/files/Z5kwSVRXktOORQJhuG5V" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/1XhbhK3dI6gZ74osFwf4" alt=""><figcaption></figcaption></figure>

You can always review and verify the accuracy of the translations by selecting languages from the dropdown menu. If a language is not supported for translation, it will default to English. If needed, you can manually edit the text in any language to ensure it meets your requirements.

#### Important note for footer link pages:

If you have set up separate refund policy webpages with unique URLs for different languages, make sure to add the corresponding footer link URLs for each language. This ensures that customers are directed to the correct refund policy page based on their language preference.


# Integrate Captain Shipping Protection with a Shopify Headless Storefront

This guide explains how to add Captain Shipping Protection to a custom Shopify storefront.

It covers two integration options:

* **React storefronts:** use Captain's standard widget and controller hook.
* **Other storefronts:** use the framework-independent SDK and render your own UI.

Both options use the same Shopify cart and checkout flow.

### Before you start

Make sure:

* Captain Shipping Protection is configured for your Shopify store.
* The Captain Shipping Protection product is published to the Shopify Headless sales channel used by your storefront.
* Your storefront can read and update a Shopify cart.
* You can install npm packages.
* Your production storefront uses HTTPS.
* You know the active shopper country, locale, and currency.

> **Important:** Captain calculates which protection variant should be used, but your storefront is responsible for adding or removing Shopify cart lines.

#### Publish Shipping Protection to your Headless sales channel

This step is required. If the Captain Shipping Protection product is not available on the same Headless sales channel as your Storefront API token, Shopify cannot add the protection variant to the cart.

In Shopify Admin:

1. Go to **Products**.
2. Open the Captain Shipping Protection product.
3. Find **Publishing**, **Sales channels**, or **Sales channels and apps**.
4. Click **Manage**.
5. Enable the Headless sales channel used by your storefront.
6. Click **Done**, then save the product if Shopify asks you to save.

The channel name depends on your Shopify setup. Select the channel associated with the Storefront API token used by this headless storefront.

If you have multiple Headless channels, publishing the product to a different channel is not sufficient. The protection product must be available to the exact channel making the cart request.

You can verify the setup by querying the protection product or variant through the same Storefront API token. Shopify must return the product and allow its variant to be used as `merchandiseId` in `cartLinesAdd`.

### Choose an integration

#### Use the React package when

* Your storefront uses React 18 or later.
* You want Captain's standard widget.
* You want checked, loading, error, and cleanup state managed for you.

Install:

```sh
npm install captain-shipping-protection-react captain-shipping-protection-sdk
```

#### Use the Core SDK when

* Your storefront uses Vue, Svelte, Angular, Solid, or Vanilla JavaScript.
* You already have a shipping protection UI.
* You want full control over state and presentation.

Install:

```sh
npm install captain-shipping-protection-sdk
```

### How the integration works

Captain recommends adding protection only when checkout begins:

1. Read the current Shopify cart.
2. Convert it to Captain's cart format.
3. Ask Captain for the current price, variant, and eligibility.
4. Show the protection option when the cart is eligible.
5. Store the shopper's checked choice in your storefront.
6. If the cart already contains protection, remove that line and keep the shopper checked.
7. When checkout begins, request the latest protection information.
8. Add one unit of the latest variant when the shopper is checked.
9. Redirect immediately to the checkout URL returned by Shopify.

This approach avoids repeatedly changing the Shopify cart while the shopper edits products or quantities.

> **Important:** Toggling the widget records shopper intent only. It should not immediately add or remove a Shopify cart line.

### Prepare your Shopify cart data

Both packages require the same `SdkCartData` structure.

Shopify Storefront GraphQL returns GIDs and decimal money strings. Captain expects numeric Shopify IDs and integer minor-unit prices.

For USD:

* `"12.99"` from Shopify becomes `1299`.
* `"100.00"` from Shopify becomes `10000`.

Use a cart mapper like this:

```ts
import type {SdkCartData} from "captain-shipping-protection-sdk";

type StorefrontCart = {
  id: string;
  totalQuantity: number;
  cost: {
    subtotalAmount: {
      amount: string;
      currencyCode: string;
    };
  };
  lines: {
    nodes: Array<{
      id: string;
      quantity: number;
      cost: {
        totalAmount: {
          amount: string;
        };
      };
      merchandise: {
        id: string;
        sku?: string | null;
        title: string;
        product: {
          id: string;
          title: string;
        };
      };
    }>;
  };
};

function numericShopifyId(gid: string): number {
  const value = Number(gid.split("/").pop());

  if (!Number.isFinite(value)) {
    throw new Error(`Invalid Shopify GID: ${gid}`);
  }

  return value;
}

function toMinorUnits(amount: string): number {
  return Math.round(Number(amount) * 100);
}

export function toSdkCartData(cart: StorefrontCart): SdkCartData {
  return {
    token: cart.id,
    currency: cart.cost.subtotalAmount.currencyCode,
    total_price: toMinorUnits(cart.cost.subtotalAmount.amount),
    item_count: cart.totalQuantity,
    items: cart.lines.nodes.map((line) => ({
      id: numericShopifyId(line.merchandise.id),
      key: line.id,
      quantity: line.quantity,
      variant_id: numericShopifyId(line.merchandise.id),
      product_id: numericShopifyId(line.merchandise.product.id),
      final_line_price: toMinorUnits(line.cost.totalAmount.amount),
      title: line.merchandise.title,
      product_title: line.merchandise.product.title,
      sku: line.merchandise.sku ?? "",
    })),
  };
}
```

Create a new mapped cart whenever products, quantities, discounts, currency, or line prices change.

### Option A: React integration

The recommended React integration combines:

* `ShippingProtectionWidget` for the standard UI.
* `useShippingProtectionController` for Captain state and requests.

#### Add the controller

```tsx
import {
  ShippingProtectionWidget,
  useShippingProtectionController,
  type SdkCartData,
} from "captain-shipping-protection-react";

interface ShippingProtectionSectionProps {
  cart: SdkCartData;
  currency: string;
  findProtectionLineIds: (productId: string) => string[];
  removeCartLines: (lineIds: string[]) => Promise<void>;
  refreshCart: () => Promise<void>;
  addProtectionAndGetCheckoutUrl: (
    variantGid: string,
  ) => Promise<string>;
  getCheckoutUrl: () => Promise<string>;
}

function toVariantGid(variantId: string): string {
  return variantId.startsWith("gid://shopify/ProductVariant/")
    ? variantId
    : `gid://shopify/ProductVariant/${variantId}`;
}

export function ShippingProtectionSection({
  cart,
  currency,
  findProtectionLineIds,
  removeCartLines,
  refreshCart,
  addProtectionAndGetCheckoutUrl,
  getCheckoutUrl,
}: ShippingProtectionSectionProps) {
  const protection = useShippingProtectionController({
    shop: "example.myshopify.com",
    country: "US",
    locale: "en",
    currency,
    cart,

    removeProtection: async (info) => {
      const lineIds = findProtectionLineIds(info.productId);

      if (lineIds.length > 0) {
        await removeCartLines(lineIds);
        await refreshCart();
      }
    },
  });

  async function handleCheckout() {
    const latestInfo = await protection.prepareCheckout();

    const checkoutUrl = latestInfo
      ? await addProtectionAndGetCheckoutUrl(
          toVariantGid(latestInfo.variantsId),
        )
      : await getCheckoutUrl();

    window.location.assign(checkoutUrl);
  }

  return (
    <>
      {protection.visible && protection.info ? (
        <ShippingProtectionWidget
          checked={protection.checked}
          currency={currency}
          disabled={
            protection.togglePending ||
            protection.removePending
          }
          info={protection.info}
          onToggle={protection.toggle}
          setting={protection.setting}
        />
      ) : null}

      {protection.removeError ? (
        <div role="alert">
          <p>Could not clean up the existing protection line.</p>
          <button type="button" onClick={() => void protection.refresh()}>
            Retry
          </button>
        </div>
      ) : null}

      <button
        type="button"
        disabled={
          protection.initPending ||
          protection.infoPending ||
          protection.removePending
        }
        onClick={() => void handleCheckout()}
      >
        Checkout
      </button>
    </>
  );
}
```

Replace the adapter props with your Storefront API or Hydrogen cart implementation.

#### React state behavior

The controller handles these rules:

* Uses the merchant's default checked setting on the first eligible cart.
* Keeps the shopper's checked choice when the cart changes.
* Sets the widget to checked when an existing protection line is found.
* Calls `removeProtection()` to clean up that existing line.
* Prevents duplicate cleanup requests.
* Hides the widget when the cart is excluded.
* Recalculates the latest price and variant in `prepareCheckout()`.

#### React checkout behavior

`prepareCheckout()` returns:

* `ShippingProtectionInfo` when protection should be added.
* `null` when the shopper is unchecked or the cart is excluded.
* `null` when an existing protection line could not be safely cleaned up.

After receiving protection info:

1. Convert `variantsId` to a Shopify ProductVariant GID.
2. Add exactly one unit to the cart.
3. Use the checkout URL returned by that mutation.
4. Redirect immediately.

Do not remain on the cart page after adding protection. The cart-page controller removes existing protection so the next checkout attempt can calculate a fresh variant.

### Option B: Core SDK integration

The Core SDK returns plain data and works with any browser framework.

#### Initialize the SDK

```ts
import {
  shippingProtection,
  type ShippingProtectionInfo,
} from "captain-shipping-protection-sdk";

await shippingProtection.init({
  shop: "example.myshopify.com",
  country: "US",
  locale: "en",
  currency: "USD",
});
```

Call `init()` again if the active shop, country, locale, or currency changes.

#### Request protection information

```ts
const info = await shippingProtection.getInfo({
  cartData: toSdkCartData(shopifyCart),
});
```

The response includes:

```ts
interface ShippingProtectionInfo {
  productId: string;
  variantsId: string;
  price: string;
  includedProtection: boolean;
  isExcluded: boolean;
  excludedReason?: string;
}
```

#### Manage your UI state

The Core SDK does not store checked state. Use your framework's normal state management.

```ts
let checked = false;
let checkedInitialized = false;
let currentInfo: ShippingProtectionInfo | null = null;
let latestRequestId = 0;

async function syncProtection(shopifyCart: StorefrontCart) {
  const requestId = ++latestRequestId;
  const info = await shippingProtection.getInfo({
    cartData: toSdkCartData(shopifyCart),
  });

  // Ignore a response for an older cart.
  if (requestId !== latestRequestId) {
    return;
  }

  currentInfo = info;

  if (info.includedProtection) {
    checked = true;
    checkedInitialized = true;
    await removeProtectionLinesByProductId(info.productId);
    await refreshHostCart();
  } else if (!checkedInitialized) {
    checked =
      shippingProtection.setting?.tm_default_display_status === 1;
    checkedInitialized = true;
  } else if (info.isExcluded) {
    checked = false;
  }

  renderProtection({
    checked,
    hidden: info.isExcluded,
    info,
    setting: shippingProtection.setting,
  });
}

function onProtectionToggle(nextChecked: boolean) {
  checked = nextChecked;

  if (currentInfo) {
    renderProtection({
      checked,
      hidden: currentInfo.isExcluded,
      info: currentInfo,
      setting: shippingProtection.setting,
    });
  }
}
```

Implement `removeProtectionLinesByProductId`, `refreshHostCart`, and `renderProtection` in your application.

#### Prepare checkout with the Core SDK

```ts
function toVariantGid(variantId: string): string {
  return variantId.startsWith("gid://shopify/ProductVariant/")
    ? variantId
    : `gid://shopify/ProductVariant/${variantId}`;
}

async function prepareProtectionForCheckout() {
  let shopifyCart = await getCurrentShopifyCart();
  let info = await shippingProtection.getInfo({
    cartData: toSdkCartData(shopifyCart),
  });

  if (info.includedProtection) {
    await removeProtectionLinesByProductId(info.productId);
    shopifyCart = await getCurrentShopifyCart();
    info = await shippingProtection.getInfo({
      cartData: toSdkCartData(shopifyCart),
    });
  }

  if (!checked || info.isExcluded) {
    return null;
  }

  return {
    ...info,
    variantGid: toVariantGid(info.variantsId),
  };
}

async function checkout() {
  const protection = await prepareProtectionForCheckout();

  const checkoutUrl = protection
    ? await addProtectionAndGetCheckoutUrl(protection.variantGid)
    : await getCheckoutUrl();

  window.location.assign(checkoutUrl);
}
```

### Connect the Shopify Storefront Cart API

Both integration options require the host storefront to add and remove cart lines.

#### Add protection at checkout

Use Shopify's `cartLinesAdd` mutation:

```graphql
mutation AddShippingProtection(
  $cartId: ID!
  $lines: [CartLineInput!]!
) {
  cartLinesAdd(cartId: $cartId, lines: $lines) {
    cart {
      id
      checkoutUrl
    }
    userErrors {
      field
      message
    }
  }
}
```

Variables:

```json
{
  "cartId": "gid://shopify/Cart/your-cart-id",
  "lines": [
    {
      "merchandiseId": "gid://shopify/ProductVariant/123456789",
      "quantity": 1
    }
  ]
}
```

#### Remove existing protection

Find cart lines whose Shopify product ID matches `info.productId`, then remove their cart line IDs with `cartLinesRemove`:

```graphql
mutation RemoveShippingProtection(
  $cartId: ID!
  $lineIds: [ID!]!
) {
  cartLinesRemove(cartId: $cartId, lineIds: $lineIds) {
    cart {
      id
      checkoutUrl
    }
    userErrors {
      field
      message
    }
  }
}
```

Match by product ID, not only by variant ID. Captain may choose a different variant when the eligible cart total changes.

Always check Shopify `userErrors` before updating your local cart or redirecting.

### SSR storefronts

Run Captain SDK operations in the browser.

#### Next.js App Router

Place the integration in a Client Component:

```tsx
"use client";

import {
  ShippingProtectionWidget,
  useShippingProtectionController,
} from "captain-shipping-protection-react";
```

Pass serializable cart data from your Server Component to the Client Component.

#### Hydrogen, Remix, Nuxt, and SvelteKit

You can load the Shopify cart on the server, but initialize Captain after the component mounts or from browser-only cart code.

Do not call `init()`, `getInfo()`, or `prepareCheckout()` during the server render.

### Content Security Policy

Captain sends configuration and eligibility requests to:

```
https://insurance.captaintop.com
```

If your storefront has a Content Security Policy, add this origin to `connect-src`:

```
connect-src 'self' https://insurance.captaintop.com;
```

The React widget may display a merchant-configured external icon. If your CSP restricts images, add the icon's exact origin to `img-src`.

Captain does not require an external script, iframe, or font origin. Do not add broad permissions such as `*` or `'unsafe-inline'` solely for this integration.

### Understand common states

#### The widget is visible and checked

The shopper wants protection. Do not add it yet. Add the latest variant when checkout begins.

#### The widget is visible and unchecked

Continue checkout without adding protection.

#### `includedProtection` is `true`

The Shopify cart already contains Captain's protection product:

1. Keep the widget checked.
2. Remove all matching protection lines.
3. Refresh your host cart.
4. Keep checked enabled after the cart refresh.

#### `isExcluded` is `true`

Hide the widget and continue checkout without protection.

Common exclusion reasons include:

* `empty_cart`
* `invalid_cart`
* `only_shipping_protection`
* `excluded_variant`
* `check_display_hidden`

Treat exclusion reasons as extensible.

#### Captain requests fail

Hide or disable the protection UI and allow checkout without protection unless your business requirements say otherwise.

### Test your integration

Before deployment, test:

* An eligible cart with the widget checked.
* An eligible cart with the widget unchecked.
* An empty cart.
* A cart containing only protection.
* A cart containing an excluded variant.
* Quantity changes that select a different protection price.
* A cart loaded with an existing protection line.
* Failure while removing an existing protection line.
* Failure while adding protection.
* A stale response from an older cart request.
* A storefront with CSP enabled.
* Checkout redirect with and without protection.

### Troubleshooting

#### The widget does not appear

Check:

* The store has an active Captain configuration.
* SDK initialization completed.
* `info.isExcluded` and `info.excludedReason`.
* Cart product and variant IDs are valid numeric IDs.
* Browser requests are not blocked by CSP or CORS.

#### Toggling does not add a Shopify cart line

This is expected. The toggle stores intent only. Add the variant returned by the latest Captain request when checkout begins.

#### The protection price is incorrect

Verify:

* `total_price` uses integer minor units.
* Every `final_line_price` uses integer minor units.
* The latest cart is passed after products, quantities, or discounts change.
* Existing protection is included in mapped cart data so Captain can subtract it from the eligible total.

#### Shopify cannot add the returned variant

Convert a numeric variant ID to:

```
gid://shopify/ProductVariant/<variantsId>
```

Then confirm the Captain Shipping Protection product is published to the exact Headless sales channel associated with your Storefront API token.

When the product is not published to that channel, Shopify commonly returns an error similar to:

```
The merchandise with id gid://shopify/ProductVariant/... does not exist.
```

The variant may exist in Shopify Admin and still be unavailable to your headless storefront. Open the protection product's publishing settings, enable the correct Headless channel, save, and retry with the same Storefront token.

#### Duplicate protection lines appear

Before adding protection:

* Remove lines matching `info.productId`.
* Refresh the cart.
* Request Captain info again.
* Add exactly one unit of the returned variant.

#### Protection is removed immediately after checkout starts

Add protection and redirect immediately using the checkout URL returned by the same mutation. Do not publish the updated cart back to the visible cart page and remain there.

### Go-live checklist

* Captain Shipping Protection is configured for the store.
* The Shipping Protection product is published to the exact Headless sales channel used by the Storefront API token.
* The correct npm package or packages are installed.
* Shopify GIDs and money values are mapped correctly.
* The active country, locale, and currency are passed to Captain.
* The UI updates after every relevant cart change.
* Shopper toggle behavior changes intent only.
* Existing protection lines are removed by product ID.
* Checkout waits for protection cleanup to finish.
* The latest variant is requested immediately before checkout.
* Exactly one protection line is added.
* Shopify `userErrors` are handled.
* Checkout redirects using the updated cart URL.
* CSP allows `https://insurance.captaintop.com`.
* Error paths allow the shopper to continue checkout safely.

### Package reference

For complete API and type details:

* React package: `captain-shipping-protection-react`
* Framework-independent SDK: `captain-shipping-protection-sdk`


# Checkout-button widget

Try out the checkout-button widget to boost your shipping protection attach rate.

We’re launching a new widget style designed to boost shipping protection conversions. This style is best suited if you prefer a cleaner format and want to achieve higher conversion rates. Depending on your store type and the products you sell, the opt-in rate can increase by more than 10% on average.

Try it out starting today and see how it performs!

<figure><img src="/files/8E8L2j8JVPjwbuLmhf7Y" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/aGvg79mVwdm1XuEcHm9Z" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/BpJdo9uHoabFI1GRlSQz" alt=""><figcaption></figcaption></figure>


# Order value correlation metric

<figure><img src="/files/JRWiTfUsuVr3g39lF5VM" alt=""><figcaption></figcaption></figure>

### What is Order Value Correlation

Order Value Correlation measures the relationship between order value and the purchase rate of shipping protection.

It helps you understand whether customers are more likely to buy shipping protection on higher-value orders, or less.

### How to interpret this metric

The correlation score ranges from -1 to 1:

* Close to 1 (positive correlation)\
  Higher-value orders are more likely to include shipping protection
* Close to 0 (no clear relationship)\
  Order value has little impact on purchase behavior
* Close to -1 (negative correlation)\
  Higher-value orders are less likely to include shipping protection

### What do different values mean

We provide automatic insights based on the score:

<table><thead><tr><th width="124.48046875"></th><th></th></tr></thead><tbody><tr><td>≥0.3</td><td><p>Higher-value orders are significantly more likely to include shipping protection.</p><p>Customers feel more confident adding protection to expensive purchases.</p></td></tr><tr><td>0 to 0.3</td><td>Purchase rate increases slightly with order value.<br>Shipping protection still appeals to higher-value orders.</td></tr><tr><td>-0.3 to 0</td><td>Purchase rate slightly decreases as order value increases.<br>Some customers may feel the protection cost is relatively high.</td></tr><tr><td>-1 to -0.3</td><td>Higher-value orders are less likely to include shipping protection.<br>This may indicate a shipping protection is too expensive for higher value order.</td></tr><tr><td>-</td><td>There isn’t enough data to calculate the correlation accurately.</td></tr></tbody></table>

We recommend using this metric together with other data points (such as purchase rate and pricing) to make informed decisions.


# More conversion-boosting tools

### Explore more conversion-boosting tools:

Our friends at **Blikket** have compiled a set of inspiring case studies that reveal how brands like yours drove dramatic uplifts in conversion. Try it out and see how it goes starting today by visiting [https://blikket.co/case-studies](https://blikket.co/case-studies/)


# Hide shipping protection products from recommendations

Before hiding the product

<figure><img src="/files/gKlIeG0VUvY09zT4mps2" alt=""><figcaption></figcaption></figure>

After hiding the product

<figure><img src="/files/zLzA5iZPlda9A9eqzx4j" alt=""><figcaption></figcaption></figure>

### Tutorials

Step 1: In Shopify admin, navigate to **Theme** > click **Customize**

<figure><img src="/files/dpD8ZZQy8XtCf7XnAySL" alt=""><figcaption></figcaption></figure>

Step 2: Click the three dots beside the theme name, click **Edit code**

<figure><img src="/files/suMeuWMva6mODFSQ3qA4" alt=""><figcaption></figcaption></figure>

Step 3: Search or select **related-products.liquid**&#x20;

<figure><img src="/files/Blj1GIde96iLcaSvOXZv" alt=""><figcaption></figcaption></figure>

Step 4: Find the following codes and select them

<figure><img src="/files/gZR8K0u7qSt35zFfeIJz" alt=""><figcaption></figcaption></figure>

Step 5: Replace them with the following new codes

```
<ul
        class="grid product-grid grid--{{ section.settings.columns_desktop }}-col-desktop grid--{{ section.settings.columns_mobile }}-col-tablet-down"
        role="list"
      >
        {% for recommendation in recommendations.products %}
          {% if recommendation.vendor contains "ShipWill" %}
           {% continue %}
           {% else %}
          <li class="grid__item">
            {% render 'card-product',
              card_product: recommendation,
              media_aspect_ratio: section.settings.image_ratio,
              image_shape: section.settings.image_shape,
              show_secondary_image: section.settings.show_secondary_image,
              show_vendor: section.settings.show_vendor,
              show_rating: section.settings.show_rating
            %}
          </li>
          {% endif %}
        {% endfor %}
      </ul>
```

Step 6: All set, below are the targeted codes, don't forget to save and check it live!

<figure><img src="/files/mdmExWjpTLuUOyRUnOFA" alt=""><figcaption></figcaption></figure>


# Exclude shipping protection products from collection

Because of Shopify's shopping cart system, Shipping Protection actually exists as a digital product in your store.

When the Shipping Protection widget is enabled, the app automatically creates a Shipping Protection product for your store so that shipping protection can be added to orders.

Because the Shipping Protection is a digital product, it may be displayed on the store website. Here are some ways to hide the Shipping Protection product display on your store website.

### Hide shipping protection products from home page

Step 1: Go to your **Shopify store’s Collections section** > Click  **Create collection**

<figure><img src="/files/KjPvBt5fCRMDiueqrSur" alt=""><figcaption></figcaption></figure>

Step 2: Fill in "all" in the collection title. Select the condition as "all conditions," then select the product type, select "is not equal to," and select the value as "ShipWill." Finally, click the "**Save**" button.

<figure><img src="/files/UYGuvOC9SMDQv131VHpX" alt=""><figcaption></figcaption></figure>

This should exclude shipping protection items from all products.

If this does not work, go to your **Shopify Admin** > **Content** > **Menu**, and replace the link for your menus with the collection named **all** you just created.

<figure><img src="/files/CqZwDCK3UExrz3jbor2P" alt=""><figcaption></figcaption></figure>

**Please note that** 👉 our app has automatically created this "**all**" collection for your store, so you don't need to create this collection again. Please rest assured that this collection will not conflict with your other collections, so there is no need to delete it. If you accidentally delete the collection, you can follow this guide to recreate the collection.

### Hide shipping protection products in specific collections

Go to your **Shopify store’s Collections section** > Click the corresponding collection

When the condition of the collection is set to "*<mark style="color:purple;">**all conditions**</mark>*", the shipping protection products need to meet all conditions to appear in the collection. So you can **add another condition**, select the **product type**, select "**is not equal to**", and select the value "**ShopWill**". Finally, click the "**Save**" button. In this way, the shipping protection products will not appear in the collection.

<figure><img src="/files/DlsrWKEqWm9wdv3oJh7W" alt=""><figcaption></figcaption></figure>

When the condition of the collection is set to "*<mark style="color:purple;">**any condition**</mark>*", the shipping protection product will appear in the collection when it meets any of the conditions. So if you want the shipping protection product not to appear in this type of collection, you need to check and make sure that the shipping protection product does not meet any of the conditions.

### How to ensure discounts do not apply to the shipping protection product?

When applying a discount to specific collections, ensure that the collections do not include the insurance product. The "all" collection that we automatically created for you does not include the shipping protection product. If you want to create other collections for a specific discount, simply do not select the shipping protection product.

Conversely, if you wish to include the shipping protection product in the discount, just add it to the discount collection.

The same logic applies when applying a discount to specific products: select the shipping protection product to include it in the discount. Deselect the shipping protection product to exclude it from the discount.

If you are still unable to hide the shipping protection products after following this guide, please contact support via **Live Chat** in the app or email **<support@shipwill.org>**, we will help you resolve this issue.


# Exclude widget in a certain market

To hide the shipping protection widget in specific markets: Go to **Market** in admin,  choose the market where you want to exclude the widget  > select the **Shipping protection** product (there may be one or two products depending on your pricing setup) > click **Exclude from market** > click **Save**

<figure><img src="/files/8WaJMz29enPsC3ExPtyU" alt=""><figcaption></figcaption></figure>


# FAQs

### **What are the benefits of Captain Protection?**

As shipping costs rise, the few orders that are "lost" each month slowly become more and more expensive. The Captain Shipping Protection helps you offset the cost of shipping issues by giving you a tool that allows you to charge your customers a small fee for shipping protection.

### **Will all shipping protection fees paid by customers be retained by the merchant? How much does the customer need to pay?**

Shipping protection fees paid by the customer are retained entirely by the merchant (we are not an insurance company and do not cover plans).

In our app, you can set up to charge for shipping protection either as a fixed price or as a percentage of the total item price.

### **Will customers actually opt in and pay for it?**

Yes, over 50% of our clients pay this small additional fee. Captain Protection is an app built by merchants for merchants. This means that we are already running our app in our own Shopify Plus store, generating a lot of extra profit every month.

### **Are we an insurance company?**

No, we are not. We are a software company that allows e-commerce stores and merchants to charge their customers a small fee for shipping protection, helping you offset the cost of issues like damaged, lost, or stolen packages.

### **How are we different from insurance companies?**

First, we are not an insurance company. We will not communicate with your customers at any time. Instead, we give you, the merchant, the tools to help you provide your customers with shipping protection, but you are the one who controls the entire experience. You collect and retain the fees, which you can use to offset the cost of the claim for a refund as needed. What's left is your profit.

### **Can you display your widget during checkout?**

Shopify currently only opens up the ability to customize checkout pages for Shopify Plus stores, so you need a Shopify Plus store to load the widget.

### **Are specific refund and compensation policies set by the merchant?**

Yes, specific refund and compensation policies are set by the merchant, and you may choose to include the refund policy URL in the shipping protection purchase instructions.

### What are some recommendations for increasing conversions?

* **Use the Checkout-Button Widget**\
  Try our checkout-button style widget to boost your shipping-protection attachment rate. It has a much higher conversion rate than the standard opt-out widget.
* **Explore Partner Case Studies**\
  See how top merchants drove higher conversions using similar tactics—check out our Partner Spotlight here: [https://blikket.co/case-studies](https://blikket.co/case-studies/)


# Privacy Policy

## Captain Shipping Protection Privacy Policy

#### 1. Introduction

Captain Shipping Protection (the "App") provides shipping protection services to merchants ("you") using Shopify-powered stores. This Privacy Policy explains how we collect, use, and protect personal information when you install or use the App.<br>

By using the App, you agree to the terms of this policy.

***

#### 2. Information We Collect

**A. From Shopify Merchants (You)**

When you install the App, we automatically access the following data from your Shopify account:

* Shopify store details (e.g., store name, domain, contact email).
* API permissions necessary for functionality:
  * write\_products, read\_products (to manage shipping protection rules).
  * write\_script\_tags, read\_script\_tags (to enable frontend features).

**B. From Your Customers**

We do not directly collect or store personal data about your store’s customers (e.g., names, addresses, payment details). Our service operates without accessing or processing sensitive customer information.

Exception: If your store shares customer data with us (e.g., for order processing), we will:

* Only collect the minimum required (e.g., order ID, shipping cost).
* Encrypt and anonymize data where possible.

**C. Technical Data**

We may log non-personal information for security and analytics:

* IP addresses, browser type, and time zone (aggregated and anonymized).
* Cookies (only for App functionality; no tracking for ads).

***

#### 3. How We Use Your Information

We use collected data solely to:

* Provide and maintain the App’s core features (e.g., shipping protection rules).
* Troubleshoot issues and improve performance.
* Communicate with you about updates or support requests.
* Comply with legal obligations (e.g., fraud prevention).

We do NOT:

* Sell or rent your data to third parties.
* Use data for advertising or unrelated marketing.

***

#### 4. Data Security

We implement industry-standard measures to protect your information:

* Encryption: All data transfers use HTTPS/TLS.
* Access controls: Limited to authorized personnel.
* Regular audits: To identify and address vulnerabilities.

Note: While we take reasonable steps, no system is 100% secure. You are responsible for securing your Shopify account (e.g., strong passwords).

***

#### 5. Data Retention & Deletion

* We retain merchant data only as long as the App is installed.
* To request deletion of your data, email [support@shipwill.org](https://mailto:support@shipwill.org/).

***

#### 6. Third-Party Services

The App integrates with:

* Shopify’s APIs (subject to [Shopify’s Privacy Policy](https://www.shopify.com/legal/privacy)).
* Payment processors (if applicable; transactions are handled by Shopify).

We do not share data with other third parties unless legally required.

***

#### 7. Changes to This Policy

We may update this policy periodically:

* Notified via email or App dashboard (for major changes).

***

#### 8. Contact Us

For questions, data requests, or compliance inquiries:

* Email: [support@shipwill.org](https://mailto:support@shipwill.org/)


