Automattic / woocommerce-payments

Accept payments via credit card. Manage transactions within WordPress.
https://wordpress.org/plugins/woocommerce-payments/
Other
173 stars 69 forks source link

Redundant payment intent on Checkout page load #3602

Closed anu-rock closed 2 years ago

anu-rock commented 2 years ago

Describe the bug

I'm not entirely sure but I think this started after I enabled the new payments experience (early access) from the Payments Settings page.

Every time the UPE element is mounted—eg. on every load of the Checkout page—a new payment intent is created:

https://github.com/Automattic/woocommerce-payments/blob/62b3e5ae9a2f72314a1a316c9019cb57f39e0122/client/checkout/classic/upe.js#L298-L300

However, this intent goes unutilized if only the card and cash-on-delivery payment methods are enabled. The card payment method creates its own new intent. The cash-on-delivery payment method neither needs an intent on checkout nor creates one.

To Reproduce

  1. Enable UPE (I guess via the "Enable the new Stripe checkout experience" option on the Settings page).
  2. Keep only card and cash-on-delivery payment methods enabled.
  3. Create a new order in WooCommerce frontend.
  4. Visit the Checkout page.
  5. Look for the create_payment_intent network call in your browser's developer tools.

Actual behavior

A network request is sent to create a new payment intent. The newly created intent may be verified in Stripe's Connect dashboard.

Screenshots

Screenshot 2022-01-05 at 7 02 56 PM

image

Expected behavior

A new intent should only be created when needed. Eg. on clicking the "Place order" button.

Additional context

See #3430 for a related discussion.

anu-rock commented 2 years ago

cc @FangedParakeet who originally worked on the UPE implementation (#1890).

FangedParakeet commented 2 years ago

Unfortunately this is a known issue with how the UPE is implemented and we don't really have any great available workarounds to avoid this. Prior to the UPE, when completing a transaction, we could create and confirm the payment intention after the payment information had been collected (i.e. when the "Place order" button is clicked). However, the UPE (the payment element itself) must be loaded with a payment intent before any inputs can be shown to the user at all. This means that in order for Stripe to generate the fields for payment methods, we must create a payment intent as soon as the checkout page loads and use it to prime the payment element. As you've discovered, if a user uses another payment method at checkout, this payment intent remains unused and abandoned.

I created #2703 to use the checkout session to potentially resolve this issue, but I haven't yet explored whether that would resolve this completely.

Did you notice these extra payment intents when only cash on delivery was enabled as a payment method or only when both a UPE payment method and cash on delivery are enabled?

I'm open to any other solutions to put this one to bed, as the current implementation is indeed a little lacky and should probably be improved in this aspect!

anu-rock commented 2 years ago

Did you notice these extra payment intents when only cash on delivery was enabled as a payment method or only when both a UPE payment method and cash on delivery are enabled?

Only when UPE is enabled (with or without an additional payment method).

anu-rock commented 2 years ago

Duplicate of #2703

anu-rock commented 2 years ago

Reopening this issue to try an alternative solution based on WC_Session. More context in this Slack thread p1644233112975839-slack-CGGCLBN58.