Skip to main content
A gift subscription is a prepaid, one-time plan that one customer buys for someone else. The buyer stays the Shopify customer, pays for every delivery up front and enters the recipient’s shipping address at checkout, because that’s where every delivery goes. After checkout, Appstle emails the recipient an invitation to a gift page, where they can follow their deliveries and thank the buyer. Appstle’s own widget collects the recipient’s details on the product page. This guide shows how to do the same from your own page: a landing page on a Shopify theme, or a headless storefront.
The cart calls and the Liquid in this guide are Shopify’s, so they need no Appstle API key. The Appstle calls (finding or creating the gift plan, and checking the subscription after checkout) use the Admin API from your server, with an API key in the X-API-Key header (see Authentication). Creating a plan needs a Read & Write key. Never put an API key in browser code.

What you’ll build

  • A gift plan attached to a product.
  • A cart add that carries the recipient’s details on the gift line.
  • Checks in your own page that match the checkout rule, and an optional send date for the invitation.

Before you start

  • A gift plan on the product. In the Appstle Subscriptions app, open Subscription Plans, create a plan, choose Prepaid, one time and turn on Sell as a gift. You can also create it from your server. A gift plan is always prepaid, one time, with one billing cycle.
  • The Subscription Validations checkout rule, active. In Shopify admin, go to Settings → Checkout → Checkout rules, choose Add rule → Subscription Validations, make sure it’s Active and save. Until you do, checkout lets a gift cart through with no recipient. The order is placed and tagged Appstle gift, but no invitation goes out until the merchant adds a recipient with Edit recipient in the subscription’s gift details.
  • A test store. Run the whole flow with a test payment before you publish the page.

How a gift is stored

A gift is one ordinary line: the product with the gift plan’s selling plan. The recipient’s details travel on that line as line item properties. Shopify’s cart API calls them properties, and its Storefront GraphQL API calls them attributes. Shopify treats properties whose names start with an underscore as private: checkout doesn’t show them, and most themes hide them in the cart. After checkout, they stay on the subscription line. A gift checkout holds one gift line, quantity 1, one recipient and nothing else. Mixed carts, several gifts and several recipients aren’t supported.

Step 1: Find the gift plan’s selling plan ID

Sell as a gift is a setting on one plan, and a plan group can hold gift and regular options side by side. Don’t pick the plan by its group’s name or its position. Find its ID once, and keep it in your page’s configuration, such as a theme or section setting. From your server, list the plan groups with Get all subscription groups. In each group’s subscriptionPlans, gift plans have gift set to true, and id is the selling plan ID:
The response lists every group. This one holds a regular plan and a gift plan, with only the fields that matter here:
Use the number at the end of id as selling_plan. For gid://shopify/SellingPlan/690123456789, that’s 690123456789. On the page, check that the product still carries the gift plan before you show the gift form:
In Liquid, the same plans are in product.selling_plan_groups.

Step 2: Add the gift to the cart

On a Shopify theme

Add the variant with the gift plan and the recipient’s details as properties. This is the same route as Adding a subscription to cart, with the extra properties.
Shopify answers 200 with an items array, and the gift line’s properties holds the four values. It answers 422 with Cannot apply selling plan to variant when the gift plan isn’t attached to the variant.
The checkout rule refuses a gift cart that holds anything else. Read /cart.js before you add the gift. If the cart already has items, ask the shopper before you empty it with POST /cart/clear.js. If the gift is already in the cart, don’t add it again: a second add leaves two gifts in the cart, which the rule also refuses.

Using a form

A product page can post the same values with a form to /cart/add:
Set the date field’s min and max from giftSendDateRange (see Schedule the invitation). The required and maxlength attributes match the table above. A browser’s email check is looser than the rule’s, and only checkout knows the buyer’s email, so the rule can still refuse an address the form accepted. Leave the date field empty to send the invitation without a date: Appstle treats an empty _appstle-gift-send-date as no date.

On a headless storefront

Send the same keys as line attributes ({ key, value } pairs) on the gift line of Shopify’s cart creation mutation, together with the gift plan’s sellingPlanId and a quantity of 1. Then redirect the shopper to the returned checkoutUrl. These are line attributes, not cart attributes or the order note. Keep them with the selling plan whenever you replace a variant or update the line. Handle userErrors before you redirect.

Step 3: Pass the checkout rule

The rule runs when the buyer presses Pay now. Earlier checkout steps let the shopper repair the cart, so a half-finished gift cart isn’t blocked while they’re still filling it in. At that point the rule returns every message that applies. Each message is the default text, and a store can replace it through its widget labels. The same rule also applies the store’s other subscription limits to the gift line. If the store limits subscriptions per customer, a buyer who already has a subscription can see Buying multiple subscriptions is not allowed., and a quantity above 1 can also show Subscription products cannot have a quantity greater than 1. The rule doesn’t check the send date. Check it in your page (see the next section), and check the other fields too, so the shopper finds out before checkout. Don’t enable accelerated checkout buttons on a gift page unless you’ve confirmed they keep the selling plan and every property. Treat names, emails and messages as customer information: keep them out of analytics events and logs.

Schedule the invitation

Without _appstle-gift-send-date, or with an empty one, Appstle sends the invitation about five minutes after the subscription is created. To schedule it, add one _appstle-gift-send-date property in the shop’s time zone, formatted exactly as YYYY-MM-DD. Appstle compares it with the purchase date in that time zone:
  • Today or an earlier date: the invitation goes out about five minutes after the subscription is created, as if there were no date.
  • A later date, within the plan’s maximum: the invitation goes out shortly after 09:00 in the shop’s time zone on that date. The maximum is the plan’s Maximum days ahead to schedule a gift invitation (giftSendMaxDays): a whole number from 1 to 365, and 90 when it’s empty.
  • A badly formatted date, a date past the maximum, or more than one send-date property: the invitation waits, and the merchant can send it with Resend invitation in the subscription’s gift details.
The date schedules the invitation email only. It doesn’t hold shipments: deliveries continue on the plan’s own schedule. The date can’t be changed after purchase.

Read the time zone and the maximum

Appstle publishes both values in the shop metafield appstle_subscription.setting.
  • On a Shopify theme, read it in Liquid as shop.metafields.appstle_subscription.setting.value. No token is needed.
  • On a headless storefront, read it with Shopify’s Storefront GraphQL API and your own Storefront access token, as shop { metafield(namespace: "appstle_subscription", key: "setting") { value } }. Shopify serves metafields only to requests with a token.
The metafield’s JSON holds two keys you need. On a headless storefront it arrives as a JSON string; on a theme, Liquid has already parsed it:
  • shopIanaTimeZone: the shop’s IANA time zone, such as America/New_York. It can arrive escaped one extra time (America\/New_York), and the function below decodes it either way. If it’s empty, don’t offer a send date: Appstle can’t evaluate one, and the invitation would wait.
  • sellingPlansJson: a JSON string that lists the shop’s plans. Find your gift plan by its id and read its giftSendMaxDays. When the field is missing, the maximum is 90.
On a theme, this snippet prints only those two keys into the page as one JSON string. Put it in a section or a snippet that renders on the gift page:
The value covers every plan in the shop and can be large, so print it only on the gift page, and on a headless storefront cache it instead of fetching it on each page view. Pass the string (window.giftSettingValue on a theme, the metafield’s value on a headless storefront) and your gift plan’s ID to this function. It accepts the plan’s numeric ID or its gid://shopify/SellingPlan/... form, and returns the time zone and the earliest and latest dates to offer, or null when scheduling isn’t available:
On a headless storefront, a null metafield means the store’s Subscription App Setting metafield definition doesn’t give Shopify’s Storefront GraphQL API access. The merchant can turn that access on in Shopify admin: go to Settings → Metafields and metaobjects → Shop, open Subscription App Setting and turn on Storefront API access under Options. Until then, leave the send date out so invitations go out without a schedule, or keep the time zone and the maximum in your storefront’s own configuration, in step with the merchant’s settings.

Step 4: Check the gift after checkout

Appstle tags the gift’s order Appstle gift, and the _appstle-gift-* properties stay on the subscription’s line. To check them from your server, read the subscription with Retrieve subscription contracts and its subscriptionContractId filter:
The response is a list with one entry. The example leaves out most fields, including contractDetailsJSON, which the next paragraph covers:
contractDetailsJSON is a JSON string. Parsed, its single entry is the gift line, with the _appstle-gift-* properties under customAttributes:
On your server, tell a gift apart by the order’s Appstle gift tag, which Appstle adds only once it has set up the gift, or by a sellingPlanId that is your gift plan’s ID. The gift keys alone don’t make a line a gift: Appstle ignores them on a plan that isn’t a gift plan. A gift has one billing cycle. If the store has Auto-pause subscriptions after maximum orders reached turned on, Appstle pauses the subscription right after it’s created, and the API lists it as paused. Otherwise it stays active with nothing scheduled. Either is expected: the buyer has paid for the whole gift.

Create the gift plan from your server

You can create a gift plan with the Admin API instead of the app. Call Create a new subscription group with gift set to true on a prepaid plan that has maxCycles of 1. This example sells three months of coffee for one payment:
The response is 201 with the group and its new id. Each plan’s id is still null in that response. Read the selling plan ID from Get subscription group by ID (subscriptionPlans[].id), or from the product’s selling_plan_groups. The call returns 400 for the first rule a gift plan breaks, checked in this order: The body is application/problem+json. This is the response to a pay-as-you-go plan sent with gift set to true:
Match on errorKey, not on the message. An update keeps each saved plan’s gift setting as it was saved, whatever the request says, so create a new plan to change it.

Verify the complete flow

  1. On a test store, complete a checkout with a test payment, using a buyer email that isn’t the recipient’s.
  2. Check the order and the subscription as in Step 4.
  3. Confirm the buyer gets the ordinary purchase confirmation, and the recipient gets the invitation about five minutes later. The invitation link works for two hours, and the recipient can ask for a fresh one by email.
  4. Test the rule’s failure cases: a missing recipient, an email that matches the buyer’s, a quantity above 1 and an ordinary item in the same cart. Checkout should refuse each one.
  5. For a scheduled invitation, check that it doesn’t arrive before 09:00 shop time on the chosen date.
The merchant manages the gift, and resends the invitation, from the subscription’s gift details in the Appstle Subscriptions app.

Next steps

Build your own frontend

Selling plans, the cart and the customer portal from your own UI.

Fixed-price Build-a-Box

Another cart-properties flow, with a box the customer fills.

Webhooks

React to new subscriptions on your server.

Admin API integration guide

Server-side calls for subscriptions and contracts.