Skip to content

Actions

SOME_CHECKOUT

Social media checkout works in the following way:

  1. A customer writes a comment on the live show on social media
  2. Sprii sends a message on direct messaging (DM) to the customer with a "Go to checkout" button
  3. The user clicks the link and ends on an landing page of your choice. The Sprii script needs to be loaded on that page
  4. The Sprii SDK triggers the action SOME_CHECKOUT

Implementing SOME_CHECKOUT

js


window.onSpriiReady = (sdk) => {
  ...
  const addProductToCart = async (product) => {
    await fetch(`shop-api?itemid=${product.product_id}&quantity=${product.quantity}`, {
      method: 'GET',
    });
  };

  const someCheckoutHandler = async (payload) => {
    for (const product of payload.products) {
      await addProductToCart(product);
    }
    return { status: sdk.actionStatuses.SUCCESS };
  };


  sdk.registerAction(sdk.actions.SOME_CHECKOUT, someCheckoutHandler);
  ...
};

Payload

js
type SoMeCheckoutActionHandler = (payload: {
  clear_cart?: boolean;
  orderNo?: string;
  products: Array<{
    product_id: string;
    quantity: number;
    sku?: string;
    custom_attributes?: { [x: string]: unknown };
  }>;
  redirect_url?: string;
}) => Promise<
  | {
      status: 'PARTIAL';
      message: string;
      failedProducts: Array<{
        product: {
          product_id: string;
          quantity: number;
          sku?: string;
          custom_attributes?: { [x: string]: unknown };
        };
        errorMessage: string;
      }>;
    }
  | { status: 'SUCCESS'; message?: string }
  | { status: 'FAILURE'; message: string }
>;

OPEN_CART

The OPEN_CART action is called in 2 scenarios

  • A user is doing SOME checkout
  • A user clicks "Go to basket" in the player

Implementing OPEN_CART

js
window.onSpriiReady = (sdk) => {
  ...
    sdk.registerAction(sdk.actions.OPEN_CART, async (payload) => {
        document.querySelector('div.cart-icon')?.click();
        return { status: sdk.actionStatuses.SUCCESS };
    });
  ...
}

payload

js
type OpenCartActionHandler = (payload: {
  orderNo?: string;
}) => Promise<{ status: 'SUCCESS'; message?: string } | { status: 'FAILURE'; message: string }>;

GET_CART_CONTENTS

When you want the e-commece basket to be shown inside the player, you must implement GET_CART_CONTENTS This action is called in the following scenaries

  • The player is opened / maximised
  • After modifying the basket

Implementing GET_CART_CONTENTS

js
window.onSpriiReady = (sdk) => {
  ...
    sdk.registerAction('GET_CART_CONTENTS', async () => {
        try {
            const cart = getCartContents();

            if (!cart) {
                return {
                status: sdk.actionStatuses.SUCCESS,
                contents: { productCount: 0, totalPrice: 0, isFullSync: true, products: [] },
                };
            }
            const contents = {
                productCount: cart.numberofproducts || 0,
                totalPrice: cart.totalpriceClean || 0,
                isFullSync: true,
                products: cart.lines
                ? cart.lines.map(
                    (line) =>
                        ({
                        product_id: line.productid,
                        quantity: line.quantity,
                        name: line.name,
                        price: line.unitPrice,
                        totalPrice: line.totalPrice,
                        unitname: orderlineLine.unitname,
                        url: line.url,
                        photoUrl: line.image,

                        })
                    )
                : [],
            };

            return { status: sdk.actionStatuses.SUCCESS, contents };
        } catch (error) {
        return { status: sdk.actionStatuses.FAILURE, message: error.message };
        }
    });
  ...

}

Payload

js
type GetCartContentsActionHandler = () => Promise<
   {
      status: "SUCCESS";
      message?: string;
      contents: {
        products: Array<{
          product_id: string;
          quantity: number;
          sku?: string ;
          custom_attributes?: { [x: string]: unknown };
          name: string;
          price: number;
          totalPrice: number;
          photoUrl?: string;
          url?: string;
        }>;
        totalPrice: number;
        productCount: number;
        isFullSync: boolean;
      };
    }
  | { status: "FAILURE"; message: string }
>;

UPDATE_CART_CONTENTS

When a user adds, removes or updates the content of the cart inside the player, this action is called

Implementing UPDATE_CART_CONTENTS

js
window.onSpriiReady = (sdk) => {
  ...
    sdk.registerAction(sdk.actions.UPDATE_CART_CONTENTS, async (payload) => {
    const errors: ShoppingCartUpdateError[] = [];
    let changed = false;

    for (const change of payload.changes) {
      try {
        switch (change.type) {
          case 'added':
            await addToCart(change.item.product_id, change.item.quantity);
            changed = true;
            break;
          case 'changed':
            await updateCart(change.item.product_id, change.item.quantity);
            changed = true;
            break;
          case 'removed':
            await updateCart(change.item.product_id, 0);
            changed = true;
            break;
        }
      } catch (error) {
        errors.push({
          item: change.item,
          type: change.type,
          errorMessage: (error as Error).message,
        });
      }
    }
    if (errors && errors.length) {
      if (changed) {
        return {
          status: sdk.actionStatuses.PARTIAL,
          message: 'Some updates could not be made.',
          changed,
          errors,
        };
      }

      return {
        status: sdk.actionStatuses.FAILURE,
        message: 'Cart could not be updated',
        changed,
        errors,
      };
    }

    return {
      status: sdk.actionStatuses.SUCCESS,
      changed,
      errors,
    };
  });

  ...

}

Payload

js
type UpdateCartContentsActionHandler = (payload: {
  orderNo?: string;
  changes: Array<{
    type: 'added' | 'changed' | 'removed';
    item: {
      product_id: string;
      quantity: number;
      sku?: string;
      custom_attributes?: { [x: string]: unknown };
    };
  }>;
}) => Promise<
  | { status: 'SUCCESS'; message?: string; changed: boolean }
  | {
      status: 'PARTIAL';
      message: string;
      errors: Array<{
        item: {
          product_id: string;
          quantity: number;
          sku?: string;
          custom_attributes?: { [x: string]: unknown };
        };
        errorMessage: string;
        type: 'added' | 'changed' | 'removed';
      }>;
      changed: boolean;
    }
  | {
      status: 'FAILURE';
      message: string;
      errors: Array<{
        item: {
          product_id: string;
          quantity: number;
          sku?: string;
          custom_attributes?: { [x: string]: unknown };
        };
        errorMessage: string;
        type: 'added' | 'changed' | 'removed';
      }>;
      changed: boolean;
    }
>;

GET_PRODUCT_REDIRECT_URL

GET_PRODUCT_REDIRECT_URL can be used for 2 purposes

  • Handle a custom redirect, like SPA redirect
  • Modify the default url to the product, based on the current user

Implementing GET_PRODUCT_REDIRECT_URL

Example 1: custom redirect

js
window.onSpriiReady = (sdk) => {
  ...
  sdk.registerAction(sdk.actions.GET_PRODUCT_REDIRECT_URL, async (payload) => {
    window.history.pushState(null, '', payload.productUrl);
    window.dispatchEvent(new PopStateEvent('popstate'));
    return { status: sdk.actionStatuses.SUCCESS, handled: true };
  });

  ...

}

Example 2: modify the default url

js
window.onSpriiReady = (sdk) => {
  ...
  sdk.registerAction(sdk.actions.GET_PRODUCT_REDIRECT_URL, async (payload) => {
    return {
      status: sdk.actionStatuses.SUCCESS,
      handled: false,
      url: getProductRedirectUrl(payload.productUrl),
    };
  });

  ...

}

Payload

js
type GetProductRedirectUrlActionHandler = (payload: {
  productUrl: string;
  productData?:
    { id?: string; sku?: string | undefined }
}) => Promise<
    {
      status: "SUCCESS";
      message?: string;
      handled: false;
      url: string;
    }
  | { status: "SUCCESS"; message?: string; handled: true }
  | { status: "FAILURE"; message: string }
>;

GET_USER_DATA

GET_USER_DATA must be implemented if the player should change currency, locale or other user specific settings

Implementing GET_USER_DATA

js
window.onSpriiReady = (sdk) => {
  ...
  sdk.registerAction(sdk.actions.GET_USER_DATA, async () => {
    try {
      const userInfo = await getUserInfo();
      if (!userInfo) {
        return { status: 'SUCCESS' };
      }
      return {
        status: 'SUCCESS',
        data: {
          id: `${userInfo.id}`,
          avatar: userInfo.avatar,
          localeCode: userInfo.localeCode,
          currencyCode: userInfo.currencyCode,
          email: userInfo.email,
          name: userInfo.name,
        },
      };
    } catch (error) {
      return { status: 'SUCCESS' };
    }
  });
  ...

}

Payload

js
type GetUserDataActionHandler = () => Promise<
  | {
      status: 'SUCCESS';
      message?: string;
      data?: {
        id?: string;
        avatar?: string;
        localeCode?: string;
        currencyCode?: string;
        email?: string;
        name?: string;
      };
    }
  | { status: 'FAILURE'; message: string }
>;

GET_PRODUCT_DATA

When users own prices must be shown in the player, GET_PRODUCT_DATA must be implemented

Implementing GET_PRODUCT_DATA

js
window.onSpriiReady = (sdk) => {
  ...
  sdk.registerAction(sdk.actions.GET_PRODUCT_DATA, async (payload) => {
    try {
      const { product_id } = payload;
      const productInfo = await getProductInfo(product_id);

      if (!productInfo) {
        return {
          status: sdk.actionStatuses.SUCCESS,
        };
      }
      const userProductInfo = {
        product_id,
        price: productInfo.price,
        suggestedRetailPrice: productInfo.suggestedRetailPrice
        b2bRetailPrice: productInfo.b2bRetailPrice
        images: produtInfo.images
      };

      return { status: sdk.actionStatuses.SUCCESS, data: userProductInfo };
    } catch (error) {
      return {
        status: sdk.actionStatuses.SUCCESS,
      };
    }
  });
  ...

}

Payload

js
type GetProductDataActionHandler = (payload: {
  product_id: string;
  sku?: string;
  custom_attributes?: { [x: string]: unknown };
  url?: string;
}) => Promise<
  | {
      status: 'SUCCESS';
      message?: string;
      data?: {
        product_id: string;
        minPurchaseQty?: number;
        price: number;
        suggestedRetailPrice?: number;
        b2bRetailPrice?: number;
        retail_markup?: number;
        salable?: boolean;
        images?: Array<string>;
        variants?: Array<{ id: string; price?: number }>;
      };
    }
  | { status: 'FAILURE'; message: string }
>;