Open WillBrubaker opened 3 years ago
Some additional context, this problem exists in Payment Request Button (PRB) in Stripe gateway plugin as well. Various solutions have been explored in the context of Strip gatway plugin but as of yet, we don't have a definitive solution. As far as I can see same issues/approaches extends to WCPay as well.
request_shipping
is not one of those that can be dynamically updated.To give accurate price/shipping requirement we will have to listen to product configuration changes via event listeners and replicate some(most?) of the processing that Bundles plugin does in WCPay.
Another approach @asumaran has suggested in pca54o-29Y-p2 to introduce temporary carts that are independent of the default cart, so that product information can be obtained without affecting the main cart.
More discussion on this issue from Stripe Gateway side is available here pcrvl0-e2-p2
@c-shultz is this a WooPayments issue rather than WooPay which has achieved compatibility?
is this a WooPayments issue
Yeah, this looks like a general WooPayments issue.
More discussion on this issue from Stripe Gateway side is available here pcrvl0-e2-p2
@diegocurbelo is this still an active issue on the Stripe plugin? It looks like we might want to prioritize a cross-team/product effort to get this fixed in the same way if so.
@c-shultz I believe this is an issue in the Payment Request API itself. The core of the problem is that we need to get the product info from the Cart every time the user clicks the G Pay/Apple Pay button.
I've tried to implement this approach when working on https://github.com/woocommerce/woocommerce-gateway-stripe/issues/1563 but ended up not working because we couldn't make an asynchronous call after the user clicks the G Pay/Apple Pay button. [^1]
--
Recently, during my parental leave I was thinking about this issue and found out the W3C did an important change to the spec of the Payment Request API. Now you can pass a promise to the show()
method (used to display the payment sheet). That way we can make an async call and update the payment details before displaying it. This sole change allow us to fix https://github.com/woocommerce/woocommerce-gateway-stripe/issues/1563 and other issues like this one.
The problem is that the JS Stripe library doesn't accept passing a promise to their show()
method.
I did a quick POC using the Payment Request API and Google Chrome (Google Pay) where we can see it's possible to update the payment sheet after an async call.
$1
– The parameter getTotalsFromCart()
passed to the show()
method is returned early just to avoid returning the promise.setTimeout
to simulate an XHR request.getTotalsFromCart()
returns the promise the payment sheets waits for the async call to finish and the amount is updated with the $200
that came from the resolved promise.So, while Stripe doesn't update their JS library, fixing issues like this one, where we need data from the backend, will be challenging. As mentioned above by @malithsen, I've suggested using "temporary" carts as a workaround. Besides not being a perfect solution, it'll also require a lot of effort from multiple teams.
[^1]: Actually, we can make async requests, the issue was Safari throwing an error after 1000ms execution which was unacceptable because we can't guarantee the request is going to take less than that. More info about this: pcrvl0-e2-p2#comment-251
So, while Stripe doesn't update their JS library,
Sooner or later @c-shultz we'll need to migrate away from Stripe's PRB element, a W3C implementation that Stripe no longer updates, to the PE element type or possibly the Express Checkout element. Adding new express checkouts beyond GPay and Apple Pay would require it.
Thanks for the digging and details on this, @asumaran.
Sooner or later @c-shultz we'll need to migrate away from Stripe's PRB element, a W3C implementation that Stripe no longer updates, to the PE element type or possibly the Express Checkout element.
That will be important to consider so we're solving this in the right place (wouldn't want to fix this for the PRB in a way that's not future proof).
Actually, we can make async requests, the issue was Safari throwing an error after 1000ms execution which was unacceptable because we can't guarantee the request is going to take less than that.
@asumaran I see the click event for the ExpressCheckoutElement has as on click callback but it also mentions a 1000ms time limit: https://stripe.com/docs/js/element/events/on_click?type=expressCheckoutElement
I don't see any show()
events for the expressCheckoutElement, but I may not be looking in the right place. Do you think we'll run into the same limitation with this implementation?
I've suggested using "temporary" carts as a workaround. Besides not being a perfect solution, it'll also require a lot of effort from multiple teams.
As I was catching up on the discussion there, I saw that the cart tokens may go a long way towards this as you discussed here with @dechov: pca54o-29Y-p2#comment-4564 Do you believe there's still promise in this direction and this likely something we would just need to prioritize? If I'm understanding correctly, the cart tokens could allow temporary cart to be created with a new token utilizing existing WooCommerce core functionality?
It looks like this issue has the same root cause, @asumaran? https://github.com/Automattic/woocommerce-payments/issues/3417 Are you aware of any other issues on WooPayments?
And also most of the open issues listed for Stripe here could be solved with temporary carts? https://github.com/woocommerce/woocommerce-gateway-stripe/issues/1563 Or am I overgeneralizing on this?
There's a tangled web of overlapping concerns among different PRB issues. Even the custom field discussion for PRBs (https://github.com/Automattic/woocommerce-payments/issues/6539#issuecomment-1792452974) touches on the management of shopping carts:
In the past, I found this payment button implementation to be the most robust one and the best candidate for inclusion in a "Core API" (product context). The code was equally well-mannered in the cart/checkout. Check out how it relays form field validation to Woo Core -- behind the scenes, and if I remember correctly, it "simulates" an add-to-cart operation and validates cart contents. Imagine having a shared foundation like this in Core for all express checkout buttons to use.
Clarification, Payment Elements are for external displaying and redirecting to 3P payments options. They are not integrated fully with Stripe. Express Checkout Element is the new element we'd want to migrate to, to unlock additional payment methods and the latest and greatest features. https://stripe.com/docs/elements/express-checkout-element/migration
Thanks @c-shultz for looking at future state to see if it would have the same issue. 👍
That will be important to consider so we're solving this in the right place.
I didn't think of making our own library to handle express checkouts before. I don't know if we have the obligation to use the JS Stripe library, if not, that seems like a good idea given that we depend on the Stripe JS library to fix many issues related to Payment Request buttons. We need to consider the cost and benefits on doing so since the JS Stripe library seems to be a wrapper of the Apple Pay JS API and the Payment Request API.
but it also mentions a 1000ms time limit:
I don't remember seeing that warning in their documentation. They may have stumbled upon into the same scenario as us.
I don't see any show() events for the expressCheckoutElement
The .show()
method it's only used when the event propagation is stopped otherwise the payment sheet will be displayed automatically. In WCStripe we stop the event propagation here and call the .show()
method here and here depending of the context. I assume it's very similar on WooPayments.
I saw that the cart tokens may go a long way towards this
Yes it does. The approach with it will be very different though. We may also need to tweak the store API since creating multiple carts from the browser is not possible IIRC since the browser sends the cookies automatically on all XHR requests (mentioned in the caveats of the POC ), so WC will always use the default cart.
It looks like this issue has the same root cause? https://github.com/Automattic/woocommerce-payments/issues/3417 Are you aware of any other issues on WooPayments?
Yes it's the same issue. I believe WC Stripe and WooPayments share the same PRB issues.
I kicked off a thread in Slack (p1705607994165039-slack-C043JN7AJHY). I think the only path forward here is to address this as part of a bigger picture project. We've seen the individual fixes get repeatedly blocked because it's hard to justify the investment to fix a single issue or two.
I've been trying to reproduce this issue with Bundles that require shipping and individual pricing, but everything seems to be working fine. (Ignore the problem with the cents. It's a rounding problem in my environment and does not require a bundle or PRB to happen)
Cart | Product Page | PRB | |
---|---|---|---|
Apple Pay | |||
Google Pay |
Am I missing something?
After talking to @asumaran, there are many fragile workarounds in PRB, and a major refactor that uses real cart data would fix most conflicts. I think we can leave this issue open but blocked until this refactor is done.
@c-shultz fyi related to planning consideration/SPIKE for possibly migrating the PRB element and getting ahead of Stripe's compliance date.
I have begun a discussion deliberating on the destiny of the PRB implementation in this post -> paJDYF-ckK-p2 FYI
Following because this is relevant to Mix and Match Products and Name Your Price as well. Anything that has custom prices or adds multiple products simultaneously has always had an issue with Payment Request buttons and we've had to disable them in lieu of displaying them when they don't work as expected.
Describe the bug
The payment request buttons on a single product page fail to use correct pricing or to add any shipping on a bundled product.
To Reproduce
Actual behavior
No shipping Price not calculated correctly if using individual pricing.
Screenshots
https://d.pr/i/9p5ORy
Expected behavior
For the price and shipping to be calculated the same as if they are added to the cart
Desktop (please complete the following information):
Smartphone (please complete the following information):
Additional context
4374404-zen