Fix retrying after failed payment processed server side. (https://github.com/woocommerce/woocommerce-blocks/pull/2655)

* add state for selected saved token in payment data

* add handling for flipping payment status back to pristine when checkout has error

If payment status is successful client side, but the checkout state goes into an error after server side processing, then we reset payment status to pristine to allow for reprocessing of payment method client side.

This is skipped for saved payment method tokens because they effectively are _only_ processed server side.
This commit is contained in:
Darren Ethier 2020-06-07 16:47:16 -04:00 committed by GitHub
parent 0ac76337d4
commit 2bbe2e63c6
4 changed files with 29 additions and 0 deletions

View File

@ -45,6 +45,7 @@ const getCcOrEcheckPaymentMethodOption = (
setPaymentStatus().success( {
payment_method: method.gateway,
[ savedTokenKey ]: token,
isSavedToken: true,
} );
},
};
@ -77,6 +78,7 @@ const getDefaultPaymentMethodOptions = (
setPaymentStatus().success( {
payment_method: method.gateway,
[ savedTokenKey ]: token,
isSavedToken: true,
} );
},
};

View File

@ -35,6 +35,7 @@ export const DEFAULT_PAYMENT_DATA = {
// wants to pass along for payment
// processing server side.
},
hasSavedToken: false,
errorMessage: '',
paymentMethods: {},
expressPaymentMethods: {},

View File

@ -276,6 +276,23 @@ export const PaymentMethodDataProvider = ( { children } ) => {
}
}, [ checkoutIsIdle, currentStatus.isSuccessful ] );
// if checkout has an error and payment is not being made with a saved token
// and payment status is success, then let's sync payment status back to
// pristine.
useEffect( () => {
if (
checkoutHasError &&
currentStatus.isSuccessful &&
! paymentData.hasSavedToken
) {
dispatch( statusOnly( PRISTINE ) );
}
}, [
checkoutHasError,
currentStatus.isSuccessful,
paymentData.hasSavedToken,
] );
// set initial active payment method if it's undefined.
useEffect( () => {
const paymentMethodKeys = Object.keys( paymentData.paymentMethods );

View File

@ -15,6 +15,12 @@ const {
SET_SHOULD_SAVE_PAYMENT_METHOD,
} = ACTION_TYPES;
const hasSavedPaymentToken = ( paymentMethodData ) => {
return !! (
typeof paymentMethodData === 'object' && paymentMethodData.isSavedToken
);
};
/**
* Reducer for payment data state
*
@ -64,6 +70,9 @@ const reducer = (
currentStatus: SUCCESS,
paymentMethodData:
paymentMethodData || state.paymentMethodData,
hasSavedToken: hasSavedPaymentToken(
paymentMethodData
),
}
: state;
case PROCESSING: