laravel / cashier-stripe

Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services.
https://laravel.com/docs/billing
MIT License
2.38k stars 679 forks source link

Stripe requesting card info twice when 3D Secure is required #778

Closed jpranskaitis closed 5 years ago

jpranskaitis commented 5 years ago

Description:

When 3D Secure is required on card user needs to be redirected to cashier.payment, which is all correct, but page requires to repeat card information for second time.

Steps To Reproduce:

 try {
     $payment = $user->newSubscription('main', $plan->stripe_plan)->create($method->id);
 }   catch (IncompletePayment $exception) {
     return redirect()->route(
          'cashier.payment',
         [$exception->payment->id, 'redirect' => route('home')]
    );
 }

If the original blade is not changed you will get empty card form again.

Possible solution:

As per https://stripe.com/docs/stripe-js/reference#stripe-handle-card-payment-no-element

Workaround (might not be very secure, but...) is to pass the same payment method to the redirection route like this:

$token = StripeToken::retrieve($request->stripeToken, Cashier::stripeOptions());
return redirect()->route(
    'cashier.payment',
    [
        $exception->payment->id, 
        'redirect' => route('home'), 
        'card_token' => $token->card->id
    ]
);

Publish blade files: php artisan vendor:publish --tag="cashier-views"

Make the cashier.payment blade trigger this.confirmPayment() on mounted().

And change stripe.handleCardPayment to:

stripe.handleCardPayment(
    '{{ $payment->clientSecret() }}', {
        payment_method: '{{ request()->get('card_token') }}',
    }, {
        payment_method_data: {
            billing_details: { name: this.name }
        }
    }
)

Also name on card should be passed on initial card charge attempt, cause cashier.payment blade will instantly ask for 3DS authentication.

Now user is not forced to fill card info again.

All the page design changes and loading spinner is up to you.

driesvints commented 5 years ago

Can you please fill out the issue template?

jpranskaitis commented 5 years ago

will that be ok ?

driesvints commented 5 years ago

I see you're using a stripe token which is unfortunately deprecated in the new cashier. we only support the payment methods api.

jpranskaitis commented 5 years ago

So here you have support for that :). Please @deprecate then.

yeah i see now, my code has a mix of old 7.0 and new 10.2 Cashier.

so just to be clear, payment setup logic is as follows:

  1. Setup Payment Intent
  2. Show user Card form (process 3Ds if needed)
  3. Get that payment method and charge or subscribe over it

am i correct ?

driesvints commented 5 years ago

I think it's best that if you need support for older versions that you try a support channel, sorry.

jpranskaitis commented 5 years ago

I don't need support for old version. As per issue details Cashier version was 10.2. But i think you are right, i should get support there.