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: tokenized ECE do not show button when missing billing email #10019

Merged
merged 2 commits into from
Dec 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Significance: patch
Type: fix
Comment: fix: tokenized ECE do not show button when missing billing email


Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ public function should_show_express_checkout_button() {

// Order total doesn't matter for Pay for Order page. Thus, this page should always display payment buttons.
if ( $this->is_pay_for_order_page() ) {
return true;
return $this->is_pay_for_order_supported();
}

// Non-shipping product and tax is calculated based on shopper billing address. Excludes Pay for Order page.
Expand Down Expand Up @@ -749,6 +749,38 @@ public function get_product_data() {
return apply_filters( 'wcpay_payment_request_product_data', $data, $product );
}

/**
* The Store API doesn't allow checkout without the billing email address present on the order data.
* https://github.com/woocommerce/woocommerce/issues/48540
*
* @return bool
*/
private function is_pay_for_order_supported() {
if ( ! WC_Payments_Features::is_tokenized_cart_ece_enabled() ) {
return true;
}

$order_id = absint( get_query_var( 'order-pay' ) );
if ( 0 === $order_id ) {
return false;
}

$order = wc_get_order( $order_id );
if ( ! is_a( $order, 'WC_Order' ) ) {
return false;
}

// we don't need to check its validity or value, we just need to ensure a billing email is present.
$billing_email = $order->get_billing_email();
if ( ! empty( $billing_email ) ) {
return true;
}

Logger::log( 'Billing email not present ( Express Checkout Element button disabled )' );

return false;
}

/**
* Whether product page has a supported product.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ public function tear_down() {
remove_filter( 'wc_tax_enabled', '__return_false' );
remove_filter( 'pre_option_woocommerce_tax_display_cart', [ $this, '__return_excl' ] );
remove_filter( 'pre_option_woocommerce_tax_display_cart', [ $this, '__return_incl' ] );
delete_option( '_wcpay_feature_tokenized_cart_ece' );

parent::tear_down();
}
Expand Down Expand Up @@ -208,6 +209,30 @@ function () {
remove_all_filters( 'wcpay_payment_request_total_label_suffix' );
}

public function test_should_show_express_checkout_button_for_tokenized_ece_with_billing_email() {
global $wp;
global $wp_query;

$this->mock_wcpay_account
->method( 'is_stripe_connected' )
->willReturn( true );
WC_Payments::mode()->dev();
$_GET['pay_for_order'] = true;

// Total is 100 USD, which is above both payment methods (Affirm and AfterPay) minimums.
$order = WC_Helper_Order::create_order( 1, 100 );
$order_id = $order->get_id();
$wp->query_vars = [ 'order-pay' => strval( $order_id ) ];
$wp_query->query_vars = [ 'order-pay' => strval( $order_id ) ];

update_option( '_wcpay_feature_tokenized_cart_ece', '1' );
add_filter( 'woocommerce_is_checkout', '__return_true' );

$this->assertTrue( $this->system_under_test->should_show_express_checkout_button() );

remove_filter( 'woocommerce_is_checkout', '__return_true' );
}
Comment on lines +212 to +234
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 attempted to create a test to negate the situation (e.g.: create a test to verify the button isn't rendered)

However, unsetting the billing email via either $order->set_billing_address( [ 'email' => '' ] ) or $order->set_billing_email('') didn't work.
I thought of querying the DB directly, but with HPOS and non-HPOS alternatives, I didn't think it was maintainable.

So here we are 🤷

Copy link
Member

Choose a reason for hiding this comment

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

I tried for a bit on this as well. The email really does not want to update. I'm getting strange results with the $order->save() method. The same order ID is returned every time and no logs set within that method are coming through. So I'm with you on this one. Directly modifying the DB seems to be the only way to remove the email address.


public function test_should_show_express_checkout_button_for_non_shipping_but_price_includes_tax() {
$this->mock_wcpay_account
->method( 'is_stripe_connected' )
Expand All @@ -229,7 +254,6 @@ public function test_should_show_express_checkout_button_for_non_shipping_but_pr
remove_filter( 'pre_option_woocommerce_tax_display_cart', [ $this, '__return_incl' ] );
}


public function test_should_not_show_express_checkout_button_for_non_shipping_but_price_does_not_include_tax() {
$this->mock_wcpay_account
->method( 'is_stripe_connected' )
Expand Down
Loading