Adding Subscription Experiences to the Novum Theme Engine

Add the Surprise and Delight banner and logic to Novum theme

🚧

Note:

You must be on the Recharge Pro plan and have Theme Engine enabled to add Subscription Experiences to the Novum portal.

This section provides step-by-step instructions for implementing the Surprise and Delight Subscription Experience for the default version of the Novum theme. The same logic applies for Novum 5.0.1 and later themes. All themes prior to Novum 5.0.1 (legacy themes) will require additional logic to fully support Subscription Experiences.

To add the Surprise and Delight Subscription Experience:

  1. In the Recharge merchant portal, click Storefront, and select Theme Editor.
  2. Make a copy of the current active theme by clicking the ellipsis and select Duplicate.
  3. Return to the Theme editor main page, and select Edit code. Navigate to subscriptions.html template and add the logic for displaying the Surprise and Delight banner at the end of the file, before {% endblock %} tag. In the default Novum 5.3.2 theme, this is located on line 203.

Code example:

const settings = {{ settings | json }};
async function fetchQueuedCharges() {
  const schema = `{ "charges": { "status": "QUEUED" } }`;
  try {
	const url = `${ReCharge.Endpoints.request_objects()}&schema=${schema}`;
	const response = await axios(url);

	return response?.data?.charges;
  } catch (error) {
	console.error({ error });
	return {
  	charges: [],
	};
  }
}

async function checkChargeLineItems() {
  const charges = await fetchQueuedCharges();

  if (!charges.length) return;

  let giftItem = null;

  charges.filter((charge) => {
	return charge.line_items.filter((lineItem) => {
  	const giftProperty = ReCharge.Utils.getGiftLineItem(lineItem);

  	if (giftProperty) {
    	giftItem = lineItem;
  	}
	});
  });

  return giftItem;
}

async function init() {
  const flowItem = await checkChargeLineItems();

  if (flowItem && settings?.customer_portal?.wfs_flows_enabled) {
	window.ReCharge.Components.renderSurpriseAndDelight({
  	selector: "#rc_te-template-wrapper",
  	className: "rc_subscription_card_element_wrapper",
  	settings,
  	flowItem,
	});
  }
}

if (settings?.customer_portal?.wfs_flows_enabled) {
  init();
}

  1. In the subscription.html template, add data attribute to <p> element that displays subscription price and below it, add an additional <p> element that would display the offer price. In the default Novum 5.3.2 theme, this is located on line 123.

Code example:

<p data-rc-subscription-price>{{ subscription.price | money_localized }}</p>
<p data-rc-flow-item-price></p>
  1. Additionally, add logic that would render the item price in the subscription.html template. In the default Novum 5.3.2 theme, this is located on line 333, above the closing script tag.

Code example:

function renderFlowItemPrice() {
  const nextCharge = ReCharge.Novum.subscription.charges[0];
  const subscriptionPriceEl = document.querySelector(
	"[data-rc-subscription-price]",
  );
  const flowItemPriceEl = document.querySelector("[data-rc-flow-item-price]");
  const currency = ReCharge.Novum.Utils.getCurrency();

  nextCharge?.line_items
	.filter((item) => item.subscription_id === ReCharge.Novum.subscription.id)
	.map((lineItem) => {
  	// Check for ACR flow item
  	const offerProperty = ReCharge.Utils.getOfferLineItem(lineItem);
  	const { price } = lineItem;
  	const formatedPrice = `${currency}${(+price).toFixed(2)}`;

  	if (offerProperty && subscriptionPriceEl && flowItemPriceEl) {
    	subscriptionPriceEl.style.textDecoration = "line-through";
    	flowItemPriceEl.innerText = `(${ReCharge.translations.flows.activeChurn.discountedOfferLabel}: ${formatedPrice})`;
  	}
	});
}

renderFlowItemPrice();

  1. In the schedule.html template, add the logic that displays discounted offer price. In the default Novum 5.3.2 theme, this is located on line 162 below the isSubscriptionSkippable constant.

Code example:

const chargeItem = charge?.line_items?.find(
  (item) => item.subscription_id === subscription.id,
);
let isOfferItem = false;
let discountedPrice = price;

if (chargeItem) {
  const offerProperty = ReCharge.Utils.getOfferLineItem(chargeItem);
  if (offerProperty) {
	isOfferItem = true;
	discountedPrice = chargeItem.price;
  }
}

const priceOutput = `${ReCharge.Novum.Utils.getCurrency()}${Number(
  discountedPrice,
).toFixed(2)}`;

  1. In the same file (schedule.html), add logic that that would dynamically render price label if the offer exists. In the default Novum 5.3.2 theme, this is located on line 212 below the <p> element that renders Quantity.

Code example:

${ isOfferItem ? `${ReCharge.translations.flows.activeChurn.discountedOfferLabel}: ${priceOutput}` : `${priceOutput}`
}
  1. In the _orders.js file, which is located inside order.line_items.forEach, deconstruct original_price from line_item on lines 69-70. Then, on lines 72-76 perform checks for gift and discount offer. On line 93, render ${lineItemLabel} in <span> element.

Code example:

// Deconstruct original_price from line_item
const { quantity, title, price, variant_title, images, original_price } =
  line_item;

// Check for gift/offer product
const giftProperty = ReCharge.Utils.getGiftLineItem(line_item);
const offerProperty = ReCharge.Utils.getOfferLineItem(line_item);

let lineItemLabel = giftProperty
  ? `${ReCharge.translations.flows.surpriseAndDelight.giftStatus}`
  : offerProperty
  ? `${formatCurrency(price, order.currency)} <s>${formatCurrency(
  	original_price,
  	order.currency,
	)}</s>`
  : formatCurrency(price, order.currency);

// Render lineItemLabel in <span> element
<span class="order-price text-font-14">${lineItemLabel}</span>;

  1. In _helpers.js, on lines 54-58 Inside the renderLineItems function, perform checks for gift and discount offer. On line 76, render ${lineItemLabel} using the <span> element.

Code example:

// Check for gift/offer product
const giftProperty = ReCharge.Utils.getGiftLineItem(line_item);
const offerProperty = ReCharge.Utils.getOfferLineItem(line_item);

let lineItemLabel = giftProperty
  ? `(${ReCharge.translations.flows.surpriseAndDelight.giftStatus})`
  : offerProperty
  ? `(${ReCharge.translations.flows.activeChurn.discountedOfferLabel})`
  : "";

// Render lineItemLabel in <span> element
<span>${lineItemLabel}</span>;

  1. In \_translations.js, add logic to support translations of the Subscription Experience.

Code example:

flows: {
  surpriseAndDelight: {
  	giftStatus: `{{ 'cp_experiences_surprise_free' | t }}`,
  	giftTitle: `{{ 'cp_experiences_surprise_title' | t }}`,
  	giftDescription: `{{ 'cp_experiences_surprise_description' | t }}`,
  	giftBody: `{{ 'cp_experiences_surprise_body' | t }}`
  },
  activeChurn: {
  	discountedOfferLabel: `{{ 'cp_active_churn_discount_label' | t }}`
  }
},

  1. After you complete adding the code into your theme, Save the updated code. You can publish the updated theme by clicking the ellipsis and selecting Publish.

📘

Tip:

Surprise and Delight must be active and customers must meet qualification criteria before they can claim offers.


Add the Active Churn Recovery landing page redirect to custom Novum theme

🚧

Note:

You must be on the Recharge Pro plan and have Theme Engine enabled to add Subscription Experience logic. Additionally, your store must allow cancellation.

This section provides step by step instructions for implementing the Active Churn Recovery Subscription Experience for the default version of the Novum theme. The same logic applies for Novum 5.0.1 and later themes. All themes prior to Novum 5.0.1 (legacy themes) require additional logic and changes to fully support Subscription Experiences.

To add the Active Churn Recovery landing page:

  1. In the Recharge merchant portal, click Storefront, and select Theme Editor.
  2. Make a copy of the current active theme by clicking the ellipsis and select Duplicate.
  3. Find the cancel button. In the default Novum 5.3.2 theme, it is located on the /subscriptions/id page. It is being referenced in _scripts.js file, on line 32.
  4. Then, modify the _scripts.js file to add the redirectToLandingPage function (on line 26, after check for hasMinimumOrderAmount).

Code example:

redirectToLandingPage: function() {
      const redirectUrl = `https://${ReCharge.Novum.store.platform_domain}/tools/recurring/pages/${ReCharge.Novum.customer.hash}/subscriptions/${ReCharge.Novum.subscription.id}/cancel?token=${window.customerToken}&subscription=${ReCharge.Novum.subscription.id}`;


        window.location.assign(redirectUrl);
 },

  1. Perform checks on whether the store has landing pages enabled. This should be added after the check for customer portal settings for the pause subscription feature, on line 43 in default Novum 5.3.2 theme.

Code example:

const isLandingPageActive = ReCharge.Novum.settings.customer_portal.wfs_active_churn_landing_page_redirect;
  1. Using an if statement, on lines 53 - 60, add the following code:
if (
            hasPauseSubscriptionEnabled
        ) {
            const handler = isLandingPageActive ? this.redirectToLandingPage : pauseSubscriptionFlow;
            cancelBtn?.addEventListener("click", handler);
            return;
        } else if (cancel_subscription && this.hasMinimumOrderAmount(orders) && !hasPauseSubscriptionEnabled) {
            const handler = isLandingPageActive ? this.redirectToLandingPage : cancelSubscriptionFlow;
            cancelBtn?.addEventListener("click", handler);
            return;
        } else {
            ReCharge.Utils.contactStoreWording(
                cancelBtn,
                ReCharge.Utils.renderCancelSubscriptionLayout(),
                `{{ 'cp_cancel_cancel_title' | t }}`
            );
        }

  1. After you complete adding the code into your theme, Save the updated code. You can publish the updated theme by clicking the ellipsis and selecting Publish.

📘

Tip:

You must have an active Cancellation Prevention Subscription Experience to redirect customers to the landing page. If there are no active experiences, the default cancellation (modal with cancellation reasons in default Novum 5.3.2 theme) will be used.



Need Help? Contact Us