php
use Stripe\Checkout\Session as CheckoutSession;
public function checkout(User $user)
{
return with($request->user(), function ($user) use ($request) {
return with(CheckoutSession::create(array_merge($user->stripe_id ? ['customer' => $user->stripe_id] : ['customer_email' => $user->email], [
'payment_method_types' => ['card'],
'subscription_data' => [
'items' => [['plan' => 'PLAN_ID_HERE']],
'trial_period_days' => 7,
],
'allow_promotion_codes' => true,
'mode' => 'subscription',
'client_reference_id' => $user->id,
'success_url' => url('/home'),
'cancel_url' => URL::previous(url('/register')),
])), fn ($session) => $session->id);
});
}
app/Http/StripeWebhookController.phpphp
use Illuminate\Support\Facades\DB;
use Laravel\Cashier\Http\Controllers\WebhookController as CashierController;
class StripeWebhookController extends CashierController
{
public function handleCheckoutSessionCompleted(array $payload)
{
$session = $payload['data']['object'];
$user = User::findOrFail($session['client_reference_id']);
DB::transaction(function () use ($session, $user) {
$user->update(['stripe_id' => $session['customer']]);
$user->subscriptions()->create([
'name' => 'default',
'stripe_id' => $session['subscription'],
'stripe_status' => 'trialing' // Or use "active" if you don't provide a trial
'stripe_plan' => 'PLAN_ID_HERE',
'quantity' => 1,
'trial_ends_at' => now()->addDays(7),
'ends_at' => null,
]);
});
return $this->successMethod();
}
}
Context
While Laravel Cashier uses Stripe Elements by default, Stripe can now handle the checkout flow themselves. The following snippet allows you to implement this new flow into your Laravel application, while keeping the rest of Cashier working.
Usage
For this to work you'll need to create a route pointing to your StripeWebhookController
and point your Stripe webhooks to that route instead of the default one provided by Cashier. You'll also need to add the checkout.session_completed
event to your webhook from the Stripe Dashboard.