phpstripe-paymentslaravel-cashier

Getting Payment incomplete after performing a subscription with a secret client from the backend


I am creating a payment intent, get the client secret and the as follows:

        $payment_intent = \Stripe\PaymentIntent::create(
            [
                'payment_method_types' => ['card'],
                'amount' => $amount,
                'currency' => $price->currency,
                'customer' => $shop->stripeId(),
                'metadata' => [
                    'store_feature' => $id,
                ],
            ]
        );
        $default_payment_method = $stripe->paymentMethods->retrieve($customer->invoice_settings->default_payment_method);
        return response([
            'client_secret' => $payment_intent->client_secret,
            'payment_method'=> $default_payment_method->id,
            'card' => [
                'brand' => $default_payment_method->card->brand,
                'exp_month' => $default_payment_method->card->exp_month,
                'exp_year' => $default_payment_method->card->exp_year,
                'exp_year' => $default_payment_method->card->exp_year,
                'last_four_digits' => $default_payment_method->card->last4,
            ],
            
        ]);

The Front-end uses the card information to let the user confirm the payment method, and use it with the client_secret to purchase a product. But finally, the payment is incomplete as it is shown in the image below:

enter image description here

Is my current implementation wrong and what's your suggestions to investigate such problems?


Solution

  • The code you shared starts by calling the Create PaymentIntent API server-side. This won't attempt any payment yet. Then, you call the Retrieve PaymentMethod API but you're using a variable ($customer) which you haven't referenced anywhere. Even in the first step you didn't use $customer->id and instead used $shop->stripeId() with also no context.

    It's plausible that this part of you code is crashing because the variables aren't set or defined properly. I'd recommend adding detailed logging around this part to ensure it works.

    Additionally, you return some information client-side after that but never shared what you client-side code does. Does it render that PaymentIntent with Stripe's PaymentElement to collect payment method details? Or something else?

    Finally, you mentioned starting a Subscription but your code just creates a one-off PaymentIntent. This is not really how Stripe's Billing product works. You should be creating a Subscription upfront with payment_behavior: 'default_incomplete' and then confirm the first Invoice's underlying PaymentIntent instead. You likely want to carefully go over Stripe's end to end guide to build a subscription integration.