Create a Trial Period in Stripe that Works

First off, I love Stripe. I have found their APIs and dashboard to be well-thought-out and well tested in general, and definitely way better in just about every way from other payment processors I have had the misfortune to use for clients.

But then I had to create free trials for a client, and I had to ask myself, what were they thinking?

While testing, I added trials to the subscription plans and…customers got charged right away. Um, that’s not how trials work!

Worst of all, the usually excellent and exhaustive Stripe API Docs were not helpful. The internet was, likewise, lacking in details are to how to get the trials to actually be applied without them being specifically added at the time of purchase by API. In my particular case, I was working with a client who was tech-savvy enough to use the Stripe Dashboard. He wanted to be allowed to create and adjust Subscription Plans as needed for marketing purposes without requiring code or database changes.

I did eventually figure it out, and so I decided to write this up to save others some time. Here you go:

Step 1: Create a Product

You may think of them as Subscription Plans, but in the Stripe Dashboard, they are called Product, and then within a Product you can have multiple Prices. When adding your Product, be sure to use the labeling fields Stripe gives you to clearly define each Price or you may get confused later.

There is an expandable field for “Add a Free Trial” to click to add it. In my case, both Prices would need to have a 30-day trial.

Create a Product Dialog in Stripe

You can create a trial for a number of Days only, but it can be up to 731 days, so…cool?

Error Message about Trial Length Limitations in Stripe

Step 2: Add All Prices

Add all of your Prices (i.e. Subscription Plans). If you screw up, or forget to label or add your trial, you need to click on the ellipses or the whole line to make your changes. From what I’ve read, changes made to a Price will only affect NEW subscribers, so you can change your trial to be shorter and it will not affect the current subscribers who were marketed a longer trial.

Viewing a Product and its Prices in Stripe
Adding an Additional Price to your Product in Stripe

Step 3: Create Your Purchase System in the API

Sorry, I’m not getting into this one, but Stripe is pretty good at describing MOST of the process. I like to use their quick-start Javascript form with my own styling and then process the purchase on the back-end.

If you test this now, you will notice that your trial does not work out-of-the-box when you process a subscription purchase. I’m sure they have a reason to leave the trial there as some kind of “optional” idea for developers to engage, or maybe it’s weird due to some long-ago coding decision, but…annoying.

Step 4: Engage Your Inner Trial

This is how one system I built using the Stripe SDK charges customers–your code may be different, but should be somewhat similar.

First, you create a customer with a payment method and set it as the default payment method.

$customer = \Stripe\Customer::create([
      'payment_method' => $_POST['payment_method'],
      'email' => $_POST['email'],
      'invoice_settings' => [
        'default_payment_method' => $_POST['payment_method']
      ]
    ]);

Then, you create a new subscription for that customer that you just created, using it’s new Stripe id:

$subscription = \Stripe\Subscription::create( [
      'customer' => $customer->id,
      'items' => [['plan' => $stripe_plan['stripe_id']]],    
      'trial_from_plan' => true, 
      'expand' => ['latest_invoice.payment_intent']    
    ]);

Did you catch that sneaky line of code in there?

'trial_from_plan' => true,

Yep, that’s all you need to tell your subscription that it should go ahead and apply that trial you setup.

Bonus Tips

When starting out working with Stripe, be sure to also watch out for these two things:

  • Use Try/Catch and allow for every error. There are several “generic” errors that, if not caught, will send your application into a customer-error-facing tizzy. This StackOverflow item has great sample code to help you out: Catching Stripe errors with Try/Catch PHP method.
  • Do not let users determine what you send to Stripe for Coupons. Stripe calls will fail if a coupon sent via API is wrong. I recommend building your own Coupon creator on your site that both creates coupons in stripe via API and establishes a database to check coupons against at checkout. If you don’t have it in your database, let the user know and only send verified coupons over.

Leave a Reply

Your email address will not be published. Required fields are marked *