Allow customers to manage bundles

🚧

Note

This guide is specifically for custom bundling solutions, not the Recharge Bundles feature. For the Recharge Bundles feature review the Help Center guide.

Once you've added the bundling feature to your Recharge store, can give customers the ability to manage their bundle subscription on their own. This guide is for stores whose customers are using the Recharge Customer Portal to manage subscriptions.

1566

This guide focuses on grouping bundles together on the main subscriptions
page and allowing customers to bulk update the next charge date for all subscriptions within a bundle.

Updating the subscriptions page

  1. In the Merchant Portal, navigate to Wrench icon > Theme
    Editor
    and create a new Recharge Novum theme using the Novum template.
  2. You will modify the subscriptions.html file.

Key concepts

Create a bundle subscriptions variable

Filter the subscriptions parent object to only include bundle subscriptions and store
the filtered list in the bundle_subscriptions variable. Use this list throughout the code,
to determine which subscriptions need to use the new bundle layout.

The example below filters by the Shopify product ID 7339618009319, but you will
update this number to match the ID of your bundle product. If you have multiple bundle
products, you can append more IDs to this list. See the logic used for the
cancelled_expired_subscriptions variable found later in this guide this file for further examples.

{% set bundle_subscriptions = subscriptions | selectattr('shopify_product_id', 'equalto', 7339618009319) | list %}

Display bundled products together

Create a blank array, bundles_displayed. As you render each bundle, add the unique bundle ID to this array to ensure you don’t display the same bundle twice.

{% set bundles_displayed = [] %}

For both the active and cancelled subscriptions sections, add a conditional statement to
check if the specific subscription is a bundle. If it’s not, render the standard subscription layout. If it is a bundle product, render the updated bundle layout.

{% if active_subscriptions | length %}
    <h2 class="page-title">
        {{ 'cp_active_subscriptions' | t }}
    </h2>
    {% for subscription in active_subscriptions | sort(attribute='next_charge_scheduled_at') %}
        {% if subscription not in bundle_subscriptions %}
            ...
        {% elif subscription in bundle_subscriptions %}
            ...

When the loop iterates over a bundle subscription, loop through all active subscriptions and check to see if the subscription is a bundle and if it’s already been displayed. If that bundle ID hasn’t been displayed, render the bundle and add the ID to the bundles_displayed array.

{% for subscription in active_subscriptions %}
    {% for property in subscription.properties %}
        {% if property.name == 'bundle_id' %}
            {% if property.value not in bundles_displayed %}
                {% if bundles_displayed.append(property.value) %}{% endif %}

Update the subscriptions card for bundles

Make the following changes to the subscriptions card.

  • Update the image - Because the main bundle image should be displayed rather than the specific variant image, update the code to display the main Shopify product image.
<img src="{{ subscription.product.shopify_details.image['src'] | img_url(image_size) }}" alt="{{ subscription.product_title }}">
  • Display all variant titles and quantities- To show the contents of the bundle, loop through the subscriptions again and render the variant titles and quantities.
{% set bundle_subscription_ids = [] %}
{% set bundle_prices = [] %}
{% for variant in bundle_subscriptions %}
    {% for variant_property in variant.properties %}
        {% if variant_property.value == property.value %}
            {% if bundle_subscription_ids.append(variant.id) %}{% endif %}
            <p>
                {{ variant.variant_title }}x{{ variant.quantity }}
            </p>
            {% if bundle_prices.append(variant.price * variant.quantity) %}{% endif %}
        {% endif %}
    {% endfor %}
{% endfor %}
  • Update the price - Show the total bundle price rather than the
    price of one variant. To do this, update the price section. In the variant title and quantity steps above, you should add the bundle prices to a new array. Get the sum of this array to calculate the total price of the bundle.
<p class="text-font-14">
{{ bundle_prices | sum | money_localized }}
</p>
  • Replace the ‘Edit’ button with an ‘Update next charge date’ button - The standard Edit
    button in Novum takes the customer to the subscription.html page. This page includes details
    about that subscription the customer can update, including adding upsells. For this customization, you only want customers to make changes to the overall bundle rather than each item within it.

👍

Tip

There are many of opportunities to get creative with editing bundles, such as adding a pop-up modal with options to edit the bundle contents, frequency, etc., or keeping the ‘Edit’ button and sending customers to a customized subscription.html page to edit the bundle. Check out all of the endpoints available in our Theme Engine docs that allow you to create a personalized experience for customers.

<a href="#" class="rc_btn--secondary rc_btn--secondary--color text-uppercase title-bold text-center
    js-bulk-edit-next-charge-date" data-date="{{ subscription.next_charge_scheduled_at }}" data-address-id="{{ subscription.address_id }}" data-status="{{ subscription.status}}" data-subscription-ids="{{bundle_subscription_ids | join(',')}}">Update Next Shipment Date</a>

You should include several data attributes in this button element such as the subscription next charge date, address IDs, and all subscription IDs in the bundle. You will use these later in the bulk update JavaScript.

  • Cancelled subscriptions - You will make very similar changes to the cancelled subscription cards towards the bottom of the page. Instead of removing the edit button, remove the Re-activate button. This example doesn't cover bulk re-activation. For the purposes of this tutorial, you should ask customers to email you to reactivate their bundle subscription. It's possible to build in bulk reactivation in the customer portal with further customization. See Recharge's theme documentation to explore the bulk subscriptions endpoint.

Full subscriptions.html example

{% extends "base.html" %}
{% block content %}
    <script>
        {% include '_subscriptions.js' %}</script>
    {% set active_subscriptions = subscriptions | selectattr('status', 'equalto', 'ACTIVE') | list %}
    {% set cancelled_expired_subscriptions = [] %}
    {% for subscription in subscriptions | selectattr('status', 'equalto', 'CANCELLED') %}
        {% if cancelled_expired_subscriptions.append(subscription) %}{% endif %}
    {% endfor %}
    {% for subscription in subscriptions | selectattr('status', 'equalto', 'EXPIRED') %}
        {% if cancelled_expired_subscriptions.append(subscription) %}{% endif %}
    {% endfor %}
    {# create bundle list #}
    {% set bundle_subscriptions = subscriptions | selectattr('shopify_product_id', 'equalto', 6779671347409)
| list %}
    <div class="rc_add_product">
        <h3>
            {{ 'Subscriptions' | t }}
        </h3>
        {% if settings.customer_portal.subscription.add_product %}
            <button class="rc_btn border-light text-uppercase title-bold" onclick="addProductHandler(event);">
                {{ 'cp_add_product_label' | t }}
            </button>
        {% endif %}
    </div>
    <br>
        {% set bundles_displayed = [] %}
        {% if active_subscriptions | length %}
            <h2 class="page-title">
                {{ 'cp_active_subscriptions' | t }}
            </h2>
            {% for subscription in active_subscriptions | sort(attribute='next_charge_scheduled_at') %}
                {% if subscription not in bundle_subscriptions %}
                    <div class="rc_subscription_card_element_wrapper rc_subscription_container">
                        <div class="rc_subscription_info_container">
                            <div class="rc_photo_container">
                                {% set image_size = '100x100' %}
                                {% include '_product_image.html' %}
                            </div>
                            <div class="rc_schedule_wrapper">
                                <div class="rc_order_title_container">
                                    <span class="rc_order_title">
                                        {{ subscription.product_title | replace('Auto
renew', '') }}
                                    </span>
                                </div>
                                <p>
                                    {% if subscription.status == 'ACTIVE' %}
                                        {% include '_subscription-icon.svg' %}
                                        {% if subscription.is_prepaid %}
                                            {{ 'pre_paid' | t }}
                                        {% endif %}
                                        {{ 'cp_subscription' | t }}
                                    {% endif %}
                                </p>
                                {% if subscription.variant_title %}
                                    <p>
                                        {{ subscription.variant_title }}
                                    </p>
                                {% endif %}
                                <p>
                                    {{ 'Quantity' | t }}:
                                    {{ subscription.quantity }}
                                </p>
                                <p class="text-font-14">
                                    {{ subscription.price | money_localized }}
                                </p>
                            </div>
                        </div>
                        <div class="rc_subscription_next_charge_date">
                            <div>
                                {% if subscription.charge_interval_frequency !=
subscription.order_interval_frequency %}
                                    <p>{{ 'next_charge' | t }}</p>
                                {% else %}
                                    <p>{{ 'cp_next_shipment' | t }}</p>
                                {% endif %}
                                {% if subscription.next_charge_scheduled_at %}
                                    <h2 class="color-light-green">
                                        {% set next_charge_date = subscription.next_charge_scheduled_at | date('%B
%d') | downcase %}
                                        {% include '_translated_month.html' %}
                                    </h2>
                                {% else %}
                                    <h2 class="color-dark-red">
                                        {{ 'cp_no_date' | t }}
                                    </h2>
                                {% endif %}
                            </div>
                            <a href="{{ subscription.id | subscription_url }}" class="rc_btn--secondary rc_btn--secondary--color text-uppercase title-bold
                                    text-center">
                                {{ 'Edit' | t }}
                            </a>
                        </div>
                    </div>
                {% elif subscription in bundle_subscriptions %}
                    {% for subscription in active_subscriptions %}
                        {% for property in subscription.properties %}
                            {% if property.name == 'bundle_id' %}
                                {% if property.value not in bundles_displayed %}
                                    {% if bundles_displayed.append(property.value) %}{% endif %}
                                    <div class="rc_subscription_card_element_wrapper rc_subscription_container">
                                        <div class="rc_subscription_info_container">
                                            <div class="rc_photo_container">
                                                {% set image_size = '100x100' %}
                                                <img src="{{ subscription.product.shopify_details.image['src'] | img_url(image_size) }}" alt="{{ subscription.product_title }}"></div>
                                                <div class="rc_schedule_wrapper">
                                                    <div class="rc_order_title_container">
                                                        <span class="rc_order_title">{{ subscription.product_title |
replace('Auto renew', '') }}</span>
                                                    </div>
                                                    <p>
                                                        {% if subscription.status == 'ACTIVE' %}
                                                            {% include '_subscription-icon.svg' %}
                                                            {% if subscription.is_prepaid %}
                                                                {{ 'pre_paid' | t }}
                                                            {% endif %}
                                                            {{ 'cp_subscription' | t }}
                                                        {% endif %}
                                                    </p>
                                                    {% set bundle_subscription_ids = [] %}
                                                    {% set quantities = [] %}
                                                    {% for variant in bundle_subscriptions %}
                                                        {% for variant_property in variant.properties %}
                                                            {% if variant_property.value == property.value %}
                                                                {% if bundle_subscription_ids.append(variant.id) %}{% endif %}
                                                                <p>
                                                                    {{ variant.variant_title }}
                                                                    x
                                                                    {{ variant.quantity }}
                                                                </p>
                                                                {% if quantities.append(variant.quantity) %}{% endif %}
                                                            {% endif %}
                                                        {% endfor %}
                                                    {% endfor %}
                                                    <p class="text-font-14">
                                                        {% set bundle_price = subscription.price * (quantities | sum) %}
                                                        {{ bundle_price | money_localized }}
                                                    </p>
                                                </div>
                                            </div>
                                            <div class="rc_subscription_next_charge_date">
                                                <div>
                                                    {% if subscription.charge_interval_frequency !=
subscription.order_interval_frequency %}
                                                        <p>{{ 'next_charge' | t }}</p>
                                                    {% else %}
                                                        <p>{{ 'cp_next_shipment' | t }}</p>
                                                    {% endif %}
                                                    {% if subscription.next_charge_scheduled_at %}
                                                        <h2 class="color-light-green">
                                                            {% set next_charge_date = subscription.next_charge_scheduled_at |
date('%B %d') | downcase %}
                                                            {% include '_translated_month.html' %}
                                                        </h2>
                                                    {% else %}
                                                        <h2 class="color-dark-red">
                                                            {{ 'cp_no_date' | t }}
                                                        </h2>
                                                    {% endif %}
                                                </div>
                                                <div class="bulk_update_btn">
                                                    <a href="#" class="rc_btn--secondary rc_btn--secondary--color text-uppercase
                                                        title-bold text-center js-bulk-edit-next-charge-date" data-date="{{ subscription.next_charge_scheduled_at }}" data-address-id="{{ subscription.address_id }}" data-status="{{ subscription.status }}" data-subscription-ids="{{ bundle_subscription_ids | join(',') }}">Update
                                                        Next Shipment Date</a>
                                                </div>
                                            </div>
                                        </div>
                                    {% endif %}
                                {% endif %}
                            {% endfor %}
                        {% endfor %}
                    {% elif not cancelled_expired_subscriptions | length %}
                        <h2>
                            {{ 'No_Subscriptions_Message' | t }}
                        </h2>
                    {% endif %}
                {% endfor %}
            {% endif %}
            {% set cancelled_bundles_displayed = [] %}
            {% if cancelled_expired_subscriptions | length %}
                <h2 class="page-title">
                    {{ 'cp_inactive_subscriptions' | t }}
                </h2>
                {% for subscription in cancelled_expired_subscriptions %}
                    {% if subscription not in bundle_subscriptions %}
                        <div class="rc_subscription_card_element_wrapper rc_inactive_subscriptions">
                            <div class="rc_subscription_info_container">
                                <div class="rc_photo_container">
                                    {% set image_size = '100x100' %}
                                    {% include '_product_image.html' %}
                                </div>
                                <div class="rc_schedule_wrapper">
                                    <div class="rc_order_title_container">
                                        <span class="rc_order_title">
                                            {{ subscription.product_title | replace('Auto
renew', '') }}
                                        </span>
                                        {% if subscription.status == 'EXPIRED' %}
                                            <p class="expired-icon">
                                                {{ 'Expired' | t }}
                                            </p>
                                        {% endif %}
                                    </div>
                                    <p>
                                        {% include '_subscription-icon.svg' %}
                                        {% if subscription.is_prepaid %}
                                            {{ 'pre_paid' | t }}
                                        {% endif %}
                                        {{ 'cp_subscription' | t }}
                                    </p>
                                    <p>
                                        {{ 'Quantity' | t }}:
                                        {{ subscription.quantity }}
                                    </p>
                                    <p class="text-font-14">
                                        {{ subscription.price | money_localized }}
                                    </p>
                                </div>
                            </div>
                            {% if settings.customer_portal.subscription.reactivate_subscription %}
                                <div>
                                    <button class="text-uppercase width-100 {{ 'expired' if subscription.status == 'EXPIRED'
                                        else 'rc_btn--secondary rc_btn--secondary--color' }}" {{ 'disabled' if subscription.status == 'EXPIRED' else '' }} onclick="reactivateSubscriptionHandler(event);" data-id="{{ subscription.id }}">
                                        {{ 'Re-activate' | t }}
                                    </button>
                                </div>
                            {% endif %}
                        </div>
                    {% elif subscription in bundle_subscriptions %}
                        {% for subscription in cancelled_expired_subscriptions %}
                            {% for property in subscription.properties %}
                                {% if property.name == 'bundle_id' %}
                                    {% if property.value not in cancelled_bundles_displayed %}
                                        {% if cancelled_bundles_displayed.append(property.value) %}{% endif %}
                                        <div class="rc_subscription_card_element_wrapper rc_subscription_container">
                                            <div class="rc_subscription_info_container">
                                                <div class="rc_photo_container">
                                                    {% set image_size = '100x100' %}
                                                    <img src="{{ subscription.product.shopify_details.image['src'] | img_url(image_size) }}" alt="{{ subscription.product_title | replace('Auto renew', '') }}"></div>
                                                    <div class="rc_schedule_wrapper">
                                                        <div class="rc_order_title_container">
                                                            <span class="rc_order_title">{{ subscription.product_title |
replace('Auto renew', '') }}</span>
                                                            {% if subscription.status == 'EXPIRED' %}
                                                                <p class="expired-icon">
                                                                    {{ 'Expired' | t }}
                                                                </p>
                                                            {% endif %}
                                                        </div>
                                                        <p>
                                                            {% if subscription.status == 'ACTIVE' %}
                                                                {% include '_subscription-icon.svg' %}
                                                                {% if subscription.is_prepaid %}
                                                                    {{ 'pre_paid' | t }}
                                                                {% endif %}
                                                                {{ 'cp_subscription' | t }}
                                                            {% endif %}
                                                        </p>
                                                        {% set bundle_subscription_ids = [] %}
                                                        {% set quantities = [] %}
                                                        {% for variant in bundle_subscriptions %}
                                                            {% for variant_property in variant.properties %}
                                                                {% if variant_property.value == property.value %}
                                                                    {% if bundle_subscription_ids.append(variant.id) %}{% endif %}
                                                                    <p>
                                                                        {{ variant.variant_title }}
                                                                        x
                                                                        {{ variant.quantity }}
                                                                    </p>
                                                                    {% if quantities.append(variant.quantity) %}{% endif %}
                                                                {% endif %}
                                                            {% endfor %}
                                                        {% endfor %}
                                                        <p class="text-font-14">
                                                            {% set bundle_price = subscription.price * (quantities | sum) %}
                                                            {{ bundle_price | money_localized }}
                                                        </p>
                                                    </div>
                                                </div>
                                                <div>
                                                    <a class="text-uppercase width-100 {{ 'expired' if subscription.status == 'EXPIRED'
                                                        else 'rc_btn--secondary rc_btn--secondary--color' }}" href="mailto: {{ store.email }}">To reactivate,
                                                        please email us at
                                                        {{ store.email }}</a>
                                                </div>
                                            </div>
                                        {% endif %}
                                    {% endif %}
                                {% endfor %}
                            {% endfor %}
                        {% endif %}
                    {% endfor %}
                {% endif %}
                <script>
                    (function () {
                        ReCharge.Novum.addresses = {{ addresses | sort(attribute='id') | json }};
                        ReCharge.Novum.store = {{ store | json }};
                        ReCharge.Novum.settings = {{ settings | json }};
                        ReCharge.Novum.subscriptions = {{ subscriptions | json }};
                        ReCharge.Novum.onetimes = {{ onetimes | json }};
                        const discounts = [];
                        ReCharge
                            .Novum
                            .addresses
                            .forEach(address => {
                                if (address.discount_id != null) {
                                    discounts.push(address.discount);
                                }
                            });
                        sessionStorage.setItem('rc_discounts', JSON.stringify(discounts));
                    })();
                </script>
            {% endblock %}
776

Add JavaScript to customer portal

For the customer portal features to work, you must add functions that update all items in the bundle when a customer makes a change to the bundle.

Create functions to bulk update next shipment

Create a new asset file called _bundle.js. In this file, create two new functions that allow customers to select a new charge date and trigger the bulk update. Model these functions off of the existing edit charge date functions in the Novum theme.

  • bulkEditNextShipment - This is the function called when the customer clicks on Update next charge date . At a high level, this function does the following.

  • Grabs the data attributes from the button element including the next charge
    date, address ID, and string of all of the bundle subscription IDs

  • Toggles a sidebar and renders a new form with a calendar that will trigger the
    bulk update when submitted.

function bulkEditNextShipment(event) {
  event.preventDefault();
  const parent = event.target.closest(".js-bulk-edit-next-charge-date");
  const subDate = parent.dataset.date;
  const status = event.target.dataset.status;
  const addressId = event.target.dataset.addressId;
  const subscriptionIds = event.target.dataset.subscriptionIds;
  const title = `{{ 'next_charge' | t }}`;
  let calendarDate = ReCharge.Novum.Utils.formatDate(new Date());
  if (subDate != "None") {
    calendarDate = subDate.split("T")[0];
  }
  let actionUrl = ReCharge.Endpoints.bulk_update_subscription_url(addressId);
  let redirect_url = ReCharge.Endpoints.list_subscriptions_url();
  ReCharge.Novum.sidebarHeading.innerHTML = title;
  ReCharge.Novum.sidebarContent.innerHTML = `
<form method="post" action="${actionUrl}" id="ReChargeForm_date">
<input type="hidden" name="redirect_url" value="${redirect_url}">
{% include '_vanilla_calendar.html' %}
<br>
<button
type="button"
class="rc_btn text-uppercase title-bold"
onclick="bulkUpdateNextChargeDateHandler(event, '${subscriptionIds}', '${addressId}')"
>
{{ 'cp_update_next_shipiment_date_button' | t }}
</button>
</form>
`;
  ReCharge.Novum.Helpers.initCalendar(calendarDate);
  if (status === "ONETIME") {
    document
      .querySelector("#next_charge_date")
      .setAttribute("name", "next_charge_scheduled_at");
  }
  ReCharge.Novum.toggleSidebar();
}
  • bulkUpdateNextChargeDateHandler() - This is the function you will call when the customer clicks Update next charge date in the sidebar. At a high level, this function does the following:
    • Retrieves the selected next charge date,
    • Creates the data object required by the Theme Engine bulk update endpoint. Include each subscription ID along with the new charge date, so you can convert the passed in subscription ID string to an array, loop through the array, and add it to the data object.
    • Calls the Recharge.Subscriptions.bulk_update() function with this newly created data object and address id, which will actually make the AJAX call.
function bulkUpdateNextChargeDateHandler(event, ids, addressId) {
  event.preventDefault();
  // Get element with the new date value
  const newDateEl = document.querySelector("#next_charge_date");
  const dataToSend = { subscriptions: [] };
  ids.split(",").forEach((id, i) => {
    dataToSend.subscriptions.push({
      id: id,
      next_charge_scheduled_at: newDateEl.value,
    });
  });
  console.log(dataToSend);
  ReCharge.Forms.toggleSubmitButton(event.target);
  ReCharge.Subscription.bulk_update(addressId, JSON.stringify(dataToSend));
}

_scripts.js file

  • ReCharge.Actions.put() - The Novum theme includes a function that makes a PUT request to the Recharge backend to make updates to subscriptions. You need to modify this function slightly, so it can handle structured data properly. Add the Content-Type header shown below:
ReCharge.Actions = {
  /*...*/
  put: async function (endpoint, id, data, productTitle = null) {
    /*...*/
    const response = await axios({
      url: dataUrl,
      headers: {
        "Content-Type": "application/json",
      },
      method: "post",
      data,
    });
    /*...*/
  },
};
  • ReCharge.Endpoints.bulk_update_subscription_url() - In order to generate the endpoint required for the AJAX request, add the code below to the ReCharge.Endpoints object.
ReCharge.Endpoints = {
...
bulk_update_subscription_url: function(id) {
return attachQueryParams(`${this.base}addresses/${id}/subscriptions-bulk-update`);
  }
};
  • ReCharge.Subscription.bulk_update() - This function is called in the bulkUpdateNextChargeDateHandler() function when a user submits their date change. It will trigger the bulk update AJAX call to the Recharge server.
ReCharge.Subscription = {
...
bulk_update: function(id, data) {
return ReCharge.Actions.put('bulk_update_subscription_url', id, data);
  }
};

_recharge.js file

The final step to allowing customers to manage their bundle is adding an event listener to the Update next shipment button that will trigger the bulkEditNextShipment() function and open the calendar sidebar. Modify existing configureStore() function in the _recharge.js asset file, which sets the standard Edit event listener. If the customer portal Edit upcoming order date setting is disabled for customers, add a listener that will trigger the default Contact store email layout instead.

function configureStore() {
  // Edit next charge date configuration
  const editNextChargeDateBtn =
    document.querySelector(".js-edit-next-charge-date-btn") || null;
  const nextDeliveryContainer =
    document.querySelector(".js-edit-next-charge-date") || null;
  // Create new variable containing all bulk edit next charge date buttons
  const editBundleNextChargeDateBtns =
    document.querySelectorAll(".js-bulk-edit-next-charge-date") || null;
  // Check if store allows editing next charge date
  // If yes, add event listener that will trigger the update charge date flow, bulk update // flow if
  //bundle. If no, trigger contact store layout
  if (settingsStore.customer_portal.subscription.edit_scheduled_date) {
    if (editNextChargeDateBtn) {
      ReCharge.Novum.Helpers.showElement(editNextChargeDateBtn);
      nextDeliveryContainer.addEventListener("click", editNextShipment);
    } else if (editBundleNextChargeDateBtns.length) {
      editBundleNextChargeDateBtns.forEach((editBundleNextChargeDateBtn) =>
        editBundleNextChargeDateBtn.addEventListener(
          "click",
          bulkEditNextShipment
        )
      );
    }
  } else {
    if (editNextChargeDateBtn) {
      ReCharge.Novum.Helpers.showElement(editNextChargeDateBtn);
      ReCharge.Utils.contactStoreWording(
        nextDeliveryContainer,
        ReCharge.Utils.renderContactStoreLayout(`{{ 'cp_next_shipment' | t }}`),
        `{{ 'cp_next_shipment' | t }}`
      );
    } else if (editBundleNextChargeDateBtns.length) {
      editBundleNextChargeDateBtns.forEach((editBundleNextChargeDateBtn) => {
        ReCharge.Utils.contactStoreWording(
          editBundleNextChargeDateBtn,
          ReCharge.Utils.renderContactStoreLayout(
            `{{ 'cp_next_shipment' | t }}`
          ),
          `{{ 'cp_next_shipment' | t }}`
        );
      });
    }
  }
}

Hide the bundle product from the Add a Product and Toss these in sections

You should ensure customers aren’t able to add individual bundle product variants via the Add a product button or via the Toss these in section because the ability to add a custom bundle in the Theme Engine is out of the scope of this guide. Additional customization is required if you’d like to allow customers to be able to purchase customized bundles post-purchase.

While you can accomplish this via custom CSS, you can use the new Recharge collections feature, which allows you to curate a custom collection of products that are available for purchase on the customer portal.

  1. Create a Recharge collection with all subscription products excluding the build-a-box
    product.
  2. Adjust the customer portal settings to only allow this collection to be available on the
    portal

Update the customer portal delivery schedule settings

For the purposes of this guide, remove access to the delivery schedule in the customer portal because it requires additional customization to group the bundle subscriptions together. However, if you’d like to keep the delivery schedule page, you can leverage the logic used in the subscriptions.html file to group the bundles together and update the edit functionality on the delivery schedule page.

To update the settings, go to the Recharge merchant portal Wrench icon > Customer portal and in the customer portal controls section, update the Delivery schedule to Storeowner
only
, then save.

782

Need Help? Contact Us