diff --git a/changelog/fix-server-5934-payment-widget-data-mismatch b/changelog/fix-server-5934-payment-widget-data-mismatch
new file mode 100644
index 00000000000..71e70f6c681
--- /dev/null
+++ b/changelog/fix-server-5934-payment-widget-data-mismatch
@@ -0,0 +1,5 @@
+Significance: patch
+Type: fix
+Comment: Make the numbers on the payment activity widget match the totals on the clicked detailed reports screen.
+
+
diff --git a/client/components/payment-activity/payment-activity-data.tsx b/client/components/payment-activity/payment-activity-data.tsx
index 09fea5b38f2..255770e587f 100644
--- a/client/components/payment-activity/payment-activity-data.tsx
+++ b/client/components/payment-activity/payment-activity-data.tsx
@@ -68,6 +68,8 @@ const PaymentActivityDataComponent: React.FC< Props > = ( {
const disputes = paymentActivityData?.disputes ?? 0;
const refunds = paymentActivityData?.refunds ?? 0;
const currency = paymentActivityData?.currency;
+ const siteTimeZone = wcSettings.admin.timeZone;
+ // We need to add a time offset to the date range to ensure the correct dates are passed on to the transactions report via the view report link.
return (
@@ -114,12 +116,12 @@ const PaymentActivityDataComponent: React.FC< Props > = ( {
path: '/payments/transactions',
filter: 'advanced',
store_currency_is: currency,
- 'date_between[0]': moment(
- paymentActivityData?.date_start
- ).format( 'YYYY-MM-DD' ),
- 'date_between[1]': moment(
- paymentActivityData?.date_end
- ).format( 'YYYY-MM-DD' ),
+ 'date_between[0]': moment( paymentActivityData?.date_start )
+ .add( siteTimeZone )
+ .format( 'YYYY-MM-DD' ),
+ 'date_between[1]': moment( paymentActivityData?.date_end )
+ .add( siteTimeZone )
+ .format( 'YYYY-MM-DD' ),
...getSearchParams(
searchTermsForViewReportLink.totalPaymentVolume
),
@@ -159,10 +161,14 @@ const PaymentActivityDataComponent: React.FC< Props > = ( {
store_currency_is: currency,
'date_between[0]': moment(
paymentActivityData?.date_start
- ).format( 'YYYY-MM-DD' ),
+ )
+ .add( siteTimeZone )
+ .format( 'YYYY-MM-DD' ),
'date_between[1]': moment(
paymentActivityData?.date_end
- ).format( 'YYYY-MM-DD' ),
+ )
+ .add( siteTimeZone )
+ .format( 'YYYY-MM-DD' ),
...getSearchParams(
searchTermsForViewReportLink.charge
),
@@ -182,10 +188,14 @@ const PaymentActivityDataComponent: React.FC< Props > = ( {
store_currency_is: currency,
'date_between[0]': moment(
paymentActivityData?.date_start
- ).format( 'YYYY-MM-DD' ),
+ )
+ .add( siteTimeZone )
+ .format( 'YYYY-MM-DD' ),
'date_between[1]': moment(
paymentActivityData?.date_end
- ).format( 'YYYY-MM-DD' ),
+ )
+ .add( siteTimeZone )
+ .format( 'YYYY-MM-DD' ),
...getSearchParams(
searchTermsForViewReportLink.refunds
),
@@ -232,10 +242,14 @@ const PaymentActivityDataComponent: React.FC< Props > = ( {
store_currency_is: currency,
'date_between[0]': moment(
paymentActivityData?.date_start
- ).format( 'YYYY-MM-DD' ),
+ )
+ .add( siteTimeZone )
+ .format( 'YYYY-MM-DD' ),
'date_between[1]': moment(
paymentActivityData?.date_end
- ).format( 'YYYY-MM-DD' ),
+ )
+ .add( siteTimeZone )
+ .format( 'YYYY-MM-DD' ),
...getSearchParams(
searchTermsForViewReportLink.dispute
),
diff --git a/client/components/payment-activity/test/index.test.tsx b/client/components/payment-activity/test/index.test.tsx
index fe3d29376de..fdba8a5a8ed 100644
--- a/client/components/payment-activity/test/index.test.tsx
+++ b/client/components/payment-activity/test/index.test.tsx
@@ -74,6 +74,11 @@ declare const global: {
country: string;
};
};
+ wcSettings: {
+ admin: {
+ timeZone: string;
+ };
+ };
};
describe( 'PaymentActivity component', () => {
@@ -118,6 +123,11 @@ describe( 'PaymentActivity component', () => {
Date.now = jest.fn( () =>
new Date( '2024-04-08T12:33:37.000Z' ).getTime()
);
+ global.wcSettings = {
+ admin: {
+ timeZone: 'UTC',
+ },
+ };
} );
afterEach( () => {
diff --git a/client/globals.d.ts b/client/globals.d.ts
index 972f0731403..ec99d1150b7 100644
--- a/client/globals.d.ts
+++ b/client/globals.d.ts
@@ -176,6 +176,7 @@ declare global {
woocommerce_coming_soon: string;
woocommerce_private_link: string;
};
+ timeZone: string;
};
adminUrl: string;
countries: Record< string, string >;
diff --git a/includes/admin/class-wc-rest-payments-reporting-controller.php b/includes/admin/class-wc-rest-payments-reporting-controller.php
index 56fce001f5e..dccc7b1a87d 100644
--- a/includes/admin/class-wc-rest-payments-reporting-controller.php
+++ b/includes/admin/class-wc-rest-payments-reporting-controller.php
@@ -6,6 +6,7 @@
*/
use WCPay\Core\Server\Request\Get_Reporting_Payment_Activity;
+use WCPay\Core\Server\Request\Request_Utils;
defined( 'ABSPATH' ) || exit;
@@ -44,11 +45,27 @@ public function register_routes() {
* @param WP_REST_Request $request The request.
*/
public function get_payment_activity( $request ) {
- $wcpay_request = Get_Reporting_Payment_Activity::create();
- $wcpay_request->set_date_start( $request->get_param( 'date_start' ) );
- $wcpay_request->set_date_end( $request->get_param( 'date_end' ) );
+ $wcpay_request = Get_Reporting_Payment_Activity::create();
+ $date_start_in_store_timezone = $this->format_date_to_wp_timezone( $request->get_param( 'date_start' ) );
+ $date_end_in_store_timezone = $this->format_date_to_wp_timezone( $request->get_param( 'date_end' ) );
+ $wcpay_request->set_date_start( $date_start_in_store_timezone );
+ $wcpay_request->set_date_end( $date_end_in_store_timezone );
$wcpay_request->set_timezone( $request->get_param( 'timezone' ) );
$wcpay_request->set_currency( $request->get_param( 'currency' ) );
return $wcpay_request->handle_rest_request();
}
+
+
+
+ /**
+ * Formats a date string to the WordPress timezone.
+ *
+ * @param string $date_string The date string to be formatted.
+ * @return string The formatted date string in the 'Y-m-d\TH:i:s' format.
+ */
+ private function format_date_to_wp_timezone( $date_string ) {
+ $date = Request_Utils::format_transaction_date_by_timezone( $date_string, '+00:00' );
+ $date = new DateTime( $date );
+ return $date->format( 'Y-m-d\\TH:i:s' );
+ }
}