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

Release branch for 7.5.3 #8688

Merged
merged 3 commits into from
Apr 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
4 changes: 4 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
*** WooPayments Changelog ***

= 7.5.3 - 2024-04-22 =
* Fix - Fix subscription renewals exceptions
* Dev - Remove deprecated param from asset data registry interface.

= 7.5.2 - 2024-04-22 =
* Fix - Bugfix for failing subscription renewal payments.
* Dev - Remove deprecated param from asset data registry interface.
Expand Down
33 changes: 13 additions & 20 deletions includes/class-wc-payment-gateway-wcpay.php
Original file line number Diff line number Diff line change
Expand Up @@ -1402,6 +1402,19 @@ public function process_payment_for_order( $cart, $payment_information, $schedul
];
list( $user, $customer_id ) = $this->manage_customer_details_for_order( $order, $customer_details_options );

// Update saved payment method async to include billing details, if missing.
if ( $payment_information->is_using_saved_payment_method() ) {
$this->action_scheduler_service->schedule_job(
time(),
self::UPDATE_SAVED_PAYMENT_METHOD,
[
'payment_method' => $payment_information->get_payment_method(),
'order_id' => $order->get_id(),
'is_test_mode' => WC_Payments::mode()->is_test(),
]
);
}

$intent_failed = false;
$payment_needed = $amount > 0;

Expand All @@ -1419,16 +1432,6 @@ public function process_payment_for_order( $cart, $payment_information, $schedul
// We need to make sure the saved payment method is saved to the order so we can
// charge the payment method for a future payment.
$this->add_token_to_order( $order, $payment_information->get_payment_token() );
// If we are not hitting the API for the intent, we need to update the saved payment method ourselves.
$this->action_scheduler_service->schedule_job(
time(),
self::UPDATE_SAVED_PAYMENT_METHOD,
[
'payment_method' => $payment_information->get_payment_method(),
'order_id' => $order->get_id(),
'is_test_mode' => WC_Payments::mode()->is_test(),
]
);
}

if ( $is_changing_payment_method_for_subscription && $payment_information->is_using_saved_payment_method() ) {
Expand Down Expand Up @@ -1511,16 +1514,6 @@ public function process_payment_for_order( $cart, $payment_information, $schedul
$request->set_payment_methods( $payment_methods );
$request->set_cvc_confirmation( $payment_information->get_cvc_confirmation() );
$request->set_hook_args( $payment_information );
if ( $payment_information->is_using_saved_payment_method() ) {
$billing_details = WC_Payments_Utils::get_billing_details_from_order( $order, $payment_information->is_merchant_initiated() );

$is_legacy_card_object = strpos( $payment_information->get_payment_method() ?? '', 'card_' ) === 0;

// Not updating billing details for legacy card objects because they have a different structure and are no longer supported.
if ( ! empty( $billing_details ) && ! $is_legacy_card_object ) {
$request->set_payment_method_update_data( [ 'billing_details' => $billing_details ] );
}
}
// Add specific payment method parameters to the request.
$this->modify_create_intent_parameters_when_processing_payment( $request, $payment_information, $order );

Expand Down
65 changes: 16 additions & 49 deletions includes/class-wc-payments-utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -338,62 +338,29 @@ public static function map_search_orders_to_charge_ids( $search ) {
}

/**
* Extract the billing details from the WC order.
* It only returns the fields that are present in the billing section of the checkout.
* Extract the billing details from the WC order
*
* @param WC_Order $order Order to extract the billing details from.
* @param bool $legacy Whether to use the legacy way of loading straight from the order.
* @todo The $legacy flag is just a patch for the current approach, fixing the linked issue.
* @see https://github.com/Automattic/woocommerce-payments/issues/8678
*
* @return array
*/
public static function get_billing_details_from_order( $order, $legacy = true ) {
if ( $legacy ) {
$billing_details = [
'address' => [
'city' => $order->get_billing_city(),
'country' => $order->get_billing_country(),
'line1' => $order->get_billing_address_1(),
'line2' => $order->get_billing_address_2(),
'postal_code' => $order->get_billing_postcode(),
'state' => $order->get_billing_state(),
],
'email' => $order->get_billing_email(),
'name' => trim( $order->get_formatted_billing_full_name() ),
'phone' => $order->get_billing_phone(),
];

return array_filter( $billing_details );
}

$billing_fields = array_keys( WC()->checkout()->get_checkout_fields( 'billing' ) );
$address_field_to_key = [
'billing_city' => 'city',
'billing_country' => 'country',
'billing_address_1' => 'line1',
'billing_address_2' => 'line2',
'billing_postcode' => 'postal_code',
'billing_state' => 'state',
public static function get_billing_details_from_order( $order ) {
$billing_details = [
'address' => [
'city' => $order->get_billing_city(),
'country' => $order->get_billing_country(),
'line1' => $order->get_billing_address_1(),
'line2' => $order->get_billing_address_2(),
'postal_code' => $order->get_billing_postcode(),
'state' => $order->get_billing_state(),
],
'email' => $order->get_billing_email(),
'name' => trim( $order->get_formatted_billing_full_name() ),
'phone' => $order->get_billing_phone(),
];
$field_to_key = [
'billing_email' => 'email',
'billing_phone' => 'phone',
];
$billing_details = [ 'address' => [] ];
foreach ( $billing_fields as $field ) {
if ( isset( $address_field_to_key[ $field ] ) ) {
$billing_details['address'][ $address_field_to_key[ $field ] ] = $order->{"get_{$field}"}();
} elseif ( isset( $field_to_key[ $field ] ) ) {
$billing_details[ $field_to_key[ $field ] ] = $order->{"get_{$field}"}();
}
}

if ( in_array( 'billing_first_name', $billing_fields, true ) && in_array( 'billing_last_name', $billing_fields, true ) ) {
$billing_details['name'] = trim( $order->get_formatted_billing_full_name() );
}

return $billing_details;
$billing_details['address'] = array_filter( $billing_details['address'] );
return array_filter( $billing_details );
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ class Create_And_Confirm_Intention extends Create_Intention {
'amount',
'currency',
'payment_method',
'payment_method_update_data',
'return_url',
];

Expand Down Expand Up @@ -91,17 +90,6 @@ public function set_payment_methods( array $payment_methods ) {
$this->set_param( 'payment_method_types', $payment_methods );
}

/**
* Payment method update data setter.
*
* @param array $payment_method_update_data Data to update on payment method.
*
* @return void
*/
public function set_payment_method_update_data( array $payment_method_update_data ) {
$this->set_param( 'payment_method_update_data', $payment_method_update_data );
}

/**
* CVC confirmation setter.
*
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "woocommerce-payments",
"version": "7.5.2",
"version": "7.5.3",
"main": "webpack.config.js",
"author": "Automattic",
"license": "GPL-3.0-or-later",
Expand Down
7 changes: 6 additions & 1 deletion readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Tags: woocommerce payments, apple pay, credit card, google pay, payment, payment
Requires at least: 6.0
Tested up to: 6.4
Requires PHP: 7.3
Stable tag: 7.5.2
Stable tag: 7.5.3
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html

Expand Down Expand Up @@ -94,6 +94,11 @@ Please note that our support for the checkout block is still experimental and th

== Changelog ==

= 7.5.3 - 2024-04-22 =
* Fix - Fix subscription renewals exceptions
* Dev - Remove deprecated param from asset data registry interface.


= 7.5.2 - 2024-04-22 =
* Fix - Bugfix for failing subscription renewal payments.
* Dev - Remove deprecated param from asset data registry interface.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,6 @@ function ( $data ): bool {
'city' => $order->get_billing_city(),
'country' => $order->get_billing_country(),
'line1' => $order->get_billing_address_1(),
'line2' => $order->get_billing_address_2(),
'postal_code' => $order->get_billing_postcode(),
'state' => $order->get_billing_state(),
],
Expand Down
13 changes: 11 additions & 2 deletions tests/unit/test-class-wc-payment-gateway-wcpay-process-payment.php
Original file line number Diff line number Diff line change
Expand Up @@ -1209,8 +1209,17 @@ public function test_updates_payment_method_billing_details() {
->willReturn( $intent );

$this->mock_action_scheduler_service
->expects( $this->never() )
->method( 'schedule_job' );
->expects( $this->once() )
->method( 'schedule_job' )
->with(
$this->anything(),
WC_Payment_Gateway_WCPay::UPDATE_SAVED_PAYMENT_METHOD,
[
'payment_method' => 'pm_mock',
'order_id' => $order_id,
'is_test_mode' => false,
]
);

$this->mock_wcpay_gateway->process_payment( $order_id );
}
Expand Down
79 changes: 0 additions & 79 deletions tests/unit/test-class-wc-payment-gateway-wcpay.php
Original file line number Diff line number Diff line change
Expand Up @@ -257,18 +257,6 @@ public function set_up() {
->method( 'get_payment_metadata' )
->willReturn( [] );
wcpay_get_test_container()->replace( OrderService::class, $mock_order_service );
$checkout_fields = [
'billing' => [
'billing_company' => '',
'billing_country' => '',
'billing_address_1' => '',
'billing_address_2' => '',
'billing_city' => '',
'billing_state' => '',
'billing_phone' => '',
],
];
WC()->checkout()->checkout_fields = $checkout_fields;
}

/**
Expand Down Expand Up @@ -304,7 +292,6 @@ public function tear_down() {
}

wcpay_get_test_container()->reset_all_replacements();
WC()->checkout()->checkout_fields = null;
}

public function test_process_redirect_payment_intent_processing() {
Expand Down Expand Up @@ -2442,72 +2429,6 @@ public function test_process_payment_for_order_not_from_request() {
$this->card_gateway->process_payment_for_order( WC()->cart, $pi );
}

public function test_no_billing_details_update_for_legacy_card_object() {
$legacy_card = 'card_mock';

// There is no payment method data within the request. This is the case e.g. for the automatic subscription renewals.
$_POST['payment_method'] = '';

$token = WC_Helper_Token::create_token( $legacy_card );

$order = WC_Helper_Order::create_order();
$order->set_currency( 'USD' );
$order->set_total( 100 );
$order->add_payment_token( $token );
$order->save();

$pi = new Payment_Information( $legacy_card, $order, null, $token, null, null, null, '', 'card' );
$payment_intent = WC_Helper_Intention::create_intention(
[
'status' => 'success',
]
);

$request = $this->mock_wcpay_request( Create_And_Confirm_Intention::class );

$request->expects( $this->once() )
->method( 'format_response' )
->will( $this->returnValue( $payment_intent ) );

$request->expects( $this->never() )
->method( 'set_payment_method_update_data' );

$this->card_gateway->process_payment_for_order( WC()->cart, $pi );
}

public function test_billing_details_update_if_not_empty() {
// There is no payment method data within the request. This is the case e.g. for the automatic subscription renewals.
$_POST['payment_method'] = '';

$token = WC_Helper_Token::create_token( 'pm_mock' );

$expected_upe_payment_method = 'card';
$order = WC_Helper_Order::create_order();
$order->set_currency( 'USD' );
$order->set_total( 100 );
$order->add_payment_token( $token );
$order->save();

$pi = new Payment_Information( 'pm_mock', $order, null, $token, null, null, null, '', 'card' );

$payment_intent = WC_Helper_Intention::create_intention(
[
'status' => 'success',
]
);

$request = $this->mock_wcpay_request( Create_And_Confirm_Intention::class );

$request->expects( $this->once() )
->method( 'format_response' )
->will( $this->returnValue( $payment_intent ) );

$request->expects( $this->once() )
->method( 'set_payment_method_update_data' );

$this->card_gateway->process_payment_for_order( WC()->cart, $pi );
}

public function test_process_payment_for_order_rejects_with_cached_minimum_amount() {
set_transient( 'wcpay_minimum_amount_usd', '50', DAY_IN_SECONDS );

Expand Down
31 changes: 1 addition & 30 deletions tests/unit/test-class-wc-payments-customer-service.php
Original file line number Diff line number Diff line change
Expand Up @@ -484,39 +484,10 @@ public function test_update_payment_method_with_billing_details_from_order() {
[
'billing_details' => [
'address' => [
'city' => 'WooCity',
'country' => Country_Code::UNITED_STATES,
'line1' => 'WooAddress',
'line2' => '',
'city' => 'WooCity',
'state' => 'NY',
'postal_code' => '12345',
],
'phone' => '555-32123',
'email' => '[email protected]',
'name' => 'Jeroen Sormani',
],
]
);

$order = WC_Helper_Order::create_order();

$this->customer_service->update_payment_method_with_billing_details_from_order( 'pm_mock', $order );
}

public function test_update_payment_method_with_billing_details_from_checkout_fields() {
$this->mock_api_client
->expects( $this->once() )
->method( 'update_payment_method' )
->with(
'pm_mock',
[
'billing_details' => [
'address' => [
'postal_code' => '12345',
'city' => 'WooCity',
'country' => 'US',
'line1' => 'WooAddress',
'line2' => '',
'state' => 'NY',
],
'email' => '[email protected]',
Expand Down
2 changes: 1 addition & 1 deletion woocommerce-payments.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* WC tested up to: 8.7.0
* Requires at least: 6.0
* Requires PHP: 7.3
* Version: 7.5.2
* Version: 7.5.3
* Requires Plugins: woocommerce
*
* @package WooCommerce\Payments
Expand Down
Loading