Managing Subscription Billing Cycles

    Learn how to change the date when your customers are billed for a subscription.

    A subscription’s billing date is determined by:

    • Its “billing cycle anchor”: This defaults to when the subscription was created, or if a trial period is used, the trial end. It can also be set explicitly at creation.
    • The billing interval of its plan(s)

    For example, a customer subscribed to a monthly or yearly plan on the 2nd will always be billed on the 2nd. A different customer subscribed to that same plan starting on the 15th will always be billed on the 15th. You can make this consistent across all customers by setting billing_cycle_anchor to fixed dates (for example, the 1st of the next month) when creating the subscriptions.

    If a month does not have the anchor day, it will be billed on the last day of the month. For example, a subscription starting on January 31st will bill on February 28th (or 29th in a leap year), then March 31st, April 30th, and so on.

    To create a subscription with a billing cycle anchor in the future and a prorated invoice until the anchor, perform a create subscription call with a timestamp for billing_cycle_anchor:

    curl https://api.stripe.com/v1/subscriptions \
       -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
       -d customer=cus_4fdAW5ftNQow1a \
       -d items[0][plan]=plan_CBb6IXqvTLXp3f \
       -d billing_cycle_anchor=1538908877
    
    # 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_CBb6IXqvTLXp3f'}],
        billing_cycle_anchor: 1538908877,
    })
    
    # 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_CBb6IXqvTLXp3f'}],
      billing_cycle_anchor=1538908877,
    )
    
    // 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_CBb6IXqvTLXp3f']],
        'billing_cycle_anchor' => 1538908877,
    ]);
    
    // 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> item = new HashMap<>();
    item.put("plan", "plan_CBb6IXqvTLXp3f");
    Map<String, Object> items = new HashMap<>();
    items.put("0", item);
    Map<String, Object> params = new HashMap<>();
    params.put("customer", "cus_4fdAW5ftNQow1a");
    params.put("items", items);
    params.put("billing_cycle_anchor", 1538908877);
    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
    var stripe = require("stripe")("sk_test_4eC39HqLyjWDarjtT1zdp7dc");
    
    const subscription = stripe.subscriptions.create({
      customer: 'cus_4fdAW5ftNQow1a',
      items: [{plan: 'plan_CBb6IXqvTLXp3f'}],
      billing_cycle_anchor: 1538908877,
    });
    
    // 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_CBb6IXqvTLXp3f"),
      },
    }
    params := &stripe.SubscriptionParams{
      Customer: stripe.String("cus_4fdAW5ftNQow1a"),
      Items: items,
      BillingCycleAnchor: stripe.Int64(1538908877),
    }
    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<StripeSubscriptionItemOption> {
        new StripeSubscriptionItemOption {PlanId = "plan_CBb6IXqvTLXp3f"}
    };
    var options = new StripeSubscriptionCreateOptions {
        Items = items,
        BillingCycleAnchor = DateTimeOffset.FromUnixTimeSeconds(1538908877).UtcDateTime,
    };
    var service = new StripeSubscriptionService();
    StripeSubscription subscription = service.Create("cus_4fdAW5ftNQow1a", options);
    

    You can also combine trials with billing_cycle_anchor, resulting in a free period followed by a prorated period.

    Changing the billing cycle

    There are two ways to change when an existing subscription is billed:

    1. By introducing a trial period. This allows the anchor to be reset to a future date. Although trial periods are normally used at the start of a subscription, applying them during a subscription is allowed. For example, if it is May 15th and a customer has an active subscription set to bill next on May 23rd, and you introduce a trial period until June 1st:

      • The customer will not be billed on May 23rd.
      • The customer will be billed next on June 1st, then on July 1st, and so on.
    2. By resetting the anchor to the current time, using billing_cycle_anchor=now. This will result in the customer receiving an invoice immediately. We do not currently support resetting the anchor to a future date using this method.)

    You can change a subscription’s billing cycle via the API or the Dashboard, but make sure to consider proration first.

    Handling prorations

    Stripe bills subscriptions with conventional fixed-rate plans and per-seat plans (where usage_type is licensed) in advance: the customer paid for the current billing interval via the previous invoice. As a trial period is by definition a free period on a subscription, introducing a trial to an existing, paid subscription results in a proration. The customer is credited for the period they’ve already paid for that is now being called “free”.

    The prorate flag on updates determines whether the customer receives a credit for the unused time of the previous period/invoice. When the value of prorate is false, the subscription’s plans are updated, but no proration adjustments are created.

    • When moving the billing cycle using a trial, if you do not want this period to be free (since the user is presumably continuing full access to your service or product), it’s important that you disable proration, so the customer is not credited for the now “free” period.

    • When resetting billing_cycle_anchor, the customer is invoiced immediately for the next period. With proration disabled, there is no credit for the unused time, so the new invoice for the full period amount might result in over-payment. Enabling proration in this case will result in the total invoiced amount being correct.

    When creating a subscription with billing_cycle_anchor, the prorate flag determines whether the customer receives a prorated invoice at all: if disabled, their initial period up to the anchor will be free—similar to a free trial. Unlike a trial, there is no $0 invoice.

    Changing the billing cycle via the API

    To add a trial period to an existing subscription, perform an update subscription call, providing a trial_end value:

    curl https://api.stripe.com/v1/subscriptions/sub_49ty4767H20z6a \
       -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
       -d trial_end=1538908877 \
       -d prorate=false
    
    # 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"
    
    Stripe::Subscription.update('sub_49ty4767H20z6a', {
      trial_end: 1538908877,
      prorate: false,
    })
    
    # 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"
    
    stripe.Subscription.modify('sub_49ty4767H20z6a',
      trial_end=1538908877,
      prorate=False,
    )
    
    // 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");
    
    \Stripe\Subscription::update('sub_49ty4767H20z6a', [
        'trial_end' => 1538908877,
        'prorate' => false,
    ]);
    
    // 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";
    
    Subscription subscription = Subscription.retrieve("sub_49ty4767H20z6a")
    Map<String, Object> params = new HashMap<>();
    params.put("trial_end", 1538908877);
    params.put("prorate", false);
    subscription.update(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
    var stripe = require("stripe")("sk_test_4eC39HqLyjWDarjtT1zdp7dc");
    
    const subscription = stripe.subscriptions.update('sub_49ty4767H20z6a', {
      trial_end: 1538908877,
      prorate: false,
    });
    
    // 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"
    
    params := &stripe.SubscriptionParams{
      TrialEnd: stripe.Int64(1538908877),
      Prorate: stripe.Bool(false),
    }
    subscription, _ := sub.Update("sub_49ty4767H20z6a", 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 options = new StripeSubscriptionUpdateOptions {
        TrialEnd = DateTimeOffset.FromUnixTimeSeconds(1538908877).UtcDateTime,
        Prorate = false,
    };
    var service = new StripeSubscriptionService();
    StripeSubscription subscription = service.Update("sub_49ty4767H20z6a", options);
    

    As a reminder, you probably want to also set prorate to false—as in the above code—so the customer is not credited for previously paid, but unused time.

    To reset the billing cycle anchor, perform an update subscription call, providing a billing_cycle_anchor value of now:

    curl https://api.stripe.com/v1/subscriptions/sub_49ty4767H20z6a \
       -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
       -d billing_cycle_anchor=now \
       -d prorate=true
    
    # 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"
    
    Stripe::Subscription.update('sub_49ty4767H20z6a', {
      billing_cycle_anchor: 'now',
      prorate: true,
    })
    
    # 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"
    
    stripe.Subscription.modify('sub_49ty4767H20z6a',
      billing_cycle_anchor='now',
      prorate=True,
    )
    
    // 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");
    
    \Stripe\Subscription::update('sub_49ty4767H20z6a', [
        'billing_cycle_anchor' => 'now',
        'prorate' => true,
    ]);
    
    // 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";
    
    Subscription subscription = Subscription.retrieve("sub_49ty4767H20z6a")
    Map<String, Object> params = new HashMap<>();
    params.put("billing_cycle_anchor", 'now');
    params.put("prorate", true);
    subscription.update(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
    var stripe = require("stripe")("sk_test_4eC39HqLyjWDarjtT1zdp7dc");
    
    const subscription = stripe.subscriptions.update('sub_49ty4767H20z6a', {
      billing_cycle_anchor: 'now',
      prorate: true,
    });
    
    // 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"
    
    params := &stripe.SubscriptionParams{
      BillingCycleAnchorNow: stripe.Bool(true),
      Prorate: stripe.Bool(true),
    }
    subscription, _ := sub.Update("sub_49ty4767H20z6a", 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 options = new StripeSubscriptionUpdateOptions {
        BillingCycleAnchorNow = true,
        Prorate = true,
    };
    var service = new StripeSubscriptionService();
    StripeSubscription subscription = service.Update("sub_49ty4767H20z6a", options);
    

    With this approach, you probably want to set prorate to true (also the default behavior)—as in that code—so the customer is not over-charged for unused time in the previous cycle.

    Changing the billing cycle with a trial via the Dashboard

    To add a trial period to an existing subscription via the Dashboard:

    1. Find the subscription you want to change.
    2. Click Edit details.
    3. Set Trial end to the date you want billing to resume.
    4. Uncheck Prorate (per the above discussion, this is likely what you want).
    5. Click Done.

    We do not currently support resetting billing_cycle_anchor via the Dashboard.

    Metered billing

    In a metered billing plan, the price paid by the customer varies based on consumption during the billing cycle. When changing the billing cycle results in ending a subscription interval early, metered billing plans simply charge for the usage accrued during the shortened billing period.

    Next steps

    Congrats! You know how to change a subscription’s billing cycle. Some resources you might want to see next:

    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.