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

Tax is calculated twice for virtual products if Apple/Google Pay is used on product pages #7577

Closed grig-23 closed 10 months ago

grig-23 commented 11 months ago

Describe the bug

With certain tax settings, tax is calculated twice for virtual products if Apple/Google Pay is used on product pages.

To Reproduce

Settings:

Screenshot 2023-10-29 at 13 45 52 Screenshot 2023-10-29 at 13 46 07 Screenshot 2023-10-29 at 13 46 55

Product settings:

Screenshot 2023-10-29 at 13 48 53
  1. Open a browser that works with Apple or Google Pay set up.
  2. Click the Apple or Google Pay button on the product page.
  3. The tax is already included into the product price but it's added again in the Apple/Google Pay window on the product page:
Screenshot 2023-10-29 at 13 50 02

If a product is not virtual, then tax is added for a couple of seconds and then removed:

Screenshot 2023-10-29 at 13 52 15 Screenshot 2023-10-29 at 13 52 24

Also, this doesn't happen on cart or checkout pages.

Actual behavior

Tax is added on top of the product price. If product is virtual, that price with 2x tax remains displayed in Apple/Google Pay window, while if a product is not virtual - it's only displayed for a few seconds and then correct price is displayed.

Expected behavior

Tax is already included in product price so shouldn't be included twice.

Desktop (please complete the following information):

Additional context

7231902-zen

htdat commented 11 months ago

This issue impacts "Additional Payment Methods (including Apple Pay / Google Pay)", so assigning to Fusion (based on team responsibilities Pc2DNy-3z-p2) cc team lead @anu-rock. Assigning as part of Gamma Triage process PcreKM-yM-p2.

anu-rock commented 11 months ago

Pinging @frosso from Heisenberg who are the new owners of Local and Additional Payment Methods.

frosso commented 10 months ago

After talking with Guilherme, we noticed that the original estimate I gave to this issue was much lower than expected. I updated it to reflect it.

gpressutto5 commented 10 months ago

Update

It's been some time since I started working on this issue, and I think it's time to write down what I've learned so far.

First of all, it is important to note that, when the bug happens, the price displayed is greater than the price that is actually charged. This means that the customer will always pay less than what is displayed. And the merchant will always get the correct amount. And the bug only happens in a very specific scenario, which is why I'm lowering the priority to low.


We have this problem only in Product pages because the price we use to initialize the Payment Request for the product comes from a different method. The reason the price updates to the correct value for physical products is because another request is required to calculate the shipping costs, and this request updates the price. Digital products don't require shipping, so the price is not updated. I started by trying to update the price when the order is created, right after the customer clicks the button, to ensure the price is always correct in the end, even if it started wrong. This would not fix the root cause of the problem, but it would help prevent this confusing situation in the future. But I couldn't do this because: "You cannot update Payment Request options while the payment sheet is showing." So I moved on to another approach.


These are the WC options that may affect how taxes are displayed:

I tested all the combinations of these options (excluding "Calculate tax based on", which was fixed to "Shop base address") and the results are in this spreadsheet.

image

It is easy to notice that the error only happens when the "Prices entered with tax" option is set to "✅ Yes, inclusive" and "Display prices during cart and checkout" is set to "❌ Excluding tax". I'm still working on this but I think that the problem is that this is related to us using the woocommerce_tax_display_cart option, while wc_get_price_including_tax uses the woocommerce_prices_include_tax option. Simply updating this option won't work because it will affect the prices in the endpoints that should use the cart prices. Now that we know what is causing the problem, the "solution" is simple, but I noticed we don't have any tests for anything related to taxes and Apple Pay, so I'm working on adding them.

❗️ Important: When "Calculate tax based on" is set to "Customer shipping address" or "Customer billing address", Default customer location is set to "No location by default", and the customer is not logged in the products will always be displayed excluding tax, even if the "Display prices in the shop" option is set to "Including tax".


Confusing setting

I also noticed a confusing situation when Prices are entered with tax ✅, Price is displayed in the shop excluding tax ❌, and Price is displayed in the checkout including tax ✅. I don't consider this wrong, because it is obeying the seeting. This is confusing in the regular checkout too, and we already show the "Inconsistent tax setting" warning.

image image image

Digital products tax calculation

Now, besides this bug, there's another thing that I need to check and fix if necessary. When the customer is using Apple Pay, the shipping address is used as the billing address as Stripe does not collect a billing address. It works for Physical products because the shipping address is used as the billing address (TODO: test this). For digital products, the shipping/billing address is not collected so we can't calculate tax. We could require a shipping address for Digital product but only offer a "Digital" free shipping method just so we have an address to calculate tax. Anyway, this is just a thought, I need to check if this is really a problem.