Solved

Assignign Subscription Plans to Variants

finedining1
Shopify Partner
10 1 1

Building a new app. I've got a button that does the following:

1) Creates a new product

2) Creates a variant on new product

3) Creates a new selling plan group.

4) Assigns the subscription selling plan group to the variant.

 

All of these things seem to happen successfully. In the Dawn theme, I've added a variant selector. When I pick the variant with the recurring subscription plan assigned to it and checkout, there is no indication that the subscription has successfully started. As far as I can tell, its a one-time purchase.

 

My question is this:

1) how can I tell if the subscription has been successfully started (aside from waiting 24hrs to see if its renewed)? 

 

2) Beyond simply submitting the variant with the subscription assigned to it, is there more I need to submit to checkout to initiate a successful subscription?

 

 

export async function action({ request }) {
    const { admin } = await authenticate.admin(request);

    const productResponse = await admin.graphql(`mutation {
        productCreate(input: {
        title: "Sweet new productzzY",
        productType: "TEST Product",
        vendor: "JadedPixel",
        options: ["Interval"]
        }) {
        product {
            id
            options {
            id
            name
            }
        }
        }
    }`,
    );

    // Convert the response into JSON
    const productData = await productResponse.json();
    const productId = productData.data.productCreate.product.id;

    const variantResponse = await admin.graphql(`
    mutation {
        productVariantCreate(input: {
            productId: "`+productId+`",
            price: "39.99",
            options: ["1 Week"],
            sku: "UNIQUE-SKU",
            title: "New Variant Title"
        }) {
          productVariant {
            id
          }
          userErrors {
            field
            message
          }
        }
      }
    `);

    const variantData = await variantResponse.json();
    const variantId =  variantData.data.productVariantCreate.productVariant.id;
    
    const planResponse = await admin.graphql(`
    mutation {
    sellingPlanGroupCreate(input: {
        name: "Subscribe and save",
        merchantCode: "subscribe-and-save",
        options: ["Delivery every"],
        position: 1,
        sellingPlansToCreate: [
        {
            name: "Delivered every week",
            options: "1 Day",
            position: 1,
            category: SUBSCRIPTION,
            billingPolicy: {
            recurring: {
                interval: DAY,
                intervalCount: 1,
                anchors: { type: WEEKDAY, day: 1 }
            }
            },
            deliveryPolicy: {
            recurring: {
                interval: DAY,
                intervalCount: 1,
                anchors: { type: WEEKDAY, day: 1 },
                preAnchorBehavior: ASAP,
                cutoff: 0,
                intent: FULFILLMENT_BEGIN
            }
            },
            pricingPolicies: [
            {
                fixed: {
                adjustmentType: PERCENTAGE,
                adjustmentValue: { percentage: 15.0 }
                }
            }
            ]
        }
        ]
    }) {
        sellingPlanGroup {
        id
        }
        userErrors {
        field
        message
        }
    }
    }
    `);

    const planData = await planResponse.json();
    const planId =  planData.data.sellingPlanGroupCreate.sellingPlanGroup.id;
    // Logging the JSON to see the structure

    const planAssocResponse = await admin.graphql(`
    mutation {
        sellingPlanGroupAddProductVariants(id: "`+planId+`", productVariantIds: ["`+variantId+`"]) {
        userErrors {
            field
            message
        }
        }
    }
    `);

 

Accepted Solution (1)
finedining1
Shopify Partner
10 1 1

This is an accepted solution.

Okay. Figured it out. I needed to add a checkout-system besides 'bogus payment processor' to get the store to make the store eligible for subscription. Duh.

View solution in original post

Replies 6 (6)

SBD_
Shopify Staff
1829 269 409

Hey @finedining1 

 

You'll need to pass along the selling plan ID when the customer adds the variant to cart as a subscription. More info here.

Scott | Developer Advocate @ Shopify 

finedining1
Shopify Partner
10 1 1

Thanks - I've got the form setup to pass along the selling Plan ID but I can't seem to access it from the frontend. While the selling plans appear in the product screen on the admin side (see below), they don't appear in the product object. I think there is an issue with how I am assigning the variants to the selling plan group.

Screenshot 2023-11-06 at 12.56.49 PM.png

Screenshot 2023-11-06 at 12.53.46 PM.png

SBD_
Shopify Staff
1829 269 409

Hey @finedining1 

 

I don't believe that information is available via the AJAX API. Try using this example code in your theme.

 

Let me know if you get stuck.

Scott | Developer Advocate @ Shopify 

finedining1
Shopify Partner
10 1 1

To be clear, I got that console.log of the product object by adding this to the product page: 

    <script>
      document.addEventListener('DOMContentLoaded', function() {
        console.log("product: ", {{ product | json }});
      });
    </script>

 

 

As for the demo code, I've tried several different ways over the last few days with no luck. I've been adding itt to the default dawn theme product page like so:

 

    <div class="product__info-wrapper grid__item{% if settings.page_width > 1400 and section.settings.media_size == "small" %} product__info-wrapper--extra-padding{% endif %}{% if settings.animations_reveal_on_scroll %} scroll-trigger animate--slide-in{% endif %}">
      <product-info
        id="ProductInfo-{{ section.id }}"
        data-section="{{ section.id }}"
        data-url="{{ product.url }}"
        class="product__info-container{% if section.settings.enable_sticky_info %} product__column-sticky{% endif %}"
      >
        {%- assign product_form_id = 'product-form-' | append: section.id -%}

        {%- for block in section.blocks -%}
          {%- case block.type -%}
            {%- when '@app' -%}
              {% render block %}
            {%- when 'text' -%}
              <p
                class="product__text inline-richtext{% if block.settings.text_style == 'uppercase' %} caption-with-letter-spacing{% elsif block.settings.text_style == 'subtitle' %} subtitle{% endif %}"
                {{ block.shopify_attributes }}
              >
                {{- block.settings.text -}}
              </p>
            {%- when 'title' -%}
              <div class="product__title" {{ block.shopify_attributes }}>
                <h1>{{ product.title | escape }}</h1>
                <a href="{{ product.url }}" class="product__title">
                  <h2 class="h1">
                    {{ product.title | escape }}
                  </h2>
                </a>
              </div>
            {%- when 'price' -%}
              <div class="no-js-hidden" id="price-{{ section.id }}" role="status" {{ block.shopify_attributes }}>
                {%- render 'price',
                  product: product,
                  use_variant: true,
                  show_badges: true,
                  price_class: 'price--large'
                -%}
              </div>
              {%- if product.quantity_price_breaks_configured? -%}
                <div class="volume-pricing-note" id="Volume-Note-{{ section.id }}">
                  <span>{{ 'products.product.volume_pricing.note' | t }}</span>
                </div>
              {%- endif -%}
                <div class="product__tax caption rte">
                  {%- if cart.taxes_included -%}
                    {{ 'products.product.include_taxes' | t }}
                  {%- endif -%}
                  {%- if shop.shipping_policy.body != blank -%}
                    {{ 'products.product.shipping_policy_html' | t: link: shop.shipping_policy.url }}
                  {%- endif -%}
                </div>
              <div {{ block.shopify_attributes }}>
                {%- assign product_form_installment_id = 'product-form-installment-' | append: section.id -%}
                {%- form 'product', product, id: product_form_installment_id, class: 'installment caption-large' -%}
                  <input type="hidden" name="id" value="{{ product.selected_or_first_available_variant.id }}">
                  {{ form | payment_terms }}

                  {%- liquid
                    assign current_variant = product.selected_or_first_available_variant | default: product.variants.first
                    assign current_selling_plan_allocation = current_variant.selected_selling_plan_allocation
                   
                    if current_selling_plan_allocation == nil and current_variant.requires_selling_plan
                     assign current_selling_plan_allocation = current_variant.selling_plan_allocations | first
                    endif
                   
                    assign offer = current_selling_plan_allocation | default: current_variant
                   -%}
                   
                   {{ product.title }}
                   {{ offer.price | money }}
                   
                   {% if offer.compare_at_price > offer.price %}
                     <s>{{ offer.compare_at_price | money }}</s>
                     <span>{% if offer.selling_plan %}Purchase options{% else %}Sale{% endif %}</span>
                   {% endif %}
                   
                   {% form 'product', product %}
                     <input type="hidden" name="id" value="{{ current_variant.id }}">
                     <input type="hidden" name="selling_plan" value="{{ current_selling_plan_allocation.selling_plan.id | default: '' }}">
                   
                     <fieldset>
                       <legend>Product options</legend>
                   
                       {% for option in product.options_with_values %}
                         <label>{{ option.name }}</label>
                   
                         <select>
                           {% for value in option.values %}
                             <option>{{ value }}</option>
                           {% endfor %}
                         </select>
                       {% endfor %}
                     </fieldset>
                   
                     <!-- Pass the product object as JSON so it can be used to update selling plan information using JavaScript -->
                     <fieldset class="selling-plan-fieldset" data-product={{ product | json }}>
                       <legend>Purchase options</legend>
                       {% unless product.requires_selling_plan %}
                       <input type="radio" name="purchase_option"> One-time purchase
                       {% endunless %}
                   
                       {% for group in product.selling_plan_groups %}
                         <input type="radio" name="purchase_option"> {{ group.name}}
                   
                         {% for option in group.options %}
                           <label>{{ option.name }}</label>
                   
                           <select data-position="{{ option.position }}">
                             {% for value in option.values %}
                               <option>{{ value }}</option>
                             {% endfor %}
                           </select>
                         {% endfor %}
                       {% endfor %}
                     </fieldset>
                   {% endform %}
                {%- endform -%}
              </div>

 

finedining1
Shopify Partner
10 1 1

Okay its been a week stuck on this issue. I've completely refactored my app. I've gone through the subscription  documentation, refactored my code, checked for correct scopes and the problem persists. I can successfully create subscriptions on the merchant side but they are not accessible on the storefront. I'm using the example code provided in the documentation on a vanilla dawn theme. No errors in the selling plan creation or association with the productid. Everything works except for the storefront. I've printed the product object into the console and there is no trace of selling plan information. Really not sure what is left to check at this point. Any ideas would be super appreciated.

finedining1
Shopify Partner
10 1 1

This is an accepted solution.

Okay. Figured it out. I needed to add a checkout-system besides 'bogus payment processor' to get the store to make the store eligible for subscription. Duh.