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

Jam0r's avatar
Level 8

Catching Stripe error within a Job

So I'm working on accepting payments for invoices and everything was working fine however as with everything I wanted to refactor and move the Stripe charging & customer creation into a job to stop the customer having to wait around for a response.

Using an accepted test card the process works fine.

I change the invoice status to 'payment-pending' before dispatching the Job.

I then call a recordPayment method on my Invoice eloquent model from within the job once the charge is made, which records the payment locally, attaches it to the invoice, updates the invoice balance and marks it as paid should no balance remain.

When using a failed test card the job process fails which is what I expect and it gives the correct reason through Horizon..

Stripe\Error\Card: Your card was declined.

But the failed method from within the job doesn't get called which is where I want to update the invoice status back to unpaid as the payment wasn't successful.

I'm using the billable trait on the user model.

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        /**
         * Create the stripe customer if not present.
         */
        if (! $this->user->hasStripeId()) {
            $this->user->createAsStripeCustomer($this->token);
        }

        $this->user->updateCard($this->token);
        
        $this->user->charge($this->invoice->total);

        $this->invoice->recordPayment($this->user, [
            'method' => 'Stripe'
        ]);
    }

    /**
     * The job failed to process.
     *
     * @param  Exception  $exception
     * @return void
     */
    public function failed(Exception $exception)
    {
        $this->invoice->forceFill([
            'status' => 'unpaid'
        ])->save();

        // Send user notification of failure, etc...
    }
0 likes
1 reply
Jam0r's avatar
Level 8

Found out why the invoice wouldn't get reverted back to unpaid in the failed method.

Stripe was giving an Error\Card exception and I was expecting a generic Exception.

    /**
     * The job failed to process.
     *
     * @param  Exception  $exception
     * @return void
     */
    public function failed(\Stripe\Error\Card $exception)
    {
        $this->invoice->forceFill([
            'status' => 'unpaid'
        ])->save();

        // Send user notification of failure, etc...
    }

This works fine now although I'd probably prefer the option to catch different errors later down the line.

Please or to participate in this conversation.