Skip to main content

Build a Customer Portal

After a customer creates a subscription, they may need to adjust their selections, change their address, change the date of their delivery, or otherwise modify their subscription. The Bold Subscriptions API enables you to create a customer portal, where customers can log in and manage their subscriptions.

With the Bold Subscriptions API, you can create a customer experience that is simple or complex as you would like. There are several options for doing so, depending on your project requirements and level of customization you require:

This document covers creating a basic customer portal from scratch, using the following steps. It includes code snippets from the Open Source Customer Portal.

  1. Create a customer portal page.
  2. Retrieve the Bold Subscriptions JWT.
  3. List and display customer subscriptions.
  4. Allow customer to edit their own subscriptions.
  5. (Optional) Integrate Subscription Builder.
note
  • Creating a customer portal requires using a different base URL from the standard Bold Subscriptions API. When calling the Bold Subscriptions API on behalf of a customer, you must use replace api.boldcommerce.com/subscriptions/v1/shops/{shopIdentifier} with sub.boldapps.net/api/customer.
  • You can use a variety of frameworks to create a customer portal. The examples in this document assume you are using a JavaScript-based frontend.

Prerequisites

Before you get started, complete the following steps:

  1. Complete all steps outlined in Getting Started with the Bold Subscriptions API.

    note

    While you may need an API access token for other calls to the Bold Subscriptions API, calls on behalf of a customer do not require one.

  2. Ensure that your platform includes a method to create, store, and authenticate customers.

  3. (Optional) Review the Open Source Customer Portal to gain an understanding of the different components of this project.

Create a customer portal page

Use the customer login flow that is provided by your platform. Once the user has logged in, direct them to a customer portal landing page. Any actions taken on this page must be authenticated to ensure the security of the customer's personal and payment information.

Retrieve the Bold Subscriptions JWT

In order to make authenticated requests as a customer, you must acquire a JSON Web Token (JWT) from the Bold Subscriptions application. The JWT is required for all API calls to endpoints beginning with sub.boldapps.net/api/customer, which encompasses all calls made in a customer portal.

The following diagram and corresponding steps depict how the JWT is used to access customer information and make requests on behalf of the customer:

  1. A customer visits the custom portal.
  2. Your storefront JavaScript makes a call to the window.BOLD.subscriptions.getJWT method.
  3. The method returns your platform’s JWT and customer ID.
  4. Your JavaScript makes a call to the Bold server to get a JWT for the customer.
  5. The Bold server returns a JWT, logged-in customer info, and an expiration time and date for the JWT.
  6. As the customer makes changes to their subscriptions in the custom portal, your JavaScript makes authenticated requests as the customer to the Bold server by passing the JWT in the Authorization header in the format Bearer {JWT}.
  7. The Bold server returns the requested data after validating the token.
  8. Your JavaScript displays content to the customer based on the response.
  9. The customer interacts with the content. Repeat steps 6 through 9 as necessary.

The following sections include more details on how to obtain and refresh a JWT:

Get the platform's JWT

Make a call to the window.BOLD.subscriptions.getJWT method, passing in a callback function that will handle the response:

window.BOLD.subscriptions.getJWT(function (data) {
// handle data...
});

The data parameter is a JSON object with the following keys:

KeyTypeDescription
successBooleanIndicates whether or not the customer is logged in.
valueObjectProvides values for the logged in customer. This key is only present when success is true.
value.jwtStringProvides the platform's JWT.
value.customerStringProvides the platform ID of the logged-in customer.
errorStringProvides an error code. Possible values are "not_logged_in" or "unknown". This key is only present when success is false.

Exchange the platform JWT for a Bold Subscriptions JWT

Using the values obtained in the previous step, make a request to the customer login endpoint to obtain the Bold Subscriptions JWT:

curl --request GET 'https://sub.boldapps.net/api/customer/login?platform_customer_id={value.customer}&customer_jwt={value.jwt}&shop={shop_domain}&platform_type={platform}'

The API returns a JSON object that contains the following keys:

KeyTypeDescription
subscriptionsWebTokenStringToken used to make authenticated requests as the customer.
subscriptionsWebTokenExpTimeIntegerEpoch timestamp when the subscriptionsWebToken expires (ms).
languageCodeStringLocal string representing the language that the user's browser is making requests in.

Refresh the token as necessary

The Bold Subscriptions JWT is an expiring token. Its expiration time is determined by the subscriptionsWebTokenExpTime key in the login response. Your storefront code must refresh the token before it expires or you will have to repeat the login process. To refresh a token, make a call to the following url:

curl --request GET 'https://sub.boldapps.net/api/customer/jwt/refresh?shop={shopDomain}&platform_type={platform}'

The response to that request is a JSON object with the following keys:

KeyTypeDescription
tokenStringThe new token.
tokenExpTimeIntegerEpoch timestamp indicating when token expires (ms).

Once the new token is retrieved, replace the old token and use the new one for any future requests.

Example: The full JWT handshake

The following JavaScript snippet shows one example of how to handle the JWT handshake. This example is taken from the Open Source Customer Portal.

Expand to view example.
// Initialize an API client (such as Axios) for talking with Bold APIs.
import axios from "axios";

const BASE_URL = process.env.REACT_APP_BASE_URL;

export const SHOP_DOMAIN = window.BOLD.subscriptions.config.shopDomain;
export const PLATFORM = "shopify";

export const Method = {
GET: "GET",
POST: "POST",
PUT: "PUT",
PATCH: "PATCH",
DELETE: "DELETE"
};

static subscriptionsToken = null;
static subscriptionsCustomerId = null;

// Retrieve the platform JWT and the platform customer ID.
static async obtainToken() {
const {
value: {jwt: platformToken, customerId: platformCustomerID}
} = await new Promise((resolve) => window.BOLD.subscriptions.getJWT(resolve));

const {
subscriptionsWebToken: boldToken,
subscriptionsWebTokenExpTime: tokenExpTime,
customer: {bold_platform_id: boldCustomerID}

// Retrieve the Bold customer JWT.
} = await this.callAPI({
method: Method.GET,
url: "/login",
params: {
platform_customer_id: platformCustomerID,
customer_jwt: platformToken,
shop: SHOP_DOMAIN,
platform_type: PLATFORM
}
});

// Bold returns the customer JWT, the customer ID, and the expiration time of the token.
this.subscriptionsToken = boldToken;
this.subscriptionsCustomerId = boldCustomerID;
this.setRefreshTokenTimeout(tokenExpTime);
}

// After a certain amount of time, refresh the JWT.
static setRefreshTokenTimeout(expTime) {
const timeoutMilliseconds = expTime - Date.now() - 60000; // 1 minute before expiration
setTimeout(async () => {
const {
token,
tokenExpTime
} = await this.callAPI({
method: Method.GET,
url: "/jwt/refresh",
params: {
shop: SHOP_DOMAIN,
platform_type: PLATFORM
}
});
this.subscriptionsToken = token;
this.setRefreshTokenTimeout(tokenExpTime);
}, timeoutMilliseconds);
}

Make authenticated calls

You can now make authenticated calls on behalf of the customer by adding the appropriate header: Authorization: Bearer {JWT}

For example, the following example shows the syntax of an API call to get a list of a customer's subscriptions:

curl --request GET 'https://sub.boldapps.net/api/customer/customers/{customer_id}/subscriptions&shop={shop_domain}&platform_type={platform}' \
--header 'Authorization: Bearer {JWT}'
note
  • All customer requests go directly to https://sub.boldapps.net/api/customer/{rest of path}. You can use the Bold Subscriptions API specification to find available endpoints, but you must replace https://api.boldcommerce.com/subscriptions/{version} with that URL in order for the API to function as expected.
  • All requests to https://sub.boldapps.net/api/customer/... must include the {shop_domain} and {platform} parameters in addition to the Authorization header with a customer JWT.

List and display subscriptions

On the customer portal page, show the customer their subscriptions. Use the List Customer Subscriptions endpoint to find each customer's subscriptions.

The following snippet shows an example of finding and displaying a customer's subscriptions upon login. This example is from the Open Source Customer Portal.

static async getSubscriptions() {
if (!this.subscriptionsCustomerId) {
await this.obtainToken();
}
const { subscriptions } = await this.callAPI({
method: Method.GET,
url: `/customers/${this.subscriptionsCustomerId}/subscriptions`,
params: {
shop: SHOP_DOMAIN,
platform_type: PLATFORM,
},
});

return subscriptions.map(SubscriptionsAdapter.fromServer);
}

Allow customer to edit their subscriptions

One key use case of a customer portal is allowing the customer to edit their subscriptions.

The Bold Subscriptions API allows you to modify a customer subscription in a variety of ways. Most of these endpoints require a subscription_id parameter. When a customer selects a subscription they would like to edit, ensure that the subscription_id is passed along with the trigger.

For example, the following snippet shows how you could allow a customer to pause their subscription through the Pause Subscription endpoint. This example is from the Open Source Customer Portal.

static async pauseSubscription(params) {
const { subscriptionID } = params;

await this.callAPI({
method: Method.POST,
url: `/subscriptions/${subscriptionID}/pause`,
params: {
shop: SHOP_DOMAIN,
platform_type: PLATFORM,
},
});
}

(Optional) Allow customer to store and edit payment methods

You can use Payment Method Management for Checkout (PMMC) to enable the customer to view, edit, and delete saved credit cards, change the default payment method, or update their billing address.

Follow the instructions in the Display Payment Method Management for Checkout (PMMC) guide for more information.

(Optional) Integrate Subscription Builder

One key use case of a customer portal is allowing customers to log into their account and change their selections in customizable subscriptions. This functionality is enabled by the Subscription Builder integration. For information on getting Subscription Builder on your store, refer to Integrate Subscription Builder.

note

For stores that have a Subscription Builder integration, a customer portal is required because the out-of-the-box customer portal does not include the functionality that allows the customer to log in and change their selections.