Skip to content

Commit

Permalink
Merge release/7.8.0 into trunk
Browse files Browse the repository at this point in the history
  • Loading branch information
dmvrtx committed Jun 19, 2024
2 parents f4804ab + bebb14b commit 8c3680d
Show file tree
Hide file tree
Showing 153 changed files with 4,929 additions and 1,667 deletions.
8 changes: 4 additions & 4 deletions .husky/pre-push
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

# check if main stream (stdout and stderr) are attached to the terminal
Expand All @@ -7,12 +7,12 @@ if [ -t 1 ] && [ -t 2 ]; then
exec < /dev/tty
fi

PROTECTED_BRANCH=("develop" "trunk")
PROTECTED_BRANCH_LIST="develop trunk"
CURRENT_BRANCH=$(git branch --show-current)

if [[ " ${PROTECTED_BRANCH[@]} " =~ " ${CURRENT_BRANCH} " ]]; then
if echo "$PROTECTED_BRANCH_LIST" | grep -q -w "$CURRENT_BRANCH"; then
read -p "$CURRENT_BRANCH is a protected branch. Are you sure you want to push? (y/n): " confirmation
if [ "$confirmation" != "y" ]; then
if [ "$confirmation" != "y" ]; then
echo "Push aborted"
exit 1
fi
Expand Down
40 changes: 40 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,45 @@
*** WooPayments Changelog ***

= 7.8.0 - 2024-06-19 =
* Add - Add a feedback survey modal upon deactivation.
* Add - Add new select component to be used for reporting filters, e.g. Payments overview currency select
* Add - Add payment processing using ECE in the Blocks checkout and cart pages.
* Add - Add the WooPay Direct Checkout flow to the classic mini cart widget.
* Add - Add woocommerce-return-previous-exceptions filter
* Add - Enable adapted extensions compatibility with Direct Checkout.
* Add - feat: add pay-for-order support w/ tokenized cart PRBs
* Add - Fix ECE not working without WooPay.
* Add - Reset notifications about duplicate enabled payment methods when new plugins are enabling them.
* Fix - Fall back to credit card as default payment method when a payment method is toggled off.
* Fix - fix: address normalization on checkout for tokenized cart PRBs
* Fix - fix: itemized totals & pending amount on tokenized cart
* Fix - fix: Store API tokenized cart payment method title
* Fix - Fixes some cases where redirects to the onboarding will open in a new tab.
* Fix - Fix input-specific credit card errors.
* Fix - Fix Payment method title for PRBs not displaying correctly because of ECE code.
* Fix - Fix Teams for WooCommerce Memberships on product WooPay Express Checkout Button.
* Fix - Fix WooPay Direct Checkout feature check.
* Fix - Improve consistency of Manage button for different WooPayments KYC states
* Fix - Make it so that the WooPay button is not triggered on Checkout pages when the "Enter" key is pressed on a keyboard.
* Fix - Prevent account creation during WooPay preflight request.
* Update - chore: update incompatibility notice wrapping
* Update - Declare compatibility with the Cart and Checkout blocks.
* Update - Improve the transition from the WCPay KYC to the WC Admin Payments Task
* Update - Update the Payments Overview screen with a new currency selection UI for stores with multiple deposit currencies
* Update - Use FILTER_SANITIZE_EMAIL to sanitize email input
* Dev - Add New_Process_Payment_Exception
* Dev - Add Order_ID_Mismatch_Exception
* Dev - Add sh support in pre-push husky script.
* Dev - Add validation for path variables.
* Dev - Bump WooCommerce Tested To version to 8.9.2
* Dev - Bump WooCommerce Tested To version to 8.9.3
* Dev - chore: EPMs to always send shipping phone
* Dev - Clean up and refactor some old code which is no longer in use.
* Dev - Fix PHPStan warnings.
* Dev - Fix unused parameter phpcs sniffs in checkout classes.
* Dev - Improve test coverage of upe.js and rename isPaymentMethodRestrictedToLocation to hasPaymentMethodCountryRestrictions
* Dev - Remove redundant wrapper around method invocation.

= 7.7.0 - 2024-05-29 =
* Add - Add share key query param when sending data to Stripe KYC.
* Add - Add the WooPay Direct Checkout flow to the blocks mini cart widget.
Expand Down
33 changes: 33 additions & 0 deletions client/checkout/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
getPaymentRequestData,
getPaymentRequestAjaxURL,
buildAjaxURL,
getExpressCheckoutAjaxURL,
getExpressCheckoutConfig,
} from 'utils/express-checkout';

/**
Expand Down Expand Up @@ -406,6 +408,37 @@ export default class WCPayAPI {
} );
}

/**
* Submits shipping address to get available shipping options
* from Express Checkout ECE payment method.
*
* @param {Object} shippingAddress Shipping details.
* @return {Promise} Promise for the request to the server.
*/
expressCheckoutECECalculateShippingOptions( shippingAddress ) {
return this.request(
getExpressCheckoutAjaxURL( 'get_shipping_options' ),
{
security: getExpressCheckoutConfig( 'nonce' )?.shipping,
is_product_page: getExpressCheckoutConfig( 'is_product_page' ),
...shippingAddress,
}
);
}

/**
* Creates order based on Express Checkout ECE payment method.
*
* @param {Object} paymentData Order data.
* @return {Promise} Promise for the request to the server.
*/
expressCheckoutECECreateOrder( paymentData ) {
return this.request( getExpressCheckoutAjaxURL( 'create_order' ), {
_wpnonce: getExpressCheckoutConfig( 'nonce' )?.checkout,
...paymentData,
} );
}

initWooPay( userEmail, woopayUserSession ) {
if ( ! this.isWooPayRequesting ) {
this.isWooPayRequesting = true;
Expand Down
7 changes: 5 additions & 2 deletions client/checkout/blocks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,11 @@ if ( getUPEConfig( 'isWooPayEnabled' ) ) {
}
}

registerExpressPaymentMethod( paymentRequestPaymentMethod( api ) );
registerExpressPaymentMethod( expressCheckoutElementPaymentMethod( api ) );
if ( getUPEConfig( 'isExpressCheckoutElementEnabled' ) ) {
registerExpressPaymentMethod( expressCheckoutElementPaymentMethod( api ) );
} else {
registerExpressPaymentMethod( paymentRequestPaymentMethod( api ) );
}
window.addEventListener( 'load', () => {
enqueueFraudScripts( getUPEConfig( 'fraudServices' ) );
addCheckoutTracking();
Expand Down
14 changes: 7 additions & 7 deletions client/checkout/blocks/payment-processor.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ const PaymentProcessor = ( {
} ) => {
const stripe = useStripe();
const elements = useElements();
const isPaymentInformationCompleteRef = useRef( false );
const hasLoadErrorRef = useRef( false );

const paymentMethodsConfig = getUPEConfig( 'paymentMethodsConfig' );
const isTestMode = getUPEConfig( 'testMode' );
Expand Down Expand Up @@ -140,11 +140,11 @@ const PaymentProcessor = ( {
return;
}

if ( ! isPaymentInformationCompleteRef.current ) {
if ( hasLoadErrorRef.current ) {
return {
type: 'error',
message: __(
'Your payment information is incomplete.',
'Invalid or missing payment details. Please ensure the provided payment method is correctly entered.',
'woocommerce-payments'
),
};
Expand Down Expand Up @@ -237,8 +237,9 @@ const PaymentProcessor = ( {
shouldSavePayment
);

const setPaymentInformationCompletionStatus = ( event ) => {
isPaymentInformationCompleteRef.current = event.complete;
const setHasLoadError = ( event ) => {
hasLoadErrorRef.current = true;
onLoadError( event );
};

return (
Expand All @@ -256,8 +257,7 @@ const PaymentProcessor = ( {
shouldSavePayment,
paymentMethodsConfig
) }
onLoadError={ onLoadError }
onChange={ setPaymentInformationCompletionStatus }
onLoadError={ setHasLoadError }
className="wcpay-payment-element"
/>
</>
Expand Down
24 changes: 12 additions & 12 deletions client/checkout/blocks/test/payment-processor.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,12 @@ jest.mock( '@stripe/react-stripe-js', () => ( {
useStripe: jest.fn(),
} ) );

const MockPaymentElement = ( { onChange } ) => {
useEffect( () => {
onChange( { complete: true } );
}, [ onChange ] );

return null;
};

describe( 'PaymentProcessor', () => {
let mockApi;
let mockCreatePaymentMethod;
beforeEach( () => {
global.wcpay_upe_config = { paymentMethodsConfig: {} };
PaymentElement.mockImplementation( MockPaymentElement );
PaymentElement.mockImplementation( () => null );
mockCreatePaymentMethod = jest
.fn()
.mockResolvedValue( { paymentMethod: {} } );
Expand Down Expand Up @@ -97,8 +89,14 @@ describe( 'PaymentProcessor', () => {
).not.toBeInTheDocument();
} );

it( 'should return an error when the payment information is incomplete', async () => {
PaymentElement.mockImplementation( () => null );
it( 'should return an error if the payment method could not be loaded', async () => {
PaymentElement.mockImplementation( ( { onLoadError } ) => {
useEffect( () => {
onLoadError();
}, [ onLoadError ] );

return null;
} );
let onPaymentSetupCallback;
render(
<PaymentProcessor
Expand All @@ -113,12 +111,14 @@ describe( 'PaymentProcessor', () => {
fingerprint=""
shouldSavePayment={ false }
upeMethods={ { card: 'woocommerce_payments' } }
onLoadError={ jest.fn() }
/>
);

expect( await onPaymentSetupCallback() ).toEqual( {
type: 'error',
message: 'Your payment information is incomplete.',
message:
'Invalid or missing payment details. Please ensure the provided payment method is correctly entered.',
} );
expect( mockCreatePaymentMethod ).not.toHaveBeenCalled();
} );
Expand Down
4 changes: 2 additions & 2 deletions client/checkout/classic/event-handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
generateCheckoutEventNames,
getSelectedUPEGatewayPaymentMethod,
isLinkEnabled,
isPaymentMethodRestrictedToLocation,
hasPaymentMethodCountryRestrictions,
isUsingSavedPaymentMethod,
togglePaymentMethodForCountry,
} from '../utils/upe';
Expand Down Expand Up @@ -228,7 +228,7 @@ jQuery( function ( $ ) {
}

function restrictPaymentMethodToLocation( upeElement ) {
if ( isPaymentMethodRestrictedToLocation( upeElement ) ) {
if ( hasPaymentMethodCountryRestrictions( upeElement ) ) {
togglePaymentMethodForCountry( upeElement );

// this event only applies to the checkout form, but not "place order" or "add payment method" pages.
Expand Down
19 changes: 8 additions & 11 deletions client/checkout/classic/payment-processing.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ for ( const paymentMethodType in getUPEConfig( 'paymentMethodsConfig' ) ) {
gatewayUPEComponents[ paymentMethodType ] = {
elements: null,
upeElement: null,
isPaymentInformationComplete: false,
hasLoadError: false,
};
}

Expand Down Expand Up @@ -406,11 +406,9 @@ export async function mountStripePaymentElement( api, domElement ) {
gatewayUPEComponents[ paymentMethodType ].upeElement ||
( await createStripePaymentElement( api, paymentMethodType ) );
upeElement.mount( domElement );
upeElement.on( 'change', ( e ) => {
gatewayUPEComponents[ paymentMethodType ].isPaymentInformationComplete =
e.complete;
} );
upeElement.on( 'loaderror', ( e ) => {
// setting the flag to true to prevent the form from being submitted.
gatewayUPEComponents[ paymentMethodType ].hasLoadError = true;
// unset any styling to ensure the WC error message wrapper can take more width.
domElement.style.padding = '0';
// creating a new element to be added to the DOM, so that the message can be displayed.
Expand Down Expand Up @@ -524,15 +522,14 @@ export const processPayment = (
try {
await blockUI( $form );

const {
elements,
isPaymentInformationComplete,
} = gatewayUPEComponents[ paymentMethodType ];
const { elements, hasLoadError } = gatewayUPEComponents[
paymentMethodType
];

if ( ! isPaymentInformationComplete ) {
if ( hasLoadError ) {
throw new Error(
__(
'Your payment information is incomplete.',
'Invalid or missing payment details. Please ensure the provided payment method is correctly entered.',
'woocommerce-payments'
)
);
Expand Down
14 changes: 0 additions & 14 deletions client/checkout/classic/test/payment-processing.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,6 @@ const mockCreateFunction = jest.fn( () => ( {
eventHandlersFromElementsCreate[ event ].push( handler );
},
} ) );
const callAllCreateHandlersWith = ( event, ...args ) => {
eventHandlersFromElementsCreate[ event ]?.forEach( ( handler ) => {
handler.apply( null, args );
} );
};
const markAllPaymentElementsAsComplete = () => {
callAllCreateHandlersWith( 'change', { complete: true } );
};

const mockSubmit = jest.fn( () => ( {
then: jest.fn(),
Expand Down Expand Up @@ -396,7 +388,6 @@ describe( 'Payment processing', () => {
mockDomElement.dataset.paymentMethodType = 'card';

await mountStripePaymentElement( apiMock, mockDomElement );
markAllPaymentElementsAsComplete();

const mockJqueryForm = {
submit: jest.fn(),
Expand Down Expand Up @@ -443,7 +434,6 @@ describe( 'Payment processing', () => {
mockDomElement.dataset.paymentMethodType = 'card';

await mountStripePaymentElement( apiMock, mockDomElement );
markAllPaymentElementsAsComplete();

const checkoutForm = {
submit: jest.fn(),
Expand Down Expand Up @@ -487,7 +477,6 @@ describe( 'Payment processing', () => {
mockDomElement.dataset.paymentMethodType = 'card';

await mountStripePaymentElement( apiMock, mockDomElement );
markAllPaymentElementsAsComplete();

const checkoutForm = {
submit: jest.fn(),
Expand Down Expand Up @@ -527,7 +516,6 @@ describe( 'Payment processing', () => {
mockDomElement.dataset.paymentMethodType = 'card';

await mountStripePaymentElement( apiMock, mockDomElement );
markAllPaymentElementsAsComplete();

const checkoutForm = {
submit: jest.fn(),
Expand Down Expand Up @@ -564,7 +552,6 @@ describe( 'Payment processing', () => {
mockDomElement.dataset.paymentMethodType = 'card';

await mountStripePaymentElement( apiMock, mockDomElement );
markAllPaymentElementsAsComplete();

const checkoutForm = {
submit: jest.fn(),
Expand Down Expand Up @@ -599,7 +586,6 @@ describe( 'Payment processing', () => {
mockDomElement.dataset.paymentMethodType = 'card';

await mountStripePaymentElement( apiMock, mockDomElement );
markAllPaymentElementsAsComplete();

const addPaymentMethodForm = {
submit: jest.fn(),
Expand Down
Loading

0 comments on commit 8c3680d

Please sign in to comment.