Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

arthurvillar's avatar

Stripe issue: Catching any wrong/invalid card errors using Customer create for subscriptions with Stripe

I am starting to create an API with Stripe for a web-app that offers memberships.

I cannot use Cashier because the web-app's server also serves an iOS app that has in-app purchases subscriptions and the entire system is already in place.

The issue is that when I fetch the user's card information and create the Customer on Stripe, that customer still gets created even when I use a test card that fails for any reason.

On Stripe's end, it does indicate that the charge failed and the payment is incomplete, but I would rather catch that error and return to the user asking them to fix their mistake before any information is actually saved on Stripe or on our server (which is what usually happens).

On the course here "How to Accept Payments" Jeff Way goes through catching such error but it looks like now Stripe is not throwing these errors anymore and lets the user through regardless.

Here is my controller that expects to catch the error but does not:

    public function purchase(Request $request)
    {
        Stripe::setApiKey(config('services.stripe.secret'));

        try {
            $customer = Customer::create([
                'description' => auth()->user()->full_name,
                'email' => auth()->user()->email,
                'source' => $request->stripeToken,
                'plan' => 'my-plan'
            ]);   
        } catch (\Stripe\Exception\CardException $e) {
	    // This is what I want to happen but never does.
            return back()->with('error', $e->getError()->message);
        }
    	
        return $customer;
    }

I expect the catch block to trigger but it never does. Any ideas? Did Stripe change the way they handle such issues, or am I missing something?

0 likes
1 reply
arthurvillar's avatar
arthurvillar
OP
Best Answer
Level 9

Problem solved! For anyone running into this same problem, I realized that the trial period for the customer was not applying until I added 'trial_from_plan' => true in the array sent to create the customer. Now that method looks like this:

            $customer = Customer::create([
                'description' => auth()->user()->full_name,
                'email' => auth()->user()->email,
                'source' => $request->stripeToken,
                'plan' => $plan,
                'trial_from_plan' => true
            ]);   

This now works as expected and Stripe is sending the errors when a card has an expired date, wrong CVC and so on.

Please or to participate in this conversation.