Create a secure customer-facing subscription portal
- updating shipping and billing addresses
- skipping, pausing, or unpausing a current subscription
- cancelling a subscription
To allow customers to manage their subscriptions, we recommend using an app proxy. In this tutorial, you’ll learn how to set up a secure customer-facing subscription portal using an app proxy.
Why an app proxy is usefulAnchor link to section titled "Why an app proxy is useful"
An app proxy fetches data from an app proxy server to display on a page of the online store. By using an app proxy, customers will have a seamless experience without having to leave the shop's domain.
For example, let’s say the shop domain is
coffee-roasters.com and the shop sells a coffee subscription. Shopify handles the storefront and the checkout through the coffee-roasters.com domain.
If the app managing the subscriptions provides its own customer-facing page, then that page might redirect the customer to a different domain. This redirection could confuse the customer. By using an app proxy, you can ensure the entire experience stays under the
To learn how to set up an app proxy, refer to our application proxy tutorial.
ConsiderationsAnchor link to section titled "Considerations"
When setting up your customer-facing subscription portal, consider the following:
Cookie headers Cookie headers are stripped on app proxies. If you need to persist information between requests, such as authentication tokens, then use query string parameters.
Assets paths Apps run behind the app proxy in the storefront. You might need to adjust how assets are served from your app, because the URLs will use the app proxy's prefix.
Rendering an app proxyAnchor link to section titled "Rendering an app proxy"
You can render an app proxy in two ways:
- Full page rendering (recommended)
- Liquid code in the shop’s theme
Full page renderingAnchor link to section titled "Full page rendering"
Liquid code in the shop’s themeAnchor link to section titled "Liquid code in the shop’s theme"
If the HTTP response from the proxy URL has
Content-Type: application/liquid set in the header, then Shopify renders any Liquid code in the request body in the context of the shop using the shop's theme.
Securely authenticate a customer into a subscription portal using an emailAnchor link to section titled "Securely authenticate a customer into a subscription portal using an email"
This section describes the steps for implementing an automated and secure customer portal that doesn't require merchant interaction.
For this example, we’ll use the following app proxy configuration:
- Sub path prefix: apps
- Sub path: my-subscriptions-app
- Proxy URL:
1. Expose an action to send an emailAnchor link to section titled "1. Expose an action to send an email"
The first step is to provide a link or button that triggers an email to be sent to a customer. You should place a link or button in an area that’s accessible to the customer.
You can provide a link or button in one of the following areas:
- on the customer account page on the storefront
- on the order thank you page
- on the order status page, by customizing the order status page to expose a link or button
- in an email, sent directly to the customer after the app receives a subscription contract creation webhook. The email should contain a secure login link for the customer. For example:
2. Authenticate and access the customer portalAnchor link to section titled "2. Authenticate and access the customer portal"
After you've exposed an action to send an email, the customer can use an email link to access the secure subscription portal. At this point, we recommend using an authentication scheme of your choice, with two considerations:
- Cookies are not available on app proxies, so any tokens or session IDs should be sent as query string parameters.
- The login link should be revocable. Emails can be forwarded, so a fixed URL is not safe to use. Simply verifying the authenticity of the URL is also not a secure method. Ideally, a tuple that includes the shop, customer, and token should be stored in the database. The token should be sent as a query string parameter and deleted whenever convenient. For example, you can expire the token after X minutes or when the customer signs off. In the case of a sign off, the customer can start the process again with another email that contains a new login URL.
3. Call the selling plan and subscription contract APIsAnchor link to section titled "3. Call the selling plan and subscription contract APIs"
After clicking the link, the customer is redirected to an endpoint predetermined by the URL.
For example, given the following URL:
Shopify will call the following endpoint:
The app can then implement the relevant views and forms, such as:
- billing and shipping addresses
- pausing, unpausing, skipping, and cancelling subscriptions
All endpoints are forwarded from the app proxy into your app, as long as the form actions and links start with
https://example-merchant.com/apps/my-subscriptions-app/, as shown in the example.
4. Update a customer's payment methodAnchor link to section titled "4. Update a customer's payment method"
For security reasons, customer payment methods, such as credit cards, can't be updated using the API. Customers need to authenticate their payment method where applicable or request a second email that redirects them to a secure flow where their payment method can be safely updated.
After a customer has updated their payment method, the information is available to the app using the same customer payment method ID.
In this example, the request returns a secure URL to send to the customer to update their payment method:
If the response is an error message or if the customer needs to update their payment method at a later date, then you can call the customerPaymentMethodSendUpdateEmail mutation to send an email to the email address associated with the specified ID: