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

Fix: BNPL payment methods should work when available in the Pay For Order page #9670

Merged
merged 10 commits into from
Nov 6, 2024

Conversation

danielmx-dev
Copy link
Contributor

@danielmx-dev danielmx-dev commented Nov 4, 2024

Fixes #8254

Changes proposed in this Pull Request

  • Make sure the wcpayCustomerData global variable is properly rendered. A couple issues related to this were fixed:
    • The payment_fields() code was running before the wcpay-upe-checkout script was registered, so when wp_localize_script ran, nothing was added to the page. This problem was solved for the wcpay_upe_config variable by adding a callback to wp_footer but the same fix wasn't applied to wcpayCustomerData. This PR should make both work consistently.
    • When multiple Payment Methods were enabled, the callbacks to localize the scripts were queued multiple times. This was unnecessary given that the variables always had the same names, so the values were overridden. To prevent rendering unnecessary data, I'm using a workaround using a dummy action to verify if the callback already run once.
  • Pass default values to the payment elements when available.
  • is_enabled_at_checkout was updated so it checks the order data instead of the cart data to determine availability

Testing instructions

  • Use a US WooPayments account.
  • Enable Affirm, AfterPay/ClearPay, and Klarna.
  • In WP Admin, create an order, make sure to include customer details as Name, Email, and Country (must be US). Add a product of at least 50 USD (which is Affirm's minimum amount).
  • Copy the Customer payment page URL.
  • As a customer, go to the Customer payment page.

Before (using develop)
BNPL payment methods showed up but nothing was rendered when selected. (Verify for all BNPL methods)
image

Clicking Pay for Order results in an error.
image

After (Using this branch)
The contents of the BNPL methods is properly rendered, customer information is prefilled based on the data filled for the order.
image

Submitting the order should result in a successful payment. Test this for all BNPL methods (Klarna, Afterpay/Clearpay, and Affirm).

Testing payment method availability

  • In WP Admin, update the Billing information of the pending order to another country.

  • If you reload the Pay for Order page, the BNPL methods should no longer show up.
    image

  • In WP Admin, restore the billing country to US but change the line items so the total is less than 50 USD.

  • Reload the pay for order page, Affirm should not be displayed:
    image

Regression Testing

  • Make sure that Credit Cards (with and without 3DS) continue to work as expected in the pay for order flow.
  • Test the Add Payment Method flow to make sure cards can still be added.
  • Test the Classic Checkout and Blocks Checkout flow to make sure BNPL and Card payments still work as expected.

  • 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

Copy link
Contributor

github-actions bot commented Nov 4, 2024

Size Change: +159 B (0%)

Total Size: 1.33 MB

Filename Size Change
release/woocommerce-payments/dist/checkout.js 33 kB +159 B (0%)
ℹ️ View Unchanged
Filename Size
release/woocommerce-payments/assets/css/admin.css 1.37 kB
release/woocommerce-payments/assets/css/admin.rtl.css 1.37 kB
release/woocommerce-payments/assets/css/success.css 173 B
release/woocommerce-payments/assets/css/success.rtl.css 173 B
release/woocommerce-payments/dist/blocks-checkout-rtl.css 2.64 kB
release/woocommerce-payments/dist/blocks-checkout.css 2.64 kB
release/woocommerce-payments/dist/blocks-checkout.js 58 kB
release/woocommerce-payments/dist/cart-block.js 16.8 kB
release/woocommerce-payments/dist/cart.js 5.73 kB
release/woocommerce-payments/dist/checkout-rtl.css 1.21 kB
release/woocommerce-payments/dist/checkout.css 1.21 kB
release/woocommerce-payments/dist/express-checkout-rtl.css 230 B
release/woocommerce-payments/dist/express-checkout.css 230 B
release/woocommerce-payments/dist/express-checkout.js 14.9 kB
release/woocommerce-payments/dist/frontend-tracks.js 858 B
release/woocommerce-payments/dist/index-rtl.css 39.3 kB
release/woocommerce-payments/dist/index.css 39.3 kB
release/woocommerce-payments/dist/index.js 302 kB
release/woocommerce-payments/dist/multi-currency-analytics.js 1.08 kB
release/woocommerce-payments/dist/multi-currency-rtl.css 4.46 kB
release/woocommerce-payments/dist/multi-currency-switcher-block.js 60.6 kB
release/woocommerce-payments/dist/multi-currency.css 4.46 kB
release/woocommerce-payments/dist/multi-currency.js 57.3 kB
release/woocommerce-payments/dist/order-rtl.css 730 B
release/woocommerce-payments/dist/order.css 730 B
release/woocommerce-payments/dist/order.js 42 kB
release/woocommerce-payments/dist/payment-gateways-rtl.css 1.32 kB
release/woocommerce-payments/dist/payment-gateways.css 1.32 kB
release/woocommerce-payments/dist/payment-gateways.js 38.4 kB
release/woocommerce-payments/dist/payment-request-rtl.css 230 B
release/woocommerce-payments/dist/payment-request.css 230 B
release/woocommerce-payments/dist/payment-request.js 14.2 kB
release/woocommerce-payments/dist/plugins-page-rtl.css 386 B
release/woocommerce-payments/dist/plugins-page.css 386 B
release/woocommerce-payments/dist/plugins-page.js 20.1 kB
release/woocommerce-payments/dist/product-details-rtl.css 433 B
release/woocommerce-payments/dist/product-details.css 436 B
release/woocommerce-payments/dist/product-details.js 12.1 kB
release/woocommerce-payments/dist/settings-rtl.css 11.6 kB
release/woocommerce-payments/dist/settings.css 11.5 kB
release/woocommerce-payments/dist/settings.js 224 kB
release/woocommerce-payments/dist/subscription-edit-page.js 703 B
release/woocommerce-payments/dist/subscription-product-onboarding-modal-rtl.css 524 B
release/woocommerce-payments/dist/subscription-product-onboarding-modal.css 524 B
release/woocommerce-payments/dist/subscription-product-onboarding-modal.js 20.2 kB
release/woocommerce-payments/dist/subscription-product-onboarding-toast.js 730 B
release/woocommerce-payments/dist/subscriptions-empty-state-rtl.css 120 B
release/woocommerce-payments/dist/subscriptions-empty-state.css 120 B
release/woocommerce-payments/dist/subscriptions-empty-state.js 19.3 kB
release/woocommerce-payments/dist/tokenized-payment-request-rtl.css 230 B
release/woocommerce-payments/dist/tokenized-payment-request.css 230 B
release/woocommerce-payments/dist/tokenized-payment-request.js 15 kB
release/woocommerce-payments/dist/tos-rtl.css 235 B
release/woocommerce-payments/dist/tos.css 235 B
release/woocommerce-payments/dist/tos.js 21.8 kB
release/woocommerce-payments/dist/woopay-direct-checkout.js 6.14 kB
release/woocommerce-payments/dist/woopay-express-button.js 24.6 kB
release/woocommerce-payments/dist/woopay-rtl.css 4.52 kB
release/woocommerce-payments/dist/woopay.css 4.49 kB
release/woocommerce-payments/dist/woopay.js 71.6 kB
release/woocommerce-payments/includes/subscriptions/assets/css/plugin-page.css 625 B
release/woocommerce-payments/includes/subscriptions/assets/js/plugin-page.js 814 B
release/woocommerce-payments/vendor/automattic/jetpack-assets/build/i18n-loader.js 2.46 kB
release/woocommerce-payments/vendor/automattic/jetpack-assets/build/jetpack-script-data.js 735 B
release/woocommerce-payments/vendor/automattic/jetpack-assets/build/react-jsx-runtime.js 553 B
release/woocommerce-payments/vendor/automattic/jetpack-assets/src/js/i18n-loader.js 1.02 kB
release/woocommerce-payments/vendor/automattic/jetpack-assets/src/js/script-data.js 69 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/babel.config.js 163 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/identity-crisis.css 2.45 kB
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/identity-crisis.js 14.2 kB
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/identity-crisis.rtl.css 2.45 kB
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-admin-create-user.css 198 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-admin-create-user.js 280 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-admin-create-user.rtl.css 198 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-login.css 625 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-login.js 333 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-login.rtl.css 626 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-users.js 417 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/tracks-ajax.js 521 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/tracks-callables.js 584 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/src/sso/jetpack-sso-admin-create-user.css 215 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/src/sso/jetpack-sso-admin-create-user.js 521 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/src/sso/jetpack-sso-login.css 721 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/src/sso/jetpack-sso-login.js 412 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/src/sso/jetpack-sso-users.js 621 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/about.css 1.04 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/admin-empty-state.css 294 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/admin-order-statuses.css 408 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/admin.css 3.59 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/checkout.css 301 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/modal.css 746 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/view-subscription.css 574 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/wcs-upgrade.css 414 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/admin-pointers.js 543 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/admin.js 9.4 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/jstz.js 6.78 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/jstz.min.js 3.84 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/meta-boxes-coupon.js 545 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/meta-boxes-subscription.js 2.52 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/moment.js 22.2 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/moment.min.js 11.7 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/payment-method-restrictions.js 1.29 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/wcs-meta-boxes-order.js 507 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/payment-methods.js 358 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/single-product.js 428 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/view-subscription.js 1.38 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/wcs-cart.js 782 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/modal.js 1.09 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/wcs-upgrade.js 1.26 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/build/index.css 391 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/build/index.js 3.04 kB

compressed-size-action

@botwoo
Copy link
Collaborator

botwoo commented Nov 4, 2024

Test the build

Option 1. Jetpack Beta

  • Install and activate Jetpack Beta.
  • Use this build by searching for PR number 9670 or branch name fix/8254-bnpl-pay-for-order in your-test.site/wp-admin/admin.php?page=jetpack-beta&plugin=woocommerce-payments

Option 2. Jurassic Ninja - available for logged-in A12s

🚀 Launch a JN site with this branch 🚀

ℹ️ Install this Tampermonkey script to get more options.


Build info:

  • Latest commit: 296a3b8
  • Build time: 2024-11-06 17:03:58 UTC

Note: the build is updated when a new commit is pushed to this PR.

@danielmx-dev danielmx-dev changed the title Fix/8254 bnpl pay for order Fix: BNPL payment methods should work when available in the Pay For Order page Nov 5, 2024
@danielmx-dev danielmx-dev marked this pull request as ready for review November 5, 2024 17:59
@danielmx-dev danielmx-dev requested review from a team and frosso and removed request for a team November 5, 2024 18:04
Comment on lines +739 to +740
// Total is 100 USD, which is above both payment methods (Affirm and AfterPay) minimums.
WC()->cart->add_to_cart( WC_Helper_Product::create_simple_product()->get_id(), 10 );
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The amount could be defined a bit more "dynamically" (in case the limits change in the future) but I didn't want to overcomplicate things, lmk what do you think.

Copy link
Contributor

@frosso frosso left a comment

Choose a reason for hiding this comment

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

Looks good, just one question on the "no-checkout context" and whether that area needs an adjustment. Good improvements 👍

if ( ! did_action( '__wcpay_customer_data_localized' ) ) {
wp_localize_script( 'wcpay-upe-checkout', 'wcpayCustomerData', $prepared_customer_data );
}
do_action( '__wcpay_customer_data_localized' );
Copy link
Contributor

Choose a reason for hiding this comment

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

I like the way you're leveraging do_action/did_action to check whether a function had already been executed.

$currency = get_woocommerce_currency();
$order = null;
if ( is_wc_endpoint_url( 'order-pay' ) ) {
$order = wc_get_order( absint( get_query_var( 'order-pay' ) ) );
Copy link
Contributor

Choose a reason for hiding this comment

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

(minor) WooCommerce Core does a similar check on the currency amount (although we're not leveraging it because of the multi-currency setup): https://github.com/woocommerce/woocommerce/blob/7eabbe4ecd7dd1cff6a36055c8a07c3bdf64abb1/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php#L290-L308

However, I noticed that they first do:

$order_id = absint( get_query_var( 'order-pay' ) )

And then:

if ( 0 < $order_id ) {
  // proceeds with getting the order
}

However, we're not doing the check on the $order_id, here.
I'm not sure if you considered it - but wanted to raise it anyways. I'm guessing that if we call wc_get_order() with '' (empty string - the default value returned by get_query_var(), we might get the order with id 0. Is that something we should be concerned about?
I don't think we'd need to be concerned about it, but wanted to double-check with you.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I followed the same approach we already use to retrieve the order in the Pay for Order flow:

$order_id = absint( get_query_var( 'order-pay' ) );
$payment_fields['orderId'] = $order_id;
$order = wc_get_order( $order_id );
if ( is_a( $order, 'WC_Order' ) ) {

I also checked the source code for wc_get_order and it should return false in case we sent either 0 or ''.
https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/includes/class-wc-order-factory.php#L28-L32
https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/includes/class-wc-order-factory.php#L210-L221

$currency = $order->get_currency();
} else {
$currency = get_woocommerce_currency();
}
// If the currency limits are not defined, we allow the PM for now (gateway has similar validation for limits).
// Additionally, we don't engage with limits verification in no-checkout context (cart is not available or empty).
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we be concerned with (or change) this comment, since maybe the pay-for-order could be considered a "no-checkout context"? 👀

I wonder if, instead, we should perform a check like this:

			$currency = get_woocommerce_currency();
			if ( $order ) {
				$currency = $order->get_currency();
			}

			// If the currency limits are not defined, we allow the PM for now (gateway has similar validation for limits).
			$total = null;
			if ( $order ) {
				$total = $order->get_total();
			} elseif ( isset( WC()->cart ) ) {
				$total = WC()->cart->get_total( '' );
			}

			if ( isset( $this->limits_per_currency[ $currency ] ) && ! empty( $total ) ) {
				$amount = WC_Payments_Utils::prepare_amount( $total, $currency );

@@ -119,6 +119,18 @@ export const getUpeSettings = () => {
};
}

if ( window.wcpayCustomerData ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

It took me a bit to find the other area where we check for window.wcpayCustomerData and pass such data to Stripe, and to identify if there are any opportunities for improvement - but I think this is the only way, good find!

@danielmx-dev
Copy link
Contributor Author

@frosso I pushed some changes to improve the compatibility with BNPL payment methods and their requirements. I also updated the test instructions to include regression testing for other payment methods/flows.

@danielmx-dev danielmx-dev requested a review from frosso November 6, 2024 17:12
Copy link
Contributor

@frosso frosso left a comment

Choose a reason for hiding this comment

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

Can confirm, it's working now 👍 thanks for catching it!

@danielmx-dev danielmx-dev added this pull request to the merge queue Nov 6, 2024
Merged via the queue into develop with commit ed04c34 Nov 6, 2024
25 checks passed
@danielmx-dev danielmx-dev deleted the fix/8254-bnpl-pay-for-order branch November 6, 2024 18:07
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.

BNPL payment method issue in the "Customer payment page" flow
3 participants