Dynamic Shipping Restrictions in the Subscription Manager

Restrict which states are available when customers edit their subscription shipping address
View as Markdown

Your site may have certain products that cannot be shipped to certain states. If this is the case, you can change the state choices available when a customer edits their subscription address.

Below is a step-by-step guide to implementing these restrictions. This guide targets restrictions by product ID, but you can use any identifier — for example, subscription.extra_data, product groups, order items, etc. See the Object Reference for a full list of available targets.


Subscription Manager Version

The implementation of dynamic shipping restrictions depends on your theme version. Choose the method that matches your installed Subscription Manager version.

How to Tell What Version You’re On

Before the September 2024 release of v25, all Subscription Manager installations were on version 0, displayed in the Theme Designer as version 0.X.X. You can check which version you’re on by going to Ordergroove > Subscription > Subscription Manager.


Current — smi-templates 25.0.0+

Log in to Ordergroove and go to Subscriptions > Subscription Manager > Advanced. Make the following changes to your code:

Views: order-summary/change-shipping-dialog.liquid

Locate {% set localized_countries = 'localized_countries' | t %} and add the following line below it. Modify the state codes to match the states you do not ship to:

1{% set excluded_states = setting('enabled_states_restricted', ['AK', 'HI']) %}

Locate the <sm-country-state-dropdown> HTML tag and add a new .excludedStates property. The full tag should appear as follows:

1<sm-country-state-dropdown
2 .localizedCountries="{{ localized_countries }}"
3 .enabledCountries="{{ enabled_countries }}"
4 .excludedStates="{{ excluded_states }}"
5>

script.js

Locate the syncCountryAndStates function inside the SMCountryStateDropdown custom element definition. Inside the states.forEach loop, add if (this.excludedStates.includes(code)) return; before calling the createOption function. The updated function should look similar to this (minor updates may have occurred in your version):

1async syncCountryAndStates(countryValue) {
2 const countriesByCode = await countriesDataPromise;
3 const selectedCountry = countriesByCode[countryValue];
4 const states = selectedCountry ? selectedCountry.regions : null;
5
6 const currentOptions = this.stateSelect.querySelectorAll('option');
7 currentOptions.forEach(option => {
8 // Clear all options except default blank option
9 if (option.value !== '') option.remove();
10 });
11
12 if (states && states.length) {
13 states.forEach(({ code, name }) => {
14 if (this.excludedStates.includes(code)) return; // this is the updated line
15 createOption(code, name, this.stateSelect);
16 });
17 }
18}

Subscription Manager 0.33.3 – 0.41.1

Log in to Ordergroove and go to Subscriptions > Subscription Manager > Advanced. Make the following changes to your code:

Views: change-shipment-address.liquid

Locate {% set localized_countries = 'localized_countries' | t %} and add the following line below it. Modify the state codes to match the states you do not ship to:

1{% set excluded_states = setting('enabled_states_restricted', ['AK', 'HI']) %}

Locate and replace the <select> element for state with the following:

1<select id='state_{{ order.public_id }}' class='og-form-select' name='state_province_code' required data-excluded_states='[{{ 'excluded_states.map(s=> `"${s}"`).join(",")' | js }}]'>

script.js

Locate const stateSelectElement = ev.target.closest('form').querySelector('[name="state_province_code"]') and add the following line below it:

1const excludedStates = JSON.parse(stateSelectElement.dataset.excluded_states || '');

Locate states.forEach(({ code, name }) => { and add the following line:

1if (excludedStates.includes(code)) return;

Legacy — Subscription Manager 0.33.2 and Earlier

Step 1: Set All States for the Shipping Dropdown

Set a list of all localized_states you want available for non-restricted products and put that in a JSON object in the en-US.json file.

Step 2: Set the Variables

In change-shipment-address.liquid, set the full list of enabled states (enabled_states_all) and the list of restricted states (enabled_states_restricted). These will be the two lists pulled into the select form based on the criteria. Also set the states object pointing to the localized_states list defined in step 1.

Then set restricted_products to false and run a for loop to iterate over all items in an order and evaluate the product group name or product ID. restricted_products becomes true if the product or group is found.

1{% set enabled_states_all = setting('enabled_states_all', ["AK", "AL", "AR", "AS", "AZ", "CA", "CO", "CT", "DC", "DE", "FL", "GA", "GU", "HI", "IA", "ID", "IL", "IN", "KS", "KY", "LA", "MA", "MD", "ME", "MI", "MN", "MO", "MP", "MS", "MT", "NC", "ND", "NE", "NH", "NJ", "NM", "NV", "NY", "OH", "OK", "OR", "PA", "PR", "RI", "SC", "SD", "TN", "TX", "UT", "VA", "VI", "VT", "WA", "WI", "WV", "WY"]) %}
2{% set enabled_states_restricted = setting('enabled_states_restricted', ["CO", "CT", "DC", "DE", "FL"]) %}
3{% set states = 'localized_states' | t %}
4{% set restricted_products = false %}
5{% set current_order_items = order_items | select(order=order.public_id) %}
6{% for order_item in current_order_items %}
7 {% set restricted_products = (restricted_products or (order_item.product == "42328611848362")) %}
8{% endfor%}

Step 3: Switch State from Input to Select

Replace the state input field with a select dropdown. Use the restricted_products flag to determine which list of states to offer:

1<div class='og-form-group og-col'>
2 <label class='og-form-label {{ 'og-required' if 'required_fields.shipping_address.state_province_code' | setting }}' for='state_{{ order.public_id }}'>
3 {{ 'form_address_state' | t }}
4 </label>
5 <select class='og-form-select' name='state_province_code' id='state_{{ order.public_id }}' ?required='{{ 'required_fields.shipping_address.state_province_code' | setting }}'>
6 {% if restricted_products %}
7 {% for state_province_code in enabled_states_restricted %}
8 <option value='{{ state_province_code }}'>{{ states[state_province_code] }}</option>
9 {% endfor %}
10 {% else %}
11 {% for state_province_code in enabled_states_all %}
12 <option value='{{ state_province_code }}'>{{ states[state_province_code] }}</option>
13 {% endfor %}
14 {% endif %}
15 </select>
16</div>

Step 4: Disable the “Update All” Checkbox

If a customer has products that aren’t shippable to certain states, suppress their ability to use the “update for all” feature when changing their address. This prevents other subscriptions and orders from being updated to an unsupported state.

1<div class='og-input-group'>
2 {% if restricted_products %}
3 <input type='checkbox' class='og-check-radio' name='use_for_all' id='use_for_all_{{ order.public_id }}' />
4 <label class='og-check-radio-label' for='use_for_all_{{ order.public_id }}'>Use for all shipments</label>
5 {% else %}
6 <input type='checkbox' disabled="disabled" class='og-check-radio' name='use_for_all' id='use_for_all_{{ order.public_id }}' />
7 <label class='og-check-radio-label' for='use_for_all_{{ order.public_id }}'>Use for all shipments disabled due to product shipping restrictions</label>
8 {% endif %}
9</div>

Example Result