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

peterdickins's avatar

Cashier

Hi,

I am using Laravel Cashier in my project for a simple shopping cart with one time purchases, users are charged with the following code:

public function charge(User $user, $total, $paymentMethodId): string
{
    $payment = $user->charge($total * 100, $paymentMethodId);

    return $payment->id;
}

If I dump the response from Stripe ($payment) I am a little confused why it returns a Payment Intent object, for example:

id: "pi_xxx"
object: "payment_intent"
...
latest_charge: "ch_xxx"

Does this mean there is a potential that the payment may be rejected without my knowledge?

Also, which id should I store against the order, I am presuming latest charge?

0 likes
3 replies
LaryAI's avatar
Level 58

The Payment Intent object returned by Stripe is used to handle more complex payment scenarios, such as subscriptions or payments that require additional authentication. It does not necessarily mean that the payment will be rejected. However, it is a good idea to handle any potential errors or exceptions that may occur during the payment process.

As for which ID to store against the order, it depends on your specific use case. If you want to track the payment itself, you can store the Payment Intent ID. If you want to track the specific charge associated with the payment, you can store the Charge ID.

Here's an updated version of the charge method that handles any potential exceptions and stores the Payment Intent ID against the order:

use Stripe\Exception\CardException;
use Stripe\Exception\InvalidRequestException;

public function charge(User $user, $total, $paymentMethodId): string
{
    try {
        $payment = $user->charge($total * 100, $paymentMethodId);
        $paymentIntentId = $payment->payment_intent;

        // Store the Payment Intent ID against the order
        $order = new Order();
        $order->payment_intent_id = $paymentIntentId;
        $order->save();

        return $paymentIntentId;
    } catch (CardException $e) {
        // Handle card errors
        return $e->getMessage();
    } catch (InvalidRequestException $e) {
        // Handle invalid request errors
        return $e->getMessage();
    } catch (\Exception $e) {
        // Handle other errors
        return $e->getMessage();
    }
}
Snapey's avatar

Payment intent is a signal that you "Intend" to charge the customer. This is not the payment itself.

You need to inspect the payment intent after the fact to see if it succeeded.

There is probably a cashier way to do this, but I never use Cashier if its just a simple one-time payment.

Herrell's avatar

This works really well for me, thank you! Facing same issue here. Help is appreciated.

Please or to participate in this conversation.