# Stripe Subscriptions for Shopify

Install and configure the Stripe Subscriptions app to accept recurring payments in your Shopify store.

The Stripe Subscriptions app for Shopify lets you create subscription plans for your products, offer discounts and free trials, and process recurring payments through Stripe. Customers can manage their own subscriptions, and you can view and manage all subscriptions from both the Shopify admin and the Stripe Dashboard.

## Before you begin

Make sure you have:

- A Shopify store on any plan that supports apps
- [Create a Stripe account](https://dashboard.stripe.com/register) if you don’t already have one.
- At least one product in your Shopify store that you want to sell as a subscription

### What this app does

The Stripe Subscriptions app allows you to:

- Create subscription plans for your products (daily, weekly, monthly or yearly billing)
- Offer discounts and free trials to attract subscribers
- Let customers manage their own subscriptions
- Process recurring payment attempts through Stripe, and process the payment on any subscription-supporting payment provider on Shopify
- View and manage all subscriptions from your Shopify admin

## Install the app

1. Go to [Stripe Subscriptions](https://apps.shopify.com/stripe-billing) in the Shopify App Store.
1. Click **Add app**.
1. Review the permissions the app needs and click **Install app**.
1. The app redirects you to the main dashboard.

## Set up the app

When you first open the app, use the setup guide to complete the following steps to fully configure your subscription offerings.

### Step 1: Connect your Stripe account

Before you can accept subscription payments, you need to connect your Stripe account.

1. In the app dashboard, find the **Connect Your Stripe Account** step and click to expand it.
1. Review the benefits of connecting:
   - Manage subscriptions and recurring payments
   - Access customer payment data and analytics
   - We never store your Stripe password
1. (Optional) To test the app before going live, select the **Use test mode** checkbox. This connects to your Stripe test environment so you can try everything without processing real payments.
1. Click **Connect Stripe Account**.
1. On the Stripe authorisation page, log in to your Stripe account and click **Connect** or **Authorise** to grant the app access. If running in test mode, you can click **Skip This Form** to bypass account activation.
1. The app redirects you back to the dashboard with a success message.

> If you don’t have a payment provider configured for test mode in Shopify, configure either Shopify Payments in test mode or a supported payment provider. Processing subscription payments on Shopify’s Bogus Gateway isn’t supported and results in failures.

### Step 2: Create your first subscription plan

A subscription plan defines how you bill customers for your products.

1. Click **Create plan** in the setup wizard, or click **Create New Selling Plan** from the main dashboard.

1. Set the **Basic Details**:

   - **Plan Name**: Give your plan a name (for example, “Subscribe and Save 10%”). This name is visible to customers and appears as the subscription option title in the widget on the product page.
   - (Optional) **Internal Description**: Add details about what’s included. This is internal only and not visible to customers. Use it to differentiate plans if you have multiple plans with the same customer-facing name.
   - **Select Products**: Click **Select products** to choose which products this plan applies to. You can select entire products or specific variants, search for products by name, and select multiple products.
   - Click **Next**.

1. Set the **Plan Type**:

   - Select **Pay-as-you-go** (customers pay at each billing cycle).
   - Choose your **Billing Interval**: daily, weekly, monthly or yearly.
   - Click **Next**.

1. Set **Discounts**: Add discounts to make your subscription more attractive.

   - **Free Trial**: Give customers a trial period before billing starts. Set the number of trial days and optionally add a discount after the trial ends.

   - **Percentage Discount**: Offer a percentage off. Choose the duration: one-time (first order only), forever or a specific number of cycles.

   - **Fixed Amount Discount**: Offer a fixed dollar amount off. Choose the duration: one-time, forever or a specific number of cycles.

   - Click **Next**.

1. **Review and confirm** your settings:

   - Review all your plan settings and click **Create Selling Plan**.

### Step 3: Add the subscription widget to product pages

Add the subscription option to your product pages so customers can see it.

1. In the setup wizard, click **Add subscription widget**.

1. In the Shopify Theme Editor, navigate to a product page template. Preview a product that has a selling plan created for it to see the widget on the page.

1. In the editor sidebar, look for **Apps** or **App blocks** and add the **Stripe Subscription** block.

1. Position the block where you want customers to see it (typically near the **Add to Cart** button).

1. Click **Save** and return to the app.

Visit one of your products with a subscription plan to see the live widget.

### Step 4: Enable customer subscription management

Let customers manage their own subscriptions from their Shopify account.

1. In the setup wizard, click **Turn on subscription management**.

1. In the Shopify Checkout Editor, find the apps section. You have three extensions you can add:

1. Enable the **Subscription Management** extension. Also add a menu item for customers to manage their subscriptions by clicking **Add to menu**.

1. Click **Save** and return to the app.

Customers can then view their active subscriptions, see upcoming billing dates, update payment and shipping information, and pause, resume or cancel subscriptions.

### Step 5: Configure post-purchase account access

Make it clear how customers can access their subscription after checkout.

1. In the setup wizard, click **Add subscription link**.
1. In Shopify Checkout Settings, find the **Thank you page** or **Order status page** settings.
1. Enable the option to show a customer account link.
1. Click **Save** and return to the app.

After completing a subscription purchase, customers see a link to manage their subscription on the thank-you page.

### Step 6: Customise notifications

Choose which emails your customers receive about their subscriptions.

1. In the setup wizard, click **Edit customer notifications**.
1. In Shopify’s Notification Settings, review and customise the order confirmation email template.
1. Click **Save** and return to the app.

> Other email notifications (such as payment success or failure) don’t send for recurring orders through Shopify. For subscriptions using a Shopify-managed payment method, configure failed payment notifications through Shopify Flow workflows or custom notifications using Stripe webhooks. For subscriptions using a Stripe-managed payment method, configure email notifications in the [Stripe Dashboard](https://dashboard.stripe.com).

To create a Shopify Flow that emails customers about failed payments, use the `Subscription billing attempt failure` trigger. You need a third-party Shopify application to provide the email send action. Refer to the application’s documentation for implementation specifics.

## Manage subscriptions

Open the app and click **Subscriptions Management** to view all active, paused and cancelled subscriptions.

From this page you can:

- **View Details**: Click a subscription to see full details including customer information, payment status, next billing date, payment method type and amount.
- **Pause or Resume**: Temporarily stop billing for a subscription.
- **Cancel**: End a subscription.
- **Edit**: Modify subscription details, such as line items or shipping address.
- **Create order**: Manually trigger a billing attempt.
- **View in Stripe**: Open the subscription in the Stripe Dashboard for advanced management.

Use filters to narrow results by subscription status (active, paused, or cancelled), search by customer name or email, or sort by billing date or amount.

### Update payment methods

Customers can update their payment method from their account page or when a payment fails.

## Configure payment retry settings

Failed payments are a normal part of subscription businesses. The app supports billing automations and custom dunning policies through Stripe.

1. In the app, go to **Dunning Settings** and click **Open Stripe Dashboard**.
1. In Stripe, navigate to **Settings** > **Billing** > **Subscriptions and emails**.
1. Configure the retry schedule, customer email notifications and subscription cancellation rules for repeated failures.

> Smart Retries (The Stripe machine-learning-based retry function) isn’t currently supported when payments are processed through Shopify’s payment platform. However, you can use standard retry schedules based on your dunning configuration.

The app supports:

- Custom dunning policies with configurable retry schedules
- Automatic subscription pausing or cancellation after failed payments
- Custom [Billing Automations](https://docs.stripe.com/billing/automations.md) built in Stripe

### Handle payment failures

When a payment fails:

1. Stripe automatically retries based on your dunning settings.
1. If all retries fail, the subscription is paused or cancelled based on your settings.
1. You can build custom notifications and actions in [Stripe Billing Automations](https://docs.stripe.com/billing/automations.md).
1. A payment failed event is created in both Stripe and Shopify.

## Configure pause subscription settings

1. In the app, go to **Settings** and find the **Pause subscription** section.
1. Configure the following options:
   - **Allow customers to pause and resume**: Toggle whether customers can pause from their account.
   - **Pause subscription intervals**: Set pre-defined duration options for customers to choose from (for example, 1 month, 2 months or 3 months). Configure each interval’s duration and unit (days, weeks, months or years).
   - **Custom duration**: Allow customers to choose their own resume date, with an optional maximum limit (for example, 45 days) or no limit.
1. Click **Save**.

## Data synchronisation

When a subscription is created or updated, the app syncs data between Shopify and Stripe.

| Shopify object        | Stripe object |
| --------------------- | ------------- |
| Subscription Contract | Subscription  |
| Customer              | Customer      |
| Selling Plan          | Price         |
| Product or Variant    | Product       |
| Discount              | Coupon        |

### Deferred product and price creation

When you create a subscription plan, the corresponding Stripe products and prices aren’t created immediately. They’re created when the first customer subscribes to that plan.

### Metadata on Stripe objects

The app automatically adds metadata to Stripe objects to link them to their corresponding Shopify objects.

**Subscription metadata:**

| Key                                | Example value                            | Description                                   |
| ---------------------------------- | ---------------------------------------- | --------------------------------------------- |
| `shopify_subscription_contract_id` | `gid://shopify/SubscriptionContract/123` | Links to the Shopify subscription contract    |
| `shopify_customer_id`              | `gid://shopify/Customer/456`             | Links to the Shopify customer                 |
| `shopify_shop_domain`              | `your-store.myshopify.com`               | The shop domain                               |
| `shopify_revision_id`              | `1`                                      | Tracks sync revisions for conflict resolution |

**Subscription item metadata:**

| Key                             | Example value                        | Description                         |
| ------------------------------- | ------------------------------------ | ----------------------------------- |
| `shopify_product_gid`           | `gid://shopify/Product/789`          | Links to the Shopify product        |
| `shopify_product_variant_gid`   | `gid://shopify/ProductVariant/101`   | Links to the specific variant       |
| `shopify_selling_plan_gid`      | `gid://shopify/SellingPlan/202`      | Links to the selling plan           |
| `shopify_subscription_line_gid` | `gid://shopify/SubscriptionLine/303` | Links to the subscription line item |

**Customer metadata:**

| Key                   | Example value                | Description                   |
| --------------------- | ---------------------------- | ----------------------------- |
| `shopify_customer_id` | `gid://shopify/Customer/456` | Links to the Shopify customer |
| `shopify_shop_domain` | `your-store.myshopify.com`   | The shop domain               |
| `stripe_merchant_id`  | `acct_xxx`                   | The connected Stripe account  |

**Product metadata:**

| Key                   | Example value               | Description                  |
| --------------------- | --------------------------- | ---------------------------- |
| `shopify_product_gid` | `gid://shopify/Product/789` | Links to the Shopify product |

**Price metadata:**

| Key                           | Example value                      | Description                  |
| ----------------------------- | ---------------------------------- | ---------------------------- |
| `shopify_product_variant_gid` | `gid://shopify/ProductVariant/101` | Links to the Shopify variant |

### Custom attributes from Shopify subscription contracts

All custom attributes defined on a Shopify subscription contract are automatically copied to the corresponding Stripe subscription’s metadata when you create the subscription.

- Custom attributes are copied at subscription creation time only
- Custom attributes with `nil` values are filtered out and not copied
- Changes to custom attributes after you create the subscription aren’t automatically synced to Stripe

For example, if a Shopify subscription contract has custom attributes `custom_field_1`, `custom_field_2`, and `order_notes`, the Stripe subscription metadata includes those keys alongside the standard Shopify metadata:

```json
{
  "custom_field_1": "custom_value_1",
  "custom_field_2": "custom_value_2",
  "order_notes": "Rush delivery requested",
  "shopify_subscription_contract_id": "gid://shopify/SubscriptionContract/123",
  "shopify_customer_id": "gid://shopify/Customer/456",
  "shopify_shop_domain": "your-store.myshopify.com",
  "shopify_revision_id": "1"
}
```

This allows you to pass additional data from Shopify to Stripe for reporting, analytics or integration purposes. Set custom attributes on the Shopify subscription contract before it first syncs to make sure they appear in Stripe.

### Metadata on Shopify objects

The app also adds attributes to Shopify objects:

- **Subscription contract**: A `stripe_subscription_id` attribute (for example, `sub_xxx`) links to the corresponding Stripe subscription.
- **Selling plan metafields** (namespace: `stripe`): A `free_trial_amount` metafield stores the number of days for a free trial, if configured.

### Special control attributes

The following attribute controls webhook processing during migrations:

| Attribute key                        | Value             | Description                                                                                                                 |
| ------------------------------------ | ----------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `disable_shopify_webhook_processing` | `true` or `false` | When set to `true` on a Shopify subscription contract, webhooks for that contract are ignored. Used during bulk migrations. |

## Report on subscriptions with Stripe Sigma

All subscriptions created through Shopify are full Stripe subscriptions, so you can use [Stripe Sigma](https://docs.stripe.com/stripe-data/sigma.md) and Dashboard Reports to build custom reports using the Shopify metadata synced to your Stripe objects.

### Available Sigma tables

| Table                         | Description                        | Key columns                                     |
| ----------------------------- | ---------------------------------- | ----------------------------------------------- |
| `subscriptions`               | All subscription data              | `id`, `status`, `customer_id`, `created`        |
| `subscription_items`          | Line items within subscriptions    | `subscription_id`, `price_id`, `quantity`       |
| `subscription_metadata`       | Metadata attached to subscriptions | `subscription_id`, `key`, `value`               |
| `subscription_items_metadata` | Metadata on subscription items     | `subscription_item_id`, `key`, `value`          |
| `customers`                   | Customer information               | `id`, `email`, `name`                           |
| `customer_metadata`           | Metadata attached to customers     | `customer_id`, `key`, `value`                   |
| `products`                    | Product catalogue                  | `id`, `name`, `description`                     |
| `product_metadata`            | Metadata on products               | `product_id`, `key`, `value`                    |
| `prices`                      | Pricing information                | `id`, `product_id`, `unit_amount`, `currency`   |
| `price_metadata`              | Metadata on prices                 | `price_id`, `key`, `value`                      |
| `invoices`                    | Invoice data                       | `id`, `subscription_id`, `amount_due`, `status` |

### Subscriptions by Shopify shop domain

```sql
SELECT
  sm.value AS shopify_shop_domain,
  COUNT(s.id) AS subscription_count,
  SUM(CASE WHEN s.status = 'active' THEN 1 ELSE 0 END) AS active_count
FROM subscriptions s
JOIN subscription_metadata sm
  ON s.id = sm.subscription_id
  AND sm.key = 'shopify_shop_domain'
GROUP BY sm.value
ORDER BY subscription_count DESC
```

### Link subscriptions to Shopify contracts

```sql
SELECT
  s.id AS stripe_subscription_id,
  s.status,
  s.customer_id,
  c.email AS customer_email,
  sm_contract.value AS shopify_subscription_contract_id,
  sm_domain.value AS shopify_shop_domain
FROM subscriptions s
JOIN customers c ON s.customer_id = c.id
LEFT JOIN subscription_metadata sm_contract
  ON s.id = sm_contract.subscription_id
  AND sm_contract.key = 'shopify_subscription_contract_id'
LEFT JOIN subscription_metadata sm_domain
  ON s.id = sm_domain.subscription_id
  AND sm_domain.key = 'shopify_shop_domain'
WHERE sm_contract.value IS NOT NULL
```

### Products by Shopify product ID

```sql
SELECT
  p.id AS stripe_product_id,
  p.name AS product_name,
  pm.value AS shopify_product_gid
FROM products p
JOIN product_metadata pm
  ON p.id = pm.product_id
  AND pm.key = 'shopify_product_gid'
```

### Subscription items with Shopify variant details

```sql
SELECT
  si.subscription_id,
  si.id AS subscription_item_id,
  si.quantity,
  p.name AS product_name,
  sim_product.value AS shopify_product_gid,
  sim_variant.value AS shopify_product_variant_gid,
  sim_plan.value AS shopify_selling_plan_gid
FROM subscription_items si
JOIN prices pr ON si.price_id = pr.id
JOIN products p ON pr.product_id = p.id
LEFT JOIN subscription_items_metadata sim_product
  ON si.id = sim_product.subscription_item_id
  AND sim_product.key = 'shopify_product_gid'
LEFT JOIN subscription_items_metadata sim_variant
  ON si.id = sim_variant.subscription_item_id
  AND sim_variant.key = 'shopify_product_variant_gid'
LEFT JOIN subscription_items_metadata sim_plan
  ON si.id = sim_plan.subscription_item_id
  AND sim_plan.key = 'shopify_selling_plan_gid'
```

### Monthly recurring revenue by Shopify store

```sql
SELECT
  sm.value AS shopify_shop_domain,
  s.currency,
  SUM(si.quantity * pr.unit_amount) / 100.0 AS monthly_recurring_revenue
FROM subscriptions s
JOIN subscription_items si ON s.id = si.subscription_id
JOIN prices pr ON si.price_id = pr.id
JOIN subscription_metadata sm
  ON s.id = sm.subscription_id
  AND sm.key = 'shopify_shop_domain'
WHERE s.status = 'active'
  AND pr.recurring_interval = 'month'
GROUP BY sm.value, s.currency
ORDER BY monthly_recurring_revenue DESC
```

### Customers with Shopify customer mapping

```sql
SELECT
  c.id AS stripe_customer_id,
  c.email,
  c.name,
  cm_shopify.value AS shopify_customer_id,
  cm_domain.value AS shopify_shop_domain
FROM customers c
LEFT JOIN customer_metadata cm_shopify
  ON c.id = cm_shopify.customer_id
  AND cm_shopify.key = 'shopify_customer_id'
LEFT JOIN customer_metadata cm_domain
  ON c.id = cm_domain.customer_id
  AND cm_domain.key = 'shopify_shop_domain'
WHERE cm_shopify.value IS NOT NULL
```

### Custom attributes for business reporting

If you’ve added custom attributes to your Shopify subscription contracts (which are copied to Stripe metadata), you can query them for reporting purposes:

```sql
SELECT
  sm_tier.value AS plan_tier,
  COUNT(s.id) AS subscription_count,
  SUM(CASE WHEN s.status = 'active' THEN 1 ELSE 0 END) AS active_subscriptions,
  SUM(CASE WHEN s.status = 'canceled' THEN 1 ELSE 0 END) AS canceled_subscriptions
FROM subscriptions s
JOIN subscription_metadata sm_tier
  ON s.id = sm_tier.subscription_id
  AND sm_tier.key = 'plan_tier'
GROUP BY sm_tier.value
ORDER BY subscription_count DESC
```

### Access Sigma

1. Go to your [Stripe Dashboard](https://dashboard.stripe.com).
1. Navigate to **Reporting** > **Sigma**.
1. Use the Query Editor to write SQL queries.
1. Save queries for repeated use.
1. Schedule queries to run automatically and export to CSV.

Sigma also supports an AI query assistant. You can describe what you want in plain English, and it generates the SQL for you.

### Dashboard financial reports

In addition to Sigma, you can use Financial Reports in the Stripe Dashboard, which support metadata columns:

1. Go to **Reports** > **Financial Reports**.
1. Select a report type (Balance, Payout Reconciliation or Activity).
1. Click **All Columns** to include metadata fields.
1. Download the report.

Metadata from your Shopify objects appears as additional columns in these reports, allowing you to reconcile Stripe data with your Shopify store data.

## Important considerations

### Payment methods on Stripe directly

The app uses Shopify-managed payment methods by default. If a subscription is migrated or a customer’s payment method is updated in Stripe to a Stripe-managed payment method:

- Payments are processed directly through Stripe
- The subscription still appears in Shopify
- Orders are *not* created in Shopify
- Payment records are *not* created in Shopify

> If a subscription moves to a Stripe-managed payment method, orders are no longer automatically created in Shopify for that subscription. This can impact fulfilment logic built in Shopify.

### Billing automations

The app supports automatic recurring billing based on your plan’s interval, custom dunning policies for failed payment handling, automatic subscription status updates and mid-cycle changes.

### Migrate existing subscriptions

Contact support for assistance with subscription migrations. A dedicated migration process can transfer subscription data while maintaining customer payment methods.

### Issue refunds

Process refunds through Shopify.
