Unique Use Cases and Enhancements (Optional)

These optional sections cover solutions for particular scenarios. For questions not answered here, please see the Stripe Billing Integration FAQ.

Delaying the start date

If you’d like to postpone starting a subscription until a particular date, there are a few different ways to accomplish this:

  1. You can change the billing cycle of an existing subscription by leveraging trial periods, using the trial_end parameter. This way, your customer wouldn’t be charged anything until the date that you supply. For details, see Changing the billing cycle via the API.

  2. Use the billing_cycle_anchor parameter, passing in a timestamp that reflects when the subscription should begin. At creation time, passing a non-now value for billing_cycle_anchor allows you to define a subscription to have its first billing date set at a specified point in the future.

    In particular (and unlike trial_end), billing_cycle_anchor lets you make a prorated charge for a fraction of the month, and then “snap” the billing cycle to the day that you want. As an example: If on January 20th, you performed a create subscription request with billing_cycle_anchor equal to February 1st, then your customer would immediately be charged for about 1/3 of a month, and would subsequently be charged the full amount on the 1st of each subsequent month.

Authorizing automatically before a trial

Any time you create a Customer object, Stripe automatically performs a $0 or $1 authorization against the customer’s card. Although the customer’s bank has the ability to decline future payments, this initial authorization confirms the card’s validity at the time the trial is created. Therefore, as long as you create a Customer object, you do not need to trigger a separate auth before a trial.

How Billing works with Connect Custom accounts

As with creating charges directly on a connected account, you can create both a customer and a subscription on a connected account. For further details, see Creating Subscriptions.

Declines reporting

This section outlines several approaches to reporting declines:

Pull a Historical Report to Analyze Unique Declines

You can pull a report to see declines codes for all historical charges by making a List all charges API call. The error will be within the Charge object, in the failure_code and failure_message attributes. It’s important to look at unique declines to ensure that you have a holistic understanding of the declines issue.

Basic approach: Listing all declines and their error codes

You can list all of the declines, and the error codes for each, by using the list charges method. Passing the undocumented paid parameter as false returns a list of charges that failed, and you’ll be able to paginate through these charges 100 at a time. The example Ruby script below creates a simple comma-separated list of charges that were declined, along with the failure code and message for each.

require 'stripe'

Stripe.api_key = "YOUR-API-KEY"

declines = Stripe::Charge.list(paid: false, limit: 100)

declines.auto_paging_each do |decline|
  puts "#{decline.id},#{decline.failure_code},#{decline.failure_message}"

Below is example output that you might receive when running this script:

ch_16vHlpLrKpFcM240Rb1vn2B2, card_declined, Your card was declined.

ch_16pkxmLrKpFcM240xRAvcy4C, expired_card, Your card has expired.

ch_16pkwvLrKpFcM240R0yjXFSC, incorrect_cvc, Your card's security code is incorrect.

ch_16pksuLrKpFcM240raFcYmAj, card_declined, Your card was declined.

Although we used Ruby in this example, you can find many other official and third-party libraries on Stripe’s API Libraries page.

Advanced approach: Listing more decline info, and identifying unique cards

To extend this a bit further, you could retrieve the id property on the source object in the charge. This is a value that uniquely identifies the card. Grouping results by this value can be helpful in determining how many declines actually occurred for different cards in your account.

The example script below uses the list charges method mentioned in the basic example. This script prints a formatted date, charge ID, card ID, brand, card’s last four digits, and decline message.

require 'stripe'

Stripe.api_key = "YOUR-API-KEY"

declines = Stripe::Charge.list(paid: false, limit: 100)

declines.auto_paging_each do |decline|
  # Format the timestamp
  formatted_date = Time.at(decline.created)
  # Output the date, card id, brand, last 4, and decline message
  puts "#{formatted_date},#{decline.id},#{decline.source.id},#{decline.source.brand},#{decline.source.last4},#{decline.failure_message}"

Below is example output from this script:

x2015-09-27 12:32:32 -0700,ch_16pksuLrKpFcM240raFcYmAj,card_16pksuLrKpFcM240fGFWFT5r,Visa,0002,Your card was declined.

2015-09-17 07:27:42 -0700,ch_16m3MQLrKpFcM240381YDEck,card_16anbcLrKpFcM240JpUhufd4,Visa,0341,Your card was declined.

2015-09-07 09:39:45 -0700,ch_16iSejLrKpFcM2407jptYL3c,card_16iSe5LrKpFcM240bRTvD0lW,Visa,0127,Your card's security code is incorrect.

You can group and sort this data by card ID to identify unique declines, by saving the results in your database or by using a spreadsheet like Microsoft Excel.

Working with advanced decline codes

Through the API, the outcome of a payment that has been declined contains the type of payment failure that has occurred, and provides the reason, using the decline code received by the card issuer. For details, please see Payments declined by card issuers.


Stripe Billing has a built-in analytics page that provides key metrics for businesses running on Stripe Billing. These metrics include MRR (monthly recurring revenue), Trial Conversion Rate, and Subscriber Churn Rate. For details on how Stripe calculates these metrics, see our Billing Analytics support page.

In addition, Stripe has a wide range of integrations with third-party providers, such as Baremetrics or Chart Mogul, which can help with analytics like MRR (monthly recurring revenue), ARR (annual recurring revenue), Customer LTV (lifetime value), and other churn metrics.

Next steps

Was this page helpful?

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

On this page