Skip to main content
The Juo subscription widget handles purchase options, pricing, and cart logic for you. Some stores need their own interface instead: a custom product page, a bundle builder, a quiz, or a headless storefront. This guide explains what any custom implementation has to get right for subscription purchases to reach checkout and become Juo subscriptions. It is written for developers working on a Shopify theme or a headless storefront. Examples use Liquid and the Ajax Cart API, with Storefront API equivalents where they differ.

How a subscription reaches checkout

Shopify has no separate “subscription product”. A subscription is a regular cart line that carries a selling plan: a variant ID, a quantity, and a selling plan ID. When an order with that line is placed, Juo creates the subscription from it. The objects you work with: Things that follow from this model:
  • A cart line has exactly one selling plan, or none. No selling plan means a one-time purchase.
  • Only Juo’s selling plans become Juo subscriptions. Plans created by other apps are handled by those apps.
  • Allocations are per variant. A variant that is not in any subscription plan has no allocations and cannot be added with a selling plan. Shopify rejects the request.
  • The plan’s price applies per unit. Shopify does not link a selling plan to a quantity. See Offers that depend on quantity.
  • Plans can be recurring or fixed. A recurring plan (recurring_deliveries: true) creates a subscription contract with a stored payment method. A fixed plan does not. Juo uses hidden fixed plans for local payment methods. See If you use local payment methods.
Set up subscription plans in Juo and assign products to them before you build the storefront. See Subscribe and save, or assign products and variants with the Juo Admin API. A selling plan group holds at most 31 plans. With local payment methods enabled, Juo’s hidden fixed plans count toward that limit, so each subscription plan supports up to 15 frequencies.

1. Expose selling plan data

Your interface needs, for each variant, the recurring Juo plans it can be bought on and their prices. In a theme, render this once into the product template as JSON.
Two filters matter here:
  • app_id: 'juo-subscriptions' keeps plans from other apps out of your interface.
  • recurring_deliveries keeps only recurring plans. When local payment methods are enabled, Juo adds a hidden fixed plan with the same name for every recurring plan. Without this filter, every frequency appears twice.
Prices are in the customer’s currency, in minor units (for example cents). Format them with your theme’s money helpers. price is what the customer pays at checkout. If a plan charges for several deliveries at once, perDeliveryPrice is the price of one delivery; otherwise the two are equal.
Query the same data from the product:
Allocations do not say which app created their plan. Collect the IDs of Juo’s recurring plans from the groups first, then keep only the allocations on those plans:
Storefront API IDs are global IDs, for example gid://shopify/SellingPlan/123. Paginate variants for products with more than 100 variants.

2. Build the purchase options

The interface can be anything: radio buttons, a dropdown, a toggle with a frequency picker, or a step in a quiz. Whatever the design, it needs to track two values, the selected variant and the selected selling plan (or none), and keep them consistent.
Rules to apply in render():
  • Hide the subscription option when the variant has no plans. Sending a selling plan that does not apply to the variant makes the add-to-cart request fail.
  • Hide the one-time option when requiresSellingPlan is true. The product is set to sell only as a subscription, and Shopify rejects lines without a plan.
  • Show prices from the allocation, not the variant. The allocation price already includes the plan’s discount. Show the saving against compareAtPrice.
  • Re-render when the variant changes. Plans and prices differ per variant.
  • Optional: keep the URL in sync for shareable links. Shopify reads ?variant= and ?selling_plan= on product URLs.

3. Add the line to the cart

The selling plan ID has to travel with every add-to-cart request for the product. How you send it depends on how the theme adds to cart.

Product forms

Shopify’s /cart/add form endpoint accepts a selling_plan field. Set it on whichever form is submitted, since product pages often have more than one (main form, sticky bar, quick add). Listening in the capture phase sets the field before the theme’s own submit handlers read the form.
If your theme builds the request from its own state instead of the form, pass the selling plan there.

Ajax Cart API

Storefront API

Pass sellingPlanId on the cart line:

4. Show and change the plan in the cart

Cart lines expose the plan as item.selling_plan_allocation.selling_plan. Show its name next to the line so customers can see which items will renew and how often.
Keep line item properties that start with an underscore, such as _selling_plan_id. Many carts hide them from customers, which is fine, but they must not be removed: Juo reads them when it creates subscriptions.
To change the plan of a line already in the cart, for example from a frequency picker in the cart drawer, use /cart/change.js:
With local payment methods enabled, the line’s plan in the cart may be a hidden fixed plan. See If you use local payment methods for how to read the selected frequency.

If you use local payment methods

When a cart contains a recurring selling plan, Shopify checkout only offers payment methods that can be charged again later, such as cards, Shop Pay, and PayPal. To support local methods like iDEAL, Bancontact, BLIK, and MB WAY for subscriptions, Juo adds a hidden fixed selling plan for each recurring plan and switches subscription lines to it in the cart. How it works: after a line is added with a recurring plan, Juo’s app embed changes the line to the fixed plan with the same name and saves the original recurring plan ID in the _selling_plan_id line property. When the order is placed, Juo creates the subscription on that recurring plan. What this means for a custom storefront:
  • Show and add only recurring plans. Filter out fixed plans as in step 1. Juo handles the switch in the cart.
  • Read the selected frequency from _selling_plan_id. In the cart, item.selling_plan_allocation.selling_plan is the fixed plan. Its name matches the recurring plan, so you can display it, but its ID is not in your list of recurring plans.
  • Clear _selling_plan_id when you change a line’s plan, as in step 4. If it still holds the old plan, the line is not switched to a fixed plan, and the subscription can be created on the old frequency.
  • Keep Juo’s app embeds enabled. In Shopify, go to Online Store → Themes → Customize → App embeds and turn on Local Payments Default and Local Payments Info. They appear once local payment methods are enabled in Juo.
  • Route subscription purchases through the cart. Dynamic checkout buttons (“Buy it now”, express wallets) skip the cart, so the switch to a fixed plan never happens. Hide them while a subscription option is selected.
For headless storefronts or other setups without Juo’s app embeds, contact Juo support before enabling local payment methods.

Other common cases

Quick add and collection pages. Every place that adds a product to the cart needs the same selling plan logic, or it adds a one-time line. For products that require a selling plan, a quick add without a plan fails. Upsell and cross-sell widgets. Third-party apps that add products to the cart usually add one-time lines. Check whether they support selling plans before offering subscription products through them. Several subscription products in one cart. Each line carries its own plan. By default, Juo combines lines that renew on the same schedule into one subscription. Bundles. Shopify Bundles cannot use selling plans. To sell a bundle as a subscription, model it as a variant or use Build-a-box. Free gifts and add-ons. A gift added as a one-time line ships with the first order only. To include it in every delivery, add it with the same selling plan. To give free products or other benefits on selected orders, see Extras.

Offers that depend on quantity

Some offers tie the quantity to the plan, for example “1 unit every month” against “3 units every 3 months”. Because a selling plan’s price applies per unit at any quantity, Shopify does not support this directly. Two options:
  • Variants per pack size. Create a variant for each size and add each to the plans it is sold on. Each variant gets its own prices and frequencies, and a quantity change in the cart cannot put a line on the wrong price.
  • A selling plan per combination. Create plans such as “Monthly · 1 unit” and “Every 3 months · 3 units”, and add quantity and plan together. Lock the quantity of these lines in the cart, or change the plan when the quantity changes.
For “the more you buy, the more you save” pricing, use Tiered discounts on a standard plan instead.

Testing checklist

Before launch, place test orders that cover:
  • One-time purchase of a product that also has subscription options.
  • Subscription purchase for each frequency, and after switching variants.
  • A subscription-only product, from the product page and from quick add.
  • Changing quantity and frequency in the cart, and switching a line to one-time.
  • A cart with both one-time and subscription lines.
  • If local payment methods are enabled: a local method is offered at checkout, and changing the frequency in the cart creates the subscription on the new frequency.
After each subscription order, open the subscription in the Juo Admin Panel and check the product, quantity, frequency, and price.

Troubleshooting

No subscription was created. Check the order in Shopify. The line needs a Juo selling plan, or a fixed plan with a _selling_plan_id property. A line with no plan, or with another app’s plan, is a one-time purchase for Juo. Add to cart fails. The selling plan does not apply to the variant, or the product requires a selling plan and none was sent. The subscription has the wrong frequency. The line’s _selling_plan_id still pointed at an earlier plan. Clear it whenever you change a line’s plan. Local payment methods are not offered at checkout. Check that Juo’s app embeds are on, that the purchase went through the cart, and that the cart lines are on fixed plans.