woocommerce / woocommerce-gateway-stripe

The official Stripe Payment Gateway for WooCommerce
https://wordpress.org/plugins/woocommerce-gateway-stripe/
229 stars 199 forks source link

Use separate Stripe Payment Elements for card and link to prevent credit card purchases being created as "Link" payments #3046

Closed mattallan closed 1 month ago

mattallan commented 4 months ago

Describe the bug When the Link payment method is enabled and the customer is logged into their Link account, choosing to pay with a credit card on the checkout incorrectly creates the Stripe payment method with the type "Link" instead of the expected "card" type.

This becomes problematic when the customer uses a 3DS card because we try to confirm the payment intent that has a Link payment method which throws the following error by Stripe:

image

What I believe is causing this issue is our createStripePaymentMethod() JS method is calling getStripe.createPaymentMethod( { elements, params } ) where elements contains both link and the credit card Payment Elements and because the customer is logged into Link, Stripe is creating the payment method with type Link.

Here's a screen recording showing the error on checkout and some quick debugging code I put inside the processPayment() JS function to confirm the paymentMethodType is 'card', but the paymentMethodObject is being created with type 'link':

https://github.com/woocommerce/woocommerce-gateway-stripe/assets/2275145/ef9199b5-e057-41d4-82e9-552b558d3c59

According to Stripe docs you cannot specify the payment method type when creating the paymentMethod and so I think we need to change createStripePaymentElement() and getPaymentMethodTypes() so that when creating the card element, it's only creating the card elements and not link as well, and then handle link payment elements separately.

To Reproduce

From my own testing, reproducing this error has been inconsistent:

  1. Connect a Stripe account that has link available
  2. Enable new checkout experience and enable the Link payment method.
  3. Add a regular product to your cart and visit the checkout page.
  4. Make sure you're logged out of Link: image
  5. Click on the Pay with Link payment request button (PRB) on checkout and log in.
  6. After successfully logging in, close the Link window: image
  7. Refresh the checkout page and confirm you're logged into link by checking your card's last is present in the PRB element: image
  8. Scroll down to Stripe card elements and insert a card number that requires customer confirmation (i.e. 3DS card: 4000002760003184) image
  9. Click on the place order and you should notice an error notice shown above
  10. Go into your stripe dashboard > developers > logs and look at the latest /v1/payment_methods request.
  11. Notice the create payment method request has type "link": image

Expected behavior

Purchases using the card payment elements create payment method objects in Stripe with the card payment type. Regardless of being logged in or logged out of link.

Mayisha commented 4 months ago

We have another Link related report in 7985872-zd-a8c

There was an error processing the payment: The PaymentMethod provided (link) is not allowed for this Setupintent. Please attach a PaymentMethod of one of the following types: card. Alternatively update the allowed payment_method_types for this Setupintent to include "link".

The error message is different and we don't have any reproduction steps for this. However, from the error message, it seems like this one was also generated because of using "link" as the payment method type instead of "card".

contemplate commented 1 month ago

We recently enabled Link on a large WooCommerce Subscriptions site and see numerous reports from customers when they try to change their credit card on file and it fails with this error: Payment failed: The PaymentMethod provided (link) is not allowed for this SetupIntent. Attaching what is shown in their order notes. image

thomasjvu commented 1 month ago

8428486-zen

setup_intent_invalid_parameter The PaymentMethod provided (link) is not allowed for this SetupIntent. Please attach a PaymentMethod of one of the following types: card. Alternatively update the allowed payment_method_types for this SetupIntent to include "link".

I will continue troubleshooting to discover how to replicate.

james-allan commented 1 month ago

In https://github.com/woocommerce/woocommerce-gateway-stripe/pull/3309 I've fixed the originally reported issue of using 3D Secure cards with Link enabled resulting in an error.

The more recent comments about the The PaymentMethod provided (link) is not allowed for this Setupintent. is a different issue and I'll submit a fix for that too.