Search code examples
laravelstripe-paymentslaravel-7laravel-cashier

Laravel Cashier: generic trials for new users do not show in Stripe dashboard


I have a register endpoint where I create a new user and set them up on a generic trial period (without credit card info needing to be entered):

public function register(Request $request) {
    //... other not important things for this

    $user = new User([
        'name' => $request->get('name'),
        'email' => $request->get('email'),
        // other fields not important...
        'trial_ends_at' => now()->addDays(1),
    ]);

    $user->createAsStripeCustomer(); // not sure if needed
    $user->save();
    return response()->json($user, 201);
}

In the database I can see that I get a user created with the following field and value: trial_ends_at: 2020-09-21 05:20:47. Also, under "customers" I can see the newly registered user email:

enter image description here

However, in the Stripe dashboard, it says that there are zero new trials:

enter image description here

I also have a customer.subscription.updated webhook that's not running when I'm expecting it to (when the trial ends), so I'm thinking whatever is causing Stripe to not detect a new trial is also what ends up causing the webhook not to fire.

Why does Stripe not "pick up"/know about the new trial?

On the Laravel side of things the user appears to be on a trial ($user->onTrial() returns true), but on the Stripe dashboard that same user does not appear to be on a trial (no new trials show, see screenshot above).


Solution

  • Stripe doesn't have a concept of "generic trials" (trials not attached to a specific subscription plan), only Laravel Cashier has a concept of this (using the trial_ends_at field).

    Instead of a generic trial I create a subscription to a plan, passing in null for the paymentMethod, and also including the trial_period_days option. This allows us to create a trial without first having a payment method on file for that user.

    Here's the code to do that:

    $trialDays = 30;
    $planId = "<your stripe price id>";
    $user->createAsStripeCustomer();
    $user->newSubscription('<name of subscription>', $planId)
        ->create(null, [
            'email' => $user->email
        ], ['trial_period_days' => $trialDays]);
    

    Also when creating the user, remember to still include the trial_ends_at field so what we have in our DB matches up with what Stripe has:

    $trialEndsAt = now()->addDays($trialDays);
    $user = new User([
        //...
        'trial_ends_at' => $trialEndsAt
    ]);
    $user->save();
    

    The user will now be on a trial period in the Stripe dashboard, and using $user->onTrial() will return true since the datetime in the trial_ends_at field is greater than the current datetime.