Working with Multiple Plans per Subscription

    Create subscriptions containing multiple plans or different variations of the same plan, all billed in a single invoice.

    If your business offers multiple products, subscribe your customer to multiple plans on a single subscription. This generates a single invoice each billing period that combines every plan. Only a single payment for that invoice is required, reducing your costs and the number of charges your customer sees.

    Creating multiple-plan subscriptions

    Create multiple-plan subscriptions on a customer using the items parameter. Provide the plan and, optionally, a quantity (when using a value other than 1), for each plan:

    curl https://api.stripe.com/v1/subscriptions \
      -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
      -d customer=cus_4fdAW5ftNQow1a \
      -d items[0][plan]=plan_CBXbz9i7AIOTzr \
      -d items[1][plan]=plan_IFuCu48Snc02bc \
      -d items[1][quantity]=2
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc'
    
    subscription = Stripe::Subscription.create({
        customer: 'cus_4fdAW5ftNQow1a',
        items: [
            {
                plan: 'plan_CBXbz9i7AIOTzr',
            },
            {
                plan: 'plan_IFuCu48Snc02bc',
                quantity: 2,
            },
        ],
    })
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc'
    
    subscription = stripe.Subscription.create(
      customer='cus_4fdAW5ftNQow1a',
      items=[
        {
          'plan': 'plan_CBXbz9i7AIOTzr',
        },
        {
          'plan': 'plan_IFuCu48Snc02bc',
          'quantity': 2,
        },
      ],
    )
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc');
    
    $subscription = \Stripe\Subscription::create([
        'customer' => 'cus_4fdAW5ftNQow1a',
        'items' => [
            [
                'plan' => 'plan_CBXbz9i7AIOTzr',
            ],
            [
                'plan' => 'plan_IFuCu48Snc02bc',
                'quantity' => 2,
            ],
        ],
    ]);
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc";
    
    Map<String, Object> itemA = new HashMap<>();
    itemA.put("plan", "plan_CBXbz9i7AIOTzr");
    Map<String, Object> itemB = new HashMap<>();
    itemB.put("plan", "plan_IFuCu48Snc02bc");
    itemB.put("quantity", 2);
    Map<String, Object> items = new HashMap<>();
    items.put("0", itemA);
    items.put("1", itemB);
    Map<String, Object> params = new HashMap<>();
    params.put("customer", "cus_4fdAW5ftNQow1a");
    params.put("items", items);
    Subscription subscription = Subscription.create(params);
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc');
    
    (async () => {
      const subscription = await stripe.subscriptions.create({
        customer: 'cus_4fdAW5ftNQow1a',
        items: [
          {
            plan: 'plan_CBXbz9i7AIOTzr',
          },
          {
            plan: 'plan_IFuCu48Snc02bc',
            quantity: 2,
          },
        ],
      });
    })();
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"
    
    items := []*stripe.SubscriptionItemsParams{
      {
        Plan: stripe.String("plan_CBXbz9i7AIOTzr"),
      },
      {
        Plan: stripe.String("plan_IFuCu48Snc02bc"),
        Quantity: stripe.Int64(2),
      },
    }
    params := &stripe.SubscriptionParams{
      Customer: stripe.String("cus_4fdAW5ftNQow1a"),
      Items: items,
    }
    subscription, _ := sub.New(params)
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    StripeConfiguration.SetApiKey("sk_test_4eC39HqLyjWDarjtT1zdp7dc");
    
    var items = new List<SubscriptionItemOption> {
        new SubscriptionItemOption {
            PlanId = "plan_CBXbz9i7AIOTzr"
        },
        new SubscriptionItemOption {
            PlanId = "plan_IFuCu48Snc02bc",
            Quantity = 2,
        },
    };
    var options = new SubscriptionCreateOptions {
        CustomerId = "cus_4fdAW5ftNQow1a",
        Items = items,
    };
    var service = new SubscriptionService();
    Subscription subscription = service.Create(options);
    

    When the subscription is created successfully, the response includes a list of all the plans:

    {
      "id": "sub_CZEpS1Zt9QLxdo",
      "object": "subscription",
      ...
      "items": {
        "object": "list",
        "data": [
          {
            "id": "si_CZEpxL7flyswvU",
            "object": "subscription_item",
            "created": 1522113139,
            "metadata": {},
            "plan": {
              "id": "plan_CZB2krKbBDOkTS",
              "object": "plan",
              "amount": 5000,
              "created": 1522098982,
              ...
            },
            "quantity": 1,
            "subscription": "sub_CZEpS1Zt9QLxdo"
          },
          {
            "id": "si_CZEpDeHTKq2iQm",
            "object": "subscription_item",
            "created": 1522113139,
            "metadata": {},
            "plan": {
              "id": "plan_CZB1AX3KOacNJw",
              "object": "plan",
              "amount": 5000,
              "created": 1522098979,
              ...
            },
            "quantity": 2,
            "subscription": "sub_CZEpS1Zt9QLxdo"
          }
        ],
        ...
      },
      ...
    }
    

    Billing periods with multiple plans

    Conventional plans that charge a fixed amount on an interval are billed at the start of each billing cycle. With each invoice, the customer effectively pays for the next interval of service. In a metered plan, the price paid by the customer varies based on consumption during the billing cycle, so the customer pays for their usage at the end.

    When a subscription combines a fixed rate plan and a metered billing plan, metered usage from the previous billing cycle is charged alongside the fixed rate for the new billing cycle at the start of each interval. The metered billing and fixed rate are combined in a single invoice.

    Restrictions

    Since putting multiple plans under a single subscription results in a single invoice and payment, all of the plans grouped together in a subscription must use the same currency and have the same billing interval. You are also limited to 20 plans in a single subscription.

    Discounts, taxes, and trial periods

    When using multiple plans on a single subscription, you can also create discounts, charge taxes, and use trial periods as you would with a single-plan subscription. Provide these as top-level arguments to the create or update subscription call, as they apply to the subscription at large:

    curl https://api.stripe.com/v1/subscriptions \
      -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
      -d customer=cus_4fdAW5ftNQow1a \
      -d coupon=free-period \
      -d default_tax_rates[0]=txr_1EO66sClCIKljWvs98IiVfHW \
      -d trial_end=1559086415 \
      -d items[0][plan]=plan_CBXbz9i7AIOTzr \
      -d items[1][plan]=plan_IFuCu48Snc02bc \
      -d items[1][quantity]=2
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc'
    
    subscription = Stripe::Subscription.create({
        customer: 'cus_4fdAW5ftNQow1a',
        coupon: 'free-period',
        default_tax_rates: ['txr_1EO66sClCIKljWvs98IiVfHW'],
        trial_end: 1559086415,
        items: [
            {
                plan: 'plan_CBXbz9i7AIOTzr',
            },
            {
                plan: 'plan_IFuCu48Snc02bc',
                quantity: 2,
            },
        ],
    })
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc'
    
    subscription = stripe.Subscription.create(
      customer='cus_4fdAW5ftNQow1a',
      coupon='free-period',
      default_tax_rates=['txr_1EO66sClCIKljWvs98IiVfHW'],
      trial_end=1559086415,
      items=[
        {
          'plan': 'plan_CBXbz9i7AIOTzr',
        },
        {
          'plan': 'plan_IFuCu48Snc02bc',
          'quantity': 2,
        },
      ],
    )
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc');
    
    $subscription = \Stripe\Subscription::create([
        'customer' => 'cus_4fdAW5ftNQow1a',
        'coupon' => 'free-period',
        'default_tax_rates' => ['txr_1EO66sClCIKljWvs98IiVfHW'],
        'trial_end' => 1559086415,
        'items' => [
            [
               'plan' => 'plan_CBXbz9i7AIOTzr',
            ],
            [
                'plan' => 'plan_IFuCu48Snc02bc',
                'quantity' => 2,
            ],
        ],
    ]);
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc";
    
    Map<String, Object> itemA = new HashMap<>();
    itemA.put("plan", "plan_CBXbz9i7AIOTzr");
    Map<String, Object> itemB = new HashMap<>();
    itemB.put("plan", "plan_IFuCu48Snc02bc");
    itemB.put("quantity", 2);
    Map<String, Object> items = new HashMap<>();
    items.put("0", itemA);
    items.put("1", itemB);
    Map<String, Object> params = new HashMap<>();
    params.put("customer", "cus_4fdAW5ftNQow1a");
    params.put("coupon", "free-period");
    String[] taxRates = {"txr_1EO66sClCIKljWvs98IiVfHW"};
    params.put("default_tax_rates", taxRates);
    params.put("trial_end", 1559086415);
    params.put("items", items);
    Subscription subscription = Subscription.create(params);
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc');
    
    (async () => {
      const subscription = await stripe.subscriptions.create({
        customer: 'cus_4fdAW5ftNQow1a',
        coupon: 'free-period',
        default_tax_rates: ['txr_1EO66sClCIKljWvs98IiVfHW'],
        trial_end: 1559086415,
        items: [
          {
            plan: 'plan_CBXbz9i7AIOTzr',
          },
          {
            plan: 'plan_IFuCu48Snc02bc',
            quantity: 2,
          },
        ],
      });
    })();
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"
    
    items := []*stripe.SubscriptionItemsParams{
      {
        Plan: stripe.String("plan_CBXbz9i7AIOTzr"),
      },
      {
        Plan: stripe.String("plan_IFuCu48Snc02bc"),
        Quantity: stripe.Int64(2),
      },
    }
    params := &stripe.SubscriptionParams{
      Customer: stripe.String("cus_4fdAW5ftNQow1a"),
      Coupon: stripe.String("free-period"),
      TaxRates = new List<string>
      {
          "txr_1EO66sClCIKljWvs98IiVfHW",
      },
      TrialEnd: stripe.Int64(1559086415),
      Items: items,
    }
    subscription, _ := sub.New(params)
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    StripeConfiguration.SetApiKey("sk_test_4eC39HqLyjWDarjtT1zdp7dc");
    
    var items = new List<SubscriptionItemOption> {
        new SubscriptionItemOption {
            PlanId = "plan_CBXbz9i7AIOTzr"
        },
        new SubscriptionItemOption {
            PlanId = "plan_IFuCu48Snc02bc",
            Quantity = 2,
        },
    };
    var options = new SubscriptionCreateOptions {
        CustomerId = "cus_4fdAW5ftNQow1a",
        CouponId = "free-period",
        TaxRates = new List<string>
        {
            "txr_1EO66sClCIKljWvs98IiVfHW",
        },
        TrialEnd = DateTimeOffset.FromUnixTimeSeconds(1559086415).UtcDateTime,
        Items = items,
    };
    var service = new SubscriptionService();
    Subscription subscription = service.Create(options);
    

    When you create a subscription by passing plans into the items attribute, it will ignore any trial period that is specified on the individual plans. The trial period is only respected if you create a subscription with a single plan via the plan attribute.

    Next steps

    Now that you understand how to use multiple plans on a single subscription, you may want to check out:

    Questions?

    We're always happy to help with code or other questions you might have. Search our documentation, contact support, or connect with our sales team. You can also chat live with other developers in #stripe on freenode.

    Was this page helpful? Yes No

    Send

    Thank you for helping improve Stripe's documentation. If you need help or have any questions, please consider contacting support.

    On this page