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

humpback's avatar

Try/Catch Stripe error handling

Hi, this video suggests to use try catch but when I tried, I got this error instead: Card in ApiRequestor.php line 102: Your card was declined.

https://laracasts.com/series/billing-with-stripe/episodes/5

Has the error class changed? Stripe's API docs seem different https://stripe.com/docs/api?lang=php#errors

My routes.php looks like this

<?php namespace Acme\Billing;

use Stripe\Stripe;
use Stripe\Charge;
use Stripe\Customer;
use Stripe\Stripe_CardError;
use Stripe\Stripe_InvalidRequestError;
use Config;

class StripeBilling implements BillingInterface {

    public function __construct() {
        Stripe::setApiKey(Config::get('stripe.secret_key'));

    }
    public function charge(array $data) {

        try {

            // this is assuming all customer is new

            $customer = Customer::create([
                'card' => $data['token'],
                'description' => $data['email']
            ]);
            Charge::create([
                'customer' => $customer->id,
                'amount' => 1000, // $10
                'currency' => 'usd',
                'customer' => $customer->id
                //'description' => $data['email'],
                //'card' => $data['token']

            ]);

            return $customer->id;
        }
        catch (Stripe_InvalidRequestError $e ) {

            // Invalid request errors arise when your request has invalid parameters.
            dd('Invalid request error');

        }
        catch (Stripe_CardError $e) {
            dd('Card was declined');
        }
        
    }
}
0 likes
5 replies
bobbybouwmann's avatar

Try this, like metioned in the documentation

try {
    // Use Stripe's bindings...
} catch(\Stripe\Error\Card $e) {
    // Since it's a decline, \Stripe\Error\Card will be caught
    $body = $e->getJsonBody();
    $err  = $body['error'];

    print('Status is:' . $e->getHttpStatus() . "\n");
    print('Type is:' . $err['type'] . "\n");
    print('Code is:' . $err['code'] . "\n");

     // param is '' in this case
    print('Param is:' . $err['param'] . "\n");
    print('Message is:' . $err['message'] . "\n");
} catch (\Stripe\Error\InvalidRequest $e) {
    // Invalid parameters were supplied to Stripe's API
} catch (\Stripe\Error\Authentication $e) {
    // Authentication with Stripe's API failed
    // (maybe you changed API keys recently)
} catch (\Stripe\Error\ApiConnection $e) {
    // Network communication with Stripe failed
} catch (\Stripe\Error\Base $e) {
    // Display a very generic error to the user, and maybe send
    // yourself an email
} catch (Exception $e) {
    // Something else happened, completely unrelated to Stripe
}

Note: the video is a few months old and with the fast changing web, you should always check the documentation when you use such an API

3 likes
humpback's avatar

@bobbybouwmann I confuse with this \Stripe\Error\Card against Stripe_CardError or Stripe_InvalidRequestError

what are the alternative of it to tidy up the code? like the use of "use Stripe\Customer" on top

bobbybouwmann's avatar
Level 88

They updated their code structure, so that's why It's changed. You can simply add the use statement with the namespace at the top and remove the namespace in the catch like so

use Stripe\Error\Card;

try {
    
} catch(Card $e) {
    
}

Note: I would recommend this, because Card is not clear here! Stripe\Error\Card reads much better to me

1 like
saurabh2836's avatar

How will catch the chaining exception of the following

$cards = $cards->sources->all(array('limit' => 3, 'object' => 'card'));

Please or to participate in this conversation.