import { PurchaseListener } from "./listeners/purchase.js";
export default function trackThankYouPage() {
const isThankYouPage = window.location.pathname.includes('/r/purchase/thanks');
if (!isThankYouPage) return;
// Uses the global `rcData` store to get the purchase data
new PurchaseListener(rcData).attach();
document.addEventListener("postPurchaseOfferAccepted", withFlowName(handleAcceptOffer));
document.addEventListener("postPurchaseOfferDeclined", withFlowName(handleDeclineOffer));
document.addEventListener("postPurchaseUpsellCompleted", withFlowName(completeUpsellFlow));
}
// The prices of each added item, used to calculate the final order value
const acceptedOfferValues = [];
/**
* Decorator for event handlers that adds the global flow name to the event.
* @param {function} handler The event handler to decorate
* @return {function} The decorated event handler
*/
function withFlowName(handler) {
return function (event) {
if (![rebuyWidgets, Shopify, offers].every(Boolean)) return null;
const flowName = getFlowName(rebuyWidgets[Shopify.shop], offers);
return handler(event, flowName);
};
}
/**
* Maps widget names to flow names.
* Widget names are keys of the global `rebuyWidgets` object.
* @type {Map<string, string>}
*/
const widgetFlowMap = [
["v1RiverRain12Pack", "Rebuy - V1 River Rain Subscription Flow"],
["v2RiverRain12Pack", "Rebuy - V2 Blind River Rain Subscription Flow"],
["v3RiverRain12Pack", "Rebuy - V3 Cornucopia River Rain Subscription Flow"],
["ecoSheets12Pack", "Rebuy - Default Subscription Flow"],
["ecoSheets3Pack", "Rebuy - Default Onetime Flow"]
];
// Flows are prefixed "Rebuy - " to differentiate from the new upsell system.
function getFlowName(widgets, offerElements) {
const offerWidgets = offerElements.map(({ dataset }) => parseInt(dataset.rebuyId, 10));
for (const [widgetName, flowName] of widgetFlowMap) {
if (offerWidgets.includes(widgets[widgetName])) return flowName;
}
return null;
}
// Gets flow/offer data and pushes it to the data layer
// The value of the accepted offer is stored in acceptedOfferValues
// Triggered by clicking the 'accept' button on a Rebuy offer
function handleAcceptOffer(event, flowName) {
const { product, widget_id } = event.detail;
const isUpsellOffer = widget_id == "34601";
const itemValue = parseFloat(product.selected_variant.price, 10);
acceptedOfferValues.push(itemValue);
// if the offer is an upsell, subtract the value of the removed item
if (isUpsellOffer) {
acceptedOfferValues.push(getRemovedItemValue() * -1);
}
dataLayer.push({
'event': 'post_purchase_offer_accepted',
'flow_name': flowName,
'offer_view': widget_id,
'variants': [product.selected_variant.id.toString()],
'offer_type': isUpsellOffer ? 'upsell' : 'cross-sell',
'value': itemValue
});
}
// Gets flow/offer data and pushes it to the data layer
// Triggered by clicking the 'decline' button on a Rebuy offer
function handleDeclineOffer(event, flowName) {
const { product, widget_id } = event.detail;
const isUpsellOffer = widget_id == "34601";
dataLayer.push({
'event': 'post_purchase_offer_declined',
'flow_name': flowName,
'offer_view': widget_id,
'variants': [product.selected_variant.id.toString()],
'offer_type': isUpsellOffer ? 'upsell' : 'cross-sell'
});
}
// Estimates the final order value and pushes it to the data layer
// Triggered when the last offer is accepted or declined
function completeUpsellFlow(_, flowName) {
dataLayer.push({
'event': 'post_purchase_upsell_completed',
'flow_name': flowName,
'value': getUpsellOrderTotal()
});
}
function getUpsellOrderTotal() {
const addedValue = acceptedOfferValues.reduce((a, b) => a + b, 0);
const initialOrderValue = rcData.cart.total_price;
return initialOrderValue + addedValue;
}
function getRemovedItemValue() {
const subItem = rcData.cart.items.find(isNonDonationSubscriptionItem);
return subItem ? parseFloat(subItem.price, 10) : 0;
}
function isNonDonationSubscriptionItem(item) {
return item.properties && item.properties.shipping_interval_frequency && item.price > 0;
}