user1456131
user1456131

Reputation: 49

Angular stripe with laravel cashier 3ds payment incomplete

I am building a frontend in angular and backend in laravel using sanctum's token based authentication. I am having a subscription module and during payment on front end I receive a 3DS popup which after verification I send the payment method id to laravel.

this.paymentService.getSecret().subscribe(async (res: any) => {

      const paymentIntent = await this.paymentService.stripe.confirmCardSetup(res.intent.client_secret, {
        payment_method: {
          card: this.paymentService.cardElement,
          billing_details: {
            name: 'John',
          }
        },
      });
      if (paymentIntent.error) {
        console.error(paymentIntent.error);
      } else {
        if (paymentIntent.setupIntent.status === "succeeded") {
          let test = {
            plan: res.plan.id,
            payment_method_id: paymentIntent.setupIntent.payment_method
          }
          this.paymentService.confirmPayment(test).subscribe(async (res1: any) => {
          }, err => {
            console.log(err)
          })
        }
      }
    });

In laravel when I validate payment_method_id it throws IncompletePayment exception below is the code.

try{
            $subscription = $request->user()->newSubscription(PLAN_NAME, PLAN_ID)
                ->create($request->payment_method_id);
            return response()->json([
                'status' => true,
                'message' => "subscription_success"
            ]);
        } catch(IncompletePayment $exception){
            return response()->json([
                'url' => route('cashier.payment', [$exception->payment->id, 'redirect' => route('subscription.done')]),
                'status' => false,
                'message' => "subscription_incomplete",
                'payment_id' => $exception->payment->id
            ]);
        }

If I receive an exception I tried to use the url returned by laravel for 3DS and subscription worked perfectly. How can I use stripe.js to handle 3DS?

Upvotes: 0

Views: 93

Answers (1)

Lucky2501
Lucky2501

Reputation: 1704

If I understand this correctly, the current flow is:
-Create Payment Method with a Setup Intent
-Create Subscription with Payment Method
And the problem is that the Subscription's first payment still requires 3DS. This would be expected, since by default Stripe's subscription attempts to save the payment method on the first payment, which makes your setup intent redundant.

This flow is pretty ancient at this point. The official flow is:
-Create Subscription with payment_behavior=default_incomplete
->This gives you an incomplete setup_intent / payment_intent which will save the card.
-Confirm the intent on the frontend
-> This will handle 3DS if necessary.

I'm not sure how possible it is for your to implement this.
An alternative way you could fix this is by setting off_session=True on the Subscription create call. This will disable the Subscription's behavior of attempting to save the payment method, and imply that the payment method is already saved and authenticated.

Upvotes: 1

Related Questions