diff --git a/changelog.txt b/changelog.txt
index d6ecbad8a2c..148a96e8062 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,5 +1,8 @@
*** WooPayments Changelog ***
+= 8.7.1 - 2025-01-14 =
+* Fix - Broaden billing field queries from form-scoped to document-scoped
+
= 8.7.0 - 2024-12-25 =
* Add - Add seller_message to failed order notes
* Add - Add WooPay Klaviyo newsletter integration.
diff --git a/changelog/add-2253-clickwrap-terms-and-conditions-2 b/changelog/add-2253-clickwrap-terms-and-conditions-2
new file mode 100644
index 00000000000..2a796e9a2e4
--- /dev/null
+++ b/changelog/add-2253-clickwrap-terms-and-conditions-2
@@ -0,0 +1,4 @@
+Significance: minor
+Type: add
+
+Falback terms and conditions for WooPay
diff --git a/changelog/as-fix-min-height-woopay-button b/changelog/as-fix-min-height-woopay-button
new file mode 100644
index 00000000000..ff43c088aef
--- /dev/null
+++ b/changelog/as-fix-min-height-woopay-button
@@ -0,0 +1,4 @@
+Significance: minor
+Type: fix
+
+Set a default minimum height to the WooPay button.
diff --git a/changelog/dev-10071-convert-shopper-pay-for-order-e2e-spec b/changelog/dev-10071-convert-shopper-pay-for-order-e2e-spec
new file mode 100644
index 00000000000..b6a0d24707a
--- /dev/null
+++ b/changelog/dev-10071-convert-shopper-pay-for-order-e2e-spec
@@ -0,0 +1,4 @@
+Significance: patch
+Type: dev
+
+Add the Playwright Pay for Order spec and remove the equivalent Puppeteer spec.
diff --git a/changelog/dev-5961-remove-unused-get-transaction-endpoint b/changelog/dev-5961-remove-unused-get-transaction-endpoint
new file mode 100644
index 00000000000..a6a4b299cbc
--- /dev/null
+++ b/changelog/dev-5961-remove-unused-get-transaction-endpoint
@@ -0,0 +1,4 @@
+Significance: patch
+Type: dev
+
+Removed unused get single transaction endpoint
diff --git a/changelog/fix-8549-phpcs-errors-woocommerce-commenting b/changelog/fix-8549-phpcs-errors-woocommerce-commenting
new file mode 100644
index 00000000000..051d08959ea
--- /dev/null
+++ b/changelog/fix-8549-phpcs-errors-woocommerce-commenting
@@ -0,0 +1,5 @@
+Significance: patch
+Type: dev
+Comment: Not user-facing: fix WC Commenting phpcs errors in misc files
+
+
diff --git a/changelog/fix-scope-out-billing-fields-selectors b/changelog/fix-scope-out-billing-fields-selectors
new file mode 100644
index 00000000000..2d064e70aab
--- /dev/null
+++ b/changelog/fix-scope-out-billing-fields-selectors
@@ -0,0 +1,4 @@
+Significance: minor
+Type: fix
+
+Broaden billing field queries from form-scoped to document-scoped
diff --git a/changelog/update-9971-simplify-localization-csv-export b/changelog/update-9971-simplify-localization-csv-export
new file mode 100644
index 00000000000..f7384ad3968
--- /dev/null
+++ b/changelog/update-9971-simplify-localization-csv-export
@@ -0,0 +1,4 @@
+Significance: minor
+Type: update
+
+Simplify localization of CSV exports to use user language settings from WP Admin, allowing the CSV export to match the localization of the data presented in the admin UI.
diff --git a/client/checkout/classic/event-handlers.js b/client/checkout/classic/event-handlers.js
index 2ad729113f0..4ed1912250f 100644
--- a/client/checkout/classic/event-handlers.js
+++ b/client/checkout/classic/event-handlers.js
@@ -76,7 +76,7 @@ jQuery( function ( $ ) {
} );
$checkoutForm.on( generateCheckoutEventNames(), function () {
- if ( isBillingInformationMissing( this ) ) {
+ if ( isBillingInformationMissing() ) {
return;
}
diff --git a/client/checkout/utils/test/upe.test.js b/client/checkout/utils/test/upe.test.js
index 91ad592d5cf..de5a870acc2 100644
--- a/client/checkout/utils/test/upe.test.js
+++ b/client/checkout/utils/test/upe.test.js
@@ -36,6 +36,7 @@ function buildForm( fields ) {
input.value = field.value;
form.appendChild( input );
} );
+ document.body.appendChild( form );
return form;
}
@@ -57,6 +58,11 @@ describe( 'UPE checkout utils', () => {
} );
beforeEach( () => {
+ const existingCheckoutForm = document.querySelector( 'form' );
+ if ( existingCheckoutForm ) {
+ existingCheckoutForm.remove();
+ }
+
getUPEConfig.mockImplementation( ( argument ) => {
if ( argument === 'enabledBillingFields' ) {
return {
@@ -99,7 +105,7 @@ describe( 'UPE checkout utils', () => {
} );
it( 'should return false when the billing information is not missing', () => {
- const form = buildForm( [
+ buildForm( [
{ id: 'billing_first_name', value: 'Test' },
{ id: 'billing_last_name', value: 'User' },
{ id: 'billing_email', value: 'test@example.com' },
@@ -108,11 +114,11 @@ describe( 'UPE checkout utils', () => {
{ id: 'billing_city', value: 'Anytown' },
{ id: 'billing_postcode', value: '12345' },
] );
- expect( isBillingInformationMissing( form ) ).toBe( false );
+ expect( isBillingInformationMissing() ).toBe( false );
} );
it( 'should return true when the billing information is missing', () => {
- const form = buildForm( [
+ buildForm( [
{ id: 'billing_first_name', value: 'Test' },
{ id: 'billing_last_name', value: 'User' },
{ id: 'billing_email', value: 'test@example.com' },
@@ -121,11 +127,11 @@ describe( 'UPE checkout utils', () => {
{ id: 'billing_city', value: 'Anytown' },
{ id: 'billing_postcode', value: '' },
] );
- expect( isBillingInformationMissing( form ) ).toBe( true );
+ expect( isBillingInformationMissing() ).toBe( true );
} );
it( 'should use the defaults when there is no specific locale data for a country', () => {
- const form = buildForm( [
+ buildForm( [
{ id: 'billing_first_name', value: 'Test' },
{ id: 'billing_last_name', value: 'User' },
{ id: 'billing_email', value: 'test@example.com' },
@@ -134,11 +140,11 @@ describe( 'UPE checkout utils', () => {
{ id: 'billing_city', value: 'Anytown' },
{ id: 'billing_postcode', value: '' },
] );
- expect( isBillingInformationMissing( form ) ).toBe( true );
+ expect( isBillingInformationMissing() ).toBe( true );
} );
it( 'should return false when the locale data for a country has no required fields', () => {
- const form = buildForm( [
+ buildForm( [
{ id: 'billing_first_name', value: 'Test' },
{ id: 'billing_last_name', value: 'User' },
{ id: 'billing_email', value: 'test@example.com' },
@@ -147,7 +153,7 @@ describe( 'UPE checkout utils', () => {
{ id: 'billing_city', value: 'Anytown' },
{ id: 'billing_postcode', value: '' },
] );
- expect( isBillingInformationMissing( form ) ).toBe( true );
+ expect( isBillingInformationMissing() ).toBe( true );
} );
} );
diff --git a/client/checkout/utils/upe.js b/client/checkout/utils/upe.js
index c8201ff1ba1..61bcfb71334 100644
--- a/client/checkout/utils/upe.js
+++ b/client/checkout/utils/upe.js
@@ -404,17 +404,18 @@ function getParsedLocale() {
}
}
-export const isBillingInformationMissing = ( form ) => {
+export const isBillingInformationMissing = () => {
const enabledBillingFields = getUPEConfig( 'enabledBillingFields' );
// first name and last name are kinda special - we just need one of them to be at checkout
const name = `${
- form.querySelector(
+ document.querySelector(
`#${ SHORTCODE_BILLING_ADDRESS_FIELDS.first_name }`
)?.value || ''
} ${
- form.querySelector( `#${ SHORTCODE_BILLING_ADDRESS_FIELDS.last_name }` )
- ?.value || ''
+ document.querySelector(
+ `#${ SHORTCODE_BILLING_ADDRESS_FIELDS.last_name }`
+ )?.value || ''
}`.trim();
if (
! name &&
@@ -435,14 +436,15 @@ export const isBillingInformationMissing = ( form ) => {
const country = billingFieldsToValidate.includes(
SHORTCODE_BILLING_ADDRESS_FIELDS.country
)
- ? form.querySelector( `#${ SHORTCODE_BILLING_ADDRESS_FIELDS.country }` )
- ?.value
+ ? document.querySelector(
+ `#${ SHORTCODE_BILLING_ADDRESS_FIELDS.country }`
+ )?.value
: null;
// We need to just find one field with missing information. If even only one is missing, just return early.
return Boolean(
billingFieldsToValidate.find( ( fieldName ) => {
- const field = form.querySelector( `#${ fieldName }` );
+ const field = document.querySelector( `#${ fieldName }` );
let isRequired = enabledBillingFields[ fieldName ]?.required;
const locale = getParsedLocale();
diff --git a/client/checkout/woopay/style.scss b/client/checkout/woopay/style.scss
index 349ebb18f7f..587f4fcf405 100644
--- a/client/checkout/woopay/style.scss
+++ b/client/checkout/woopay/style.scss
@@ -142,6 +142,7 @@
white-space: nowrap;
text-transform: none;
list-style-type: none;
+ min-height: auto;
&:not( :disabled ):hover {
background: #e0e0e0 !important;
diff --git a/client/components/csv-export-modal/index.tsx b/client/components/csv-export-modal/index.tsx
deleted file mode 100644
index 2cddf0908ab..00000000000
--- a/client/components/csv-export-modal/index.tsx
+++ /dev/null
@@ -1,227 +0,0 @@
-/** @format */
-/**
- * External dependencies
- */
-import React, { useState } from 'react';
-import { __ } from '@wordpress/i18n';
-import {
- Button,
- SelectControl,
- CheckboxControl,
- ExternalLink,
-} from '@wordpress/components';
-import interpolateComponents from '@automattic/interpolate-components';
-import { useDispatch } from '@wordpress/data';
-import DomainsIcon from 'gridicons/dist/domains';
-
-/**
- * Internal dependencies
- */
-import { ReportingExportLanguageHook } from 'wcpay/settings/reporting-settings/interfaces';
-import { useReportingExportLanguage, useSettings } from 'wcpay/data';
-import ConfirmationModal from 'wcpay/components/confirmation-modal';
-import { getAdminUrl, getExportLanguageOptions } from 'wcpay/utils';
-import './styles.scss';
-
-interface CSVExportModalProps {
- totalItems: number;
- exportType: 'transactions' | 'deposits' | 'disputes';
- onClose: () => void;
- onSubmit: ( language: string ) => void;
-}
-
-interface SettingsHook {
- isSaving: boolean;
- isLoading: boolean;
- saveSettings: () => void;
-}
-
-const CVSExportModal: React.FunctionComponent< CSVExportModalProps > = ( {
- totalItems,
- exportType,
- onClose,
- onSubmit,
-} ) => {
- const { updateOptions } = useDispatch( 'wc/admin/options' );
- const { saveSettings } = useSettings() as SettingsHook;
-
- const [
- exportLanguage,
- updateExportLanguage,
- ] = useReportingExportLanguage() as ReportingExportLanguageHook;
-
- const [ modalLanguage, setModalLanguage ] = useState( exportLanguage );
- const [ modalRemember, setModalRemember ] = useState( true );
-
- const onDownload = async () => {
- onSubmit( modalLanguage );
-
- // If the Remember checkbox is checked, dismiss the modal.
- if ( modalRemember ) {
- await updateOptions( {
- wcpay_reporting_export_modal_dismissed: modalRemember,
- } );
-
- updateExportLanguage( modalLanguage );
- saveSettings();
-
- wcpaySettings.reporting.exportModalDismissed = true;
- }
- };
-
- const buttonContent = (
- <>
-
-
- >
- );
-
- const getModalTitle = ( type: string ): string => {
- switch ( type ) {
- case 'transactions':
- return __(
- 'Export transactions report',
- 'woocommerce-payments'
- );
- case 'deposits':
- return __( 'Export deposits report', 'woocommerce-payments' );
- case 'disputes':
- return __( 'Export disputes report', 'woocommerce-payments' );
- default:
- return __( 'Export report', 'woocommerce-payments' );
- }
- };
-
- const getExportNumberText = ( type: string ): string => {
- switch ( type ) {
- case 'transactions':
- return __(
- 'Exporting {{total/}} transactions…',
- 'woocommerce-payments'
- );
- case 'deposits':
- return __(
- 'Exporting {{total/}} deposits…',
- 'woocommerce-payments'
- );
- case 'disputes':
- return __(
- 'Exporting {{total/}} disputes…',
- 'woocommerce-payments'
- );
- default:
- return __(
- 'Exporting {{total/}} rows…',
- 'woocommerce-payments'
- );
- }
- };
-
- const getExportLabel = ( type: string ): string => {
- switch ( type ) {
- case 'transactions':
- return __(
- 'Export transactions report in',
- 'woocommerce-payments'
- );
- case 'deposits':
- return __(
- 'Export deposits report in',
- 'woocommerce-payments'
- );
- case 'disputes':
- return __(
- 'Export disputes report in',
- 'woocommerce-payments'
- );
- default:
- return __( 'Export report in', 'woocommerce-payments' );
- }
- };
-
- const handleExportLanguageChange = ( language: string ) => {
- setModalLanguage( language );
- };
-
- const handleExportLanguageRememberChange = ( value: boolean ) => {
- setModalRemember( value );
- };
-
- return (
- {
- return false;
- } }
- >
-
- { interpolateComponents( {
- mixedString: getExportNumberText( exportType ),
- components: {
- total: { totalItems },
- },
- } ) }
-
-
-
-
Settings
-
-
-
-
-
- { getExportLabel( exportType ) }
-
-
-
-
-
-
-
-
-
- ),
- },
- } ) }
- checked={ modalRemember }
- onChange={ handleExportLanguageRememberChange }
- data-testid="export-modal-remember"
- />
-
-
-
- );
-};
-
-export default CVSExportModal;
diff --git a/client/components/csv-export-modal/styles.scss b/client/components/csv-export-modal/styles.scss
deleted file mode 100644
index 600a6d2a18a..00000000000
--- a/client/components/csv-export-modal/styles.scss
+++ /dev/null
@@ -1,51 +0,0 @@
-.reporting-export-modal {
- .components-modal__header {
- border-bottom: 1px solid #dcdcde !important;
- }
-
- .wcpay-confirmation-modal__footer {
- .is-secondary {
- box-shadow: none;
- }
- }
-
- &__items-number {
- border-bottom: 1px solid #dcdcde;
- padding: 15px 0;
- }
-
- &__settings {
- @include breakpoint( '>660px' ) {
- min-width: 500px;
- }
-
- &--language {
- display: flex;
- flex-wrap: wrap;
- }
-
- &--language-label {
- flex: 1 1 200px;
- display: flex;
-
- .domains-icon {
- width: 16px;
- margin: 7px 0;
- }
-
- .export-label {
- padding: 10px 0 0 8px;
- }
- }
-
- &--language-select {
- flex: 1 1 200px;
- }
-
- &--remember {
- p {
- padding-top: 0 !important;
- }
- }
- }
-}
diff --git a/client/components/csv-export-modal/test/__snapshots__/index.test.tsx.snap b/client/components/csv-export-modal/test/__snapshots__/index.test.tsx.snap
deleted file mode 100644
index 251b5f8438f..00000000000
--- a/client/components/csv-export-modal/test/__snapshots__/index.test.tsx.snap
+++ /dev/null
@@ -1,7 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`RefundModal it renders correctly 1`] = `
-
-`;
diff --git a/client/components/csv-export-modal/test/index.test.tsx b/client/components/csv-export-modal/test/index.test.tsx
deleted file mode 100644
index 731abf9f136..00000000000
--- a/client/components/csv-export-modal/test/index.test.tsx
+++ /dev/null
@@ -1,72 +0,0 @@
-/** @format */
-
-/**
- * External dependencies
- */
-import React from 'react';
-import { render } from '@testing-library/react';
-
-/**
- * Internal dependencies
- */
-import CVSExportModal from '..';
-import { useReportingExportLanguage, useSettings } from 'wcpay/data';
-
-declare const global: {
- wcpaySettings: {
- locale: {
- code: string;
- native_name: string;
- };
- };
-};
-
-jest.mock( '@wordpress/data', () => ( {
- useDispatch: jest.fn( () => ( { updateOptions: jest.fn() } ) ),
-} ) );
-
-jest.mock( 'wcpay/data', () => ( {
- useReportingExportLanguage: jest.fn( () => [ 'en', jest.fn() ] ),
- useSettings: jest.fn(),
-} ) );
-
-const mockUseSettings = useSettings as jest.MockedFunction<
- typeof useSettings
->;
-
-const mockUseReportingExportLanguage = useReportingExportLanguage as jest.MockedFunction<
- typeof useReportingExportLanguage
->;
-
-describe( 'RefundModal', () => {
- beforeEach( () => {
- mockUseReportingExportLanguage.mockReturnValue( [ 'en', jest.fn() ] );
-
- mockUseSettings.mockReturnValue( {
- isLoading: false,
- isDirty: false,
- isSaving: false,
- saveSettings: ( a ) => a,
- } );
-
- global.wcpaySettings = {
- locale: {
- code: 'es_ES',
- native_name: 'Spanish',
- },
- };
- } );
-
- test( 'it renders correctly', () => {
- const { container: modal } = render(
-
- );
-
- expect( modal ).toMatchSnapshot();
- } );
-} );
diff --git a/client/data/deposits/resolvers.js b/client/data/deposits/resolvers.js
index a4a0ad14e26..dd815282329 100644
--- a/client/data/deposits/resolvers.js
+++ b/client/data/deposits/resolvers.js
@@ -84,7 +84,7 @@ const formatQueryFilters = ( query ) => ( {
],
status_is: query.statusIs,
status_is_not: query.statusIsNot,
- locale: query.locale,
+ locale: query.userLocale,
} );
export function getDepositsCSV( query ) {
diff --git a/client/data/disputes/resolvers.js b/client/data/disputes/resolvers.js
index ce748a46562..ccc72c001f3 100644
--- a/client/data/disputes/resolvers.js
+++ b/client/data/disputes/resolvers.js
@@ -38,7 +38,7 @@ const formatQueryFilters = ( query ) => ( {
: query.search,
status_is: query.statusIs,
status_is_not: query.statusIsNot,
- locale: query.locale,
+ locale: query.userLocale,
} );
export function getDisputesCSV( query ) {
diff --git a/client/data/settings/actions.js b/client/data/settings/actions.js
index 6a2e315657c..93fb135fc7a 100644
--- a/client/data/settings/actions.js
+++ b/client/data/settings/actions.js
@@ -204,12 +204,6 @@ export function updateDepositScheduleMonthlyAnchor(
} );
}
-export function updateExportLanguage( language ) {
- return updateSettingsValues( {
- reporting_export_language: language,
- } );
-}
-
export function* saveSettings() {
let error = null;
try {
diff --git a/client/data/settings/hooks.js b/client/data/settings/hooks.js
index 873cc22a1ea..659249b9a62 100644
--- a/client/data/settings/hooks.js
+++ b/client/data/settings/hooks.js
@@ -265,16 +265,6 @@ export const useDepositScheduleMonthlyAnchor = () => {
return [ depositScheduleMonthlyAnchor, updateDepositScheduleMonthlyAnchor ];
};
-export const useReportingExportLanguage = () => {
- const { updateExportLanguage } = useDispatch( STORE_NAME );
-
- const exportLanguage = useSelect( ( select ) =>
- select( STORE_NAME ).getExportLanguage()
- );
-
- return [ exportLanguage, updateExportLanguage ];
-};
-
export const useDepositDelayDays = () =>
useSelect( ( select ) => select( STORE_NAME ).getDepositDelayDays(), [] );
diff --git a/client/data/settings/selectors.js b/client/data/settings/selectors.js
index 16cd1b4ec55..f36f402527a 100644
--- a/client/data/settings/selectors.js
+++ b/client/data/settings/selectors.js
@@ -121,10 +121,6 @@ export const getDepositScheduleInterval = ( state ) => {
return getSettings( state ).deposit_schedule_interval || '';
};
-export const getExportLanguage = ( state ) => {
- return getSettings( state ).reporting_export_language || '';
-};
-
export const getDepositScheduleWeeklyAnchor = ( state ) => {
return getSettings( state ).deposit_schedule_weekly_anchor || '';
};
diff --git a/client/data/transactions/resolvers.js b/client/data/transactions/resolvers.js
index 8ca3b5973ae..9bcefa2ce56 100644
--- a/client/data/transactions/resolvers.js
+++ b/client/data/transactions/resolvers.js
@@ -58,7 +58,7 @@ export const formatQueryFilters = ( query ) => ( {
source_is_not: query.sourceIsNot,
search: query.search,
user_timezone: getUserTimeZone(),
- locale: query.locale,
+ locale: query.userLocale,
} );
/**
diff --git a/client/deposits/list/index.tsx b/client/deposits/list/index.tsx
index 52194cb184f..9d01ca4e853 100644
--- a/client/deposits/list/index.tsx
+++ b/client/deposits/list/index.tsx
@@ -23,7 +23,6 @@ import { parseInt } from 'lodash';
*/
import type { DepositsTableHeader } from 'wcpay/types/deposits';
import { useDeposits, useDepositsSummary } from 'wcpay/data';
-import { useReportingExportLanguage } from 'data/index';
import { displayType, depositStatusLabels } from '../strings';
import {
formatExplicitCurrency,
@@ -37,13 +36,6 @@ import DownloadButton from 'components/download-button';
import { getDepositsCSV } from 'wcpay/data/deposits/resolvers';
import { applyThousandSeparator } from '../../utils/index.js';
import DepositStatusChip from 'components/deposit-status-chip';
-import {
- isExportModalDismissed,
- getExportLanguage,
- isDefaultSiteLanguage,
-} from 'utils';
-import CSVExportModal from 'components/csv-export-modal';
-import { ReportingExportLanguageHook } from 'wcpay/settings/reporting-settings/interfaces';
import './style.scss';
import { formatDateTimeFromString } from 'wcpay/utils/date-time';
@@ -104,10 +96,6 @@ const getColumns = ( sortByDate?: boolean ): DepositsTableHeader[] => [
];
export const DepositsList = (): JSX.Element => {
- const [
- exportLanguage,
- ] = useReportingExportLanguage() as ReportingExportLanguageHook;
-
const [ isDownloading, setIsDownloading ] = useState( false );
const { createNotice } = useDispatch( 'core/notices' );
const { deposits, isLoading } = useDeposits( getQuery() );
@@ -115,8 +103,6 @@ export const DepositsList = (): JSX.Element => {
getQuery()
);
- const [ isCSVExportModalOpen, setCSVExportModalOpen ] = useState( false );
-
const sortByDate = ! getQuery().orderby || 'date' === getQuery().orderby;
const columns = useMemo( () => getColumns( sortByDate ), [ sortByDate ] );
const totalRows = depositsSummary.count || 0;
@@ -220,12 +206,9 @@ export const DepositsList = (): JSX.Element => {
const downloadable = !! rows.length;
- const endpointExport = async ( language: string ) => {
- // We destructure page and path to get the right params.
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- const { page, path, ...params } = getQuery();
+ const endpointExport = async () => {
const userEmail = wcpaySettings.currentUserEmail;
- const locale = getExportLanguage( language, exportLanguage );
+ const userLocale = wcpaySettings.userLocale.code;
const {
date_before: dateBefore,
@@ -268,7 +251,7 @@ export const DepositsList = (): JSX.Element => {
} >( {
path: getDepositsCSV( {
userEmail,
- locale,
+ userLocale,
dateAfter,
dateBefore,
dateBetween,
@@ -313,11 +296,7 @@ export const DepositsList = (): JSX.Element => {
const downloadType = totalRows > rows.length ? 'endpoint' : 'browser';
if ( 'endpoint' === downloadType ) {
- if ( ! isDefaultSiteLanguage() && ! isExportModalDismissed() ) {
- setCSVExportModalOpen( true );
- } else {
- endpointExport( '' );
- }
+ endpointExport();
} else {
const params = getQuery();
@@ -353,16 +332,6 @@ export const DepositsList = (): JSX.Element => {
setIsDownloading( false );
};
- const closeModal = () => {
- setCSVExportModalOpen( false );
- };
-
- const exportDeposits = ( language: string ) => {
- endpointExport( language );
-
- closeModal();
- };
-
return (
@@ -387,16 +356,6 @@ export const DepositsList = (): JSX.Element => {
),
] }
/>
- { ! isDefaultSiteLanguage() &&
- ! isExportModalDismissed() &&
- isCSVExportModalOpen && (
-
- ) }
);
};
diff --git a/client/deposits/list/test/index.tsx b/client/deposits/list/test/index.tsx
index ee2077da8f9..a36d41c5c20 100644
--- a/client/deposits/list/test/index.tsx
+++ b/client/deposits/list/test/index.tsx
@@ -14,11 +14,7 @@ import os from 'os';
* Internal dependencies
*/
import { DepositsList } from '../';
-import {
- useDeposits,
- useDepositsSummary,
- useReportingExportLanguage,
-} from 'wcpay/data';
+import { useDeposits, useDepositsSummary } from 'wcpay/data';
import { getUnformattedAmount } from 'wcpay/utils/test-utils';
import {
CachedDeposit,
@@ -30,7 +26,6 @@ import React from 'react';
jest.mock( 'wcpay/data', () => ( {
useDeposits: jest.fn(),
useDepositsSummary: jest.fn(),
- useReportingExportLanguage: jest.fn( () => [ 'en', jest.fn() ] ),
} ) );
jest.mock( '@woocommerce/csv-export', () => {
@@ -85,10 +80,10 @@ declare const global: {
connect: {
country: string;
};
- reporting?: {
- exportModalDismissed: boolean;
- };
dateFormat: string;
+ userLocale: {
+ code: string;
+ };
};
};
@@ -122,10 +117,6 @@ const mockDownloadCSVFile = downloadCSVFile as jest.MockedFunction<
typeof downloadCSVFile
>;
-const mockUseReportingExportLanguage = useReportingExportLanguage as jest.MockedFunction<
- typeof useReportingExportLanguage
->;
-
describe( 'Deposits list', () => {
beforeEach( () => {
jest.clearAllMocks();
@@ -133,8 +124,6 @@ describe( 'Deposits list', () => {
// the query string is preserved across tests, so we need to reset it
updateQueryString( {}, '/', {} );
- mockUseReportingExportLanguage.mockReturnValue( [ 'en', jest.fn() ] );
-
global.wcpaySettings = {
zeroDecimalCurrencies: [],
connect: {
@@ -151,10 +140,10 @@ describe( 'Deposits list', () => {
precision: 2,
},
},
- reporting: {
- exportModalDismissed: true,
- },
dateFormat: 'M j Y',
+ userLocale: {
+ code: 'en',
+ },
};
} );
diff --git a/client/disputes/index.tsx b/client/disputes/index.tsx
index ad5e8258d7f..77aeec36712 100644
--- a/client/disputes/index.tsx
+++ b/client/disputes/index.tsx
@@ -23,11 +23,7 @@ import NoticeOutlineIcon from 'gridicons/dist/notice-outline';
/**
* Internal dependencies.
*/
-import {
- useDisputes,
- useDisputesSummary,
- useReportingExportLanguage,
-} from 'data/index';
+import { useDisputes, useDisputesSummary } from 'data/index';
import OrderLink from 'components/order-link';
import DisputeStatusChip from 'components/dispute-status-chip';
import ClickableCell from 'components/clickable-cell';
@@ -45,16 +41,9 @@ import DownloadButton from 'components/download-button';
import disputeStatusMapping from 'components/dispute-status-chip/mappings';
import { CachedDispute, DisputesTableHeader } from 'wcpay/types/disputes';
import { getDisputesCSV } from 'wcpay/data/disputes/resolvers';
-import {
- applyThousandSeparator,
- isExportModalDismissed,
- getExportLanguage,
- isDefaultSiteLanguage,
-} from 'wcpay/utils';
+import { applyThousandSeparator } from 'wcpay/utils';
import { useSettings } from 'wcpay/data';
import { isAwaitingResponse } from 'wcpay/disputes/utils';
-import CSVExportModal from 'components/csv-export-modal';
-import { ReportingExportLanguageHook } from 'wcpay/settings/reporting-settings/interfaces';
import DateFormatNotice from 'wcpay/components/date-format-notice';
import './style.scss';
import { formatDateTimeFromString } from 'wcpay/utils/date-time';
@@ -218,12 +207,6 @@ export const DisputesList = (): JSX.Element => {
getQuery()
);
- const [ isCSVExportModalOpen, setCSVExportModalOpen ] = useState( false );
-
- const [
- exportLanguage,
- ] = useReportingExportLanguage() as ReportingExportLanguageHook;
-
const headers = getHeaders( getQuery().orderby );
const totalRows = disputesSummary.count || 0;
@@ -358,13 +341,13 @@ export const DisputesList = (): JSX.Element => {
const downloadable = !! rows.length;
- const endpointExport = async ( language: string ) => {
+ const endpointExport = async () => {
// We destructure page and path to get the right params.
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { page, path, ...params } = getQuery();
const userEmail = wcpaySettings.currentUserEmail;
- const locale = getExportLanguage( language, exportLanguage );
+ const userLocale = wcpaySettings.userLocale.code;
const {
date_before: dateBefore,
date_after: dateAfter,
@@ -405,7 +388,7 @@ export const DisputesList = (): JSX.Element => {
} >( {
path: getDisputesCSV( {
userEmail,
- locale,
+ userLocale,
dateAfter,
dateBefore,
dateBetween,
@@ -451,11 +434,7 @@ export const DisputesList = (): JSX.Element => {
const downloadType = totalRows > rows.length ? 'endpoint' : 'browser';
if ( 'endpoint' === downloadType ) {
- if ( ! isDefaultSiteLanguage() && ! isExportModalDismissed() ) {
- setCSVExportModalOpen( true );
- } else {
- endpointExport( '' );
- }
+ endpointExport();
} else {
const csvColumns = [
{
@@ -543,16 +522,6 @@ export const DisputesList = (): JSX.Element => {
disputesSummary.currencies ||
( isCurrencyFiltered ? [ getQuery().store_currency_is ?? '' ] : [] );
- const closeModal = () => {
- setCSVExportModalOpen( false );
- };
-
- const exportDisputes = ( language: string ) => {
- endpointExport( language );
-
- closeModal();
- };
-
return (
@@ -579,16 +548,6 @@ export const DisputesList = (): JSX.Element => {
),
] }
/>
- { ! isDefaultSiteLanguage() &&
- ! isExportModalDismissed() &&
- isCSVExportModalOpen && (
-
- ) }
);
};
diff --git a/client/disputes/test/index.tsx b/client/disputes/test/index.tsx
index 37bbd2e93af..d01c0b4e4fa 100644
--- a/client/disputes/test/index.tsx
+++ b/client/disputes/test/index.tsx
@@ -11,12 +11,7 @@ import os from 'os';
* Internal dependencies
*/
import DisputesList from '..';
-import {
- useDisputes,
- useDisputesSummary,
- useReportingExportLanguage,
- useSettings,
-} from 'data/index';
+import { useDisputes, useDisputesSummary, useSettings } from 'data/index';
import { getUnformattedAmount } from 'wcpay/utils/test-utils';
import React from 'react';
import {
@@ -55,7 +50,6 @@ jest.mock( '@wordpress/data', () => ( {
jest.mock( 'data/index', () => ( {
useDisputes: jest.fn(),
useDisputesSummary: jest.fn(),
- useReportingExportLanguage: jest.fn( () => [ 'en', jest.fn() ] ),
useSettings: jest.fn(),
} ) );
@@ -77,10 +71,6 @@ const mockUseSettings = useSettings as jest.MockedFunction<
typeof useSettings
>;
-const mockUseReportingExportLanguage = useReportingExportLanguage as jest.MockedFunction<
- typeof useReportingExportLanguage
->;
-
declare const global: {
wcpaySettings: {
zeroDecimalCurrencies: string[];
@@ -98,11 +88,11 @@ declare const global: {
precision: number;
};
};
- reporting?: {
- exportModalDismissed: boolean;
- };
dateFormat?: string;
timeFormat?: string;
+ userLocale: {
+ code: string;
+ };
};
};
@@ -173,8 +163,6 @@ describe( 'Disputes list', () => {
new Date( '2019-11-07T12:33:37.000Z' ).getTime()
);
- mockUseReportingExportLanguage.mockReturnValue( [ 'en', jest.fn() ] );
-
mockUseSettings.mockReturnValue( {
isLoading: false,
isSaving: false,
@@ -198,11 +186,11 @@ describe( 'Disputes list', () => {
precision: 2,
},
},
- reporting: {
- exportModalDismissed: true,
- },
dateFormat: 'Y-m-d',
timeFormat: 'g:iA',
+ userLocale: {
+ code: 'en',
+ },
};
} );
diff --git a/client/globals.d.ts b/client/globals.d.ts
index 482b6a436d7..8335f711516 100644
--- a/client/globals.d.ts
+++ b/client/globals.d.ts
@@ -123,12 +123,26 @@ declare global {
isNextDepositNoticeDismissed: boolean;
isInstantDepositNoticeDismissed: boolean;
isDateFormatNoticeDismissed: boolean;
- reporting: {
- exportModalDismissed?: boolean;
- };
- locale: {
+ userLocale: {
+ /**
+ * The locale of the current user profile, represented as a locale code supported by transact-platform-server.
+ *
+ * @example 'es' // Spanish
+ *
+ * @see WC_Payments_Utils::convert_locale_to_language_code
+ */
code: string;
+ /**
+ * The English name of the locale.
+ *
+ * @example 'Spanish'
+ */
english_name: string;
+ /**
+ * The native name of the locale.
+ *
+ * @example 'Español'
+ */
native_name: string;
};
trackingInfo?: {
@@ -188,6 +202,20 @@ declare global {
adminUrl: string;
countries: Record< string, string >;
homeUrl: string;
+ locale: {
+ /**
+ * The locale of the current site, as set in WP Admin → Settings → General.
+ *
+ * @example 'en_AU' // English (Australia)
+ */
+ siteLocale: string;
+ /**
+ * The locale of the current user profile, as set in WP Admin → Users → Profile → Language.
+ *
+ * @example 'en_UK' // English (United Kingdom)
+ */
+ userLocale: string;
+ };
siteTitle: string;
};
diff --git a/client/settings/reporting-settings/components/export-language/index.tsx b/client/settings/reporting-settings/components/export-language/index.tsx
deleted file mode 100644
index 950d43f5584..00000000000
--- a/client/settings/reporting-settings/components/export-language/index.tsx
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * External dependencies
- */
-import React from 'react';
-import { __ } from '@wordpress/i18n';
-import { addQueryArgs } from '@wordpress/url';
-import { SelectControl, ExternalLink } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import interpolateComponents from '@automattic/interpolate-components';
-import { ReportingExportLanguageHook } from '../../interfaces';
-import { useReportingExportLanguage } from 'wcpay/data';
-import { getExportLanguageOptions } from 'wcpay/utils';
-
-const ExportLanguage: React.FC = () => {
- const [
- exportLanguage,
- updateExportLanguage,
- ] = useReportingExportLanguage() as ReportingExportLanguageHook;
-
- const handleExportLanguageChange = ( language: string ) => {
- updateExportLanguage( language );
- };
-
- return (
-
-
-
- { interpolateComponents( {
- mixedString: __(
- 'You can change your global site language preferences in {{learnMoreLink}}General Settings{{/learnMoreLink}}.',
- 'woocommerce-payments'
- ),
- components: {
- learnMoreLink: (
- // eslint-disable-next-line max-len
-
- ),
- },
- } ) }
-
-
- );
-};
-
-export default ExportLanguage;
diff --git a/client/settings/reporting-settings/components/index.ts b/client/settings/reporting-settings/components/index.ts
deleted file mode 100644
index 3c3360bd22a..00000000000
--- a/client/settings/reporting-settings/components/index.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * Internal dependencies
- */
-import ExportLanguage from './export-language';
-
-export { ExportLanguage };
diff --git a/client/settings/reporting-settings/index.tsx b/client/settings/reporting-settings/index.tsx
deleted file mode 100644
index 9e2ee4a0178..00000000000
--- a/client/settings/reporting-settings/index.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * External dependencies
- */
-import React from 'react';
-import { __ } from '@wordpress/i18n';
-import { Card } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import CardBody from '../card-body';
-import { ExportLanguage } from './components';
-import './style.scss';
-
-const Reporting: React.FC = () => {
- return (
- <>
-
-
-
-
- { __(
- 'Report exporting default language',
- 'woocommerce-payments'
- ) }
-
-
-
-
-
- >
- );
-};
-
-export default Reporting;
diff --git a/client/settings/reporting-settings/interfaces.ts b/client/settings/reporting-settings/interfaces.ts
deleted file mode 100644
index 22f37cb1e7b..00000000000
--- a/client/settings/reporting-settings/interfaces.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export type ReportingExportLanguageHook = [
- string,
- ( language: string ) => void
-];
diff --git a/client/settings/reporting-settings/style.scss b/client/settings/reporting-settings/style.scss
deleted file mode 100644
index 354c2530e61..00000000000
--- a/client/settings/reporting-settings/style.scss
+++ /dev/null
@@ -1,17 +0,0 @@
-.reporting-settings {
- &__text--help-text {
- font-size: 12px;
- color: #757575;
- margin: 0;
- display: inline-block;
- }
-
- .reporting-export-language {
- flex-wrap: wrap;
- margin-bottom: 0;
- .components-select-control {
- padding-right: 16px;
- margin-bottom: 0;
- }
- }
-}
diff --git a/client/settings/reporting-settings/test/__snapshots__/index.test.js.snap b/client/settings/reporting-settings/test/__snapshots__/index.test.js.snap
deleted file mode 100644
index aef73119cb9..00000000000
--- a/client/settings/reporting-settings/test/__snapshots__/index.test.js.snap
+++ /dev/null
@@ -1,151 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Reporting Settings should render correctly 1`] = `
-
-
-
-
-
-
- Report exporting default language
-
-
-
-
-
-
-
-
-
-`;
diff --git a/client/settings/reporting-settings/test/index.test.js b/client/settings/reporting-settings/test/index.test.js
deleted file mode 100644
index ef0a2437145..00000000000
--- a/client/settings/reporting-settings/test/index.test.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * External dependencies
- */
-import { render, screen, within } from '@testing-library/react';
-
-/**
- * Internal dependencies
- */
-import Reporting from '..';
-import { useReportingExportLanguage } from 'wcpay/data';
-
-jest.mock( '@wordpress/data' );
-
-jest.mock( 'wcpay/data', () => ( {
- useReportingExportLanguage: jest.fn(),
-} ) );
-
-describe( 'Reporting Settings', () => {
- beforeEach( () => {
- useReportingExportLanguage.mockReturnValue( [ 'en_US', jest.fn() ] );
-
- global.wcpaySettings = {
- locale: {
- code: 'es_ES',
- native_name: 'Spanish',
- },
- };
- } );
-
- it( 'should render correctly', () => {
- const { container } = render( );
- expect( container ).toMatchSnapshot();
-
- expect(
- screen.getByText( /Report exporting default language/ )
- ).toBeInTheDocument();
- expect(
- screen.getByText(
- /You can change your global site language preferences/
- )
- ).toBeInTheDocument();
- } );
-
- it( 'renders the language select', () => {
- render( );
-
- const languageSelect = screen.getByLabelText( /Language/ );
- expect( languageSelect ).toHaveValue( 'en_US' );
-
- within( languageSelect ).getByRole( 'option', { name: /English/ } );
- within( languageSelect ).getByRole( 'option', {
- name: /Site Language - Spanish/,
- } );
- } );
-} );
diff --git a/client/settings/settings-manager/index.js b/client/settings/settings-manager/index.js
index fc238c706b2..3da257c9074 100644
--- a/client/settings/settings-manager/index.js
+++ b/client/settings/settings-manager/index.js
@@ -14,7 +14,6 @@ import AdvancedSettings from '../advanced-settings';
import ExpressCheckout from '../express-checkout';
import SettingsSection from '../settings-section';
import GeneralSettings from '../general-settings';
-import ReportingSettings from '../reporting-settings';
import SettingsLayout from '../settings-layout';
import SaveSettingsSection from '../save-settings-section';
import Transactions from '../transactions';
@@ -29,7 +28,6 @@ import {
useSettings,
} from '../../data';
import FraudProtection from '../fraud-protection';
-import { isDefaultSiteLanguage } from 'wcpay/utils';
import DuplicatedPaymentMethodsContext from './duplicated-payment-methods-context';
const ExpressCheckoutDescription = () => (
@@ -124,20 +122,6 @@ const FraudProtectionDescription = () => {
);
};
-const ReportingDescription = () => {
- return (
- <>
- { __( 'Reporting', 'woocommerce-payments' ) }
-
- { __(
- 'Adjust your report exporting language preferences.',
- 'woocommerce-payments'
- ) }
-
- >
- );
-};
-
const AdvancedDescription = () => {
return (
<>
@@ -260,18 +244,6 @@ const SettingsManager = () => {
- { ! isDefaultSiteLanguage() && (
-
-
-
-
-
-
-
- ) }
getColumns(
@@ -600,14 +582,14 @@ export const TransactionsList = (
const downloadable = !! rows.length;
- const endpointExport = async ( language: string ) => {
+ const endpointExport = async () => {
const downloadType = totalRows > rows.length ? 'async' : 'sync';
// We destructure page and path to get the right params.
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { page, path, ...params } = getQuery();
const userEmail = wcpaySettings.currentUserEmail;
- const locale = getExportLanguage( language, exportLanguage );
+ const userLocale = wcpaySettings.userLocale.code;
const {
date_after: dateAfter,
date_before: dateBefore,
@@ -667,7 +649,7 @@ export const TransactionsList = (
const response = await apiFetch< TransactionExportResponse >( {
path: getTransactionsCSV( {
userEmail,
- locale,
+ userLocale,
dateAfter,
dateBefore,
dateBetween,
@@ -736,11 +718,7 @@ export const TransactionsList = (
total_transactions: transactionsSummary.count,
} );
- if ( ! isDefaultSiteLanguage() && ! isExportModalDismissed() ) {
- setCSVExportModalOpen( true );
- } else {
- endpointExport( '' );
- }
+ endpointExport();
setIsDownloading( false );
};
@@ -812,16 +790,6 @@ export const TransactionsList = (
}
}
- const closeModal = () => {
- setCSVExportModalOpen( false );
- };
-
- const exportTransactions = ( language: string ) => {
- endpointExport( language );
-
- closeModal();
- };
-
const showFilters = ! props.depositId;
const storeCurrencies =
transactionsSummary.store_currencies ||
@@ -874,17 +842,6 @@ export const TransactionsList = (
),
] }
/>
-
- { ! isDefaultSiteLanguage() &&
- ! isExportModalDismissed() &&
- isCSVExportModalOpen && (
-
- ) }
);
};
diff --git a/client/transactions/list/test/index.tsx b/client/transactions/list/test/index.tsx
index 0c191b8c1d0..ed826c029d1 100644
--- a/client/transactions/list/test/index.tsx
+++ b/client/transactions/list/test/index.tsx
@@ -14,11 +14,7 @@ import { getUserTimeZone } from 'wcpay/utils/test-utils';
* Internal dependencies
*/
import { TransactionsList } from '../';
-import {
- useTransactions,
- useTransactionsSummary,
- useReportingExportLanguage,
-} from 'data/index';
+import { useTransactions, useTransactionsSummary } from 'data/index';
import type { Transaction } from 'data/transactions/hooks';
jest.mock( '@wordpress/api-fetch', () => jest.fn() );
@@ -42,7 +38,6 @@ jest.mock( '@wordpress/data', () => ( {
jest.mock( 'data/index', () => ( {
useTransactions: jest.fn(),
useTransactionsSummary: jest.fn(),
- useReportingExportLanguage: jest.fn( () => [ 'en', jest.fn() ] ),
} ) );
// Mock dateI18n
@@ -64,10 +59,6 @@ const mockUseTransactionsSummary = useTransactionsSummary as jest.MockedFunction
typeof useTransactionsSummary
>;
-const mockUseReportingExportLanguage = useReportingExportLanguage as jest.MockedFunction<
- typeof useReportingExportLanguage
->;
-
declare const global: {
wcpaySettings: {
isSubscriptionsActive: boolean;
@@ -89,8 +80,8 @@ declare const global: {
precision: number;
};
};
- reporting?: {
- exportModalDismissed: boolean;
+ userLocale: {
+ code: string;
};
};
};
@@ -198,8 +189,6 @@ describe( 'Transactions list', () => {
// the query string is preserved across tests, so we need to reset it
updateQueryString( {}, '/', {} );
- mockUseReportingExportLanguage.mockReturnValue( [ 'en', jest.fn() ] );
-
global.wcpaySettings = {
featureFlags: {
customSearch: true,
@@ -220,8 +209,8 @@ describe( 'Transactions list', () => {
precision: 2,
},
},
- reporting: {
- exportModalDismissed: true,
+ userLocale: {
+ code: 'en',
},
};
window.wcpaySettings.dateFormat = 'M j, Y';
diff --git a/client/transactions/test/index.tsx b/client/transactions/test/index.tsx
index 9eae004fd90..1a979376127 100644
--- a/client/transactions/test/index.tsx
+++ b/client/transactions/test/index.tsx
@@ -18,7 +18,6 @@ import {
useSettings,
useTransactions,
useTransactionsSummary,
- useReportingExportLanguage,
} from 'data/index';
jest.mock( '@wordpress/api-fetch', () => jest.fn() );
@@ -46,7 +45,6 @@ jest.mock( 'data/index', () => ( {
useManualCapture: jest.fn(),
useSettings: jest.fn(),
useAuthorizationsSummary: jest.fn(),
- useReportingExportLanguage: jest.fn( () => [ 'en', jest.fn() ] ),
} ) );
const mockUseTransactions = useTransactions as jest.MockedFunction<
@@ -73,10 +71,6 @@ const mockUseFraudOutcomeTransactionsSummary = useFraudOutcomeTransactionsSummar
typeof useFraudOutcomeTransactionsSummary
>;
-const mockUseReportingExportLanguage = useReportingExportLanguage as jest.MockedFunction<
- typeof useReportingExportLanguage
->;
-
declare const global: {
wcpaySettings: {
featureFlags: {
@@ -97,8 +91,6 @@ describe( 'TransactionsPage', () => {
beforeEach( () => {
jest.clearAllMocks();
- mockUseReportingExportLanguage.mockReturnValue( [ 'en', jest.fn() ] );
-
// the query string is preserved across tests, so we need to reset it
updateQueryString( {}, '/', {} );
diff --git a/client/utils/index.js b/client/utils/index.js
index c642c1034e1..99f7f96f3e5 100644
--- a/client/utils/index.js
+++ b/client/utils/index.js
@@ -7,7 +7,6 @@ import moment from 'moment';
import { dateI18n } from '@wordpress/date';
import { NAMESPACE } from 'wcpay/data/constants';
import { numberFormat } from '@woocommerce/number';
-import { __ } from '@wordpress/i18n';
/**
* Returns whether a value is an object.
@@ -237,80 +236,6 @@ export const applyThousandSeparator = ( trxCount ) => {
return formattedNumber( trxCount );
};
-/**
- * Returns true if Export Modal is dismissed, false otherwise.
- *
- * @return {boolean} True if dismissed, false otherwise.
- */
-export const isExportModalDismissed = () => {
- if ( typeof wcpaySettings === 'undefined' ) {
- return true;
- }
-
- return wcpaySettings?.reporting?.exportModalDismissed ?? false;
-};
-
-/**
- * Returns true if Export Modal is dismissed, false otherwise.
- *
- * @return {boolean} True if dismissed, false otherwise.
- */
-
-export const isDefaultSiteLanguage = () => {
- if ( typeof wcpaySettings === 'undefined' ) {
- return true;
- }
-
- return wcpaySettings.locale?.code === 'en_US';
-};
-
-/**
- * Returns the language code for CSV exports.
- *
- * @param {string} language Selected language code.
- * @param {string} storedLanguage Stored language code.
- *
- * @return {string} Language code.
- */
-export const getExportLanguage = ( language, storedLanguage ) => {
- let siteLanguage = 'en_US';
-
- // If the default site language is en_US, skip
- if ( isDefaultSiteLanguage() ) {
- return siteLanguage;
- }
-
- if ( typeof wcpaySettings !== 'undefined' ) {
- siteLanguage = wcpaySettings?.locale?.code ?? siteLanguage;
- }
-
- // In case the default export setting is not present, use the site locale.
- const defaultLanguage = storedLanguage ?? siteLanguage;
-
- // When modal is dismissed use the default language locale.
- return language !== '' ? language : defaultLanguage;
-};
-
-/**
- * Returns the language options for CSV exports language selector.
- *
- * @return {Array} Language options.
- */
-export const getExportLanguageOptions = () => {
- return [
- {
- label: __( 'English (United States)', 'woocommerce-payments' ),
- value: 'en_US',
- },
- {
- label:
- __( 'Site Language - ', 'woocommerce-payments' ) +
- wcpaySettings.locale.native_name,
- value: wcpaySettings.locale.code,
- },
- ];
-};
-
/**
* Given an object, remove all properties with null or undefined values.
*
diff --git a/includes/admin/class-wc-payments-admin.php b/includes/admin/class-wc-payments-admin.php
index 92010e4c302..2a6c3b5d17a 100644
--- a/includes/admin/class-wc-payments-admin.php
+++ b/includes/admin/class-wc-payments-admin.php
@@ -973,11 +973,8 @@ private function get_js_settings(): array {
'isNextDepositNoticeDismissed' => WC_Payments_Features::is_next_deposit_notice_dismissed(),
'isInstantDepositNoticeDismissed' => get_option( 'wcpay_instant_deposit_notice_dismissed', false ),
'isDateFormatNoticeDismissed' => get_option( 'wcpay_date_format_notice_dismissed', false ),
- 'reporting' => [
- 'exportModalDismissed' => get_option( 'wcpay_reporting_export_modal_dismissed', false ),
- ],
'dismissedDuplicateNotices' => get_option( 'wcpay_duplicate_payment_method_notices_dismissed', [] ),
- 'locale' => WC_Payments_Utils::get_language_data( get_locale() ),
+ 'userLocale' => WC_Payments_Utils::get_language_data( get_user_locale() ), // Language code found in current user's profile. This is different from the site's locale.
'isOverviewSurveySubmitted' => get_option( 'wcpay_survey_payment_overview_submitted', false ),
'trackingInfo' => $this->account->get_tracking_info(),
'lifetimeTPV' => $this->account->get_lifetime_total_payment_volume(),
@@ -987,6 +984,11 @@ private function get_js_settings(): array {
'timeFormat' => get_option( 'time_format' ),
];
+ /**
+ * Filter the WCPay JS settings.
+ *
+ * @since 6.1.0
+ */
return apply_filters( 'wcpay_js_settings', $this->wcpay_js_settings );
}
@@ -1000,6 +1002,11 @@ private function get_plugins_page_js_settings(): array {
'exitSurveyLastShown' => get_option( 'wcpay_exit_survey_last_shown', null ),
];
+ /**
+ * Filter the plugins page settings.
+ *
+ * @since 7.8.0
+ */
return apply_filters( 'wcpay_plugins_page_js_settings', $plugins_page_settings );
}
diff --git a/includes/admin/class-wc-rest-payments-settings-controller.php b/includes/admin/class-wc-rest-payments-settings-controller.php
index 1e6c21a54e3..bb0c3b00847 100644
--- a/includes/admin/class-wc-rest-payments-settings-controller.php
+++ b/includes/admin/class-wc-rest-payments-settings-controller.php
@@ -200,10 +200,6 @@ public function register_routes() {
'description' => __( 'Monthly anchor for deposit scheduling when interval is set to monthly', 'woocommerce-payments' ),
'type' => [ 'integer', 'null' ],
],
- 'reporting_export_language' => [
- 'description' => __( 'The language for an exported report for transactions, deposits, or disputes.', 'woocommerce-payments' ),
- 'type' => 'string',
- ],
'is_payment_request_enabled' => [
'description' => sprintf(
/* translators: %s: WooPayments */
@@ -525,7 +521,6 @@ public function get_settings(): WP_REST_Response {
'deposit_status' => $this->wcpay_gateway->get_option( 'deposit_status' ),
'deposit_restrictions' => $this->wcpay_gateway->get_option( 'deposit_restrictions' ),
'deposit_completed_waiting_period' => $this->wcpay_gateway->get_option( 'deposit_completed_waiting_period' ),
- 'reporting_export_language' => $this->wcpay_gateway->get_option( 'reporting_export_language' ),
'current_protection_level' => $this->wcpay_gateway->get_option( 'current_protection_level' ),
'advanced_fraud_protection_settings' => $this->wcpay_gateway->get_option( 'advanced_fraud_protection_settings' ),
'is_migrating_stripe_billing' => $is_migrating_stripe_billing ?? false,
@@ -554,7 +549,6 @@ public function update_settings( WP_REST_Request $request ) {
$this->update_is_saved_cards_enabled( $request );
$this->update_is_woopay_enabled( $request );
$this->update_is_woopay_global_theme_support_enabled( $request );
- $this->update_reporting_export_language( $request );
$this->update_woopay_store_logo( $request );
$this->update_woopay_custom_message( $request );
$this->update_woopay_enabled_locations( $request );
@@ -1100,19 +1094,4 @@ private function get_avs_check_enabled( array $ruleset_config ) {
return $avs_check_enabled;
}
-
- /**
- * Updates the "reporting_export_language" setting.
- *
- * @param WP_REST_Request $request Request object.
- */
- private function update_reporting_export_language( WP_REST_Request $request ) {
- if ( ! $request->has_param( 'reporting_export_language' ) ) {
- return;
- }
-
- $reporting_export_language = $request->get_param( 'reporting_export_language' );
-
- $this->wcpay_gateway->update_option( 'reporting_export_language', $reporting_export_language );
- }
}
diff --git a/includes/admin/class-wc-rest-payments-transactions-controller.php b/includes/admin/class-wc-rest-payments-transactions-controller.php
index 960b0667ef5..5eb7f7fe635 100644
--- a/includes/admin/class-wc-rest-payments-transactions-controller.php
+++ b/includes/admin/class-wc-rest-payments-transactions-controller.php
@@ -98,15 +98,6 @@ public function register_routes() {
'permission_callback' => [ $this, 'check_permission' ],
]
);
- register_rest_route(
- $this->namespace,
- '/' . $this->rest_base . '/(?P\w+)',
- [
- 'methods' => WP_REST_Server::READABLE,
- 'callback' => [ $this, 'get_transaction' ],
- 'permission_callback' => [ $this, 'check_permission' ],
- ]
- );
}
/**
@@ -180,16 +171,6 @@ public function get_transactions_export( $request ) {
return $this->forward_request( 'get_transactions_export', [ $filters, $user_email, $deposit_id, $locale, $download_type ] );
}
- /**
- * Retrieve transaction to respond with via API.
- *
- * @param WP_REST_Request $request Full data about the request.
- */
- public function get_transaction( $request ) {
- $transaction_id = $request->get_param( 'transaction_id' );
- return $this->forward_request( 'get_transactions', [ 'transaction_id' ] );
- }
-
/**
* Retrieve transactions summary to respond with via API.
*
diff --git a/includes/woopay/class-woopay-session.php b/includes/woopay/class-woopay-session.php
index 5c799ee0ead..aa004cc03ac 100644
--- a/includes/woopay/class-woopay-session.php
+++ b/includes/woopay/class-woopay-session.php
@@ -520,7 +520,7 @@ public static function get_init_session_request( $order_id = null, $key = null,
'store_data' => [
'store_name' => get_bloginfo( 'name' ),
'store_logo' => $store_logo,
- 'custom_message' => self::get_formatted_custom_message(),
+ 'custom_message' => self::get_formatted_custom_terms(),
'blog_id' => Jetpack_Options::get_option( 'id' ),
'blog_url' => get_site_url(),
'blog_checkout_url' => ! $is_pay_for_order ? wc_get_checkout_url() : $order->get_checkout_payment_url(),
@@ -871,7 +871,7 @@ private static function create_woopay_nonce( int $uid ) {
*
* @return string The custom message with the placeholders replaced.
*/
- private static function get_formatted_custom_message() {
+ private static function get_formatted_custom_terms() {
$custom_message = WC_Payments::get_gateway()->get_option( 'platform_checkout_custom_message' );
$terms_value = wc_terms_and_conditions_page_id() ?
@@ -898,10 +898,15 @@ private static function get_formatted_custom_message() {
*/
private static function get_option_fields_status() {
// Shortcode checkout options.
- $company = get_option( 'woocommerce_checkout_company_field', 'optional' );
- $address_2 = get_option( 'woocommerce_checkout_address_2_field', 'optional' );
- $phone = get_option( 'woocommerce_checkout_phone_field', 'required' );
- $terms_checkbox = ! empty( get_option( 'woocommerce_terms_page_id', null ) );
+ $company = get_option( 'woocommerce_checkout_company_field', 'optional' );
+ $address_2 = get_option( 'woocommerce_checkout_address_2_field', 'optional' );
+ $phone = get_option( 'woocommerce_checkout_phone_field', 'required' );
+ $has_terms_and_condition_page = ! empty( get_option( 'woocommerce_terms_page_id', null ) );
+ $terms_and_conditions = wp_kses_post( wc_replace_policy_page_link_placeholders( wc_get_terms_and_conditions_checkbox_text() ) );
+ $has_privacy_policy_page = ! empty( get_option( 'wp_page_for_privacy_policy', null ) );
+ $custom_below_place_order_button_text = self::get_formatted_custom_terms();
+ $below_place_order_button_text = $custom_below_place_order_button_text;
+ $show_terms_checkbox = false;
// Blocks checkout options. To get the blocks checkout options, we need
// to parse the checkout page content because the options are stored
@@ -909,12 +914,29 @@ private static function get_option_fields_status() {
$checkout_page_id = get_option( 'woocommerce_checkout_page_id' );
$checkout_page = get_post( $checkout_page_id );
+ /*
+ * Will show the terms checkbox if the terms page is set.
+ * Will show the checkbox even when the text is loaded from the custom field or the policy page field.
+ */
+ if ( $has_terms_and_condition_page && $terms_and_conditions ) {
+ $show_terms_checkbox = true;
+ if ( ! $below_place_order_button_text ) {
+ $below_place_order_button_text = $terms_and_conditions;
+ }
+ }
+
+ if ( ! $below_place_order_button_text && $has_privacy_policy_page ) {
+ $show_terms_checkbox = false;
+ $below_place_order_button_text = wp_kses_post( wc_replace_policy_page_link_placeholders( wc_get_privacy_policy_text( 'checkout' ) ) );
+ }
+
if ( empty( $checkout_page ) ) {
return [
'company' => $company,
'address_2' => $address_2,
'phone' => $phone,
- 'terms_checkbox' => $terms_checkbox,
+ 'terms_checkbox' => $show_terms_checkbox,
+ 'custom_terms' => $below_place_order_button_text,
];
}
@@ -922,44 +944,48 @@ private static function get_option_fields_status() {
$checkout_block_index = array_search( 'woocommerce/checkout', array_column( $checkout_page_blocks, 'blockName' ), true );
// If we can find the index, it means the merchant checkout page is using blocks checkout.
- if ( false !== $checkout_block_index && ! empty( $checkout_page_blocks[ $checkout_block_index ]['attrs'] ) ) {
- $checkout_block_attrs = $checkout_page_blocks[ $checkout_block_index ]['attrs'];
+ if ( false !== $checkout_block_index ) {
+ $below_place_order_button_text = $custom_below_place_order_button_text;
+ $company = 'optional';
+ $address_2 = 'optional';
+ $phone = 'optional';
- $company = 'optional';
- $address_2 = 'optional';
- $phone = 'optional';
+ if ( ! empty( $checkout_page_blocks[ $checkout_block_index ]['attrs'] ) ) {
+ $checkout_block_attrs = $checkout_page_blocks[ $checkout_block_index ]['attrs'];
- if ( ! empty( $checkout_block_attrs['requireCompanyField'] ) ) {
- $company = 'required';
- }
+ if ( ! empty( $checkout_block_attrs['requireCompanyField'] ) ) {
+ $company = 'required';
+ }
- if ( ! empty( $checkout_block_attrs['requirePhoneField'] ) ) {
- $phone = 'required';
- }
+ if ( ! empty( $checkout_block_attrs['requirePhoneField'] ) ) {
+ $phone = 'required';
+ }
- // showCompanyField is undefined by default.
- if ( empty( $checkout_block_attrs['showCompanyField'] ) ) {
- $company = 'hidden';
- }
+ // showCompanyField is undefined by default.
+ if ( empty( $checkout_block_attrs['showCompanyField'] ) ) {
+ $company = 'hidden';
+ }
- if ( isset( $checkout_block_attrs['showApartmentField'] ) && false === $checkout_block_attrs['showApartmentField'] ) {
- $address_2 = 'hidden';
- }
+ if ( isset( $checkout_block_attrs['showApartmentField'] ) && false === $checkout_block_attrs['showApartmentField'] ) {
+ $address_2 = 'hidden';
+ }
- if ( isset( $checkout_block_attrs['showPhoneField'] ) && false === $checkout_block_attrs['showPhoneField'] ) {
- $phone = 'hidden';
+ if ( isset( $checkout_block_attrs['showPhoneField'] ) && false === $checkout_block_attrs['showPhoneField'] ) {
+ $phone = 'hidden';
+ }
}
- $fields_block = self::get_inner_block( $checkout_page_blocks[ $checkout_block_index ], 'woocommerce/checkout-fields-block' );
- $terms_block = self::get_inner_block( $fields_block, 'woocommerce/checkout-terms-block' );
- $terms_checkbox = isset( $terms_block['attrs']['checkbox'] ) && $terms_block['attrs']['checkbox'];
+ $fields_block = self::get_inner_block( $checkout_page_blocks[ $checkout_block_index ], 'woocommerce/checkout-fields-block' );
+ $terms_block = self::get_inner_block( $fields_block, 'woocommerce/checkout-terms-block' );
+ $show_terms_checkbox = isset( $terms_block['attrs']['checkbox'] ) && $terms_block['attrs']['checkbox'];
}
return [
'company' => $company,
'address_2' => $address_2,
'phone' => $phone,
- 'terms_checkbox' => $terms_checkbox,
+ 'terms_checkbox' => $show_terms_checkbox,
+ 'custom_terms' => $below_place_order_button_text,
];
}
diff --git a/package-lock.json b/package-lock.json
index faa46475b89..590f98a6a74 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "woocommerce-payments",
- "version": "8.7.0",
+ "version": "8.7.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "woocommerce-payments",
- "version": "8.7.0",
+ "version": "8.7.1",
"hasInstallScript": true,
"license": "GPL-3.0-or-later",
"dependencies": {
diff --git a/package.json b/package.json
index 8a148ce18ca..85fc67ad46a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "woocommerce-payments",
- "version": "8.7.0",
+ "version": "8.7.1",
"main": "webpack.config.js",
"author": "Automattic",
"license": "GPL-3.0-or-later",
diff --git a/readme.txt b/readme.txt
index e9679c21243..ea3927b6349 100644
--- a/readme.txt
+++ b/readme.txt
@@ -4,7 +4,7 @@ Tags: woocommerce payments, apple pay, credit card, google pay, payment, payment
Requires at least: 6.0
Tested up to: 6.7
Requires PHP: 7.3
-Stable tag: 8.7.0
+Stable tag: 8.7.1
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -87,6 +87,10 @@ You can read our Terms of Service and other policies [here](https://woocommerce.
== Changelog ==
+= 8.7.1 - 2025-01-14 =
+* Fix - Broaden billing field queries from form-scoped to document-scoped
+
+
= 8.7.0 - 2024-12-25 =
* Add - Add seller_message to failed order notes
* Add - Add WooPay Klaviyo newsletter integration.
diff --git a/templates/emails/customer-ipp-receipt.php b/templates/emails/customer-ipp-receipt.php
index 45dad05f8d8..f5e78e28338 100644
--- a/templates/emails/customer-ipp-receipt.php
+++ b/templates/emails/customer-ipp-receipt.php
@@ -15,8 +15,11 @@
defined( 'ABSPATH' ) || exit;
-/*
+/**
+ * Output the email header.
+ *
* @hooked WC_Emails::email_header() Output the email header
+ * @since 4.0.0
*/
do_action( 'woocommerce_email_header', $email_heading, $email ); ?>
@@ -25,12 +28,16 @@
get_order_number() ) ); ?>
get_order_number() ) ) . "\n\n";
+/**
+ * Outputs the store details section of the IPP receipt email.
+ *
+ * @since 4.0.0
+ */
do_action( 'woocommerce_payments_email_ipp_receipt_store_details', $merchant_settings, $plain_text );
echo "\n----------------------------------------\n\n";
-/*
+/**
+ * Outputs the order details section of the email.
+ *
* @hooked WC_Emails::order_details() Shows the order details table.
* @hooked WC_Structured_Data::generate_order_data() Generates structured data.
* @hooked WC_Structured_Data::output_structured_data() Outputs structured data.
@@ -39,12 +46,20 @@
echo "\n----------------------------------------\n\n";
+/**
+ * Outputs the compliance details section of the IPP receipt email.
+ *
+ * @since 4.0.0
+ */
do_action( 'woocommerce_payments_email_ipp_receipt_compliance_details', $charge, $plain_text );
echo "\n\n----------------------------------------\n\n";
-/*
+/**
+ * Outputs the order meta data section of the email.
+ *
* @hooked WC_Emails::order_meta() Shows order meta data.
+ * @since 4.0.0
*/
do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email );
@@ -56,4 +71,9 @@
echo "\n\n----------------------------------------\n\n";
}
+/**
+ * Outputs the footer text of the email.
+ *
+ * @since 4.0.0
+ */
echo wp_kses_post( apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ) );
diff --git a/tests/e2e-pw/specs/shopper/shopper-pay-for-order.spec.ts b/tests/e2e-pw/specs/shopper/shopper-pay-for-order.spec.ts
new file mode 100644
index 00000000000..843fad52478
--- /dev/null
+++ b/tests/e2e-pw/specs/shopper/shopper-pay-for-order.spec.ts
@@ -0,0 +1,91 @@
+/**
+ * External dependencies
+ */
+import { test, expect } from '@playwright/test';
+
+/**
+ * Internal dependencies
+ */
+import { config } from '../../config/default';
+import * as shopper from '../../utils/shopper';
+import * as shopperNavigation from '../../utils/shopper-navigation';
+import * as devtools from '../../utils/devtools';
+import { getMerchant, getShopper } from '../../utils/helpers';
+
+const cardTestingPreventionStates = [
+ { cardTestingPreventionEnabled: false },
+ { cardTestingPreventionEnabled: true },
+];
+
+test.describe( 'Shopper > Pay for Order', () => {
+ cardTestingPreventionStates.forEach(
+ ( { cardTestingPreventionEnabled } ) => {
+ test( `should be able to pay for a failed order with card testing protection ${ cardTestingPreventionEnabled }`, async ( {
+ browser,
+ } ) => {
+ const { merchantPage } = await getMerchant( browser );
+ const { shopperPage } = await getShopper( browser );
+
+ // Enable or disable card testing protection.
+ if ( ! cardTestingPreventionEnabled ) {
+ await devtools.disableCardTestingProtection( merchantPage );
+ } else {
+ await devtools.enableCardTestingProtection( merchantPage );
+ }
+
+ // Attempt to pay with a declined card.
+ await shopper.addCartProduct( shopperPage );
+ await shopper.setupCheckout(
+ shopperPage,
+ config.addresses.customer.billing
+ );
+ await shopper.fillCardDetails(
+ shopperPage,
+ config.cards.declined
+ );
+ await shopper.placeOrder( shopperPage );
+
+ await expect(
+ shopperPage.getByText( 'Your card was declined' ).first()
+ ).toBeVisible();
+
+ // Go to the orders page and pay with a basic card.
+ await shopperNavigation.goToOrders( shopperPage );
+
+ const payForOrderButton = shopperPage
+ .locator( '.woocommerce-button.button.pay', {
+ hasText: 'Pay',
+ } )
+ .first();
+ await payForOrderButton.click();
+ await shopper.fillCardDetails(
+ shopperPage,
+ config.cards.basic
+ );
+
+ // Check for the fraud prevenction token presence.
+ const token = await shopperPage.evaluate( () => {
+ return ( window as any ).wcpayFraudPreventionToken;
+ } );
+
+ if ( cardTestingPreventionEnabled ) {
+ expect( token ).not.toBeUndefined();
+ } else {
+ expect( token ).toBeUndefined();
+ }
+
+ // Click the pay for order button.
+ await shopper.placeOrder( shopperPage );
+
+ await expect(
+ shopperPage.getByText( 'Order received' ).first()
+ ).toBeVisible();
+
+ // Disable card testing protection if necessary.
+ if ( cardTestingPreventionEnabled ) {
+ await devtools.disableCardTestingProtection( merchantPage );
+ }
+ } );
+ }
+ );
+} );
diff --git a/tests/e2e-pw/utils/devtools.ts b/tests/e2e-pw/utils/devtools.ts
new file mode 100644
index 00000000000..0ad37df9b3e
--- /dev/null
+++ b/tests/e2e-pw/utils/devtools.ts
@@ -0,0 +1,40 @@
+/**
+ * External dependencies
+ */
+import { Page, expect } from '@playwright/test';
+
+const goToDevToolsSettings = ( page: Page ) =>
+ page.goto( 'wp-admin/admin.php?page=wcpaydev', {
+ waitUntil: 'load',
+ } );
+
+const saveDevToolsSettings = async ( page: Page ) => {
+ await page.getByRole( 'button', { name: 'Save Changes' } ).click();
+ expect( page.getByText( /Settings saved/ ) ).toBeVisible();
+};
+
+const getIsCardTestingProtectionEnabled = ( page: Page ) =>
+ page.getByLabel( 'Card testing mitigations enabled' ).isChecked();
+
+const toggleCardTestingProtection = ( page: Page ) =>
+ page
+ .locator( 'label[for="wcpaydev_force_card_testing_protection_on"]' )
+ .click();
+
+export const enableCardTestingProtection = async ( page: Page ) => {
+ await goToDevToolsSettings( page );
+
+ if ( ! ( await getIsCardTestingProtectionEnabled( page ) ) ) {
+ await toggleCardTestingProtection( page );
+ await saveDevToolsSettings( page );
+ }
+};
+
+export const disableCardTestingProtection = async ( page: Page ) => {
+ await goToDevToolsSettings( page );
+
+ if ( await getIsCardTestingProtectionEnabled( page ) ) {
+ await toggleCardTestingProtection( page );
+ await saveDevToolsSettings( page );
+ }
+};
diff --git a/tests/e2e/specs/wcpay/shopper/shopper-pay-for-order.spec.js b/tests/e2e/specs/wcpay/shopper/shopper-pay-for-order.spec.js
deleted file mode 100644
index b0ebc0b8696..00000000000
--- a/tests/e2e/specs/wcpay/shopper/shopper-pay-for-order.spec.js
+++ /dev/null
@@ -1,84 +0,0 @@
-const { uiUnblocked, shopper, merchant } = require( '@woocommerce/e2e-utils' );
-const {
- setupProductCheckout,
- fillCardDetails,
- fillCardDetailsPayForOrder,
-} = require( '../../../utils/payments' );
-const config = require( 'config' );
-const { shopperWCP, merchantWCP } = require( '../../../utils' );
-
-const cardTestingPreventionStates = [
- { cardTestingPreventionEnabled: false },
- { cardTestingPreventionEnabled: true },
-];
-
-describe.each( cardTestingPreventionStates )(
- 'Shopper > Pay for Order',
- ( { cardTestingPreventionEnabled } ) => {
- beforeAll( async () => {
- if ( cardTestingPreventionEnabled ) {
- await merchant.login();
- await merchantWCP.enableCardTestingProtection();
- await merchant.logout();
- }
- await shopper.login();
- await setupProductCheckout(
- config.get( 'addresses.customer.billing' )
- );
- } );
-
- afterAll( async () => {
- await shopper.logout();
- if ( cardTestingPreventionEnabled ) {
- await merchant.login();
- await merchantWCP.disableCardTestingProtection();
- await merchant.logout();
- }
- } );
-
- it( `should be able to pay for a failed order, carding protection ${ cardTestingPreventionEnabled }`, async () => {
- // try to pay with a declined card
- const declinedCard = config.get( 'cards.declined' );
- await shopperWCP.selectNewPaymentMethod();
- await fillCardDetails( page, declinedCard );
- await expect( page ).toClick( '#place_order' );
- await uiUnblocked();
- await shopperWCP.waitForErrorBanner(
- 'Error: Your card was declined.',
- 'div.wc-block-components-notice-banner',
- 'div.woocommerce-NoticeGroup > ul.woocommerce-error > li'
- );
-
- // after the card has been declined, go to the order page and pay with a basic card
- await shopperWCP.goToOrders();
-
- const payButtons = await page.$$(
- '.woocommerce-button.button.pay'
- );
- const payButton = payButtons.find(
- async ( button ) =>
- ( await page.evaluate(
- ( elem ) => elem.innerText,
- button
- ) ) === 'Pay'
- );
- await payButton.click();
- const card = config.get( 'cards.basic' );
- await fillCardDetailsPayForOrder( page, card );
-
- // Check the token presence when card testing prevention is enabled.
- if ( cardTestingPreventionEnabled ) {
- const token = await page.evaluate( () => {
- return window.wcpayFraudPreventionToken;
- } );
- expect( token ).not.toBeUndefined();
- }
-
- await expect( page ).toClick( 'button', { text: 'Pay for order' } );
- await page.waitForNavigation( {
- waitUntil: 'networkidle0',
- } );
- await expect( page ).toMatchTextContent( 'Order received' );
- } );
- }
-);
diff --git a/tests/unit/admin/test-class-wc-payments-admin-sections-overwrite.php b/tests/unit/admin/test-class-wc-payments-admin-sections-overwrite.php
index 3a308511249..893cbf40433 100644
--- a/tests/unit/admin/test-class-wc-payments-admin-sections-overwrite.php
+++ b/tests/unit/admin/test-class-wc-payments-admin-sections-overwrite.php
@@ -53,7 +53,7 @@ public function test_checkout_sections_are_modified() {
$this->assertEquals(
$expected_sections,
- apply_filters( 'woocommerce_get_sections_checkout', $sections )
+ apply_filters( 'woocommerce_get_sections_checkout', $sections ) // phpcs:ignore WooCommerce.Commenting.CommentHooks.MissingHookComment
);
}
}
diff --git a/woocommerce-payments.php b/woocommerce-payments.php
index 2fb84450d01..546b6d41f0e 100644
--- a/woocommerce-payments.php
+++ b/woocommerce-payments.php
@@ -11,7 +11,7 @@
* WC tested up to: 9.5.1
* Requires at least: 6.0
* Requires PHP: 7.3
- * Version: 8.7.0
+ * Version: 8.7.1
* Requires Plugins: woocommerce
*
* @package WooCommerce\Payments