Skip to main content

Update Subscriptions

The Bold Subscriptions API enables you to update a customer’s subscription programmatically, without the customer needing to take any action. You can use this functionality to create convertible subscriptions, such as:

  • Offering a free, trial-sized version of a subscription product before billing begins (such as a sample size of a cosmetic).
  • Offering a 30-day free trial before billing begins (such as a media streaming service).
  • Converting a one-time purchase to a subscription (such as purchasing a coffee maker and a subscription for coffee beans every month).

This tutorial covers the first example in the previous list. In this example, a customer signs up for a subscription service that sends them a cosmetic product every month, and they receive a sample size of the product for free before the subscription starts.

This example is implemented by creating two separate products — one free and one full price — and swapping them before it's time to charge the customer for the first time. This implementation, and many other examples of convertible subscriptions, has the following high-level steps:

  1. Add products to the same subscription group.
  2. Customize the Bold Subscriptions widget.
  3. Listen to the subscription_created webhook.
  4. Create a controller to trigger the swap.
  5. Swap the products.

Prerequisites

  1. Complete all steps of the Quick Start guide (for private integrations) or the Building Public Integrations guide (for public integrations). Read more about the difference between private and public integrations.
  2. Create two products: a sample-size free trial product with a price of $0 and a full-sized product with a price of $10 (or any other value).

Add products to the same subscription group

In order to swap one project for another, both products must be in the same subscription group within Bold Subscriptions.

To add products to a subscription group, open the Bold Subscriptions App and click Subscription groups in the left-hand menu. Use this interface to create a new subscription group with the desired products or add the products to an existing subscription group.

For this example, ensure that the trial-sized and full-sized products are both in the same subscription group. Store the subscription_group_id for use later.

Customize the Bold Subscriptions widget

The Bold Subscriptions widget appears on the product page and informs the customer about their subscription options. Customer interactions with the widget, such as confirming a subscription choice, trigger calls to the Bold Subscriptions API.

For this example, build a custom widget that adds a subscription that contains only the trial-sized product to the cart. For more information about widgets, refer to Building Custom Widgets.

Listen to the subscription_created webhook

At some point in the customer journey, you must trigger the swap of the two products in order to begin billing the customer. This swap can happen at a variety of times, and how you choose to implement it may differ.

One way to trigger this swap is to listen to the subscription_created webhook, and identify the line item id you would like to swap. Refer to Register for Webhooks for more information about the Bold Subscriptions webhooks.

The following code snippet shows one possible mechanism to listen to the subscription_created webhook and trigger a product swap. This JavaScript snippet is written using Express. It uses a controller (webhookEventManager(req)) to handle the payload of the webhook.

app.post("/subscription/webhooks", async (req, res) => {
await webhookEventManager(req);
res.status(200).send("ok");
});

Create a controller to trigger the swap

When you receive a callback payload from the webhook, you must be able to consume the payload and determine whether the subscription contains the free trial-sized product which therefore needs to be swapped out for a full-size, full-price product.

The following snippet shows an example of a controller that identifies the free sample and triggers a swap:

const webhookEventManager = async (req) => {
const webhook = {
event: req.headers["event-identifier"],
payload: req.body,
store_id: req.headers["shop-identifier"],
};
switch (webhook.event) {
case "subscription_created":
// Do logic here for subscription_created event

const subs = new SubscriptionsController();
const triggerItem = webhook.payload.line_items.find((item) => item.product_name === "Free Sample");
if (triggerItem) {
//List the swappable items
let swappableProducts = await subs.listSwappableProductsByLineItems(
webhook.store_id,
webhook.payload.id,
triggerItem.id
);

//Create the product swap
await subs.createSwap(webhook.store_id, webhook.payload.id, swappableProducts);
}
break;
case "subscription_updated":
// Do logic here for subscription_updated event
break;
default:
console.log("Couldn't process webhook event");
}
};

Swap the products

To swap products in a subscription, you must first determine which line items are swappable using the List Swappable Products by Line Item endpoint.

The following code snippet shows an example of listing the swappable items and finding the item you want to swap:

async listSwappableProductsByLineItems(shopIdentifier, subscriptionId, lineItemId){
let { data } = await store.api.get(`/subscriptions/v2/shops/${shopIdentifier}/subscriptions/${subscriptionId}/line_items/${lineItemId}/products_swap`)

let filteredItem = data.swappable_products.find(item => item.product_name === "Full-Sized Product")

return {
"line_item_id": lineItemId,
"platform_product_id": filteredItem.platform_product_id,
"platform_variant_id": filteredItem.variants[0].platform_id,
"subscription_group_id": filteredItem.subscription_group_id
}
}

Once you identify the product to swap, use the Swap Line Items endpoint to swap the free product with the full-price product.

The following code snippet shows an example of swapping the free trial for the full-priced product, where data includes information about the full-sized product:

async createSwap(shopIdentifier, subscriptionId, body) {
let { data } = await store.api.put(`/subscriptions/v2/shops/${shopIdentifier}/subscriptions/${subscriptionId}/products_swap`, { swap_products: [body] })
return data
}

Next steps

Convertible subscriptions are very flexible, and you can create a wide variety of offerings. Try creating one of the other examples listed in the overview of this page.

If you are interested in allowing customers to customize what they want in their subscription or curating custom boxes for your customers, read about integrating Subscription Builder.