Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for WooCommerce Deposits when using Apple Pay and Google Pay #7910

Merged
merged 32 commits into from
Feb 21, 2024
Merged

Add support for WooCommerce Deposits when using Apple Pay and Google Pay #7910

merged 32 commits into from
Feb 21, 2024

Conversation

peterwilsoncc
Copy link
Contributor

@peterwilsoncc peterwilsoncc commented Dec 14, 2023

Fixes #7907
Fixes woocommerce/woocommerce-deposits#569

Changes proposed in this Pull Request

This modifies the add to cart AJAX request made during express payments to include field names prefixed with wc_. This is to account for fields added by extensions, for example the deposits extensions fields wc_deposit_option and wc_deposit_payment_plan.

The goal is to include extension fields during an express payment request so if an input affects the price, that is reflected in the data added to the cart.

Testing instructions

This has been tested with the deposits extension.

  1. Enable Express Pay options (Google and Apple Pay) to be displayed on product pages.
  2. Install and enable WooCommerce Deposits
  3. Create a virtual simple product with an optional deposit of 50%
  4. Visit virtual simple product with optional deposit of 50%
    1. Select "Pay Deposit"
    2. Click Apple/Google Pay button
    3. The price in the platforms popover should reflect the deposit amount
    4. Proceed with purchase
    5. The deposit amount should be recorded as paid against the order
    6. The remaining amount should be recorded against the order
  5. Update the Deposit options ensure it works as expected. Special attention to Enable Deposits and Default Deposit Selected Type.
    image
  6. Update the product to Physical (or create a new product) an check the price is not updated after the shipping methods load (more info about that in the second part of Tax is calculated twice for virtual products if Apple/Google Pay is used on product pages #7577 (comment))
  7. Create a virtual simple product with an optional payment plan
  8. Visit virtual simple product with optional payment plan
    1. Select "Pay Deposit"
    2. Select payment plan
    3. Click Apple/Google Pay button
    4. Proceed with purchase
    5. The first payment amount should be recorded as paid against the order
    6. The remaining amount should be recorded against the order

  • Run npm run changelog to add a changelog file, choose patch to leave it empty if the change is not significant. You can add multiple changelog files in one PR by running this command a few times.
  • Covered with tests (or have a good reason not to test in description ☝️)
  • Tested on mobile (or does not apply)

Post merge

@gpressutto5 gpressutto5 requested review from a team and timur27 and removed request for a team January 3, 2024 22:05
@gpressutto5
Copy link
Contributor

Thank you for starting this PR @peterwilsoncc. I fixed the remaining issues and updated the test instruction.

@gpressutto5 gpressutto5 marked this pull request as ready for review January 3, 2024 22:06
@gpressutto5 gpressutto5 enabled auto-merge January 3, 2024 22:06
@gpressutto5 gpressutto5 disabled auto-merge January 4, 2024 20:01
Copy link
Contributor

@timur27 timur27 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @peterwilsoncc @gpressutto5 for improving this area! 🚀

I went through the code and am leaving a few comments. The testing result will follow in a separate comment because it takes me a bit longer and I want to post these comments in the meantime to speed up the process.

Comment on lines 192 to 204
let allowedFieldNames = applyFilters(
'wcpayPaymentRequestAllowedFieldNames',
[]
);
// Ensure allowedFieldNames is an array.
if ( ! Array.isArray( allowedFieldNames ) ) {
allowedFieldNames = [ allowedFieldNames ];
}
$.each( formData, ( i, field ) => {
if ( /^addon-/.test( field.name ) ) {
if (
allowedFieldNames.includes( field.name ) ||
/^(addon-|wc_)/.test( field.name )
) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking and nice-to-have (or a good candidate for a separate small issue): It'd be beneficial to streamline this data variable appending implementation with the identical one from woopay/express-button/use-express-checkout-product-handler.js, to avoid code duplication and all the potential future regressions because of it. Both are located in different places which might be complicating things, but just a little bit.

@timur27
Copy link
Contributor

timur27 commented Jan 8, 2024

I tested deposits with virtual and physical products. I successfully tested physical product payment by paying the deposit first and paying the rest with a pay-for-order flow.

One thing that doesn't work for me as expected yet is the product price within the Google Pay window for a virtual product with deposits enabled. It isn't updated, although the final order reflects the deposit amount only. @gpressutto5 may I ask you to double-check this if possible? Thanks!

@gpressutto5
Copy link
Contributor

Thanks @timur27! It is working fine here, maybe it was fixed by something I changed now. Could you clear cache and test it again, please?

Jan-08-2024 12-40-38

@gpressutto5 gpressutto5 requested a review from timur27 January 8, 2024 15:55
@gpressutto5 gpressutto5 changed the title Send wc_ prefixed fields for express payments. Add support for WooCommerce Deposits when using Apple Pay and Google Pay Jan 8, 2024
@peterwilsoncc
Copy link
Contributor Author

Thanks for picking this up @gpressutto5! It looks in much better shape now than it did before I went on holiday.

I've tested it with the following and it seems fine:

  • percentage, optional
  • percentage, required
  • fixed amount, optional
  • fixed amount, required

For payment plan purchases, I am seeing JS errors on this branch: wcpayPaymentRequestParams.product is set to an empty string, so wcpayPaymentRequestParams.product.total.amount throws a type error on this line:

total: wcpayPaymentRequestParams.product.total.amount,

The key product details are:

  • Price: $1
  • Deposit: Optional, payment plan and Required, payment plan both affected
  • Payment Plan: Two Easy Payments (but not important)
  • Default Deposit Selected Type: Pay deposit

I'm not seeing this bug on trunk so I think it's coming from this branch rather than deposits.

Copy link
Contributor

@timur27 timur27 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is working fine here, maybe it was fixed by something I changed now. Could you clear cache and test it again, please?

@gpressutto5 It works for me now, thank you! I'm approving the PR from my side. Feel free to 🚢 once threads from Peter are resolved.

E2E tests are failing on the env setup stage, I assume it has something to do with how the PR is opened from a fork.

@gpressutto5
Copy link
Contributor

I created #8110 to run CI tests, and they passed. The tests that are not passing are the same that are broken in develop already.

The payment itself is working as expected. The remaining issue is just the tax price being displayed incorrectly when you click the ℹ button with a deposit in the cart, but we are still investigating if taxes are broken in WooCommerce Deposits.
I added a comment explaining this might not work correctly when using Deposits + Taxes so we can get this released and work on the remaining items in another issue. The payment works successfully with the correct amount.

@timur27 would you please review the new changes?
@peterwilsoncc feel free to review this too and let me know if you find anything that is not working correctly. We can create a new issue (maybe in the WooCommerce Deposits repository) to continue investigating the tax issue if it is reproducible.

@peterwilsoncc
Copy link
Contributor Author

@peterwilsoncc feel free to review this too and let me know if you find anything that is not working correctly. We can create a new issue (maybe in the WooCommerce Deposits repository) to continue investigating the tax issue if it is reproducible.

I'll take a look.

I've been working through the tax display issues on the Deposits#569. Switching the store to USD and the default tax rates revealed the error for me. I'll need to test any changes against other payment gateways to make sure any changes to the Deposits code doesn't result in undercharging elsewhere.

@peterwilsoncc
Copy link
Contributor Author

@gpressutto5 I've created Deposits#583 for the data storage issue.

Modifying the data as items are added to the cart (be it in session storage or a draft order) makes sense to me but we'll need to identify the risk involved in making the change.

Copy link
Contributor

@timur27 timur27 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @gpressutto5 @peterwilsoncc! Thanks again for all your efforts so far! 🚀 I left two comments and look forward to following them up with you all.

In terms of testing, I've tested deposits and deposit plans, and it works well for me, with the caveat that there are some open issues you moved to separate tickets. 👍

Overall, I think it'd be great to merge this PR as soon as possible and keep all the non-critical items or items from different areas for follow-up issues due to PR's complexity at this point.

@peterwilsoncc
Copy link
Contributor Author

peterwilsoncc commented Feb 5, 2024

@gpressutto5 @timur27 I was considering this overnight and how it could be fixed in Deposits and worked around in Payments for the time being.

The risk of adding a work around in Payments is that once it's fixed, the maths may be doubled up here and reintroduce a problem.

Until deposits is fixed, would it be possible to remove itemisation from Apple Pay for carts containing a deposit? The total is correct. Provided, of course, that the Apple terms and conditions allow for this.

@gpressutto5
Copy link
Contributor

Hi @peterwilsoncc. Itemization is not an issue anymore, only taxes, and removing it for carts with a deposit would require even more code specific for Deposits. I suggest one of the following:

  1. Leave it as it is, and then when refactoring WC Deposits, consider fixing the possible math conflict.
  2. Remove the itemization fix and fix it only in WC Deposits as suggested here: Add support for WooCommerce Deposits when using Apple Pay and Google Pay #7910 (comment). Meanwhile, itemization being wrong for Deposits is a known conflict.

I like the option 2 better as it does not require updating WCPay, only WC Deposits.

@gpressutto5
Copy link
Contributor

Hi @peterwilsoncc, did you have a chance to look at the options I suggested? It would be great to merge or close this PR as soon as possible to avoid conflicts.

@peterwilsoncc
Copy link
Contributor Author

@gpressutto5 I think two is best, is it possible to remove itemization when there is a deposit so customers aren't confused.

I looked at doing it in deposits with the wcpay_payment_request_hide_itemization filter but it's not possible due to the or condition used in the if statement within build_display_items()

@peterwilsoncc
Copy link
Contributor Author

Thanks for changing the filter in 369509e, I've tested it with the following and it works as expected:

/**
 * Hide itemization for Apple Pay and Google Pay when deposits are present.
 *
 * Compatibility with WooCommerce Payments. This filter is used to hide itemization
 * due to an issue in which the itemized amount shows the full price of the product
 * rather than the deposit amount.
 *
 * @todo Remove this filter once the issue is resolved in the extension.
 * @see https://github.com/woocommerce/woocommerce-deposits/issues/583
 *
 * @param bool $hide_itemization Whether to hide itemization for Apple Pay and Google Pay.
 * @return bool Modified value based on whether the cart has deposits.
 */
public function wcpay_payment_request_hide_itemization( $hide_itemization ) {
	// Hide itemization for carts containing deposits.
	if ( $this->has_deposit() ) {
		$hide_itemization = true;
	}
	return $hide_itemization;
}

@gpressutto5 gpressutto5 requested a review from timur27 February 20, 2024 18:48
@gpressutto5
Copy link
Contributor

The build is failing here because it is a fork. I created #8110 only to run CI, and it is passing.

@gpressutto5 gpressutto5 added this pull request to the merge queue Feb 21, 2024
Merged via the queue into Automattic:develop with commit 97df788 Feb 21, 2024
30 of 52 checks passed
@peterwilsoncc peterwilsoncc deleted the fix/7907-addon-express-pay-fields branch February 22, 2024 21:55
@peterwilsoncc
Copy link
Contributor Author

Thank you so much for your help wrapping this up and catching all the gotchas and items I was unaware of.

Once this is released, we'll declare compatibility in the Deposits readme for the relevant versions of Payments.

Jinksi pushed a commit that referenced this pull request Mar 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Express Pay buttons expect extension field names to be prefix with addon- which isn't always the case.
3 participants