This article covers the following:
- Enable Event Payload Customization
- Event Payload Structure
- Examples
- Debug Your Custom Code
- Need more help?
Note: This article explains a feature available in the Shopify Wingify App for Integration, which allows you to customize standard Shopify events before they are imported into your Wingify account. This feature also simplifies Shopify Checkout Extensibility by giving you control over event names and properties.
When configuring the Shopify Wingify App, you can import Shopify standard events directly into your Wingify account. During this setup, you also have the option to customize the event payload, for example, renaming events, modifying properties, or adding calculated values.
Wingify provides a custom middleware layer that lets you intercept and modify the Shopify event payload before Wingify receives it.
Enable Event Payload Customization
In the Shopify Wingify App, under Advanced Code Customization, enable:
Yes, I'd like to customize event payload according to my preferences.
This opens a code editor where you can add one or more middleware functions.
All custom logic written here executes before events are sent to Wingify.
Event Payload Structure
Each event Wingify receives is structured as:
wingifyEventPayload = {
name: "shopify.eventName", // Mandatory
props: {
// Event-specific properties visible in Wingify
}
}
- Do not remove the payload.name in the custom code as it represents the event name.
- Always return the modified payload; otherwise, the updated payload will not be populated in Wingify.
Middleware Function Structure
Wingify provides a middleware function that receives four parameters:
wingify.addShopifyMiddleware(
(wingifyEventPayload, shopifyEvent, browser, customerPrivacyStatus) => {
let newPayload = wingifyEventPayload;
// custom logic here
return newPayload;
}
);
Parameter Details
wingifyEventPayload
The Wingify event payload that will be sent after processing.
Contains:
- name - event name (string)
- props - transformed event properties
Reference for Wingify Shopify event properties:
See "Shopify’s Standard Events Imported Into Wingify" in Wingify docs.
shopifyEvent
The raw Shopify Standard Event object as emitted from the Web Pixels API.
Examples:
- https://shopify.dev/docs/api/web-pixels-api/standard-events/product_viewed
- https://shopify.dev/docs/api/web-pixels-api/standard-events/checkout_completed
Use this when you need data not already mapped into Wingify’s default event properties.
browser (Shopify Browser API - Asynchronous Top-Frame Access)
The browser object exposes a set of asynchronous methods provided by Shopify’s Web Pixels API.
These methods allow your middleware code to safely read and write browser-level data in the top frame, even if your pixel runs inside an iframe.
The browser parameter provides async access to:
Cookies
await browser.cookie.get('key');
await browser.cookie.set('key', 'value');
Local Storage
await browser.localStorage.getItem('key');
await browser.localStorage.setItem('key', 'value');
Session Storage
await browser.sessionStorage.getItem('key');
await browser.sessionStorage.setItem('key', 'value');
These APIs allow you to persist or retrieve user/browser-specific information in a privacy-compliant and secure way.
Reference:
https://shopify.dev/docs/api/web-pixels-api/standard-api/browser
customerPrivacyStatus
Indicates user consent for analytics and marketing:
{
analyticsProcessingAllowed: boolean,
marketingAllowed: boolean,
preferencesProcessingAllowed: boolean,
saleOfDataAllowed: boolean
}
Docs: https://shopify.dev/docs/api/web-pixels-api/standard-api/customerprivacy
Use this to configure event-level privacy logic.
Examples
Rename an Event
wingify.addShopifyMiddleware((wingifyEventPayload) => {
let newPayload = wingifyEventPayload;
if (newPayload.name === "shopify.productViewed") {
newPayload.name = "custom.productViewed";
}
return newPayload;
});
Add Custom Properties From Shopify Event
wingify.addShopifyMiddleware((wingifyEventPayload, shopifyEvent) => {
let newPayload = wingifyEventPayload;
if (newPayload.name === "shopify.productAddedToCart") {
const cartLine = shopifyEvent.data.cartLine;
newPayload.props.sku = cartLine.merchandise.sku;
newPayload.props.cartLineCost = cartLine.cost.totalAmount.amount;
}
return newPayload;
});
Add Page/Browser Context
wingify.addShopifyMiddleware((wingifyEventPayload, shopifyEvent, browser) => {
let newPayload = wingifyEventPayload;
// Read from localStorage
const lastViewed = await browser.localStorage.getItem('lastViewed');
// Add to Wingify props
newPayload.props.lastViewed = lastViewed;
// Store current event name in session storage
await browser.sessionStorage.setItem('lastEvent', newPayload.name);
return newPayload;
});
Filter Events Based on Customer Privacy
wingifyaddShopifyMiddleware((wingifyEventPayload, shopifyEvent, browser, privacy) => {
if (!privacy.analyticsProcessingAllowed) {
// Do not track this event
return null;
}
return wingifyEventPayload;
});
Debug Your Custom Code
Use the Browser Console
Add logs:
console.log("Wingify Payload:", wingifyEventPayload);
console.log("Shopify Event:", shopifyEvent);
For Events That Redirect
Some events, such as checkout_started and checkout_completed, may trigger a page redirect. Because the browser Console is typically cleared when a new page loads, any logs generated before the redirect may disappear.
To retain logs across page navigations, enable Preserve log in Chrome DevTools:
- Open the Console tab.
- Select Preserve log.
This allows you to view console messages generated before and after the redirect, making it easier to troubleshoot your custom code.
Need more help?
For more information or further assistance, contact Wingify Support.