Actions
SOME_CHECKOUT
Social media checkout works in the following way:
- A customer writes a comment on the live show on social media
- Sprii sends a message on direct messaging (DM) to the customer with a "Go to checkout" button
- The user clicks the link and ends on an landing page of your choice. The Sprii script needs to be loaded on that page
- 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 }
>;