laravel / cashier-stripe

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

Bug finding payment method causing error on payment.blade.php #1665

Closed logtivity closed 4 months ago

logtivity commented 5 months ago

Cashier Stripe Version

v15.2.2

Laravel Version

10.46.0

PHP Version

8.3.3

Database Driver & Version

MySQL8

Description

Hi there,

Just upgraded to Laravel 10/cashier v15.2.2 and had a report from a customer that the confirm payment page isn't working upon their renewal payment needing confirming due to their card being expired. The payment.blade.php view is not published/overridden in our application.

Error message in console tab:

vue.min.js:6 TypeError: Cannot read properties of undefined (reading 'element')
    at wn.configureStripeElements

Line of code causing the error:

// Create the Stripe element based on the currently selected payment method...
if (this.paymentMethod.element) {

After debugging I've found that it isn't setting their payment method in this line:

this.paymentMethod = this.paymentMethods.filter(
    paymentMethod => paymentMethod.type === type
)[0];

The reason for this is that the type variable is returning bacs_debit which for some reason was enabled.

Doing a console log of the following line:

const paymentMethodTypes = paymentIntent.payment_method_types;

returns ['bacs_debit', 'card', 'link']

As a result the following code snippet was looking for a payment method with a type of 'bacs_debit' and so returned null because it's only searching for paymentMethodTypes[0] which according to the above is 'bacs_debit'.

const type = this.paymentMethod === null
    ? ('{{ $paymentMethod }}' ? '{{ $paymentMethod }}' : paymentMethodTypes[0])
    : (((this.paymentIntent || {}).payment_method || {}).type ?? paymentMethodTypes[0]);

this.paymentMethod = this.paymentMethods.filter(
    paymentMethod => paymentMethod.type === type
)[0];

I have removed bacs_debit from our settings but think this could technically still cause an error if 'card' is the value of 'type' but the customer only has a 'link' payment method. Shouldn't the above search for any matching 'type' not just paymentMethodTypes[0])?

Cheers

Ralph

Steps To Reproduce

Any cashier installation. Have multiple payment methods enabled. Test 3DS payment confirmation page with customer that doesn't have a payment method equal to the 'type' variable in the following payment.blade.php code snippet.

const type = this.paymentMethod === null
    ? ('{{ $paymentMethod }}' ? '{{ $paymentMethod }}' : paymentMethodTypes[0])
    : (((this.paymentIntent || {}).payment_method || {}).type ?? paymentMethodTypes[0]);

this.paymentMethod = this.paymentMethods.filter(
    paymentMethod => paymentMethod.type === type
)[0];
driesvints commented 5 months ago

Sorry, I didn't get to this this week. Will follow up next week.

driesvints commented 4 months ago

Hi there. Sorry it took this long for me to get back. Unfortunately the payment page currently does not support this payment method. We'd appreciate any PR's for it to be added! See https://laravel.com/docs/11.x/billing#handling-failed-payments

I'm not sure how Link should be integrated here, sorry.