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

Naman178's avatar

Laravel Cashier Stripe Subscription 3D Authentication

I want to create the subscription and need to make a first payment for the subscription

but when I create the subscription it gives me an error like this: https://prnt.sc/9dOwo6kuKwI- "The payment attempt failed because additional action is required before it can be completed."

I am attaching the screenshot of the code

  1. Creating the intent and sending it to the checkout: https://prnt.sc/iak0vqAVYQ_I
  2. Checkout form and submit button : https://prnt.sc/l9RbTwfBlnGQ
  3. Subscription JS : https://prnt.sc/WUoruKGlxgDT
  4. Subscription Controller : https://prnt.sc/t3GHBVqXkt5w

Please help me with the 3D Authentication or solving the error then it will be so grateful.

thanking you in anticipation

0 likes
4 replies
LaryAI's avatar
Level 58

The error message "The payment attempt failed because additional action is required before it can be completed" indicates that the payment requires 3D Secure authentication. To handle this, you need to implement the 3D Secure flow in your checkout process.

Here are the steps to implement 3D Secure authentication in Laravel Cashier Stripe Subscription:

  1. Update your Stripe API version to at least 2019-05-16, which supports 3D Secure 2.0.

  2. In your subscription controller, after creating the payment intent, check if it requires 3D Secure authentication by checking the status property of the payment intent object. If the status is requires_action, it means that 3D Secure authentication is required.

  3. If 3D Secure authentication is required, you need to redirect the user to the Stripe hosted authentication page. To do this, you can use the redirectToCheckout method provided by Laravel Cashier. Pass the client_secret of the payment intent as a parameter to this method.

  4. After the user completes the authentication process, they will be redirected back to your website. You can handle the success_url and cancel_url parameters in your subscription controller to update the subscription status accordingly.

Here's an example code snippet for the subscription controller:

use Stripe\PaymentIntent;

public function createSubscription(Request $request)
{
    $user = $request->user();
    $plan = $request->input('plan');

    $paymentIntent = $user->createSetupIntent();

    $subscription = $user->newSubscription('default', $plan)
        ->create($paymentIntent->id);

    $paymentIntent = PaymentIntent::retrieve($paymentIntent->id);

    if ($paymentIntent->status === 'requires_action') {
        return redirect()->route('cashier.payment', [
            'payment_intent_client_secret' => $paymentIntent->client_secret,
            'success_url' => route('subscription.success'),
            'cancel_url' => route('subscription.cancel'),
        ]);
    }

    // Subscription created successfully
    return redirect()->route('subscription.success');
}

In this example, we check if the payment intent requires 3D Secure authentication by checking its status property. If it does, we redirect the user to the Stripe hosted authentication page using the redirectToCheckout method. If it doesn't, we assume that the subscription was created successfully and redirect the user to the success page.

Note that you need to handle the success_url and cancel_url parameters in your subscription controller to update the subscription status accordingly.

Naman178's avatar

@LaryAI I have already tried with this but this is not working for me you can check my code in screenshot also

ToroLoco's avatar

I would like to add that when you create a new subscription, you pass the paymentIntent->paymentMethod and not the id of the intent. Also since we need to confirm the secure 3D page, the subscription cannot be created (we have the failure message at that point) and for the cashier.payment route we get the below error:

Missing required parameter for [Route: cashier.payment] [URI: stripe/payment/{id}] [Missing parameter: id].

As @naman178 wrote the solution that was given from A.I was not functional.

1 like

Please or to participate in this conversation.