All Collections
Subscriptions
Gifting Subscriptions
Gifting Subscriptions
Karin Brashears avatar
Written by Karin Brashears
Updated over a week ago

Gifting overview

Stay.AI offers merchants the ability to stand up a gifting platform. Meaning your customers can now both subscribe to your products for themselves or send a set amount of shipments to others. Let your product be a gift to your customers' loved ones!

General guidelines

  • Gifts will be configured in the Stay.AI merchant portal.

  • Only prepaid selling plans can be configured as gifts.

  • The out-of-the-box gifting solution will populate in the buy box, but customizations can be made per the merchant’s request

Getting started

In the Merchant Portal:

  • Navigate to the Stay.AI merchant portal

    1. Open your Shopify Admin store

    2. Go to Apps

    3. Select “Stay.AI Subscriptions”

  • Ensure the products you would like to setup for Gifting are setup in Shopify. If so, you are ready to setup Gifts!

  • Navigate to the Selling Plans page

    • In the Stay.AI Merchant Portal, navigate to the Settings section

    • Open “Selling Plans”

  • To setup a NEW selling plan for gifting, create a “New Prepaid Selling Plan Group”

    • Select “New Prepaid Selling Plan Group”

    • Select the products you would like to be available as prepaid gifts in this selling plan group

    • Provide Selection and Checkout Cart Labels, the desired discount amount for the selling plan, the shipping schedule, and the amount of shipments desired for the prepaid plan.

      • NOTE: If you select a shipping schedule of every 1 month, and 2 shipments in this section, your customers will be charged for the price of the product, minus the established discount for the plan, times the number of shipments. They will receive the shipments every month.

    • Setup as many frequencies as desired. For instance, if you would like to offer a monthly prepaid subscription for 2 shipments, 3 shipments, and 4 shipments, these can all be configured within this view.

  • Select the “Allow Gifting for this Selling Plan Group” checkbox on the selling plan

    • This will enable an option on the customer portal to select the prepaid subscription as a gift. The customers will then go through the gifting flow on the customer portal.

  • Provide the Storefront Selling Plan Group labels

    • NOTE: Pick something here that will make it clear to your users that they are paying for a prepaid subscription. These labels are customer facing.

  • Submit your changes!

In your Shopify Store:

  • Confirm whether gifting has already been set up for your Shopify store.

    • Some stores are already set up for full gifting support. You will need to navigate to a product with a selling plan group that you have set up for gifting. Confirm whether the gifting options are already displayed or not.

    • If the gifting options are present and performing as expected then you’re all set!

  • If it has not been set up, start by navigating to your Shopify Admin Panel

  • On the main navigation (on the left-hand side of the screen), Click “Sales Channels” and then select “Online Store”

  • It is recommended to create a backup / duplicate of your current theme before proceeding. To do this, locate your current published theme, and click the “…” menu, and then select “Duplicate”

    • In the event that installing gift boxes causes some issues with your existing theme, you can publish the backup you have just created.

  • After creating a backup, select the “…” menu on the published theme again, and select “Edit Code”

  • From the Code view, find the search bar in the left panel. Type “rtx-pdp” in the search and locate the file “rtx-pdp.liquid” underneath the “snippets” folder. Select this file by clicking on it.

    • If there is no “rtx-pdp.liquid” file, please follow the Buy Box installation guide within the Stay.AI App.

  • In the right-hand side of the screen will appear the code. Replace the contents of the entire file with the following code.

    • {% comment %} v1.0.0 {% endcomment %} {%- if product.selling_plan_groups.size > 0 -%} {%- comment -%} Shorthand Variables {%- endcomment -%} {%- liquid assign currentVariant = variant | default: product.selected_or_first_available_variant assign requiresPlan = product.requires_selling_plan assign selectedAllocation = product.selected_or_first_available_selling_plan_allocation assign currentAllocations = currentVariant.selling_plan_allocations -%} {%- comment -%} Buy Box Styles {%- endcomment -%} <style type="text/css"> .rtx-subscription-box { display: none; } .rtx-subscription-box.is-visible { display: block; } .rtx-gift-box { display: none; } .rtx-gift-box.is-visible { display: block; } </style> <div data-rtx-subscription-{{ product.id }}-{{ section.id }}-{{ block.id }}> {%- comment -%} Subscription type toggle {%- endcomment -%} {%- unless requiresPlan -%} <div> <input type="radio" id="purchaseTypeOneTime" name="purchaseType" value="purchaseTypeOneTime" {% if selectedAllocation == blank %}checked{% endif %} /> <label for="purchaseTypeOneTime">One Time Purchase</label> <input type="radio" id="purchaseTypeSbubscription" name="purchaseType" value="purchaseTypeSubscription" {% if selectedAllocation != blank %}checked{% endif %} /> <label for="purchaseTypeSbubscription">Subscription Purchase</label> </div> {%- endunless -%} {%- comment -%} Subscription Box {%- endcomment -%} <div data-retextion-subscription-box class=" rtx-subscription-box {% if requiresPlan or selectedAllocation != blank %} is-visible {% endif %} "> <p>Subscription</p> {%- comment -%} Subscription Gift Box Toggle {%- endcomment -%} <div> <input id="subscriptionGift" type="checkbox" name="properties[_gifted-subscription]" /> <label for="subscriptionGift">Gift Subscription</label> </div> {%- comment -%} Gift Box {%- endcomment -%} <div data-retextion-gift-box class="rtx-gift-box"> <div> <label for="subscriptionEmail">Recipient's Email</label> <input id="subscriptionEmail" type="email" name="properties[Gift Recipient Email]" placeholder="Enter the recipient's email" /> </div> <div> <label for="subscriptionFirstName">Recipient's First Name</label> <input id="subscriptionFirstName" type="text" name="properties[Gift Recipient First Name]" placeholder="Enter the recipient's first name" /> </div> <div> <label for="subscriptionLastName">Recipient's Last Name</label> <input id="subscriptionLastName" type="text" name="properties[Gift Recipient Last Name]" placeholder="Enter the recipient's last name" /> </div> <div> <label for="subscriptionMessage">Gift Message</label> <textarea id="subscriptionMessage" name="properties[Gift Message]" maxlength="1024" placeholder="Enter a short message"></textarea> </div> <p> You will provide the shipping information during checkout. </p> </div> {%- comment -%} Selling Plan Options {%- endcomment -%} <select name="selling_plan"> {%- liquid for allocation in currentAllocations assign plan = allocation.selling_plan echo '<option' if plan.selected or sellectedAllocation == blank and forloop.first echo ' selected' endif echo ' value="' | append: plan.id | append: '">' echo plan.name | escape echo '</option>' endfor -%} </select> </div> </div> <script type="text/javascript"> ((api) => { const boxId = "{{ product.id }}-{{ section.id }}-{{ block.id }}"; const boxProduct = {{ product | json }}; const elementRoot = document.querySelector('[data-rtx-subscription-' + boxId + ']'); const productForm = elementRoot.closest('form[action="/cart/add"]') || elementRoot.closest('form') || document.querySelector('form[action="/cart/add"]') || document.documentElement; const elementSubscriptionBox = elementRoot.querySelector('[data-retextion-subscription-box]'); const elementGiftBox = elementRoot.querySelector('[data-retextion-gift-box]'); const elementGiftCheckbox = elementRoot.querySelector('[name="properties[_gifted-subscription]"]'); const elementSellingPlan = elementRoot.querySelector('[name="selling_plan"]'); const elementQuantitySelector = productForm.querySelector('[name="quantity"]'); const elementsPurcahseTypeRadio = elementRoot.querySelectorAll('[name="purchaseType"]'); const elementsVariantSelectors = productForm.querySelectorAll('[name="id"]'); const elementsInputs = productForm.querySelectorAll('button,input,textarea,select,option,datalist,optgroup'); let selectedVariantId = {{ currentVariant.id | json }}; const queryParamsGet = () => { let [ origin, searchAndHash ] = window.location.toString().split('?'); searchAndHash = searchAndHash || ""; let [ search ] = searchAndHash.split('#'); return (search||'').split('&').reduce((o,e) => { let [ key, value ] = e.split('=').map(x => decodeURIComponent(x)); if(!key || !value) return o; o[key] = value; return o; },{}); }; const queryParamsGenerate = (qp) => { qp = qp || {}; //Remove undefined Object.keys(qp).forEach(key => { if(typeof qp[key] !== typeof undefined) return; delete qp[key]; }); return Object.keys(qp).reduce((x,key,i) => { let value = qp[key]; if(i != 0) x += '&'; return x += encodeURIComponent(key)+'='+encodeURIComponent(value); }, ''); }; const subscriptionBoxHide = () => { elementSubscriptionBox.classList.remove('is-visible'); } const subscriptionBoxShow = () => { elementSubscriptionBox.classList.add('is-visible'); } const subscriptionGiftShow = () => { elementGiftBox.classList.add('is-visible'); } const subscriptionGiftHide = () => { elementGiftBox.classList.remove('is-visible'); } const sellingPlanQueryUpdate = () => { const queryParams = queryParamsGet(); if(elementSubscriptionBox.classList.contains('is-visible')) { queryParams['selling_plan'] = sellingPlanSelectionGet() || undefined; } else { delete queryParams['selling_plan']; } const qs = queryParamsGenerate(queryParams); try { let hash; hash = (hash = window.location.toString().split('#')).length > 1 ? hash[1] : null; const url = window.location.toString().split('?')[0] + '?' + qs + (hash ? '#' + hash : ''); history.pushState(queryParams, '', url); } catch(e) { // Catching since older browsers and iOS can have issues console.error(e); } } const sellingPlanSelectionGet = () => { return parseInt(elementSellingPlan.value); } const sellingPlanSelectionSet = (sellingPlan) => { sellingPlan = sellingPlan && sellingPlan.id ? sellingPlan.id : sellingPlan; elementSellingPlan.value = sellingPlan.toString(); } const sellingPlanPropertiesGet = () => { const formData = new FormData(productForm); return Array.from(formData.entries()); } const sellingPlanUrlGenerate = () => { const props = sellingPlanPropertiesGet(); let strProperties = ''; sellingPlanPropertiesGet().forEach(prop => { const key = prop[0]; if(!key.startsWith('properties[')) return; const val = prop[1]; if(!val || !val.toString().length) return; strProperties += '&items[][' + encodeURIComponent(key) + ']=' + encodeURIComponent(val); }); return window.location.origin + '/cart/clear?return_to=' + encodeURIComponent('/cart/add' + '?items[][id]=' + selectedVariantId + '&items[][quantity]=' + (elementQuantitySelector ? elementQuantitySelector.value : 1) + strProperties + '&items[][selling_plan]=' + sellingPlanSelectionGet() + '&return_to=/checkout' ); } const sellingPlanUpdate = () => { sellingPlanQueryUpdate(); console.log(sellingPlanUrlGenerate()); } const sellingPlanUpdateVariant = () => { const variant = ( boxProduct.variants.find(v => v.id == selectedVariantId) || boxProduct.variants.find(v => v.available) || boxProduct.variants[0] ); let newOptions = ''; // Determine the selected option let selected = sellingPlanSelectionGet(); if(!variant.selling_plan_allocations.some(spa => { return spa.selling_plan_id == selected; })) { selected = variant.selling_plan_allocations[0].selling_plan_id; } // Generate new options variant.selling_plan_allocations.forEach((spa,i) => { const sellingGroup = boxProduct.selling_plan_groups.find(spg => spg.id === spa.selling_plan_group_id); const sellingPlan = sellingGroup.selling_plans.find(sp => sp.id === spa.selling_plan_id); const opt = document.createElement('option'); if(sellingPlan.id == selected) { opt.setAttribute('selected', 'selected'); } opt.value = sellingPlan.id; opt.textContent = sellingPlan.name; newOptions += opt.outerHTML; }); // Update select elementSellingPlan.innerHTML = newOptions; sellingPlanUpdate(); } // Event Listeners elementsPurcahseTypeRadio.forEach(el => { el.addEventListener('change', e => { if(el.value === 'purchaseTypeSubscription') { subscriptionBoxShow(); } else { subscriptionBoxHide(); } sellingPlanUpdate(); }); }); elementGiftCheckbox.addEventListener('change', e => { if(e.target.checked) { subscriptionGiftShow(); } else { subscriptionGiftHide(); } sellingPlanUpdate(); }); elementSellingPlan.addEventListener('change', e => { sellingPlanUpdate(); }); elementsVariantSelectors.forEach(vs => { vs.addEventListener('change', e => { selectedVariantId = e.target.value; sellingPlanUpdateVariant(); }); }); elementsInputs.forEach(inp => { inp.addEventListener('change', e => { sellingPlanUpdate(); }); }); // Public API return Object.assign(api, { [boxId]: { boxId, boxProduct, subscriptionBoxHide, subscriptionBoxShow, subscriptionGiftShow, subscriptionGiftHide, sellingPlanUrlGenerate } }); })((window.retextionBuyBox = {})); </script> {%- endif -%}

  • Select “save” and perform additional testing to ensure functionality is matching expectations.

You’re All Set! Now What Will Your Customers See?

You’re officially ready to be gifted! A few guidelines about what your customers will see and experience as they decide to send gifts.

Checkout Process

  • Customers will have to opt in to sending the gift. This will be configured per merchant in the buy box.

  • Once customers select to send a gift, they will have to provide the following information:

    • Gift Recipient First Name

    • Gift Recipient Last Name

    • Gift Recipient Email

    • Gift message for the recipient

  • Upon checkout, they will provide the following information:

    • Their OWN email address

    • The shipping address for the recipient

    • Billing information

Notifications

Once the customer has succesfully checked out, we let them know it! The following notifications are triggered for the gifter and the gift recipient.

Gifter:

  • You have sent a gift! This is a confirmation email, letting the gifter know that we have successfully processed their order, and their gift is on the way.

  • Your gift is shipped! This is an email alerting the gifter that one of the prepaid shipments is on the way

  • Your last order has shipped! This alerts the gifter that the last order has been shipped for the prepaid subscription.

Gift Recipient:

  • You have been sent a gift! This is an email to the gift recipient, alerting them that they have a prepaid subscription gift, and giving them access to the customer portal to manage their subscriptions.

  • Your gift is shipped! This is an email alerting the gift recipient that one of the prepaid shipments is on the way.

  • Your last order has shipped! This alerts the gift recipient that the last order has been shipped for the prepaid subscription.

Customer Portal Access

Both the gift recipient and the gifter will now have access to manage the subscription on their customer portal. Some awesome notes from our team:

  • Let’s say your gift recipient has other subscriptions to the same email on your site - they will be able to manage them all from the same portal

  • Gifts are gifts! Because of that, we hide the price of the subscription for the recipient

  • To prevent any mistakes, permissions are limited on both the recipient and the gifter’s portal (swaps, and skip next orders are not available for gifts!)

Are you as excited as we are? Go ahead and get gifiting!

Did this answer your question?