From ba36a35e39d6c9d181f10a0b72dbd4131a17904f Mon Sep 17 00:00:00 2001 From: leonardo lopes de albuquerque Date: Fri, 26 Apr 2024 19:13:49 -0300 Subject: [PATCH 01/15] Fixed exception that would happen when pre_check_save_my_info was not in the cached $account_data (#8721) --- changelog/fix-pre-check-sve-my-info-exception | 5 +++++ includes/woopay-user/class-woopay-save-user.php | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 changelog/fix-pre-check-sve-my-info-exception diff --git a/changelog/fix-pre-check-sve-my-info-exception b/changelog/fix-pre-check-sve-my-info-exception new file mode 100644 index 00000000000..9d7aa69ddf7 --- /dev/null +++ b/changelog/fix-pre-check-sve-my-info-exception @@ -0,0 +1,5 @@ +Significance: patch +Type: fix +Comment: just a bug fix for a feature that did not make into the release yet + + diff --git a/includes/woopay-user/class-woopay-save-user.php b/includes/woopay-user/class-woopay-save-user.php index 91b61f5d1c8..78096190fba 100644 --- a/includes/woopay-user/class-woopay-save-user.php +++ b/includes/woopay-user/class-woopay-save-user.php @@ -63,7 +63,7 @@ public function register_checkout_page_scripts() { 'WCPAY_WOOPAY', 'woopayCheckout', [ - 'PRE_CHECK_SAVE_MY_INFO' => $account_data['pre_check_save_my_info'] + 'PRE_CHECK_SAVE_MY_INFO' => isset( $account_data['pre_check_save_my_info'] ) ? $account_data['pre_check_save_my_info'] : false, ] ); From 0d89ec7ac749e370d74522668f93643b5877736a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20L=C3=B3pez=20Ariza?= <45979455+alopezari@users.noreply.github.com> Date: Mon, 29 Apr 2024 08:10:03 +0200 Subject: [PATCH 02/15] Update post-release-updates GitHub Actions workflow to delete all trailing newlines from Release-testing-instructions.md before adding new entries. (#8719) --- .github/workflows/post-release-updates.yml | 4 +++- changelog/update-post-release-updates | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 changelog/update-post-release-updates diff --git a/.github/workflows/post-release-updates.yml b/.github/workflows/post-release-updates.yml index 813c9fd0bc1..bb9a1ef1175 100644 --- a/.github/workflows/post-release-updates.yml +++ b/.github/workflows/post-release-updates.yml @@ -155,8 +155,10 @@ jobs: echo ":warning: File "$NEXT_RELEASE_VERSION_INSTRUCTIONS_FILENAME.md" already exists. No action needed." >> $GITHUB_STEP_SUMMARY fi - # If an entry for the next version doesn't exist yet + # Check if this release version exists in Release-testing-instructions.md if ! grep -q "v$NEXT_RELEASE_VERSION" Release-testing-instructions.md; then + # If it doesn't exist, remove all trailing newlines and add the new version for this release + perl -pi -e 'BEGIN{undef $/;} s/\n+\z//' Release-testing-instructions.md echo -ne "\n* [v$NEXT_RELEASE_VERSION](https://github.com/Automattic/woocommerce-payments/wiki/$NEXT_RELEASE_VERSION_INSTRUCTIONS_FILENAME)" >> Release-testing-instructions.md echo "Added a new entry for v$NEXT_RELEASE_VERSION in \"Release-testing-instructions.md\"." >> $GITHUB_STEP_SUMMARY HAS_CHANGES=true diff --git a/changelog/update-post-release-updates b/changelog/update-post-release-updates new file mode 100644 index 00000000000..83360bae0a3 --- /dev/null +++ b/changelog/update-post-release-updates @@ -0,0 +1,5 @@ +Significance: patch +Type: dev +Comment: Just a minor change in a GitHub Actions workflow to make it more robust. + + From eddecf7e1fb961dc289f05628c7d033c6cc0b45e Mon Sep 17 00:00:00 2001 From: Jesse Pearson Date: Mon, 29 Apr 2024 08:40:51 -0300 Subject: [PATCH 03/15] Fix type error for fraud outcome API (#8713) --- changelog/fix-5151-fraud-outcome-type-error | 4 +++ .../class-list-fraud-outcome-transactions.php | 5 ++++ ...ist-fraud-outcome-transactions-request.php | 27 +++++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 changelog/fix-5151-fraud-outcome-type-error diff --git a/changelog/fix-5151-fraud-outcome-type-error b/changelog/fix-5151-fraud-outcome-type-error new file mode 100644 index 00000000000..43dcb1cf8c4 --- /dev/null +++ b/changelog/fix-5151-fraud-outcome-type-error @@ -0,0 +1,4 @@ +Significance: patch +Type: fix + +Fix type error for fraud outcome API. diff --git a/includes/core/server/request/class-list-fraud-outcome-transactions.php b/includes/core/server/request/class-list-fraud-outcome-transactions.php index d7d3770c7c5..4d01cff2666 100644 --- a/includes/core/server/request/class-list-fraud-outcome-transactions.php +++ b/includes/core/server/request/class-list-fraud-outcome-transactions.php @@ -11,6 +11,7 @@ use WC_Payments_Utils; use WC_Payments_API_Client; use WCPay\Constants\Fraud_Meta_Box_Type; +use WCPay\Fraud_Prevention\Models\Rule; /** * Request class for getting intents. @@ -37,6 +38,10 @@ class List_Fraud_Outcome_Transactions extends Paginated { * @throws Invalid_Request_Parameter_Exception */ public function get_api(): string { + $status = $this->status ?? 'null'; + if ( ! Rule::is_valid_fraud_outcome_status( $status ) ) { + throw new Invalid_Request_Parameter_Exception( "Invalid fraud outcome status provided: $status", 'invalid_fraud_outcome_status' ); + } return WC_Payments_API_Client::FRAUD_OUTCOMES_API . '/status/' . $this->status; } diff --git a/tests/unit/core/server/request/test-class-list-fraud-outcome-transactions-request.php b/tests/unit/core/server/request/test-class-list-fraud-outcome-transactions-request.php index 2e08bf04425..9a77afb8537 100644 --- a/tests/unit/core/server/request/test-class-list-fraud-outcome-transactions-request.php +++ b/tests/unit/core/server/request/test-class-list-fraud-outcome-transactions-request.php @@ -6,6 +6,7 @@ */ use PHPUnit\Framework\MockObject\MockObject; +use WCPay\Core\Exceptions\Server\Request\Invalid_Request_Parameter_Exception; use WCPay\Core\Server\Request\List_Fraud_Outcome_Transactions; /** @@ -68,6 +69,7 @@ public function test_list_fraud_outcome_transactions_request() { $this->assertSame( 'GET', $request->get_method() ); $this->assertSame( WC_Payments_API_Client::FRAUD_OUTCOMES_API . '/status/' . $status, $request->get_api() ); } + public function test_list_fraud_outcome_transactions_request_using_from_rest_request_function() { $page = 2; $page_size = 50; @@ -569,4 +571,29 @@ public function test_list_fraud_outcome_transactions_request_filters_out_non_blo $this->assertEquals( $expected, $result ); } + + /** + * Checks to see if the get_api method throws an exception if an invalid status is passed. + * + * @param ?string $status The status to check. + * + * @return void + * + * @dataProvider provider_get_api_exception_on_invalid_status + */ + public function test_get_api_exception_on_invalid_status( $status ): void { + $request = new List_Fraud_Outcome_Transactions( $this->mock_api_client, $this->mock_wc_payments_http_client ); + $request->set_status( $status ); + + $status = $status ?? 'null'; + + $this->expectException( Invalid_Request_Parameter_Exception::class ); + $this->expectExceptionMessage( "Invalid fraud outcome status provided: $status" ); + + $request->get_api(); + } + + public function provider_get_api_exception_on_invalid_status(): array { + return [ [ 'invalid' ], [ null ] ]; + } } From 993ff401a9f85d16836771022e68b30fab7622f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20L=C3=B3pez=20Ariza?= <45979455+alopezari@users.noreply.github.com> Date: Mon, 29 Apr 2024 15:54:42 +0200 Subject: [PATCH 04/15] Update README to explain how the WCPay Dev Tools plugin is automatically updated. (#8729) --- README.md | 1 + changelog/update-readme-wcpay-dev-tools-updates | 5 +++++ 2 files changed, 6 insertions(+) create mode 100644 changelog/update-readme-wcpay-dev-tools-updates diff --git a/README.md b/README.md index 4e3804e580c..80174d5115a 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ Install the following plugins: - WooCommerce - WCPay Dev Tools (clone or download [the GitHub repo](https://github.com/Automattic/woocommerce-payments-dev-tools)) + - This dependency is automatically updated to the latest version each time you perform a `git pull` or `git merge` in this repository, as long as the WCPay Dev Tools repository is cloned locally and remains on the `trunk` branch. For more details, please refer to the [post-merge](.husky/post-merge) hook. ### Optional local.env file diff --git a/changelog/update-readme-wcpay-dev-tools-updates b/changelog/update-readme-wcpay-dev-tools-updates new file mode 100644 index 00000000000..297e1b05599 --- /dev/null +++ b/changelog/update-readme-wcpay-dev-tools-updates @@ -0,0 +1,5 @@ +Significance: patch +Type: dev +Comment: This change doesn't impact production code, just updates the README file to clarify how the WCPay Dev Tools dependency is updated in this repository. + + From c9a8761b2145c5bfa985ebac8024230af6a80a25 Mon Sep 17 00:00:00 2001 From: Malith Senaweera <6216000+malithsen@users.noreply.github.com> Date: Mon, 29 Apr 2024 09:24:25 -0500 Subject: [PATCH 05/15] Track used gateway when placing the order (#8717) --- changelog/add-track-gateway-type | 5 +++ includes/class-woopay-tracker.php | 68 +++++++++++++++++++++++++++---- 2 files changed, 64 insertions(+), 9 deletions(-) create mode 100644 changelog/add-track-gateway-type diff --git a/changelog/add-track-gateway-type b/changelog/add-track-gateway-type new file mode 100644 index 00000000000..4145c577c60 --- /dev/null +++ b/changelog/add-track-gateway-type @@ -0,0 +1,5 @@ +Significance: patch +Type: dev +Comment: Record gateway name when placing the order + + diff --git a/includes/class-woopay-tracker.php b/includes/class-woopay-tracker.php index 04312026ebc..511aeafc5cd 100644 --- a/includes/class-woopay-tracker.php +++ b/includes/class-woopay-tracker.php @@ -13,6 +13,7 @@ use WC_Payments_Features; use WCPay\Constants\Country_Code; use WP_Error; +use Exception; defined( 'ABSPATH' ) || exit; // block direct access. @@ -42,6 +43,13 @@ class WooPay_Tracker extends Jetpack_Tracks_Client { */ private $http; + /** + * Base URL for stats counter. + * + * @var string + */ + private static $pixel_base_url = 'https://pixel.wp.com/g.gif'; + /** * Constructor. @@ -63,8 +71,8 @@ public function __construct( $http ) { add_action( 'woocommerce_after_single_product', [ $this, 'classic_product_page_view' ] ); add_action( 'woocommerce_blocks_enqueue_checkout_block_scripts_after', [ $this, 'blocks_checkout_start' ] ); add_action( 'woocommerce_blocks_enqueue_cart_block_scripts_after', [ $this, 'blocks_cart_page_view' ] ); - add_action( 'woocommerce_checkout_order_processed', [ $this, 'checkout_order_processed' ] ); - add_action( 'woocommerce_blocks_checkout_order_processed', [ $this, 'checkout_order_processed' ] ); + add_action( 'woocommerce_checkout_order_processed', [ $this, 'checkout_order_processed' ], 10, 2 ); + add_action( 'woocommerce_blocks_checkout_order_processed', [ $this, 'checkout_order_processed' ], 10, 2 ); add_action( 'woocommerce_payments_save_user_in_woopay', [ $this, 'must_save_payment_method_to_platform' ] ); add_action( 'before_woocommerce_pay_form', [ $this, 'pay_for_order_page_view' ] ); add_action( 'woocommerce_thankyou', [ $this, 'thank_you_page_view' ] ); @@ -370,7 +378,6 @@ public function tracks_get_identity() { ]; } - /** * Record a Tracks event that the classic checkout page has loaded. */ @@ -445,13 +452,56 @@ public function pay_for_order_page_view() { } /** - * Record a Tracks event that the order has been processed. + * Bump a counter. No user identifiable information is sent. + * + * @param string $group The group to bump the stat in. + * @param string $stat_name The name of the stat to bump. + * + * @return bool + */ + public function bump_stats( $group, $stat_name ) { + $pixel_url = sprintf( + self::$pixel_base_url . '?v=wpcom-no-pv&x_%s=%s', + $group, + $stat_name + ); + + $response = wp_remote_get( esc_url_raw( $pixel_url ) ); + + if ( is_wp_error( $response ) ) { + return false; + } + + if ( 200 !== wp_remote_retrieve_response_code( $response ) ) { + return false; + } + + return true; + } + + /** + * Record that the order has been processed. */ - public function checkout_order_processed() { - $is_woopay_order = ( isset( $_SERVER['HTTP_USER_AGENT'] ) && 'WooPay' === $_SERVER['HTTP_USER_AGENT'] ); - // Don't track WooPay orders. They will be tracked on WooPay side with more flow specific details. - if ( ! $is_woopay_order ) { - $this->maybe_record_wcpay_shopper_event( 'checkout_order_placed' ); + public function checkout_order_processed( $order_id ) { + + $payment_gateway = wc_get_payment_gateway_by_order( $order_id ); + $properties = [ 'payment_title' => 'other' ]; + + // If the order was placed using WooCommerce Payments, record the payment title using Tracks. + if (strpos( $payment_gateway->id, 'woocommerce_payments') === 0 ) { + $order = wc_get_order( $order_id ); + $payment_title = $order->get_payment_method_title(); + $properties = [ 'payment_title' => $payment_title ]; + + $is_woopay_order = ( isset( $_SERVER['HTTP_USER_AGENT'] ) && 'WooPay' === $_SERVER['HTTP_USER_AGENT'] ); + + // Don't track WooPay orders. They will be tracked on WooPay side with more details. + if ( ! $is_woopay_order ) { + $this->maybe_record_wcpay_shopper_event( 'checkout_order_placed', $properties ); + } + // If the order was placed using a different payment gateway, just increment a counter. + } else { + $this->bump_stats( 'wcpay_order_completed_gateway', 'other' ); } } From 3c6bba13c5340c5ea0927fb621c76cba32554a1c Mon Sep 17 00:00:00 2001 From: Timur Karimov Date: Mon, 29 Apr 2024 17:29:18 +0200 Subject: [PATCH 06/15] misc: fix warning during plugin update due to problems with initialization (#8728) Co-authored-by: Timur Karimov Co-authored-by: Timur Karimov --- changelog/fix-fatals-on-plugin-update | 4 ++ ...s-wc-rest-payments-settings-controller.php | 27 ++++-------- .../class-duplicates-detection-service.php | 1 - includes/class-wc-payment-gateway-wcpay.php | 42 ++++++++++++++----- includes/class-wc-payments.php | 4 +- ...s-wc-rest-payments-settings-controller.php | 5 ++- ...-class-wc-rest-payments-tos-controller.php | 25 ++++++----- .../test-class-upe-payment-gateway.php | 17 ++++++-- .../test-class-upe-split-payment-gateway.php | 18 +++++++- ...wc-payment-gateway-wcpay-payment-types.php | 2 + ...-payment-gateway-wcpay-process-payment.php | 2 + ...c-payment-gateway-wcpay-process-refund.php | 4 +- ...ubscriptions-payment-method-order-note.php | 4 +- ...ay-wcpay-subscriptions-process-payment.php | 2 + ...wc-payment-gateway-wcpay-subscriptions.php | 22 +++++++--- .../test-class-wc-payment-gateway-wcpay.php | 17 +++++++- ...xpress-checkout-button-display-handler.php | 4 +- ...ayments-express-checkout-button-helper.php | 4 +- ...ayments-payment-request-button-handler.php | 4 +- ...lass-wc-payments-woopay-button-handler.php | 4 +- 20 files changed, 147 insertions(+), 65 deletions(-) create mode 100644 changelog/fix-fatals-on-plugin-update diff --git a/changelog/fix-fatals-on-plugin-update b/changelog/fix-fatals-on-plugin-update new file mode 100644 index 00000000000..a63e19bdb3c --- /dev/null +++ b/changelog/fix-fatals-on-plugin-update @@ -0,0 +1,4 @@ +Significance: minor +Type: dev + +Avoid warnings about fatal error during plugin update due to problems with plugin initialization. diff --git a/includes/admin/class-wc-rest-payments-settings-controller.php b/includes/admin/class-wc-rest-payments-settings-controller.php index ffd941feee8..9664d5a54a5 100644 --- a/includes/admin/class-wc-rest-payments-settings-controller.php +++ b/includes/admin/class-wc-rest-payments-settings-controller.php @@ -8,7 +8,6 @@ use WCPay\Constants\Country_Code; use WCPay\Fraud_Prevention\Fraud_Risk_Tools; use WCPay\Constants\Track_Events; -use WCPay\Duplicates_Detection_Service; defined( 'ABSPATH' ) || exit; @@ -37,34 +36,22 @@ class WC_REST_Payments_Settings_Controller extends WC_Payments_REST_Controller { */ protected $account; - - /** - * Duplicates detection service. - * - * @var Duplicates_Detection_Service - */ - private $duplicates_detection_service; - - /** * WC_REST_Payments_Settings_Controller constructor. * - * @param WC_Payments_API_Client $api_client WC_Payments_API_Client instance. - * @param WC_Payment_Gateway_WCPay $wcpay_gateway WC_Payment_Gateway_WCPay instance. - * @param WC_Payments_Account $account Account class instance. - * @param Duplicates_Detection_Service $duplicates_detection_service Duplicates detection service. + * @param WC_Payments_API_Client $api_client WC_Payments_API_Client instance. + * @param WC_Payment_Gateway_WCPay $wcpay_gateway WC_Payment_Gateway_WCPay instance. + * @param WC_Payments_Account $account Account class instance. */ public function __construct( WC_Payments_API_Client $api_client, WC_Payment_Gateway_WCPay $wcpay_gateway, - WC_Payments_Account $account, - Duplicates_Detection_Service $duplicates_detection_service + WC_Payments_Account $account ) { parent::__construct( $api_client ); - $this->wcpay_gateway = $wcpay_gateway; - $this->account = $account; - $this->duplicates_detection_service = $duplicates_detection_service; + $this->wcpay_gateway = $wcpay_gateway; + $this->account = $account; } /** @@ -486,7 +473,7 @@ public function get_settings(): WP_REST_Response { 'enabled_payment_method_ids' => $enabled_payment_methods, 'available_payment_method_ids' => $available_upe_payment_methods, 'payment_method_statuses' => $this->wcpay_gateway->get_upe_enabled_payment_method_statuses(), - 'duplicated_payment_method_ids' => $this->duplicates_detection_service->find_duplicates(), + 'duplicated_payment_method_ids' => $this->wcpay_gateway->find_duplicates(), 'is_wcpay_enabled' => $this->wcpay_gateway->is_enabled(), 'is_manual_capture_enabled' => 'yes' === $this->wcpay_gateway->get_option( 'manual_capture' ), 'is_test_mode_enabled' => WC_Payments::mode()->is_test(), diff --git a/includes/class-duplicates-detection-service.php b/includes/class-duplicates-detection-service.php index 3c49a0ab4fe..abf47a4c382 100644 --- a/includes/class-duplicates-detection-service.php +++ b/includes/class-duplicates-detection-service.php @@ -11,7 +11,6 @@ exit; // Exit if accessed directly. } -use Exception; use WC_Payments; use WCPay\Payment_Methods\Affirm_Payment_Method; use WCPay\Payment_Methods\Afterpay_Payment_Method; diff --git a/includes/class-wc-payment-gateway-wcpay.php b/includes/class-wc-payment-gateway-wcpay.php index 48e1399e146..12c72c479f3 100644 --- a/includes/class-wc-payment-gateway-wcpay.php +++ b/includes/class-wc-payment-gateway-wcpay.php @@ -30,6 +30,7 @@ use WCPay\Core\Server\Request\List_Charge_Refunds; use WCPay\Core\Server\Request\Refund_Charge; use WCPay\Duplicate_Payment_Prevention_Service; +use WCPay\Duplicates_Detection_Service; use WCPay\Fraud_Prevention\Fraud_Prevention_Service; use WCPay\Fraud_Prevention\Fraud_Risk_Tools; use WCPay\Internal\Payment\State\AuthenticationRequiredState; @@ -196,6 +197,13 @@ class WC_Payment_Gateway_WCPay extends WC_Payment_Gateway_CC { */ protected $duplicate_payment_prevention_service; + /** + * Duplicate payment methods detection service + * + * @var Duplicates_Detection_Service + */ + protected $duplicate_payment_methods_detection_service; + /** * WC_Payments_Localization_Service instance. * @@ -246,6 +254,7 @@ class WC_Payment_Gateway_WCPay extends WC_Payment_Gateway_CC { * @param Duplicate_Payment_Prevention_Service $duplicate_payment_prevention_service - Service for preventing duplicate payments. * @param WC_Payments_Localization_Service $localization_service - Localization service instance. * @param WC_Payments_Fraud_Service $fraud_service - Fraud service instance. + * @param Duplicates_Detection_Service $duplicate_payment_methods_detection_service - Service for finding duplicate enabled payment methods. */ public function __construct( WC_Payments_API_Client $payments_api_client, @@ -259,22 +268,24 @@ public function __construct( WC_Payments_Order_Service $order_service, Duplicate_Payment_Prevention_Service $duplicate_payment_prevention_service, WC_Payments_Localization_Service $localization_service, - WC_Payments_Fraud_Service $fraud_service + WC_Payments_Fraud_Service $fraud_service, + Duplicates_Detection_Service $duplicate_payment_methods_detection_service ) { $this->payment_methods = $payment_methods; $this->payment_method = $payment_method; $this->stripe_id = $payment_method->get_id(); - $this->payments_api_client = $payments_api_client; - $this->account = $account; - $this->customer_service = $customer_service; - $this->token_service = $token_service; - $this->action_scheduler_service = $action_scheduler_service; - $this->failed_transaction_rate_limiter = $failed_transaction_rate_limiter; - $this->order_service = $order_service; - $this->duplicate_payment_prevention_service = $duplicate_payment_prevention_service; - $this->localization_service = $localization_service; - $this->fraud_service = $fraud_service; + $this->payments_api_client = $payments_api_client; + $this->account = $account; + $this->customer_service = $customer_service; + $this->token_service = $token_service; + $this->action_scheduler_service = $action_scheduler_service; + $this->failed_transaction_rate_limiter = $failed_transaction_rate_limiter; + $this->order_service = $order_service; + $this->duplicate_payment_prevention_service = $duplicate_payment_prevention_service; + $this->localization_service = $localization_service; + $this->fraud_service = $fraud_service; + $this->duplicate_payment_methods_detection_service = $duplicate_payment_methods_detection_service; $this->id = static::GATEWAY_ID; $this->icon = $this->get_theme_icon(); @@ -4346,6 +4357,15 @@ public function get_method_description() { return $description; } + /** + * Calls duplicate payment methods detection service to find duplicates. + * This method acts as a wrapper. The approach should be reverted once + * https://github.com/Automattic/woocommerce-payments/issues/7464 is resolved. + */ + public function find_duplicates() { + return $this->duplicate_payment_methods_detection_service->find_duplicates(); + } + // Start: Deprecated functions. /** diff --git a/includes/class-wc-payments.php b/includes/class-wc-payments.php index 9dbd87c85df..e465834adc0 100644 --- a/includes/class-wc-payments.php +++ b/includes/class-wc-payments.php @@ -538,7 +538,7 @@ public static function init() { foreach ( $payment_methods as $payment_method ) { self::$payment_method_map[ $payment_method->get_id() ] = $payment_method; - $split_gateway = new WC_Payment_Gateway_WCPay( self::$api_client, self::$account, self::$customer_service, self::$token_service, self::$action_scheduler_service, $payment_method, $payment_methods, self::$failed_transaction_rate_limiter, self::$order_service, self::$duplicate_payment_prevention_service, self::$localization_service, self::$fraud_service ); + $split_gateway = new WC_Payment_Gateway_WCPay( self::$api_client, self::$account, self::$customer_service, self::$token_service, self::$action_scheduler_service, $payment_method, $payment_methods, self::$failed_transaction_rate_limiter, self::$order_service, self::$duplicate_payment_prevention_service, self::$localization_service, self::$fraud_service, self::$duplicates_detection_service ); // Card gateway hooks are registered once below. if ( 'card' !== $payment_method->get_id() ) { @@ -1020,7 +1020,7 @@ public static function init_rest_api() { $reporting_controller->register_routes(); include_once WCPAY_ABSPATH . 'includes/admin/class-wc-rest-payments-settings-controller.php'; - $settings_controller = new WC_REST_Payments_Settings_Controller( self::$api_client, self::get_gateway(), self::$account, self::$duplicates_detection_service ); + $settings_controller = new WC_REST_Payments_Settings_Controller( self::$api_client, self::get_gateway(), self::$account ); $settings_controller->register_routes(); include_once WCPAY_ABSPATH . 'includes/admin/class-wc-rest-payments-reader-controller.php'; diff --git a/tests/unit/admin/test-class-wc-rest-payments-settings-controller.php b/tests/unit/admin/test-class-wc-rest-payments-settings-controller.php index 7c152626ad0..6bfaff2b816 100644 --- a/tests/unit/admin/test-class-wc-rest-payments-settings-controller.php +++ b/tests/unit/admin/test-class-wc-rest-payments-settings-controller.php @@ -175,9 +175,10 @@ public function set_up() { $order_service, $mock_dpps, $this->mock_localization_service, - $this->mock_fraud_service + $this->mock_fraud_service, + $this->mock_duplicates_detection_service ); - $this->controller = new WC_REST_Payments_Settings_Controller( $this->mock_api_client, $this->gateway, $this->mock_wcpay_account, $this->mock_duplicates_detection_service ); + $this->controller = new WC_REST_Payments_Settings_Controller( $this->mock_api_client, $this->gateway, $this->mock_wcpay_account ); $this->mock_api_client ->method( 'is_server_connected' ) diff --git a/tests/unit/admin/test-class-wc-rest-payments-tos-controller.php b/tests/unit/admin/test-class-wc-rest-payments-tos-controller.php index 9597390a9a0..f2f5b4274f7 100644 --- a/tests/unit/admin/test-class-wc-rest-payments-tos-controller.php +++ b/tests/unit/admin/test-class-wc-rest-payments-tos-controller.php @@ -9,6 +9,7 @@ use WCPay\Core\Server\Request\Add_Account_Tos_Agreement; use WCPay\Database_Cache; use WCPay\Duplicate_Payment_Prevention_Service; +use WCPay\Duplicates_Detection_Service; use WCPay\Payment_Methods\CC_Payment_Method; use WCPay\Session_Rate_Limiter; @@ -55,16 +56,17 @@ public function set_up() { ->disableOriginalConstructor() ->getMock(); - $mock_wcpay_account = $this->createMock( WC_Payments_Account::class ); - $mock_fraud_service = $this->createMock( WC_Payments_Fraud_Service::class ); - $mock_db_cache = $this->createMock( Database_Cache::class ); - $mock_session_service = $this->createMock( WC_Payments_Session_Service::class ); - $customer_service = new WC_Payments_Customer_Service( $mock_api_client, $mock_wcpay_account, $mock_db_cache, $mock_session_service ); - $token_service = new WC_Payments_Token_Service( $mock_api_client, $customer_service ); - $order_service = new WC_Payments_Order_Service( $this->createMock( WC_Payments_API_Client::class ) ); - $action_scheduler_service = new WC_Payments_Action_Scheduler_Service( $mock_api_client, $order_service ); - $mock_dpps = $this->createMock( Duplicate_Payment_Prevention_Service::class ); - $mock_payment_method = $this->createMock( CC_Payment_Method::class ); + $mock_wcpay_account = $this->createMock( WC_Payments_Account::class ); + $mock_fraud_service = $this->createMock( WC_Payments_Fraud_Service::class ); + $mock_db_cache = $this->createMock( Database_Cache::class ); + $mock_session_service = $this->createMock( WC_Payments_Session_Service::class ); + $customer_service = new WC_Payments_Customer_Service( $mock_api_client, $mock_wcpay_account, $mock_db_cache, $mock_session_service ); + $token_service = new WC_Payments_Token_Service( $mock_api_client, $customer_service ); + $order_service = new WC_Payments_Order_Service( $this->createMock( WC_Payments_API_Client::class ) ); + $action_scheduler_service = new WC_Payments_Action_Scheduler_Service( $mock_api_client, $order_service ); + $mock_dpps = $this->createMock( Duplicate_Payment_Prevention_Service::class ); + $mock_payment_method = $this->createMock( CC_Payment_Method::class ); + $mock_duplicates_detection_service = $this->createMock( Duplicates_Detection_Service::class ); $this->gateway = new WC_Payment_Gateway_WCPay( $mock_api_client, @@ -78,7 +80,8 @@ public function set_up() { $order_service, $mock_dpps, $this->createMock( WC_Payments_Localization_Service::class ), - $mock_fraud_service + $mock_fraud_service, + $mock_duplicates_detection_service ); $this->controller = new WC_REST_Payments_Tos_Controller( $mock_api_client, $this->gateway, $mock_wcpay_account ); diff --git a/tests/unit/payment-methods/test-class-upe-payment-gateway.php b/tests/unit/payment-methods/test-class-upe-payment-gateway.php index 8260f8707b5..137a283a944 100644 --- a/tests/unit/payment-methods/test-class-upe-payment-gateway.php +++ b/tests/unit/payment-methods/test-class-upe-payment-gateway.php @@ -33,6 +33,7 @@ use WC_Payments_Localization_Service; use WCPay\Core\Server\Request\Create_And_Confirm_Intention; use WCPay\Database_Cache; +use WCPay\Duplicates_Detection_Service; use WCPay\Internal\Service\Level3Service; use WCPay\Internal\Service\OrderService; @@ -170,6 +171,13 @@ class UPE_Payment_Gateway_Test extends WCPAY_UnitTestCase { */ private $mock_fraud_service; + /** + * Mock Duplicates Detection Service. + * + * @var Duplicates_Detection_Service + */ + private $mock_duplicates_detection_service; + /** * Pre-test setup */ @@ -230,8 +238,9 @@ public function set_up() { $this->mock_dpps = $this->createMock( Duplicate_Payment_Prevention_Service::class ); - $this->mock_localization_service = $this->createMock( WC_Payments_Localization_Service::class ); - $this->mock_fraud_service = $this->createMock( WC_Payments_Fraud_Service::class ); + $this->mock_localization_service = $this->createMock( WC_Payments_Localization_Service::class ); + $this->mock_fraud_service = $this->createMock( WC_Payments_Fraud_Service::class ); + $this->mock_duplicates_detection_service = $this->createMock( Duplicates_Detection_Service::class ); $this->mock_payment_methods = []; $payment_method_classes = [ @@ -294,6 +303,7 @@ public function set_up() { $this->mock_dpps, $this->mock_localization_service, $this->mock_fraud_service, + $this->mock_duplicates_detection_service, ] ) ->setMethods( @@ -961,7 +971,8 @@ public function test_get_upe_available_payment_methods( $payment_methods, $expec $this->mock_order_service, $this->mock_dpps, $this->mock_localization_service, - $this->mock_fraud_service + $this->mock_fraud_service, + $this->mock_duplicates_detection_service ); $this->assertEquals( $expected_result, $gateway->get_upe_available_payment_methods() ); diff --git a/tests/unit/payment-methods/test-class-upe-split-payment-gateway.php b/tests/unit/payment-methods/test-class-upe-split-payment-gateway.php index 22653a4cba9..8ac1db139a5 100644 --- a/tests/unit/payment-methods/test-class-upe-split-payment-gateway.php +++ b/tests/unit/payment-methods/test-class-upe-split-payment-gateway.php @@ -35,6 +35,7 @@ use WC_Payments_Localization_Service; use WCPay\Core\Server\Request\Create_And_Confirm_Intention; use WCPay\Database_Cache; +use WCPay\Duplicates_Detection_Service; use WCPay\Internal\Service\Level3Service; use WCPay\Internal\Service\OrderService; /** @@ -158,6 +159,13 @@ class UPE_Split_Payment_Gateway_Test extends WCPAY_UnitTestCase { */ private $mock_fraud_service; + /** + * Mock Duplicates Detection Service. + * + * @var Duplicates_Detection_Service + */ + private $mock_duplicates_detection_service; + /** * Mapping for payment ID to payment method. * @@ -247,8 +255,9 @@ public function set_up() { $this->mock_dpps = $this->createMock( Duplicate_Payment_Prevention_Service::class ); - $this->mock_localization_service = $this->createMock( WC_Payments_Localization_Service::class ); - $this->mock_fraud_service = $this->createMock( WC_Payments_Fraud_Service::class ); + $this->mock_localization_service = $this->createMock( WC_Payments_Localization_Service::class ); + $this->mock_fraud_service = $this->createMock( WC_Payments_Fraud_Service::class ); + $this->mock_duplicates_detection_service = $this->createMock( Duplicates_Detection_Service::class ); // Arrange: Define a $_POST array which includes the payment method, // so that get_payment_method_from_request() does not throw error. @@ -281,6 +290,7 @@ public function set_up() { $this->mock_dpps, $this->mock_localization_service, $this->mock_fraud_service, + $this->mock_duplicates_detection_service, ] ) ->setMethods( @@ -1060,6 +1070,7 @@ public function test_get_payment_methods_with_request_context() { $this->mock_dpps, $this->mock_localization_service, $this->mock_fraud_service, + $this->mock_duplicates_detection_service, ] ) ->setMethods( [ 'get_payment_methods_from_gateway_id' ] ) @@ -1105,6 +1116,7 @@ public function test_get_payment_methods_without_request_context() { $this->mock_dpps, $this->mock_localization_service, $this->mock_fraud_service, + $this->mock_duplicates_detection_service, ] ) ->setMethods( [ 'get_payment_methods_from_gateway_id' ] ) @@ -1149,6 +1161,7 @@ public function test_get_payment_methods_without_request_context_or_token() { $this->mock_dpps, $this->mock_localization_service, $this->mock_fraud_service, + $this->mock_duplicates_detection_service, ] ) ->setMethods( @@ -1202,6 +1215,7 @@ public function test_get_payment_methods_from_gateway_id_upe() { $this->mock_dpps, $this->mock_localization_service, $this->mock_fraud_service, + $this->mock_duplicates_detection_service, ] ) ->onlyMethods( diff --git a/tests/unit/test-class-wc-payment-gateway-wcpay-payment-types.php b/tests/unit/test-class-wc-payment-gateway-wcpay-payment-types.php index 8caaadb9ea4..c4ae5f729ee 100644 --- a/tests/unit/test-class-wc-payment-gateway-wcpay-payment-types.php +++ b/tests/unit/test-class-wc-payment-gateway-wcpay-payment-types.php @@ -9,6 +9,7 @@ use WCPay\Core\Server\Request\Create_And_Confirm_Intention; use WCPay\Constants\Payment_Method; use WCPay\Duplicate_Payment_Prevention_Service; +use WCPay\Duplicates_Detection_Service; use WCPay\Session_Rate_Limiter; use WCPay\Fraud_Prevention\Fraud_Prevention_Service; use WCPay\Payment_Methods\CC_Payment_Method; @@ -153,6 +154,7 @@ public function set_up() { $mock_dpps, $this->createMock( WC_Payments_Localization_Service::class ), $this->createMock( WC_Payments_Fraud_Service::class ), + $this->createMock( Duplicates_Detection_Service::class ), ] ) ->setMethods( diff --git a/tests/unit/test-class-wc-payment-gateway-wcpay-process-payment.php b/tests/unit/test-class-wc-payment-gateway-wcpay-process-payment.php index 79f6cd75d9b..3962272376d 100644 --- a/tests/unit/test-class-wc-payment-gateway-wcpay-process-payment.php +++ b/tests/unit/test-class-wc-payment-gateway-wcpay-process-payment.php @@ -15,6 +15,7 @@ use WCPay\Exceptions\Connection_Exception; use WCPay\Session_Rate_Limiter; use WCPay\Constants\Payment_Method; +use WCPay\Duplicates_Detection_Service; use WCPay\Payment_Methods\CC_Payment_Method; // Need to use WC_Mock_Data_Store. @@ -167,6 +168,7 @@ public function set_up() { $this->mock_dpps, $this->createMock( WC_Payments_Localization_Service::class ), $this->createMock( WC_Payments_Fraud_Service::class ), + $this->createMock( Duplicates_Detection_Service::class ), ] ) ->setMethods( diff --git a/tests/unit/test-class-wc-payment-gateway-wcpay-process-refund.php b/tests/unit/test-class-wc-payment-gateway-wcpay-process-refund.php index 49746ef3ca3..24f06d99933 100644 --- a/tests/unit/test-class-wc-payment-gateway-wcpay-process-refund.php +++ b/tests/unit/test-class-wc-payment-gateway-wcpay-process-refund.php @@ -12,6 +12,7 @@ use WCPay\Core\Server\Request\Refund_Charge; use WCPay\Core\Server\Response; use WCPay\Duplicate_Payment_Prevention_Service; +use WCPay\Duplicates_Detection_Service; use WCPay\Exceptions\API_Exception; use WCPay\Payment_Methods\CC_Payment_Method; use WCPay\Session_Rate_Limiter; @@ -104,7 +105,8 @@ public function set_up() { $this->mock_order_service, $mock_dpps, $this->createMock( WC_Payments_Localization_Service::class ), - $this->createMock( WC_Payments_Fraud_Service::class ) + $this->createMock( WC_Payments_Fraud_Service::class ), + $this->createMock( Duplicates_Detection_Service::class ) ); } diff --git a/tests/unit/test-class-wc-payment-gateway-wcpay-subscriptions-payment-method-order-note.php b/tests/unit/test-class-wc-payment-gateway-wcpay-subscriptions-payment-method-order-note.php index 9715d61a193..fd4352ac0b2 100644 --- a/tests/unit/test-class-wc-payment-gateway-wcpay-subscriptions-payment-method-order-note.php +++ b/tests/unit/test-class-wc-payment-gateway-wcpay-subscriptions-payment-method-order-note.php @@ -6,6 +6,7 @@ */ use WCPay\Duplicate_Payment_Prevention_Service; +use WCPay\Duplicates_Detection_Service; use WCPay\Payment_Methods\CC_Payment_Method; use WCPay\Session_Rate_Limiter; @@ -139,7 +140,8 @@ public function set_up() { $this->mock_order_service, $mock_dpps, $this->createMock( WC_Payments_Localization_Service::class ), - $this->createMock( WC_Payments_Fraud_Service::class ) + $this->createMock( WC_Payments_Fraud_Service::class ), + $this->createMock( Duplicates_Detection_Service::class ), ); $this->wcpay_gateway->init_hooks(); diff --git a/tests/unit/test-class-wc-payment-gateway-wcpay-subscriptions-process-payment.php b/tests/unit/test-class-wc-payment-gateway-wcpay-subscriptions-process-payment.php index 434bbd971fd..622e7cbe1d9 100644 --- a/tests/unit/test-class-wc-payment-gateway-wcpay-subscriptions-process-payment.php +++ b/tests/unit/test-class-wc-payment-gateway-wcpay-subscriptions-process-payment.php @@ -10,6 +10,7 @@ use WCPay\Constants\Order_Status; use WCPay\Constants\Intent_Status; use WCPay\Duplicate_Payment_Prevention_Service; +use WCPay\Duplicates_Detection_Service; use WCPay\Payment_Methods\CC_Payment_Method; use WCPay\Session_Rate_Limiter; @@ -160,6 +161,7 @@ public function set_up() { $mock_dpps, $this->createMock( WC_Payments_Localization_Service::class ), $this->createMock( WC_Payments_Fraud_Service::class ), + $this->createMock( Duplicates_Detection_Service::class ), ] ) ->setMethods( diff --git a/tests/unit/test-class-wc-payment-gateway-wcpay-subscriptions.php b/tests/unit/test-class-wc-payment-gateway-wcpay-subscriptions.php index a5b33c1581c..151b3b919fe 100644 --- a/tests/unit/test-class-wc-payment-gateway-wcpay-subscriptions.php +++ b/tests/unit/test-class-wc-payment-gateway-wcpay-subscriptions.php @@ -8,6 +8,7 @@ use PHPUnit\Framework\MockObject\MockObject; use WCPay\Core\Server\Request\Create_And_Confirm_Intention; use WCPay\Duplicate_Payment_Prevention_Service; +use WCPay\Duplicates_Detection_Service; use WCPay\Exceptions\API_Exception; use WCPay\Internal\Service\Level3Service; use WCPay\Internal\Service\OrderService; @@ -102,6 +103,13 @@ class WC_Payment_Gateway_WCPay_Subscriptions_Test extends WCPAY_UnitTestCase { */ private $mock_fraud_service; + /** + * Mock Duplicates Detection Service. + * + * @var Duplicates_Detection_Service + */ + private $mock_duplicates_detection_service; + public function set_up() { parent::set_up(); @@ -136,8 +144,9 @@ public function set_up() { $this->mock_dpps = $this->createMock( Duplicate_Payment_Prevention_Service::class ); - $this->mock_localization_service = $this->createMock( WC_Payments_Localization_Service::class ); - $this->mock_fraud_service = $this->createMock( WC_Payments_Fraud_Service::class ); + $this->mock_localization_service = $this->createMock( WC_Payments_Localization_Service::class ); + $this->mock_fraud_service = $this->createMock( WC_Payments_Fraud_Service::class ); + $this->mock_duplicates_detection_service = $this->createMock( Duplicates_Detection_Service::class ); $mock_payment_method = $this->getMockBuilder( CC_Payment_Method::class ) ->setConstructorArgs( [ $this->mock_token_service ] ) @@ -156,7 +165,8 @@ public function set_up() { $this->order_service, $this->mock_dpps, $this->mock_localization_service, - $this->mock_fraud_service + $this->mock_fraud_service, + $this->mock_duplicates_detection_service, ); $this->wcpay_gateway->init_hooks(); WC_Payments::set_gateway( $this->wcpay_gateway ); @@ -830,7 +840,8 @@ public function test_adds_custom_payment_meta_input_fallback_until_subs_3_0_7() $this->order_service, $this->mock_dpps, $this->mock_localization_service, - $this->mock_fraud_service + $this->mock_fraud_service, + $this->mock_duplicates_detection_service, ); // Ensure the has_attached_integration_hooks property is set to false so callbacks can be attached in maybe_init_subscriptions(). @@ -864,7 +875,8 @@ public function test_does_not_add_custom_payment_meta_input_fallback_for_subs_3_ $this->order_service, $this->mock_dpps, $this->mock_localization_service, - $this->mock_fraud_service + $this->mock_fraud_service, + $this->mock_duplicates_detection_service, ); $this->assertFalse( has_action( 'woocommerce_admin_order_data_after_billing_address' ) ); diff --git a/tests/unit/test-class-wc-payment-gateway-wcpay.php b/tests/unit/test-class-wc-payment-gateway-wcpay.php index 38b299129d8..c485a19ecb3 100644 --- a/tests/unit/test-class-wc-payment-gateway-wcpay.php +++ b/tests/unit/test-class-wc-payment-gateway-wcpay.php @@ -17,6 +17,7 @@ use WCPay\Constants\Intent_Status; use WCPay\Constants\Payment_Method; use WCPay\Duplicate_Payment_Prevention_Service; +use WCPay\Duplicates_Detection_Service; use WCPay\Exceptions\Amount_Too_Small_Exception; use WCPay\Exceptions\API_Exception; use WCPay\Exceptions\Process_Payment_Exception; @@ -177,6 +178,13 @@ class WC_Payment_Gateway_WCPay_Test extends WCPAY_UnitTestCase { */ private $mock_fraud_service; + /** + * Mock Duplicates Detection Service. + * + * @var Duplicates_Detection_Service + */ + private $mock_duplicates_detection_service; + /** * Pre-test setup */ @@ -229,7 +237,8 @@ public function set_up() { 'currency_code' => 'usd', ] ); - $this->mock_fraud_service = $this->createMock( WC_Payments_Fraud_Service::class ); + $this->mock_fraud_service = $this->createMock( WC_Payments_Fraud_Service::class ); + $this->mock_duplicates_detection_service = $this->createMock( Duplicates_Detection_Service::class ); $this->mock_payment_method = $this->getMockBuilder( CC_Payment_Method::class ) ->setConstructorArgs( [ $this->mock_token_service ] ) @@ -897,6 +906,7 @@ public function test_process_redirect_setup_intent_succeded() { $this->mock_dpps, $this->mock_localization_service, $this->mock_fraud_service, + $this->mock_duplicates_detection_service, ] ) ->onlyMethods( @@ -1004,6 +1014,7 @@ public function test_process_redirect_payment_save_payment_token() { $this->mock_dpps, $this->mock_localization_service, $this->mock_fraud_service, + $this->mock_duplicates_detection_service, ] ) ->onlyMethods( @@ -3203,6 +3214,7 @@ private function get_partial_mock_for_gateway( array $methods = [], array $const $this->mock_dpps, $this->mock_localization_service, $this->mock_fraud_service, + $this->mock_duplicates_detection_service, ]; foreach ( $constructor_replacement as $key => $value ) { @@ -3688,7 +3700,8 @@ private function init_gateways() { $this->order_service, $this->mock_dpps, $this->mock_localization_service, - $this->mock_fraud_service + $this->mock_fraud_service, + $this->mock_duplicates_detection_service ); } diff --git a/tests/unit/test-class-wc-payments-express-checkout-button-display-handler.php b/tests/unit/test-class-wc-payments-express-checkout-button-display-handler.php index 1bd4dbeeafc..8a6a1b7f4f3 100644 --- a/tests/unit/test-class-wc-payments-express-checkout-button-display-handler.php +++ b/tests/unit/test-class-wc-payments-express-checkout-button-display-handler.php @@ -7,6 +7,7 @@ use PHPUnit\Framework\MockObject\MockObject; use WCPay\Duplicate_Payment_Prevention_Service; +use WCPay\Duplicates_Detection_Service; use WCPay\Payment_Methods\CC_Payment_Method; use WCPay\Session_Rate_Limiter; use WCPay\WooPay\WooPay_Utilities; @@ -177,7 +178,8 @@ private function make_wcpay_gateway() { $mock_order_service, $mock_dpps, $this->createMock( WC_Payments_Localization_Service::class ), - $this->createMock( WC_Payments_Fraud_Service::class ) + $this->createMock( WC_Payments_Fraud_Service::class ), + $this->createMock( Duplicates_Detection_Service::class ) ); } diff --git a/tests/unit/test-class-wc-payments-express-checkout-button-helper.php b/tests/unit/test-class-wc-payments-express-checkout-button-helper.php index 8b3312dcf30..3dc7878ba39 100644 --- a/tests/unit/test-class-wc-payments-express-checkout-button-helper.php +++ b/tests/unit/test-class-wc-payments-express-checkout-button-helper.php @@ -6,6 +6,7 @@ */ use WCPay\Duplicate_Payment_Prevention_Service; +use WCPay\Duplicates_Detection_Service; use WCPay\Payment_Methods\CC_Payment_Method; use WCPay\Session_Rate_Limiter; @@ -91,7 +92,8 @@ private function make_wcpay_gateway() { $mock_order_service, $mock_dpps, $this->createMock( WC_Payments_Localization_Service::class ), - $this->createMock( WC_Payments_Fraud_Service::class ) + $this->createMock( WC_Payments_Fraud_Service::class ), + $this->createMock( Duplicates_Detection_Service::class ) ); } diff --git a/tests/unit/test-class-wc-payments-payment-request-button-handler.php b/tests/unit/test-class-wc-payments-payment-request-button-handler.php index fe703f8ee94..672a4cdaeac 100644 --- a/tests/unit/test-class-wc-payments-payment-request-button-handler.php +++ b/tests/unit/test-class-wc-payments-payment-request-button-handler.php @@ -7,6 +7,7 @@ use WCPay\Constants\Country_Code; use WCPay\Duplicate_Payment_Prevention_Service; +use WCPay\Duplicates_Detection_Service; use WCPay\Payment_Methods\CC_Payment_Method; use WCPay\Session_Rate_Limiter; @@ -223,7 +224,8 @@ private function make_wcpay_gateway() { $mock_order_service, $mock_dpps, $this->createMock( WC_Payments_Localization_Service::class ), - $this->createMock( WC_Payments_Fraud_Service::class ) + $this->createMock( WC_Payments_Fraud_Service::class ), + $this->createMock( Duplicates_Detection_Service::class ) ); } diff --git a/tests/unit/test-class-wc-payments-woopay-button-handler.php b/tests/unit/test-class-wc-payments-woopay-button-handler.php index 1c87f05a4b7..dbb5cefe960 100644 --- a/tests/unit/test-class-wc-payments-woopay-button-handler.php +++ b/tests/unit/test-class-wc-payments-woopay-button-handler.php @@ -6,6 +6,7 @@ */ use WCPay\Duplicate_Payment_Prevention_Service; +use WCPay\Duplicates_Detection_Service; use WCPay\Payment_Methods\CC_Payment_Method; use WCPay\Session_Rate_Limiter; use WCPay\WooPay\WooPay_Utilities; @@ -163,7 +164,8 @@ private function make_wcpay_gateway() { $mock_order_service, $mock_dpps, $this->createMock( WC_Payments_Localization_Service::class ), - $this->createMock( WC_Payments_Fraud_Service::class ) + $this->createMock( WC_Payments_Fraud_Service::class ), + $this->createMock( Duplicates_Detection_Service::class ) ); } From ebee3fefa45195fc68f933c1d406b360a86ca95f Mon Sep 17 00:00:00 2001 From: Rua Haszard Date: Tue, 30 Apr 2024 09:03:56 +1200 Subject: [PATCH 07/15] tweak emoji survey prompt - "these", was "those" (#8725) Co-authored-by: Rua Haszard Co-authored-by: Eric Jinks <3147296+Jinksi@users.noreply.github.com> --- changelog/fix-8724-are-these-metrics | 5 +++++ client/components/payment-activity/survey/index.tsx | 2 +- .../survey/test/__snapshots__/index.test.tsx.snap | 4 ++-- .../components/payment-activity/survey/test/index.test.tsx | 2 +- .../payment-activity/test/__snapshots__/index.test.tsx.snap | 2 +- client/components/payment-activity/test/index.test.tsx | 4 ++-- 6 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 changelog/fix-8724-are-these-metrics diff --git a/changelog/fix-8724-are-these-metrics b/changelog/fix-8724-are-these-metrics new file mode 100644 index 00000000000..a0c2f5aa55d --- /dev/null +++ b/changelog/fix-8724-are-these-metrics @@ -0,0 +1,5 @@ +Significance: patch +Type: fix +Comment: This is covered by emoji survey changelog from #8506 + + diff --git a/client/components/payment-activity/survey/index.tsx b/client/components/payment-activity/survey/index.tsx index 0067159ff18..cb2bd8abe16 100644 --- a/client/components/payment-activity/survey/index.tsx +++ b/client/components/payment-activity/survey/index.tsx @@ -99,7 +99,7 @@ const Survey: React.FC = () => {
{ __( - 'Are those metrics helpful?', + 'Are these metrics helpful?', 'woocommerce-payments' ) } diff --git a/client/components/payment-activity/survey/test/__snapshots__/index.test.tsx.snap b/client/components/payment-activity/survey/test/__snapshots__/index.test.tsx.snap index aacb8aa6f5f..571ede8a94e 100644 --- a/client/components/payment-activity/survey/test/__snapshots__/index.test.tsx.snap +++ b/client/components/payment-activity/survey/test/__snapshots__/index.test.tsx.snap @@ -13,7 +13,7 @@ exports[`WcPayOverviewSurveyContextProvider test survey initial display 1`] = `
- Are those metrics helpful? + Are these metrics helpful?
@@ -92,7 +92,7 @@ exports[`WcPayOverviewSurveyContextProvider test survey with comments textbox 1`
- Are those metrics helpful? + Are these metrics helpful?
diff --git a/client/components/payment-activity/survey/test/index.test.tsx b/client/components/payment-activity/survey/test/index.test.tsx index 1b6ffef0147..35554f33340 100644 --- a/client/components/payment-activity/survey/test/index.test.tsx +++ b/client/components/payment-activity/survey/test/index.test.tsx @@ -53,7 +53,7 @@ describe( 'WcPayOverviewSurveyContextProvider', () => { ); - const surveyText = screen.getByText( 'Are those metrics helpful?' ); + const surveyText = screen.getByText( 'Are these metrics helpful?' ); expect( surveyText ).toBeInTheDocument(); const buttons = screen.getAllByRole( 'button' ); diff --git a/client/components/payment-activity/test/__snapshots__/index.test.tsx.snap b/client/components/payment-activity/test/__snapshots__/index.test.tsx.snap index 7e02d2dfc65..1b655775699 100644 --- a/client/components/payment-activity/test/__snapshots__/index.test.tsx.snap +++ b/client/components/payment-activity/test/__snapshots__/index.test.tsx.snap @@ -260,7 +260,7 @@ exports[`PaymentActivity component should render 1`] = `
- Are those metrics helpful? + Are these metrics helpful?
diff --git a/client/components/payment-activity/test/index.test.tsx b/client/components/payment-activity/test/index.test.tsx index 3d16ad70846..49e8726c02e 100644 --- a/client/components/payment-activity/test/index.test.tsx +++ b/client/components/payment-activity/test/index.test.tsx @@ -120,7 +120,7 @@ describe( 'PaymentActivity component', () => { const { container, getByText } = render( ); // Check survey is rendered. - getByText( 'Are those metrics helpful?' ); + getByText( 'Are these metrics helpful?' ); expect( container ).toMatchSnapshot(); } ); @@ -140,7 +140,7 @@ describe( 'PaymentActivity component', () => { const { queryByText } = render( ); expect( - queryByText( 'Are those metrics helpful?' ) + queryByText( 'Are these metrics helpful?' ) ).not.toBeInTheDocument(); } ); } ); From 15e8a88e3f28e8da450391587d589aff236a8077 Mon Sep 17 00:00:00 2001 From: Eric Jinks <3147296+Jinksi@users.noreply.github.com> Date: Tue, 30 Apr 2024 07:53:55 +1000 Subject: [PATCH 08/15] Use correct currency in Payment Activity Card (#8701) Co-authored-by: Shendy <73803630+shendy-a8c@users.noreply.github.com> --- ...ent-activity-card-default-account-currency | 5 +++ .../payment-activity-data.tsx | 12 +++---- .../payment-activity/payment-data-tile.tsx | 8 ++--- .../test/__snapshots__/index.test.tsx.snap | 35 +++++++++++-------- .../payment-data-tile.test.tsx.snap | 5 +-- .../payment-activity/test/index.test.tsx | 17 +++++++-- .../test/payment-data-tile.test.tsx | 15 ++++---- client/data/payment-activity/resolvers.ts | 4 +-- client/data/payment-activity/selectors.ts | 6 ++-- .../data/payment-activity/test/hooks.test.ts | 1 + .../payment-activity/test/reducer.test.ts | 5 +++ client/data/payment-activity/types.d.ts | 33 +++++++++++------ 12 files changed, 95 insertions(+), 51 deletions(-) create mode 100644 changelog/fix-8700-payment-activity-card-default-account-currency diff --git a/changelog/fix-8700-payment-activity-card-default-account-currency b/changelog/fix-8700-payment-activity-card-default-account-currency new file mode 100644 index 00000000000..73671f1477b --- /dev/null +++ b/changelog/fix-8700-payment-activity-card-default-account-currency @@ -0,0 +1,5 @@ +Significance: patch +Type: fix +Comment: Update Payment Activity Card to use correct currency for rendering amounts. + + diff --git a/client/components/payment-activity/payment-activity-data.tsx b/client/components/payment-activity/payment-activity-data.tsx index 5816c6fc540..2596079ceba 100644 --- a/client/components/payment-activity/payment-activity-data.tsx +++ b/client/components/payment-activity/payment-activity-data.tsx @@ -41,14 +41,14 @@ const PaymentActivityData: React.FC = () => { const fees = paymentActivityData?.fees ?? 0; const disputes = paymentActivityData?.disputes ?? 0; const refunds = paymentActivityData?.refunds ?? 0; - const { storeCurrency } = wcpaySettings; + const currency = paymentActivityData?.currency; return (
{ { { { = ( { reportLink, } ) => { return ( -
+

- { label } + { label } { ! isLoading && tooltip }

diff --git a/client/components/payment-activity/test/__snapshots__/index.test.tsx.snap b/client/components/payment-activity/test/__snapshots__/index.test.tsx.snap index 1b655775699..0b4f5e397a8 100644 --- a/client/components/payment-activity/test/__snapshots__/index.test.tsx.snap +++ b/client/components/payment-activity/test/__snapshots__/index.test.tsx.snap @@ -27,12 +27,13 @@ exports[`PaymentActivity component should render 1`] = ` >
diff --git a/client/components/payment-activity/test/__snapshots__/payment-data-tile.test.tsx.snap b/client/components/payment-activity/test/__snapshots__/payment-data-tile.test.tsx.snap index b822f04944a..b2b397d5d5f 100644 --- a/client/components/payment-activity/test/__snapshots__/payment-data-tile.test.tsx.snap +++ b/client/components/payment-activity/test/__snapshots__/payment-data-tile.test.tsx.snap @@ -4,12 +4,13 @@ exports[`PaymentDataTile renders correctly 1`] = `

- + Total payment volume

diff --git a/client/components/payment-activity/test/index.test.tsx b/client/components/payment-activity/test/index.test.tsx index 49e8726c02e..cfd35de8451 100644 --- a/client/components/payment-activity/test/index.test.tsx +++ b/client/components/payment-activity/test/index.test.tsx @@ -38,11 +38,16 @@ const mockUsePaymentActivityData = usePaymentActivityData as jest.MockedFunction mockUsePaymentActivityData.mockReturnValue( { paymentActivityData: { + currency: 'eur', total_payment_volume: 123456, charges: 9876, fees: 1234, disputes: 5555, refunds: 4444, + date_start: '2024-01-01', + date_end: '2024-01-31', + timezone: 'UTC', + interval: 'daily', }, isLoading: false, } ); @@ -83,10 +88,10 @@ describe( 'PaymentActivity component', () => { }, }, }, - accountDefaultCurrency: 'USD', + accountDefaultCurrency: 'eur', zeroDecimalCurrencies: [], connect: { - country: 'US', + country: 'DE', }, currencyData: { US: { @@ -117,11 +122,17 @@ describe( 'PaymentActivity component', () => { } ); it( 'should render', () => { - const { container, getByText } = render( ); + const { container, getByText, getByLabelText } = render( + + ); // Check survey is rendered. getByText( 'Are these metrics helpful?' ); + // Check correct currency/value is displayed. + const tpvElement = getByLabelText( 'Total payment volume' ); + expect( tpvElement ).toHaveTextContent( '€1.234,56' ); + expect( container ).toMatchSnapshot(); } ); diff --git a/client/components/payment-activity/test/payment-data-tile.test.tsx b/client/components/payment-activity/test/payment-data-tile.test.tsx index 2409d4f634e..2621cbbf8ac 100644 --- a/client/components/payment-activity/test/payment-data-tile.test.tsx +++ b/client/components/payment-activity/test/payment-data-tile.test.tsx @@ -22,7 +22,7 @@ declare const global: { describe( 'PaymentDataTile', () => { global.wcpaySettings = { - accountDefaultCurrency: 'USD', + accountDefaultCurrency: 'usd', zeroDecimalCurrencies: [], connect: { country: 'US', @@ -43,7 +43,7 @@ describe( 'PaymentDataTile', () => { const { container } = render( ); @@ -55,17 +55,18 @@ describe( 'PaymentDataTile', () => { render( ); - const labelElement = screen.getByText( label ); - expect( labelElement ).toBeInTheDocument(); + expect( screen.getByText( label ) ).toBeInTheDocument(); + expect( screen.getByLabelText( label ) ).toHaveTextContent( '$1.23' ); } ); test( 'renders amount correctly', () => { const amount = 10000; - const currencyCode = 'USD'; + const currencyCode = 'usd'; render( { id="charges-test-tile" label="Charges" amount={ 10000 } - currencyCode="USD" + currencyCode="usd" reportLink={ reportLink } /> ); diff --git a/client/data/payment-activity/resolvers.ts b/client/data/payment-activity/resolvers.ts index 9df0602577f..64d9ade814a 100644 --- a/client/data/payment-activity/resolvers.ts +++ b/client/data/payment-activity/resolvers.ts @@ -13,7 +13,7 @@ import { __ } from '@wordpress/i18n'; */ import { NAMESPACE } from '../constants'; import { updatePaymentActivity } from './actions'; -import { PaymentActivityData, QueryDate } from './types'; +import type { PaymentActivityData, PaymentActivityQuery } from './types'; /** * Retrieves payment activity data from the reporting API. @@ -21,7 +21,7 @@ import { PaymentActivityData, QueryDate } from './types'; * @param {string} query Data on which to parameterize the selection. */ export function* getPaymentActivityData( - query: QueryDate + query: PaymentActivityQuery ): Generator< unknown > { const path = addQueryArgs( `${ NAMESPACE }/reporting/payment_activity`, diff --git a/client/data/payment-activity/selectors.ts b/client/data/payment-activity/selectors.ts index ab7a58201b7..3432c80d9fc 100644 --- a/client/data/payment-activity/selectors.ts +++ b/client/data/payment-activity/selectors.ts @@ -6,6 +6,8 @@ import { State } from 'wcpay/data/types'; import { PaymentActivityData } from './types'; -export const getPaymentActivityData = ( state: State ): PaymentActivityData => { - return state?.paymentActivity?.paymentActivityData || {}; +export const getPaymentActivityData = ( + state: State +): PaymentActivityData | undefined => { + return state?.paymentActivity?.paymentActivityData; }; diff --git a/client/data/payment-activity/test/hooks.test.ts b/client/data/payment-activity/test/hooks.test.ts index a11822f17c9..03d1d2834d7 100644 --- a/client/data/payment-activity/test/hooks.test.ts +++ b/client/data/payment-activity/test/hooks.test.ts @@ -13,6 +13,7 @@ jest.mock( '@wordpress/data' ); describe( 'usePaymentActivityData', () => { test( 'should return the correct payment activity data and loading state', () => { const mockPaymentActivityData = { + currency: 'jpy', total_payment_volume: 2500, charges: 3000, fees: 300, diff --git a/client/data/payment-activity/test/reducer.test.ts b/client/data/payment-activity/test/reducer.test.ts index b5943426212..cbbbd1eb5b2 100644 --- a/client/data/payment-activity/test/reducer.test.ts +++ b/client/data/payment-activity/test/reducer.test.ts @@ -12,6 +12,11 @@ describe( 'receivePaymentActivity', () => { fees: 300, disputes: 315, refunds: 200, + currency: 'jpy', + timezone: 'UTC', + date_start: '2024-01-01', + date_end: '2024-01-31', + interval: 'daily', }; test( 'should set payment activity data correctly', () => { diff --git a/client/data/payment-activity/types.d.ts b/client/data/payment-activity/types.d.ts index d7c4315b16e..ef388d2b899 100644 --- a/client/data/payment-activity/types.d.ts +++ b/client/data/payment-activity/types.d.ts @@ -1,11 +1,26 @@ /** @format */ export interface PaymentActivityData { - total_payment_volume?: number; // Total payment volume - charges?: number; // Charges - fees?: number; // Fees - disputes?: number; // Disputes - refunds?: number; // Refunds + /** The currency code for the amounts below, e.g. `usd` */ + currency: string; + /** Total payment volume amount */ + total_payment_volume: number; + /** Charges total amount */ + charges: number; + /** Fees total amount */ + fees: number; + /** Disputes total amount */ + disputes: number; + /** Refunds total amount */ + refunds: number; + /** The timezone used to calculate the date range, e.g. 'UTC' */ + timezone: string; + /** The date range start datetime used to calculate transaction data, e.g. 2024-04-29T16:19:29 */ + date_start: string; + /** The date range end datetime used to calculate transaction data, e.g. 2024-04-29T16:19:29 */ + date_end: string; + /** The interval used to calculate transaction data, e.g. 'daily' */ + interval: string; } export interface PaymentActivityState { @@ -18,13 +33,11 @@ export interface PaymentActivityAction { data: PaymentActivityData; } -export interface QueryDate { - date_start: string; - date_end: string; -} - export interface PaymentActivityQuery { + /** The date range start datetime used to calculate transaction data, e.g. 2024-04-29T16:19:29 */ date_start: string; + /** The date range end datetime used to calculate transaction data, e.g. 2024-04-29T16:19:29 */ date_end: string; + /** The timezone used to calculate the transaction data date range, e.g. 'UTC' */ timezone?: string; } From 0d5b2e1fb154d965d76ecd504216703eda4f60e5 Mon Sep 17 00:00:00 2001 From: Brett Shumaker Date: Tue, 30 Apr 2024 13:34:22 -0400 Subject: [PATCH 09/15] Add bnpl logos to thank you page. (#8650) Co-authored-by: Samir Merchant --- assets/css/success.css | 8 +- .../8249-add-bnpl-icons-to-thank-you-page | 4 + includes/class-wc-payment-gateway-wcpay.php | 18 ++++ .../class-wc-payments-order-success-page.php | 90 ++++++++++++++++--- includes/class-wc-payments-utils.php | 53 +++++++++++ .../class-affirm-payment-method.php | 1 + .../class-afterpay-payment-method.php | 1 + .../class-klarna-payment-method.php | 1 + .../class-upe-payment-method.php | 35 ++++++++ ...t-class-wc-payments-order-success-page.php | 9 +- tests/unit/test-class-wc-payments-utils.php | 49 ++++++++++ 11 files changed, 253 insertions(+), 16 deletions(-) create mode 100644 changelog/8249-add-bnpl-icons-to-thank-you-page diff --git a/assets/css/success.css b/assets/css/success.css index 6d5200174b0..8ada2af0ee6 100644 --- a/assets/css/success.css +++ b/assets/css/success.css @@ -1,11 +1,15 @@ -.wc-payment-gateway-method-name-woopay-wrapper { +.wc-payment-gateway-method-logo-wrapper { display: flex; align-items: center; flex-wrap: wrap; line-height: 1; } -.wc-payment-gateway-method-name-woopay-wrapper img { +.wc-payment-gateway-method-logo-wrapper img { margin-right: 0.5rem; padding-top: 4px; } + +.wc-payment-gateway-method-logo-wrapper.wc-payment-bnpl-logo img { + max-height: 30px; +} diff --git a/changelog/8249-add-bnpl-icons-to-thank-you-page b/changelog/8249-add-bnpl-icons-to-thank-you-page new file mode 100644 index 00000000000..7433d75e770 --- /dev/null +++ b/changelog/8249-add-bnpl-icons-to-thank-you-page @@ -0,0 +1,4 @@ +Significance: minor +Type: add + +Display BNPL payment method logos on the thank you page. diff --git a/includes/class-wc-payment-gateway-wcpay.php b/includes/class-wc-payment-gateway-wcpay.php index 12c72c479f3..a64817190f3 100644 --- a/includes/class-wc-payment-gateway-wcpay.php +++ b/includes/class-wc-payment-gateway-wcpay.php @@ -127,6 +127,24 @@ class WC_Payment_Gateway_WCPay extends WC_Payment_Gateway_CC { const UPE_BNPL_CLASSIC_CART_APPEARANCE_THEME_TRANSIENT = 'wcpay_upe_bnpl_classic_cart_appearance_theme'; const UPE_BNPL_CART_BLOCK_APPEARANCE_THEME_TRANSIENT = 'wcpay_upe_bnpl_cart_block_appearance_theme'; + /** + * The locations of appearance transients. + */ + const APPEARANCE_THEME_TRANSIENTS = [ + 'checkout' => [ + 'blocks' => self::WC_BLOCKS_UPE_APPEARANCE_THEME_TRANSIENT, + 'classic' => self::UPE_APPEARANCE_THEME_TRANSIENT, + ], + 'product_page' => [ + 'blocks' => self::UPE_BNPL_PRODUCT_PAGE_APPEARANCE_THEME_TRANSIENT, + 'classic' => self::UPE_BNPL_PRODUCT_PAGE_APPEARANCE_THEME_TRANSIENT, + ], + 'cart' => [ + 'blocks' => self::UPE_BNPL_CART_BLOCK_APPEARANCE_THEME_TRANSIENT, + 'classic' => self::UPE_BNPL_CLASSIC_CART_APPEARANCE_THEME_TRANSIENT, + ], + ]; + /** * Client for making requests to the WooCommerce Payments API * diff --git a/includes/class-wc-payments-order-success-page.php b/includes/class-wc-payments-order-success-page.php index 42081e2c718..323b82cf6dc 100644 --- a/includes/class-wc-payments-order-success-page.php +++ b/includes/class-wc-payments-order-success-page.php @@ -28,25 +28,25 @@ public function __construct() { */ public function register_payment_method_override() { // Override the payment method title on the order received page. - add_filter( 'woocommerce_order_get_payment_method_title', [ $this, 'show_woopay_payment_method_name' ], 10, 2 ); + add_filter( 'woocommerce_order_get_payment_method_title', [ $this, 'show_woocommerce_payments_payment_method_name' ], 10, 2 ); } /** * Remove the hook to override the payment method name on the order received page before the order summary. */ public function unregister_payment_method_override() { - remove_filter( 'woocommerce_order_get_payment_method_title', [ $this, 'show_woopay_payment_method_name' ], 10 ); + remove_filter( 'woocommerce_order_get_payment_method_title', [ $this, 'show_woocommerce_payments_payment_method_name' ], 10 ); } /** - * Add the WooPay logo and the last 4 digits of the card used to the payment method name - * on the order received page. + * Hooked into `woocommerce_order_get_payment_method_title` to change the payment method title on the + * order received page for WooPay and BNPL orders. * - * @param string $payment_method_title the default payment method title. - * @param WC_Abstract_Order $abstract_order the order being shown. + * @param string $payment_method_title Original payment method title. + * @param WC_Abstract_Order $abstract_order Successful received order being shown. + * @return string */ - public function show_woopay_payment_method_name( $payment_method_title, $abstract_order ) { - + public function show_woocommerce_payments_payment_method_name( $payment_method_title, $abstract_order ) { // Only change the payment method title on the order received page. if ( ! is_order_received_page() ) { return $payment_method_title; @@ -54,13 +54,54 @@ public function show_woopay_payment_method_name( $payment_method_title, $abstrac $order_id = $abstract_order->get_id(); $order = wc_get_order( $order_id ); - if ( ! $order || ! $order->get_meta( 'is_woopay' ) ) { + + if ( ! $order ) { + return $payment_method_title; + } + + $payment_method_id = $order->get_payment_method(); + + if ( stripos( $payment_method_id, 'woocommerce_payments' ) !== 0 ) { + return $payment_method_title; + } + + // If this is a WooPay order, return the html for the WooPay payment method name. + if ( $order->get_meta( 'is_woopay' ) ) { + return $this->show_woopay_payment_method_name( $order ); + } + + $gateway = WC()->payment_gateways()->payment_gateways()[ $payment_method_id ]; + + if ( ! is_object( $gateway ) || ! method_exists( $gateway, 'get_payment_method' ) ) { return $payment_method_title; } + $payment_method = $gateway->get_payment_method( $order ); + + // If this is a BNPL order, return the html for the BNPL payment method name. + if ( $payment_method->is_bnpl() ) { + $bnpl_output = $this->show_bnpl_payment_method_name( $gateway, $payment_method ); + + if ( $bnpl_output !== false ) { + return $bnpl_output; + } + } + + return $payment_method_title; + } + + /** + * Returns the HTML to add the WooPay logo and the last 4 digits of the card used to the + * payment method name on the order received page. + * + * @param WC_Order $order the order being shown. + * + * @return string + */ + public function show_woopay_payment_method_name( $order ) { ob_start(); ?> -
+
WooPay get_meta( 'last4' ) ) { @@ -73,6 +114,35 @@ public function show_woopay_payment_method_name( $payment_method_title, $abstrac return ob_get_clean(); } + /** + * Add the BNPL logo to the payment method name on the order received page. + * + * @param WC_Payment_Gateway_WCPay $gateway the gateway being shown. + * @param WCPay\Payment_Methods\UPE_Payment_Method $payment_method the payment method being shown. + * + * @return string|false + */ + public function show_bnpl_payment_method_name( $gateway, $payment_method ) { + $method_logo_url = apply_filters( + 'wc_payments_thank_you_page_bnpl_payment_method_logo_url', + $payment_method->get_payment_method_icon_for_location( 'checkout', false, $gateway->get_account_country() ), + $payment_method->get_id() + ); + + // If we don't have a logo URL here for some reason, bail. + if ( ! $method_logo_url ) { + return false; + } + + ob_start(); + ?> + + $contexts ) { + // We don't need to check the same location again. + if ( $location_const === $location ) { + continue; + } + + foreach ( $contexts as $context => $transient ) { + $active_theme = get_transient( $transient ); + if ( $active_theme ) { + break 2; // This will break both loops. + } + } + } + } + + // If $active_theme is still false, we don't have any theme set in the transients, so we fallback to 'stripe'. + if ( $active_theme ) { + return $active_theme; + } + + // Fallback to 'stripe' if no transients are set. + return 'stripe'; + } } diff --git a/includes/payment-methods/class-affirm-payment-method.php b/includes/payment-methods/class-affirm-payment-method.php index a51967ef3bb..f65794e555d 100644 --- a/includes/payment-methods/class-affirm-payment-method.php +++ b/includes/payment-methods/class-affirm-payment-method.php @@ -30,6 +30,7 @@ public function __construct( $token_service ) { $this->stripe_id = self::PAYMENT_METHOD_STRIPE_ID; $this->title = __( 'Affirm', 'woocommerce-payments' ); $this->is_reusable = false; + $this->is_bnpl = true; $this->icon_url = plugins_url( 'assets/images/payment-methods/affirm-logo.svg', WCPAY_PLUGIN_FILE ); $this->dark_icon_url = plugins_url( 'assets/images/payment-methods/affirm-logo-dark.svg', WCPAY_PLUGIN_FILE ); $this->currencies = [ Currency_Code::UNITED_STATES_DOLLAR, Currency_Code::CANADIAN_DOLLAR ]; diff --git a/includes/payment-methods/class-afterpay-payment-method.php b/includes/payment-methods/class-afterpay-payment-method.php index 6df0697c473..01690b64f1b 100644 --- a/includes/payment-methods/class-afterpay-payment-method.php +++ b/includes/payment-methods/class-afterpay-payment-method.php @@ -29,6 +29,7 @@ public function __construct( $token_service ) { $this->stripe_id = self::PAYMENT_METHOD_STRIPE_ID; $this->title = __( 'Afterpay', 'woocommerce-payments' ); $this->is_reusable = false; + $this->is_bnpl = true; $this->icon_url = plugins_url( 'assets/images/payment-methods/afterpay-logo.svg', WCPAY_PLUGIN_FILE ); $this->currencies = [ Currency_Code::UNITED_STATES_DOLLAR, Currency_Code::CANADIAN_DOLLAR, Currency_Code::AUSTRALIAN_DOLLAR, Currency_Code::NEW_ZEALAND_DOLLAR, Currency_Code::POUND_STERLING ]; $this->countries = [ Country_Code::UNITED_STATES, Country_Code::CANADA, Country_Code::AUSTRALIA, Country_Code::NEW_ZEALAND, Country_Code::UNITED_KINGDOM ]; diff --git a/includes/payment-methods/class-klarna-payment-method.php b/includes/payment-methods/class-klarna-payment-method.php index 2e446ead208..fa30154c226 100644 --- a/includes/payment-methods/class-klarna-payment-method.php +++ b/includes/payment-methods/class-klarna-payment-method.php @@ -30,6 +30,7 @@ public function __construct( $token_service ) { $this->stripe_id = self::PAYMENT_METHOD_STRIPE_ID; $this->title = __( 'Klarna', 'woocommerce-payments' ); $this->is_reusable = false; + $this->is_bnpl = true; $this->icon_url = plugins_url( 'assets/images/payment-methods/klarna-pill.svg', WCPAY_PLUGIN_FILE ); $this->currencies = [ Currency_Code::UNITED_STATES_DOLLAR, Currency_Code::POUND_STERLING, Currency_Code::EURO, Currency_Code::DANISH_KRONE, Currency_Code::NORWEGIAN_KRONE, Currency_Code::SWEDISH_KRONA ]; $this->accept_only_domestic_payment = true; diff --git a/includes/payment-methods/class-upe-payment-method.php b/includes/payment-methods/class-upe-payment-method.php index 2cdd1a9cb01..51d091328fd 100644 --- a/includes/payment-methods/class-upe-payment-method.php +++ b/includes/payment-methods/class-upe-payment-method.php @@ -90,6 +90,13 @@ abstract class UPE_Payment_Method { */ protected $dark_icon_url; + /** + * Is the payment method a BNPL (Buy Now Pay Later) method? + * + * @var boolean + */ + protected $is_bnpl = false; + /** * Supported customer locations for which charges for a payment method can be processed * Empty if all customer locations are supported @@ -198,6 +205,16 @@ public function is_reusable() { return $this->is_reusable; } + /** + * Returns boolean dependent on whether payment method + * will support BNPL (Buy Now Pay Later) payments + * + * @return bool + */ + public function is_bnpl() { + return $this->is_bnpl; + } + /** * Returns boolean dependent on whether payment method will accept charges * with chosen currency @@ -258,6 +275,24 @@ public function get_dark_icon( string $account_country = null ) { return isset( $this->dark_icon_url ) ? $this->dark_icon_url : $this->get_icon( $account_country ); } + /** + * Gets the theme appropriate icon for the payment method for a given location and context. + * + * @param string $location The location to get the icon for. + * @param boolean $is_blocks Whether the icon is for blocks. + * @param string $account_country Optional account country. + * @return string + */ + public function get_payment_method_icon_for_location( string $location = 'checkout', bool $is_blocks = true, string $account_country = null ) { + $appearance_theme = WC_Payments_Utils::get_active_upe_theme_transient_for_location( $location, $is_blocks ? 'blocks' : 'classic' ); + + if ( 'night' === $appearance_theme ) { + return $this->get_dark_icon( $account_country ); + } + + return $this->get_icon( $account_country ); + } + /** * Returns payment method supported countries * diff --git a/tests/unit/test-class-wc-payments-order-success-page.php b/tests/unit/test-class-wc-payments-order-success-page.php index 20c0edeaf27..df92e94a482 100644 --- a/tests/unit/test-class-wc-payments-order-success-page.php +++ b/tests/unit/test-class-wc-payments-order-success-page.php @@ -24,7 +24,7 @@ public function set_up() { public function test_show_woopay_payment_method_name_empty_order() { $method_name = 'Credit card'; - $result = $this->payments_order_success_page->show_woopay_payment_method_name( $method_name, null ); + $result = $this->payments_order_success_page->show_woocommerce_payments_payment_method_name( $method_name, null ); $this->assertSame( $method_name, $result ); } @@ -34,7 +34,7 @@ public function test_show_woopay_payment_method_name_without_woopay_meta() { $order->save(); $method_name = 'Credit card'; - $result = $this->payments_order_success_page->show_woopay_payment_method_name( $method_name, $order ); + $result = $this->payments_order_success_page->show_woocommerce_payments_payment_method_name( $method_name, $order ); $this->assertSame( $method_name, $result ); } @@ -43,13 +43,14 @@ public function test_show_woopay_payment_method_name_order_with_woopay_meta() { $order = WC_Helper_Order::create_order(); $order->add_meta_data( 'is_woopay', true ); $order->add_meta_data( 'last4', '1234' ); + $order->set_payment_method( 'woocommerce_payments' ); $order->save(); add_filter( 'woocommerce_is_order_received_page', '__return_true' ); - $result = $this->payments_order_success_page->show_woopay_payment_method_name( 'Credit card', $order ); + $result = $this->payments_order_success_page->show_woocommerce_payments_payment_method_name( 'Credit card', $order ); remove_filter( 'woocommerce_is_order_received_page', '__return_true' ); - $this->assertStringContainsString( 'wc-payment-gateway-method-name-woopay-wrapper', $result ); + $this->assertStringContainsString( 'wc-payment-gateway-method-logo-wrapper woopay', $result ); $this->assertStringContainsString( 'img alt="WooPay"', $result ); $this->assertStringContainsString( sprintf( 'Card ending in %s', $order->get_meta( 'last4' ) ), $result ); } diff --git a/tests/unit/test-class-wc-payments-utils.php b/tests/unit/test-class-wc-payments-utils.php index a1a016a4c14..27c9c8e2c3b 100644 --- a/tests/unit/test-class-wc-payments-utils.php +++ b/tests/unit/test-class-wc-payments-utils.php @@ -555,4 +555,53 @@ public function test_get_filtered_error_status_code_with_api_exception() { public function test_get_filtered_error_status_code_with_api_exception_and_402_status() { $this->assertSame( 400, WC_Payments_Utils::get_filtered_error_status_code( new \WCPay\Exceptions\API_Exception( 'Error: Your card was declined.', 'card_declined', 402 ) ) ); } + + private function delete_appearance_theme_transients( $transients ) { + foreach ( $transients as $location => $contexts ) { + foreach ( $contexts as $context => $transient ) { + delete_transient( $transient ); + } + } + } + + private function set_appearance_theme_transients( $transients ) { + foreach ( $transients as $location => $contexts ) { + foreach ( $contexts as $context => $transient ) { + set_transient( $transient, $location . '_' . $context . '_value', DAY_IN_SECONDS ); + } + } + } + + public function test_get_active_upe_theme_transient_for_location() { + $theme_transients = \WC_Payment_Gateway_WCPay::APPEARANCE_THEME_TRANSIENTS; + + // Test with no transients set. + $this->assertSame( 'stripe', WC_Payments_Utils::get_active_upe_theme_transient_for_location( 'checkout', 'blocks' ) ); + + // Set the transients. + $this->set_appearance_theme_transients( $theme_transients ); + + // Test with transients set. + // Test with invalid location. + $this->assertSame( 'checkout_blocks_value', WC_Payments_Utils::get_active_upe_theme_transient_for_location( 'invalid_location', 'blocks' ) ); + + // Test with valid location and invalid context. + $this->assertSame( 'checkout_blocks_value', WC_Payments_Utils::get_active_upe_theme_transient_for_location( 'checkout', 'invalid_context' ) ); + + // Test with valid location and context. + foreach ( $theme_transients as $location => $contexts ) { + foreach ( $contexts as $context => $transient ) { + // Our transient for the product page is the same transient for both block and classic. + if ( 'product_page' === $location ) { + $this->assertSame( 'product_page_classic_value', WC_Payments_Utils::get_active_upe_theme_transient_for_location( $location, 'blocks' ) ); + $this->assertSame( 'product_page_classic_value', WC_Payments_Utils::get_active_upe_theme_transient_for_location( $location, 'classic' ) ); + } else { + $this->assertSame( $location . '_' . $context . '_value', WC_Payments_Utils::get_active_upe_theme_transient_for_location( $location, $context ) ); + } + } + } + + // Remove the transients. + $this->delete_appearance_theme_transients( $theme_transients ); + } } From b4d4a0b89333f207ddb44c308fb5354cfa67c0fb Mon Sep 17 00:00:00 2001 From: Nagesh Pai <4162931+nagpai@users.noreply.github.com> Date: Wed, 1 May 2024 12:15:59 +0530 Subject: [PATCH 10/15] Reporting: Track events for `View report` links on Payment activity widget (#8687) Co-authored-by: Nagesh Pai Co-authored-by: Jessy Pappachan <32092402+jessy-p@users.noreply.github.com> Co-authored-by: Rua Haszard Co-authored-by: Shendy <73803630+shendy-a8c@users.noreply.github.com> --- .../add-8686-track-events-payment-activity-widget | 5 +++++ .../payment-activity/payment-activity-data.tsx | 4 ++++ .../payment-activity/payment-data-tile.tsx | 13 ++++++++++++- client/tracks/event.d.ts | 1 + 4 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 changelog/add-8686-track-events-payment-activity-widget diff --git a/changelog/add-8686-track-events-payment-activity-widget b/changelog/add-8686-track-events-payment-activity-widget new file mode 100644 index 00000000000..f5ddfd553c0 --- /dev/null +++ b/changelog/add-8686-track-events-payment-activity-widget @@ -0,0 +1,5 @@ +Significance: patch +Type: add +Comment: The PR adds track events for clicks on `View report` links on the Payment activity widget. Changes currently behind a feature flag. + + diff --git a/client/components/payment-activity/payment-activity-data.tsx b/client/components/payment-activity/payment-activity-data.tsx index 2596079ceba..d9944671434 100644 --- a/client/components/payment-activity/payment-activity-data.tsx +++ b/client/components/payment-activity/payment-activity-data.tsx @@ -94,6 +94,7 @@ const PaymentActivityData: React.FC = () => { ), filter: 'advanced', } ) } + tracksSource="total_payment_volume" isLoading={ isLoading } />
@@ -127,6 +128,7 @@ const PaymentActivityData: React.FC = () => { filter: 'advanced', type_is: 'charge', } ) } + tracksSource="charges" isLoading={ isLoading } /> { getDateRange().date_end ).format( 'YYYY-MM-DD' ), } ) } + tracksSource="refunds" isLoading={ isLoading } /> { ).format( 'YYYY-MM-DD' ), status_is: 'needs_response', } ) } + tracksSource="disputes" isLoading={ isLoading } /> = ( { @@ -51,7 +56,13 @@ const PaymentDataTile: React.FC< PaymentDataTileProps > = ( { amount = 0, isLoading = false, reportLink, + tracksSource, } ) => { + const handleReportLinkClick = () => { + recordEvent( 'wcpay_overview_payment_activity_click', { + source: tracksSource, + } ); + }; return (

@@ -71,7 +82,7 @@ const PaymentDataTile: React.FC< PaymentDataTileProps > = ( { />

{ reportLink && ( - + { __( 'View report', 'woocommerce_payments' ) } ) } diff --git a/client/tracks/event.d.ts b/client/tracks/event.d.ts index 9f605763ac7..2bdd756102f 100644 --- a/client/tracks/event.d.ts +++ b/client/tracks/event.d.ts @@ -63,6 +63,7 @@ export type Event = | 'wcpay_overview_deposits_view_history_click' | 'wcpay_overview_deposits_change_schedule_click' | 'wcpay_overview_task_click' + | 'wcpay_overview_payment_activity_click' | 'wcpay_view_submitted_evidence_clicked' | 'wcpay_settings_deposits_manage_in_stripe_click' | 'wcpay_merchant_settings_file_upload_started' From 4919b0f3baa35c452563b6b3f6779dd4379a42f5 Mon Sep 17 00:00:00 2001 From: Timur Karimov Date: Wed, 1 May 2024 17:49:08 +0200 Subject: [PATCH 11/15] Add PRBs support for `express_checkout_enabled ` settings while detecting duplicates (#8744) Co-authored-by: Timur Karimov --- .../add-third-party-plugin-support-for-duplicates-detection | 4 ++++ includes/class-duplicates-detection-service.php | 3 +++ 2 files changed, 7 insertions(+) create mode 100644 changelog/add-third-party-plugin-support-for-duplicates-detection diff --git a/changelog/add-third-party-plugin-support-for-duplicates-detection b/changelog/add-third-party-plugin-support-for-duplicates-detection new file mode 100644 index 00000000000..ea1730ed5cc --- /dev/null +++ b/changelog/add-third-party-plugin-support-for-duplicates-detection @@ -0,0 +1,4 @@ +Significance: minor +Type: update + +Add support of a third-party plugin with PRBs into duplicates detection mechanism. diff --git a/includes/class-duplicates-detection-service.php b/includes/class-duplicates-detection-service.php index abf47a4c382..b494bd213b2 100644 --- a/includes/class-duplicates-detection-service.php +++ b/includes/class-duplicates-detection-service.php @@ -150,6 +150,9 @@ private function search_for_payment_request_buttons() { } elseif ( 'yes' === $gateway->get_option( 'payment_request' ) && 'woocommerce_payments' === $gateway->id ) { $this->gateways_qualified_by_duplicates_detector[ $prb_payment_method ][] = $gateway->id; break; + } elseif ( 'yes' === $gateway->get_option( 'express_checkout_enabled' ) ) { + $this->gateways_qualified_by_duplicates_detector[ $prb_payment_method ][] = $gateway->id; + break; } } } From bf7a243eabeca51346a7fa0ca3ef0ed58e13a112 Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Wed, 1 May 2024 17:13:35 -0300 Subject: [PATCH 12/15] Fix WooPay tracks user ID for logged in users (#8690) --- ...x-woopay-tracks-userid-for-logged-in-users | 4 ++ client/tracks/index.ts | 53 +++++++++---------- 2 files changed, 30 insertions(+), 27 deletions(-) create mode 100644 changelog/fix-woopay-tracks-userid-for-logged-in-users diff --git a/changelog/fix-woopay-tracks-userid-for-logged-in-users b/changelog/fix-woopay-tracks-userid-for-logged-in-users new file mode 100644 index 00000000000..b448ea209de --- /dev/null +++ b/changelog/fix-woopay-tracks-userid-for-logged-in-users @@ -0,0 +1,4 @@ +Significance: patch +Type: fix + +Fix WooPay tracks user ID for logged in users. diff --git a/client/tracks/index.ts b/client/tracks/index.ts index 5b459fde5fa..7b07931ee5b 100644 --- a/client/tracks/index.ts +++ b/client/tracks/index.ts @@ -111,36 +111,35 @@ export const getTracksIdentity = async (): Promise< string | undefined > => { // if cookie is set, get identity from the cookie. // eslint-disable-next-line let _ui = getIdentityCookieValue(); + if ( _ui ) { + const data = { _ut: 'anon', _ui: _ui }; + return JSON.stringify( data ); + } // Otherwise get it via an Ajax request. - if ( ! _ui ) { - const nonce = - getConfig( 'platformTrackerNonce' ) ?? - getPaymentRequestData( 'nonce' )?.platform_tracker; - const ajaxUrl = - getConfig( 'ajaxUrl' ) ?? getPaymentRequestData( 'ajax_url' ); - const body = new FormData(); - - body.append( 'tracksNonce', nonce ); - body.append( 'action', 'get_identity' ); - try { - const response = await fetch( ajaxUrl, { - method: 'post', - body, - } ); - if ( ! response.ok ) { - return undefined; - } + const nonce = + getConfig( 'platformTrackerNonce' ) ?? + getPaymentRequestData( 'nonce' )?.platform_tracker; + const ajaxUrl = + getConfig( 'ajaxUrl' ) ?? getPaymentRequestData( 'ajax_url' ); + const body = new FormData(); - const data = await response.json(); - if ( data.success && data.data ) { - _ui = data.data._ui; - } else { - return undefined; - } - } catch ( error ) { + body.append( 'tracksNonce', nonce ); + body.append( 'action', 'get_identity' ); + try { + const response = await fetch( ajaxUrl, { + method: 'post', + body, + } ); + if ( ! response.ok ) { return undefined; } + + const data = await response.json(); + if ( data.success && data.data && data.data._ui && data.data._ut ) { + return JSON.stringify( data.data ); + } + return undefined; + } catch ( error ) { + return undefined; } - const data = { _ut: 'anon', _ui: _ui }; - return JSON.stringify( data ); }; From 8882064c3360ae24a4746aa5efd807af4caadf7f Mon Sep 17 00:00:00 2001 From: Ricardo Metring Date: Wed, 1 May 2024 18:25:45 -0300 Subject: [PATCH 13/15] Revert Add Multi-Currency Support to Page Caching via Cookies (#8738) --- ...4-8130-add-cookie-product-cache-per-currency | 4 ++++ includes/multi-currency/MultiCurrency.php | 17 ----------------- 2 files changed, 4 insertions(+), 17 deletions(-) create mode 100644 changelog/revert-8534-8130-add-cookie-product-cache-per-currency diff --git a/changelog/revert-8534-8130-add-cookie-product-cache-per-currency b/changelog/revert-8534-8130-add-cookie-product-cache-per-currency new file mode 100644 index 00000000000..5bcd2d09175 --- /dev/null +++ b/changelog/revert-8534-8130-add-cookie-product-cache-per-currency @@ -0,0 +1,4 @@ +Significance: minor +Type: fix + +Revert: Add Multi-Currency Support to Page Caching via Cookies. diff --git a/includes/multi-currency/MultiCurrency.php b/includes/multi-currency/MultiCurrency.php index cc279200108..c0698eddf1c 100644 --- a/includes/multi-currency/MultiCurrency.php +++ b/includes/multi-currency/MultiCurrency.php @@ -316,8 +316,6 @@ public function init() { // Update the customer currencies option after an order status change. add_action( 'woocommerce_order_status_changed', [ $this, 'maybe_update_customer_currencies_option' ] ); - $this->maybe_add_cache_cookie(); - static::$is_initialized = true; } @@ -830,8 +828,6 @@ public function update_selected_currency( string $currency_code, bool $persist_c } else { add_action( 'wp_loaded', [ $this, 'recalculate_cart' ] ); } - - $this->maybe_add_cache_cookie(); } /** @@ -1657,17 +1653,4 @@ private function log_and_throw_invalid_currency_exception( $method, $currency_co private function is_customer_currencies_data_valid( $currencies ) { return ! empty( $currencies ) && is_array( $currencies ); } - - /** - * Sets the cache cookie for currency code and exchange rate. - * - * This private method sets the 'wcpay_currency' cookie if HTTP headers - * have not been sent. This cookie stores the selected currency's code and its exchange rate, - * and is intended exclusively for caching purposes, not for application logic. - */ - private function maybe_add_cache_cookie() { - if ( ! headers_sent() && ! is_admin() && ! defined( 'DOING_CRON' ) && ! Utils::is_admin_api_request() ) { - wc_setcookie( 'wcpay_currency', sprintf( '%s_%s', $this->get_selected_currency()->get_code(), $this->get_selected_currency()->get_rate() ), time() + HOUR_IN_SECONDS ); - } - } } From dd286951ca9d385313943b4687052e0fee45ad48 Mon Sep 17 00:00:00 2001 From: Eric Jinks <3147296+Jinksi@users.noreply.github.com> Date: Thu, 2 May 2024 14:52:12 +1000 Subject: [PATCH 14/15] Allow non-account-owner admin users to submit the payment activity survey (#8739) Co-authored-by: Shendy <73803630+shendy-a8c@users.noreply.github.com> --- ...10-payment-activity-survey-all-admin-users | 5 +++ ...ass-wc-rest-payments-survey-controller.php | 39 ++++++++++--------- .../wc-payment-api/class-wc-payments-http.php | 2 +- ...ass-wc-rest-payments-survey-controller.php | 33 ++++++++++------ 4 files changed, 47 insertions(+), 32 deletions(-) create mode 100644 changelog/fix-8710-payment-activity-survey-all-admin-users diff --git a/changelog/fix-8710-payment-activity-survey-all-admin-users b/changelog/fix-8710-payment-activity-survey-all-admin-users new file mode 100644 index 00000000000..1855a4385bb --- /dev/null +++ b/changelog/fix-8710-payment-activity-survey-all-admin-users @@ -0,0 +1,5 @@ +Significance: patch +Type: fix +Comment: Part of Payment Activity Card behind feature flag. Allow non-accountholder users to submit the feedback survey. + + diff --git a/includes/admin/class-wc-rest-payments-survey-controller.php b/includes/admin/class-wc-rest-payments-survey-controller.php index fb3f53b9b40..7c8be6ae13d 100644 --- a/includes/admin/class-wc-rest-payments-survey-controller.php +++ b/includes/admin/class-wc-rest-payments-survey-controller.php @@ -98,23 +98,15 @@ public function submit_payments_overview_survey( WP_REST_Request $request ): WP_ ); } - // Jetpack connection 1.27.0 created a default value for this constant, but we're using an older version of the package - // https://github.com/Automattic/jetpack/blob/master/projects/packages/connection/CHANGELOG.md#1270---2021-05-25 - // - Connection: add the default value of JETPACK__WPCOM_JSON_API_BASE to the Connection Utils class - // this is just a patch so that we don't need to upgrade. - // as an alternative, I could have also used the `jetpack_constant_default_value` filter, but this is shorter and also provides a fallback. - defined( 'JETPACK__WPCOM_JSON_API_BASE' ) || define( 'JETPACK__WPCOM_JSON_API_BASE', 'https://public-api.wordpress.com' ); - - $wpcom_request = $this->http_client->wpcom_json_api_request_as_user( - '/marketing/survey', - '2', - [ - 'method' => 'POST', - 'headers' => [ - 'Content-Type' => 'application/json', - 'X-Forwarded-For' => \WC_Geolocation::get_ip_address(), - ], + $request_args = [ + 'url' => WC_Payments_API_Client::ENDPOINT_BASE . '/marketing/survey', + 'method' => 'POST', + 'headers' => [ + 'Content-Type' => 'application/json', + 'X-Forwarded-For' => \WC_Geolocation::get_ip_address(), ], + ]; + $request_body = wp_json_encode( [ 'site_id' => $this->http_client->get_blog_id(), 'survey_id' => 'wcpay-payment-activity', @@ -125,14 +117,23 @@ public function submit_payments_overview_survey( WP_REST_Request $request ): WP_ ], ] ); + $is_site_specific = true; + $use_user_token = true; + + $wpcom_response = $this->http_client->remote_request( + $request_args, + $request_body, + $is_site_specific, + $use_user_token + ); - $wpcom_request_body = json_decode( wp_remote_retrieve_body( $wpcom_request ) ); + $wpcom_response_status_code = wp_remote_retrieve_response_code( $wpcom_response ); - if ( ! is_wp_error( $wpcom_request ) ) { + if ( 200 === $wpcom_response_status_code ) { update_option( 'wcpay_survey_payment_overview_submitted', true ); } - return new WP_REST_Response( $wpcom_request_body, wp_remote_retrieve_response_code( $wpcom_request ) ); + return new WP_REST_Response( $wpcom_response, $wpcom_response_status_code ); } /** diff --git a/includes/wc-payment-api/class-wc-payments-http.php b/includes/wc-payment-api/class-wc-payments-http.php index ba7c6fe4a52..65081e8be10 100644 --- a/includes/wc-payment-api/class-wc-payments-http.php +++ b/includes/wc-payment-api/class-wc-payments-http.php @@ -49,7 +49,7 @@ public function init_hooks() { * @param array $args - The arguments to passed to Jetpack. * @param string $body - The body passed on to the HTTP request. * @param bool $is_site_specific - If true, the site ID will be included in the request url. Defaults to true. - * @param bool $use_user_token - If true, the request will be signed with the user token rather than blog token. Defaults to false. + * @param bool $use_user_token - If true, the request will be signed with the Jetpack connection owner user token rather than blog token. Defaults to false. * * @return array HTTP response on success. * @throws API_Exception - If not connected or request failed. diff --git a/tests/unit/admin/test-class-wc-rest-payments-survey-controller.php b/tests/unit/admin/test-class-wc-rest-payments-survey-controller.php index edc7d5aad60..cf0480ec993 100644 --- a/tests/unit/admin/test-class-wc-rest-payments-survey-controller.php +++ b/tests/unit/admin/test-class-wc-rest-payments-survey-controller.php @@ -38,7 +38,7 @@ public function setUp(): void { // Set the user so that we can pass the authentication. wp_set_current_user( 1 ); - $this->http_client_stub = $this->getMockBuilder( WC_Payments_Http::class )->disableOriginalConstructor()->setMethods( [ 'wpcom_json_api_request_as_user' ] )->getMock(); + $this->http_client_stub = $this->getMockBuilder( WC_Payments_Http::class )->disableOriginalConstructor()->setMethods( [ 'remote_request' ] )->getMock(); $this->controller = new WC_REST_Payments_Survey_Controller( $this->http_client_stub ); } @@ -63,33 +63,42 @@ public function test_empty_rating_returns_400_status_code() { $this->assertEquals( 400, $response->get_status() ); } + public function test_valid_request_forwards_data_to_jetpack() { + $request_url = WC_Payments_API_Client::ENDPOINT_BASE . '/marketing/survey'; + $this->http_client_stub ->expects( $this->any() ) - ->method( 'wpcom_json_api_request_as_user' ) + ->method( 'remote_request' ) ->with( - $this->stringContains( '/marketing/survey' ), - $this->anything(), - $this->anything(), + // Check the request argument URL is the same. + $this->callback( + function ( $argument ) use ( $request_url ) { + return $request_url === $argument['url']; + } + ), $this->logicalAnd( - $this->arrayHasKey( 'survey_id' ), - $this->arrayHasKey( 'survey_responses' ), $this->callback( function ( $argument ) { - return 'wcpay-payment-activity' === $argument['survey_id']; + $json_body = json_decode( $argument, true ); + return 'wcpay-payment-activity' === $json_body['survey_id']; } ), $this->callback( function ( $argument ) { - return 'happy' === $argument['survey_responses']['rating']; + $json_body = json_decode( $argument, true ); + return 'happy' === $json_body['survey_responses']['rating']; } ), $this->callback( function ( $argument ) { - return 'test comment' === $argument['survey_responses']['comments']['text']; + $json_body = json_decode( $argument, true ); + return 'test comment' === $json_body['survey_responses']['comments']['text']; } - ) - ) + ), + ), + $this->isTrue(), + $this->isTrue(), ) ->willReturn( [ From b6e8874d5fbc3a2f0c80d6940e0ccd17e417b607 Mon Sep 17 00:00:00 2001 From: Nagesh Pai <4162931+nagpai@users.noreply.github.com> Date: Thu, 2 May 2024 14:27:49 +0530 Subject: [PATCH 15/15] Reporting: Fix the `View report` link URL on Total payment volume tile, within Payment activity widget (#8726) Co-authored-by: Nagesh Pai Co-authored-by: Jessy Pappachan <32092402+jessy-p@users.noreply.github.com> --- changelog/fix-8706-tpv-view-report-link | 5 +++ .../payment-activity-data.tsx | 33 +++++++++++++++++-- .../test/__snapshots__/index.test.tsx.snap | 6 ++-- client/transactions/list/style.scss | 7 ++-- 4 files changed, 43 insertions(+), 8 deletions(-) create mode 100644 changelog/fix-8706-tpv-view-report-link diff --git a/changelog/fix-8706-tpv-view-report-link b/changelog/fix-8706-tpv-view-report-link new file mode 100644 index 00000000000..296aa87cf5c --- /dev/null +++ b/changelog/fix-8706-tpv-view-report-link @@ -0,0 +1,5 @@ +Significance: patch +Type: fix +Comment: Comment: Fix the `View report` link on Total payment volume tile on the Payment activity widget. Changes behind feature flag, and part of larger change that adds the Payment activity widget. + + diff --git a/client/components/payment-activity/payment-activity-data.tsx b/client/components/payment-activity/payment-activity-data.tsx index d9944671434..788f678dce0 100644 --- a/client/components/payment-activity/payment-activity-data.tsx +++ b/client/components/payment-activity/payment-activity-data.tsx @@ -23,14 +23,38 @@ import './style.scss'; */ const getDateRange = (): DateRange => { return { - // Subtract 7 days from the current date. + // Subtract 6 days from the current date. 7 days including the current day. date_start: moment() - .subtract( 7, 'd' ) + .subtract( 6, 'd' ) .format( 'YYYY-MM-DD\\THH:mm:ss' ), date_end: moment().format( 'YYYY-MM-DD\\THH:mm:ss' ), }; }; +const searchTermsForViewReportLink = { + totalPaymentVolume: [ + 'charge', + 'payment', + 'payment_failure_refund', + 'payment_refund', + 'refund', + 'refund_failure', + 'dispute', + 'dispute_reversal', + 'card_reader_fee', + ], +}; + +const getSearchParams = ( searchTerms: string[] ) => { + return searchTerms.reduce( + ( acc, term, index ) => ( { + ...acc, + [ `search[${ index }]` ]: term, + } ), + {} + ); +}; + const PaymentActivityData: React.FC = () => { const { paymentActivityData, isLoading } = usePaymentActivityData( getDateRange() @@ -86,13 +110,16 @@ const PaymentActivityData: React.FC = () => { reportLink={ getAdminUrl( { page: 'wc-admin', path: '/payments/transactions', + filter: 'advanced', 'date_between[0]': moment( getDateRange().date_start ).format( 'YYYY-MM-DD' ), 'date_between[1]': moment( getDateRange().date_end ).format( 'YYYY-MM-DD' ), - filter: 'advanced', + ...getSearchParams( + searchTermsForViewReportLink.totalPaymentVolume + ), } ) } tracksSource="total_payment_volume" isLoading={ isLoading } diff --git a/client/components/payment-activity/test/__snapshots__/index.test.tsx.snap b/client/components/payment-activity/test/__snapshots__/index.test.tsx.snap index 0b4f5e397a8..a45a33735e0 100644 --- a/client/components/payment-activity/test/__snapshots__/index.test.tsx.snap +++ b/client/components/payment-activity/test/__snapshots__/index.test.tsx.snap @@ -76,7 +76,7 @@ exports[`PaymentActivity component should render 1`] = `

View report @@ -165,7 +165,7 @@ exports[`PaymentActivity component should render 1`] = `

View report @@ -194,7 +194,7 @@ exports[`PaymentActivity component should render 1`] = `

View report diff --git a/client/transactions/list/style.scss b/client/transactions/list/style.scss index e33b7755e91..90288f81f17 100644 --- a/client/transactions/list/style.scss +++ b/client/transactions/list/style.scss @@ -121,8 +121,11 @@ $gap-small: 12px; .woocommerce-search { margin: 0 $gap; - .woocommerce-select-control__control { - height: 38px; + .components-base-control { + &.woocommerce-select-control__control { + min-height: 38px; + height: auto; + } } }