woocommerce/plugins/woocommerce-blocks/assets/js/base/context/cart-checkout/payment-methods/use-payment-method-registra...

190 lines
5.8 KiB
JavaScript
Raw Normal View History

/**
* External dependencies
*/
import { __, sprintf } from '@wordpress/i18n';
import {
getPaymentMethods,
getExpressPaymentMethods,
} from '@woocommerce/blocks-registry';
import { useState, useEffect, useRef, useCallback } from '@wordpress/element';
import {
useEditorContext,
useShippingDataContext,
} from '@woocommerce/base-context';
allow payment methods to disable based on shipping (API change) (https://github.com/woocommerce/woocommerce-blocks/pull/2840) * allow payment methods to disable based on shipping or other factors: - renamed 'initialized' array 'available' to match primary purpose of `canMakePayment` api - whether payment method should be available - trigger refresh of available payment methods when shopper chooses different shipping method - rename resolveCanMakePayments => refreshCanMakePayments - tweaked some variable names and scope for clarity - added comments to clarify things Note this should not affect behaviour yet - no existing payment methods use this new feature. COD payment method will need this - woocommerce/woocommerce-blocks#2831 * optimise refreshCanMakePayments: - useShallowEqual to avoid unnecessary call when shipping methods have not actually changed (but object value has) * replace ("set") payment methods in store, was appending: - payment methods may come and go depending on cart/checkout state - the previous SET action appended provided payment methods to the collection - this prevents dynamic payment methods e.g. COD from being able to hide i.e. disable * cache test payment request to avoid unnecessary stripe API calls: - in the canMakePayment callback there's a test payment to determine if chrome pay/apple pay is set up and available - canMakePayment is now called multiple times as checkout state changes - now the results of the test payment are stored in variable, and returned on subsequent calls * set init flag to avoid additional attempts to init stripe API: + tweak naming of init flag
2020-07-13 22:52:13 +00:00
import { useStoreCart, useShallowEqual } from '@woocommerce/base-hooks';
Show payment gateways in correct (merchant-configured) order (https://github.com/woocommerce/woocommerce-blocks/pull/2934) * enqueue order of payment gateways as script data * use configured gateway order for payment method tabs * clarify name of payment gateway sort order setting * fix formatting Co-authored-by: Darren Ethier <darren@roughsmootheng.in> * fix bug - express payment methods not working due to ordering logic: - move ordering code to payment methods in usePaymentMethods hook; - this only applies to standard (non express) payment methods - also any code that uses payment methods will get them in correct order * why did this formatting not happen pre-commit? * move method ordering into refreshPaymentMethods to avoid infinite loop: - pass keys of express payment methods so they work correctly (show up) - refreshPaymentMethods dispatches availablePaymentMethods to redux store; I suspect this was causing infinite loop as the callback depends on registeredPaymentMethods - handle case when a payment method is not in PAYMENT_GATEWAY_SORT_ORDER - this happens with COD when dependent on shipping * fix formatting * use shallow equal to prevent refreshCanMakePayments infinite loop * use native Set instead of lodash.union for unique gateway names * code formatting * check to ensure we register paymentGatewaySortOrder asset once only * fix COD tab showing out of order if not available at page load: - return ALL gateways in sort order array - note this includes gateways that are not enabled by merchant * reinstate return bool from usePaymentMethods hook (broken in refactor) * add basic typedefs for payment methods hooks Co-authored-by: Darren Ethier <darren@roughsmootheng.in>
2020-08-05 01:56:33 +00:00
import {
CURRENT_USER_IS_ADMIN,
PAYMENT_GATEWAY_SORT_ORDER,
} from '@woocommerce/block-settings';
/**
* If there was an error registering a payment method, alert the admin.
*
* @param {Object} error Error object.
*/
const handleRegistrationError = ( error ) => {
if ( CURRENT_USER_IS_ADMIN ) {
throw new Error(
sprintf(
__(
// translators: %s is the error method returned by the payment method.
'Problem with payment method initialization: %s',
'woo-gutenberg-products-block'
),
error.message
)
);
}
};
/**
* This hook handles initializing registered payment methods and exposing all
* registered payment methods that can be used in the current environment (via
* the payment method's `canMakePayment` property).
*
* @param {function(Object):undefined} dispatcher A dispatcher for setting registered
* payment methods to an external
* state.
* @param {Object} registeredPaymentMethods Registered payment methods to
* process.
Show payment gateways in correct (merchant-configured) order (https://github.com/woocommerce/woocommerce-blocks/pull/2934) * enqueue order of payment gateways as script data * use configured gateway order for payment method tabs * clarify name of payment gateway sort order setting * fix formatting Co-authored-by: Darren Ethier <darren@roughsmootheng.in> * fix bug - express payment methods not working due to ordering logic: - move ordering code to payment methods in usePaymentMethods hook; - this only applies to standard (non express) payment methods - also any code that uses payment methods will get them in correct order * why did this formatting not happen pre-commit? * move method ordering into refreshPaymentMethods to avoid infinite loop: - pass keys of express payment methods so they work correctly (show up) - refreshPaymentMethods dispatches availablePaymentMethods to redux store; I suspect this was causing infinite loop as the callback depends on registeredPaymentMethods - handle case when a payment method is not in PAYMENT_GATEWAY_SORT_ORDER - this happens with COD when dependent on shipping * fix formatting * use shallow equal to prevent refreshCanMakePayments infinite loop * use native Set instead of lodash.union for unique gateway names * code formatting * check to ensure we register paymentGatewaySortOrder asset once only * fix COD tab showing out of order if not available at page load: - return ALL gateways in sort order array - note this includes gateways that are not enabled by merchant * reinstate return bool from usePaymentMethods hook (broken in refactor) * add basic typedefs for payment methods hooks Co-authored-by: Darren Ethier <darren@roughsmootheng.in>
2020-08-05 01:56:33 +00:00
* @param {Array} paymentMethodsSortOrder Array of payment method names to
* sort by. This should match keys of
* registeredPaymentMethods.
*
* @return {boolean} Whether the payment methods have been initialized or not. True when all payment
* methods have been initialized.
*/
const usePaymentMethodRegistration = (
dispatcher,
Show payment gateways in correct (merchant-configured) order (https://github.com/woocommerce/woocommerce-blocks/pull/2934) * enqueue order of payment gateways as script data * use configured gateway order for payment method tabs * clarify name of payment gateway sort order setting * fix formatting Co-authored-by: Darren Ethier <darren@roughsmootheng.in> * fix bug - express payment methods not working due to ordering logic: - move ordering code to payment methods in usePaymentMethods hook; - this only applies to standard (non express) payment methods - also any code that uses payment methods will get them in correct order * why did this formatting not happen pre-commit? * move method ordering into refreshPaymentMethods to avoid infinite loop: - pass keys of express payment methods so they work correctly (show up) - refreshPaymentMethods dispatches availablePaymentMethods to redux store; I suspect this was causing infinite loop as the callback depends on registeredPaymentMethods - handle case when a payment method is not in PAYMENT_GATEWAY_SORT_ORDER - this happens with COD when dependent on shipping * fix formatting * use shallow equal to prevent refreshCanMakePayments infinite loop * use native Set instead of lodash.union for unique gateway names * code formatting * check to ensure we register paymentGatewaySortOrder asset once only * fix COD tab showing out of order if not available at page load: - return ALL gateways in sort order array - note this includes gateways that are not enabled by merchant * reinstate return bool from usePaymentMethods hook (broken in refactor) * add basic typedefs for payment methods hooks Co-authored-by: Darren Ethier <darren@roughsmootheng.in>
2020-08-05 01:56:33 +00:00
registeredPaymentMethods,
paymentMethodsSortOrder
) => {
const [ isInitialized, setIsInitialized ] = useState( false );
const { isEditor } = useEditorContext();
allow payment methods to disable based on shipping (API change) (https://github.com/woocommerce/woocommerce-blocks/pull/2840) * allow payment methods to disable based on shipping or other factors: - renamed 'initialized' array 'available' to match primary purpose of `canMakePayment` api - whether payment method should be available - trigger refresh of available payment methods when shopper chooses different shipping method - rename resolveCanMakePayments => refreshCanMakePayments - tweaked some variable names and scope for clarity - added comments to clarify things Note this should not affect behaviour yet - no existing payment methods use this new feature. COD payment method will need this - woocommerce/woocommerce-blocks#2831 * optimise refreshCanMakePayments: - useShallowEqual to avoid unnecessary call when shipping methods have not actually changed (but object value has) * replace ("set") payment methods in store, was appending: - payment methods may come and go depending on cart/checkout state - the previous SET action appended provided payment methods to the collection - this prevents dynamic payment methods e.g. COD from being able to hide i.e. disable * cache test payment request to avoid unnecessary stripe API calls: - in the canMakePayment callback there's a test payment to determine if chrome pay/apple pay is set up and available - canMakePayment is now called multiple times as checkout state changes - now the results of the test payment are stored in variable, and returned on subsequent calls * set init flag to avoid additional attempts to init stripe API: + tweak naming of init flag
2020-07-13 22:52:13 +00:00
const { selectedRates, shippingAddress } = useShippingDataContext();
const selectedShippingMethods = useShallowEqual( selectedRates );
Show payment gateways in correct (merchant-configured) order (https://github.com/woocommerce/woocommerce-blocks/pull/2934) * enqueue order of payment gateways as script data * use configured gateway order for payment method tabs * clarify name of payment gateway sort order setting * fix formatting Co-authored-by: Darren Ethier <darren@roughsmootheng.in> * fix bug - express payment methods not working due to ordering logic: - move ordering code to payment methods in usePaymentMethods hook; - this only applies to standard (non express) payment methods - also any code that uses payment methods will get them in correct order * why did this formatting not happen pre-commit? * move method ordering into refreshPaymentMethods to avoid infinite loop: - pass keys of express payment methods so they work correctly (show up) - refreshPaymentMethods dispatches availablePaymentMethods to redux store; I suspect this was causing infinite loop as the callback depends on registeredPaymentMethods - handle case when a payment method is not in PAYMENT_GATEWAY_SORT_ORDER - this happens with COD when dependent on shipping * fix formatting * use shallow equal to prevent refreshCanMakePayments infinite loop * use native Set instead of lodash.union for unique gateway names * code formatting * check to ensure we register paymentGatewaySortOrder asset once only * fix COD tab showing out of order if not available at page load: - return ALL gateways in sort order array - note this includes gateways that are not enabled by merchant * reinstate return bool from usePaymentMethods hook (broken in refactor) * add basic typedefs for payment methods hooks Co-authored-by: Darren Ethier <darren@roughsmootheng.in>
2020-08-05 01:56:33 +00:00
const paymentMethodsOrder = useShallowEqual( paymentMethodsSortOrder );
const { cartTotals, cartNeedsShipping } = useStoreCart();
const canPayArgument = useRef( {
cartTotals,
cartNeedsShipping,
shippingAddress,
allow payment methods to disable based on shipping (API change) (https://github.com/woocommerce/woocommerce-blocks/pull/2840) * allow payment methods to disable based on shipping or other factors: - renamed 'initialized' array 'available' to match primary purpose of `canMakePayment` api - whether payment method should be available - trigger refresh of available payment methods when shopper chooses different shipping method - rename resolveCanMakePayments => refreshCanMakePayments - tweaked some variable names and scope for clarity - added comments to clarify things Note this should not affect behaviour yet - no existing payment methods use this new feature. COD payment method will need this - woocommerce/woocommerce-blocks#2831 * optimise refreshCanMakePayments: - useShallowEqual to avoid unnecessary call when shipping methods have not actually changed (but object value has) * replace ("set") payment methods in store, was appending: - payment methods may come and go depending on cart/checkout state - the previous SET action appended provided payment methods to the collection - this prevents dynamic payment methods e.g. COD from being able to hide i.e. disable * cache test payment request to avoid unnecessary stripe API calls: - in the canMakePayment callback there's a test payment to determine if chrome pay/apple pay is set up and available - canMakePayment is now called multiple times as checkout state changes - now the results of the test payment are stored in variable, and returned on subsequent calls * set init flag to avoid additional attempts to init stripe API: + tweak naming of init flag
2020-07-13 22:52:13 +00:00
selectedShippingMethods,
} );
useEffect( () => {
canPayArgument.current = {
cartTotals,
cartNeedsShipping,
shippingAddress,
allow payment methods to disable based on shipping (API change) (https://github.com/woocommerce/woocommerce-blocks/pull/2840) * allow payment methods to disable based on shipping or other factors: - renamed 'initialized' array 'available' to match primary purpose of `canMakePayment` api - whether payment method should be available - trigger refresh of available payment methods when shopper chooses different shipping method - rename resolveCanMakePayments => refreshCanMakePayments - tweaked some variable names and scope for clarity - added comments to clarify things Note this should not affect behaviour yet - no existing payment methods use this new feature. COD payment method will need this - woocommerce/woocommerce-blocks#2831 * optimise refreshCanMakePayments: - useShallowEqual to avoid unnecessary call when shipping methods have not actually changed (but object value has) * replace ("set") payment methods in store, was appending: - payment methods may come and go depending on cart/checkout state - the previous SET action appended provided payment methods to the collection - this prevents dynamic payment methods e.g. COD from being able to hide i.e. disable * cache test payment request to avoid unnecessary stripe API calls: - in the canMakePayment callback there's a test payment to determine if chrome pay/apple pay is set up and available - canMakePayment is now called multiple times as checkout state changes - now the results of the test payment are stored in variable, and returned on subsequent calls * set init flag to avoid additional attempts to init stripe API: + tweak naming of init flag
2020-07-13 22:52:13 +00:00
selectedShippingMethods,
};
allow payment methods to disable based on shipping (API change) (https://github.com/woocommerce/woocommerce-blocks/pull/2840) * allow payment methods to disable based on shipping or other factors: - renamed 'initialized' array 'available' to match primary purpose of `canMakePayment` api - whether payment method should be available - trigger refresh of available payment methods when shopper chooses different shipping method - rename resolveCanMakePayments => refreshCanMakePayments - tweaked some variable names and scope for clarity - added comments to clarify things Note this should not affect behaviour yet - no existing payment methods use this new feature. COD payment method will need this - woocommerce/woocommerce-blocks#2831 * optimise refreshCanMakePayments: - useShallowEqual to avoid unnecessary call when shipping methods have not actually changed (but object value has) * replace ("set") payment methods in store, was appending: - payment methods may come and go depending on cart/checkout state - the previous SET action appended provided payment methods to the collection - this prevents dynamic payment methods e.g. COD from being able to hide i.e. disable * cache test payment request to avoid unnecessary stripe API calls: - in the canMakePayment callback there's a test payment to determine if chrome pay/apple pay is set up and available - canMakePayment is now called multiple times as checkout state changes - now the results of the test payment are stored in variable, and returned on subsequent calls * set init flag to avoid additional attempts to init stripe API: + tweak naming of init flag
2020-07-13 22:52:13 +00:00
}, [
cartTotals,
cartNeedsShipping,
shippingAddress,
selectedShippingMethods,
] );
allow payment methods to disable based on shipping (API change) (https://github.com/woocommerce/woocommerce-blocks/pull/2840) * allow payment methods to disable based on shipping or other factors: - renamed 'initialized' array 'available' to match primary purpose of `canMakePayment` api - whether payment method should be available - trigger refresh of available payment methods when shopper chooses different shipping method - rename resolveCanMakePayments => refreshCanMakePayments - tweaked some variable names and scope for clarity - added comments to clarify things Note this should not affect behaviour yet - no existing payment methods use this new feature. COD payment method will need this - woocommerce/woocommerce-blocks#2831 * optimise refreshCanMakePayments: - useShallowEqual to avoid unnecessary call when shipping methods have not actually changed (but object value has) * replace ("set") payment methods in store, was appending: - payment methods may come and go depending on cart/checkout state - the previous SET action appended provided payment methods to the collection - this prevents dynamic payment methods e.g. COD from being able to hide i.e. disable * cache test payment request to avoid unnecessary stripe API calls: - in the canMakePayment callback there's a test payment to determine if chrome pay/apple pay is set up and available - canMakePayment is now called multiple times as checkout state changes - now the results of the test payment are stored in variable, and returned on subsequent calls * set init flag to avoid additional attempts to init stripe API: + tweak naming of init flag
2020-07-13 22:52:13 +00:00
const refreshCanMakePayments = useCallback( async () => {
let availablePaymentMethods = {};
const addAvailablePaymentMethod = ( paymentMethod ) => {
availablePaymentMethods = {
...availablePaymentMethods,
[ paymentMethod.name ]: paymentMethod,
};
};
Show payment gateways in correct (merchant-configured) order (https://github.com/woocommerce/woocommerce-blocks/pull/2934) * enqueue order of payment gateways as script data * use configured gateway order for payment method tabs * clarify name of payment gateway sort order setting * fix formatting Co-authored-by: Darren Ethier <darren@roughsmootheng.in> * fix bug - express payment methods not working due to ordering logic: - move ordering code to payment methods in usePaymentMethods hook; - this only applies to standard (non express) payment methods - also any code that uses payment methods will get them in correct order * why did this formatting not happen pre-commit? * move method ordering into refreshPaymentMethods to avoid infinite loop: - pass keys of express payment methods so they work correctly (show up) - refreshPaymentMethods dispatches availablePaymentMethods to redux store; I suspect this was causing infinite loop as the callback depends on registeredPaymentMethods - handle case when a payment method is not in PAYMENT_GATEWAY_SORT_ORDER - this happens with COD when dependent on shipping * fix formatting * use shallow equal to prevent refreshCanMakePayments infinite loop * use native Set instead of lodash.union for unique gateway names * code formatting * check to ensure we register paymentGatewaySortOrder asset once only * fix COD tab showing out of order if not available at page load: - return ALL gateways in sort order array - note this includes gateways that are not enabled by merchant * reinstate return bool from usePaymentMethods hook (broken in refactor) * add basic typedefs for payment methods hooks Co-authored-by: Darren Ethier <darren@roughsmootheng.in>
2020-08-05 01:56:33 +00:00
for ( let i = 0; i < paymentMethodsOrder.length; i++ ) {
const paymentMethodName = paymentMethodsOrder[ i ];
allow payment methods to disable based on shipping (API change) (https://github.com/woocommerce/woocommerce-blocks/pull/2840) * allow payment methods to disable based on shipping or other factors: - renamed 'initialized' array 'available' to match primary purpose of `canMakePayment` api - whether payment method should be available - trigger refresh of available payment methods when shopper chooses different shipping method - rename resolveCanMakePayments => refreshCanMakePayments - tweaked some variable names and scope for clarity - added comments to clarify things Note this should not affect behaviour yet - no existing payment methods use this new feature. COD payment method will need this - woocommerce/woocommerce-blocks#2831 * optimise refreshCanMakePayments: - useShallowEqual to avoid unnecessary call when shipping methods have not actually changed (but object value has) * replace ("set") payment methods in store, was appending: - payment methods may come and go depending on cart/checkout state - the previous SET action appended provided payment methods to the collection - this prevents dynamic payment methods e.g. COD from being able to hide i.e. disable * cache test payment request to avoid unnecessary stripe API calls: - in the canMakePayment callback there's a test payment to determine if chrome pay/apple pay is set up and available - canMakePayment is now called multiple times as checkout state changes - now the results of the test payment are stored in variable, and returned on subsequent calls * set init flag to avoid additional attempts to init stripe API: + tweak naming of init flag
2020-07-13 22:52:13 +00:00
const paymentMethod = registeredPaymentMethods[ paymentMethodName ];
Show payment gateways in correct (merchant-configured) order (https://github.com/woocommerce/woocommerce-blocks/pull/2934) * enqueue order of payment gateways as script data * use configured gateway order for payment method tabs * clarify name of payment gateway sort order setting * fix formatting Co-authored-by: Darren Ethier <darren@roughsmootheng.in> * fix bug - express payment methods not working due to ordering logic: - move ordering code to payment methods in usePaymentMethods hook; - this only applies to standard (non express) payment methods - also any code that uses payment methods will get them in correct order * why did this formatting not happen pre-commit? * move method ordering into refreshPaymentMethods to avoid infinite loop: - pass keys of express payment methods so they work correctly (show up) - refreshPaymentMethods dispatches availablePaymentMethods to redux store; I suspect this was causing infinite loop as the callback depends on registeredPaymentMethods - handle case when a payment method is not in PAYMENT_GATEWAY_SORT_ORDER - this happens with COD when dependent on shipping * fix formatting * use shallow equal to prevent refreshCanMakePayments infinite loop * use native Set instead of lodash.union for unique gateway names * code formatting * check to ensure we register paymentGatewaySortOrder asset once only * fix COD tab showing out of order if not available at page load: - return ALL gateways in sort order array - note this includes gateways that are not enabled by merchant * reinstate return bool from usePaymentMethods hook (broken in refactor) * add basic typedefs for payment methods hooks Co-authored-by: Darren Ethier <darren@roughsmootheng.in>
2020-08-05 01:56:33 +00:00
if ( ! paymentMethod ) {
continue;
}
allow payment methods to disable based on shipping (API change) (https://github.com/woocommerce/woocommerce-blocks/pull/2840) * allow payment methods to disable based on shipping or other factors: - renamed 'initialized' array 'available' to match primary purpose of `canMakePayment` api - whether payment method should be available - trigger refresh of available payment methods when shopper chooses different shipping method - rename resolveCanMakePayments => refreshCanMakePayments - tweaked some variable names and scope for clarity - added comments to clarify things Note this should not affect behaviour yet - no existing payment methods use this new feature. COD payment method will need this - woocommerce/woocommerce-blocks#2831 * optimise refreshCanMakePayments: - useShallowEqual to avoid unnecessary call when shipping methods have not actually changed (but object value has) * replace ("set") payment methods in store, was appending: - payment methods may come and go depending on cart/checkout state - the previous SET action appended provided payment methods to the collection - this prevents dynamic payment methods e.g. COD from being able to hide i.e. disable * cache test payment request to avoid unnecessary stripe API calls: - in the canMakePayment callback there's a test payment to determine if chrome pay/apple pay is set up and available - canMakePayment is now called multiple times as checkout state changes - now the results of the test payment are stored in variable, and returned on subsequent calls * set init flag to avoid additional attempts to init stripe API: + tweak naming of init flag
2020-07-13 22:52:13 +00:00
// In editor, shortcut so all payment methods show as available.
if ( isEditor ) {
allow payment methods to disable based on shipping (API change) (https://github.com/woocommerce/woocommerce-blocks/pull/2840) * allow payment methods to disable based on shipping or other factors: - renamed 'initialized' array 'available' to match primary purpose of `canMakePayment` api - whether payment method should be available - trigger refresh of available payment methods when shopper chooses different shipping method - rename resolveCanMakePayments => refreshCanMakePayments - tweaked some variable names and scope for clarity - added comments to clarify things Note this should not affect behaviour yet - no existing payment methods use this new feature. COD payment method will need this - woocommerce/woocommerce-blocks#2831 * optimise refreshCanMakePayments: - useShallowEqual to avoid unnecessary call when shipping methods have not actually changed (but object value has) * replace ("set") payment methods in store, was appending: - payment methods may come and go depending on cart/checkout state - the previous SET action appended provided payment methods to the collection - this prevents dynamic payment methods e.g. COD from being able to hide i.e. disable * cache test payment request to avoid unnecessary stripe API calls: - in the canMakePayment callback there's a test payment to determine if chrome pay/apple pay is set up and available - canMakePayment is now called multiple times as checkout state changes - now the results of the test payment are stored in variable, and returned on subsequent calls * set init flag to avoid additional attempts to init stripe API: + tweak naming of init flag
2020-07-13 22:52:13 +00:00
addAvailablePaymentMethod( paymentMethod );
continue;
}
allow payment methods to disable based on shipping (API change) (https://github.com/woocommerce/woocommerce-blocks/pull/2840) * allow payment methods to disable based on shipping or other factors: - renamed 'initialized' array 'available' to match primary purpose of `canMakePayment` api - whether payment method should be available - trigger refresh of available payment methods when shopper chooses different shipping method - rename resolveCanMakePayments => refreshCanMakePayments - tweaked some variable names and scope for clarity - added comments to clarify things Note this should not affect behaviour yet - no existing payment methods use this new feature. COD payment method will need this - woocommerce/woocommerce-blocks#2831 * optimise refreshCanMakePayments: - useShallowEqual to avoid unnecessary call when shipping methods have not actually changed (but object value has) * replace ("set") payment methods in store, was appending: - payment methods may come and go depending on cart/checkout state - the previous SET action appended provided payment methods to the collection - this prevents dynamic payment methods e.g. COD from being able to hide i.e. disable * cache test payment request to avoid unnecessary stripe API calls: - in the canMakePayment callback there's a test payment to determine if chrome pay/apple pay is set up and available - canMakePayment is now called multiple times as checkout state changes - now the results of the test payment are stored in variable, and returned on subsequent calls * set init flag to avoid additional attempts to init stripe API: + tweak naming of init flag
2020-07-13 22:52:13 +00:00
// In front end, ask payment method if it should be available.
try {
allow payment methods to disable based on shipping (API change) (https://github.com/woocommerce/woocommerce-blocks/pull/2840) * allow payment methods to disable based on shipping or other factors: - renamed 'initialized' array 'available' to match primary purpose of `canMakePayment` api - whether payment method should be available - trigger refresh of available payment methods when shopper chooses different shipping method - rename resolveCanMakePayments => refreshCanMakePayments - tweaked some variable names and scope for clarity - added comments to clarify things Note this should not affect behaviour yet - no existing payment methods use this new feature. COD payment method will need this - woocommerce/woocommerce-blocks#2831 * optimise refreshCanMakePayments: - useShallowEqual to avoid unnecessary call when shipping methods have not actually changed (but object value has) * replace ("set") payment methods in store, was appending: - payment methods may come and go depending on cart/checkout state - the previous SET action appended provided payment methods to the collection - this prevents dynamic payment methods e.g. COD from being able to hide i.e. disable * cache test payment request to avoid unnecessary stripe API calls: - in the canMakePayment callback there's a test payment to determine if chrome pay/apple pay is set up and available - canMakePayment is now called multiple times as checkout state changes - now the results of the test payment are stored in variable, and returned on subsequent calls * set init flag to avoid additional attempts to init stripe API: + tweak naming of init flag
2020-07-13 22:52:13 +00:00
const canPay = await Promise.resolve(
paymentMethod.canMakePayment( canPayArgument.current )
);
if ( canPay ) {
if ( canPay.error ) {
throw new Error( canPay.error.message );
}
allow payment methods to disable based on shipping (API change) (https://github.com/woocommerce/woocommerce-blocks/pull/2840) * allow payment methods to disable based on shipping or other factors: - renamed 'initialized' array 'available' to match primary purpose of `canMakePayment` api - whether payment method should be available - trigger refresh of available payment methods when shopper chooses different shipping method - rename resolveCanMakePayments => refreshCanMakePayments - tweaked some variable names and scope for clarity - added comments to clarify things Note this should not affect behaviour yet - no existing payment methods use this new feature. COD payment method will need this - woocommerce/woocommerce-blocks#2831 * optimise refreshCanMakePayments: - useShallowEqual to avoid unnecessary call when shipping methods have not actually changed (but object value has) * replace ("set") payment methods in store, was appending: - payment methods may come and go depending on cart/checkout state - the previous SET action appended provided payment methods to the collection - this prevents dynamic payment methods e.g. COD from being able to hide i.e. disable * cache test payment request to avoid unnecessary stripe API calls: - in the canMakePayment callback there's a test payment to determine if chrome pay/apple pay is set up and available - canMakePayment is now called multiple times as checkout state changes - now the results of the test payment are stored in variable, and returned on subsequent calls * set init flag to avoid additional attempts to init stripe API: + tweak naming of init flag
2020-07-13 22:52:13 +00:00
addAvailablePaymentMethod( paymentMethod );
}
} catch ( e ) {
allow payment methods to disable based on shipping (API change) (https://github.com/woocommerce/woocommerce-blocks/pull/2840) * allow payment methods to disable based on shipping or other factors: - renamed 'initialized' array 'available' to match primary purpose of `canMakePayment` api - whether payment method should be available - trigger refresh of available payment methods when shopper chooses different shipping method - rename resolveCanMakePayments => refreshCanMakePayments - tweaked some variable names and scope for clarity - added comments to clarify things Note this should not affect behaviour yet - no existing payment methods use this new feature. COD payment method will need this - woocommerce/woocommerce-blocks#2831 * optimise refreshCanMakePayments: - useShallowEqual to avoid unnecessary call when shipping methods have not actually changed (but object value has) * replace ("set") payment methods in store, was appending: - payment methods may come and go depending on cart/checkout state - the previous SET action appended provided payment methods to the collection - this prevents dynamic payment methods e.g. COD from being able to hide i.e. disable * cache test payment request to avoid unnecessary stripe API calls: - in the canMakePayment callback there's a test payment to determine if chrome pay/apple pay is set up and available - canMakePayment is now called multiple times as checkout state changes - now the results of the test payment are stored in variable, and returned on subsequent calls * set init flag to avoid additional attempts to init stripe API: + tweak naming of init flag
2020-07-13 22:52:13 +00:00
// If user is admin, show payment `canMakePayment` errors as a notice.
handleRegistrationError( e );
}
}
allow payment methods to disable based on shipping (API change) (https://github.com/woocommerce/woocommerce-blocks/pull/2840) * allow payment methods to disable based on shipping or other factors: - renamed 'initialized' array 'available' to match primary purpose of `canMakePayment` api - whether payment method should be available - trigger refresh of available payment methods when shopper chooses different shipping method - rename resolveCanMakePayments => refreshCanMakePayments - tweaked some variable names and scope for clarity - added comments to clarify things Note this should not affect behaviour yet - no existing payment methods use this new feature. COD payment method will need this - woocommerce/woocommerce-blocks#2831 * optimise refreshCanMakePayments: - useShallowEqual to avoid unnecessary call when shipping methods have not actually changed (but object value has) * replace ("set") payment methods in store, was appending: - payment methods may come and go depending on cart/checkout state - the previous SET action appended provided payment methods to the collection - this prevents dynamic payment methods e.g. COD from being able to hide i.e. disable * cache test payment request to avoid unnecessary stripe API calls: - in the canMakePayment callback there's a test payment to determine if chrome pay/apple pay is set up and available - canMakePayment is now called multiple times as checkout state changes - now the results of the test payment are stored in variable, and returned on subsequent calls * set init flag to avoid additional attempts to init stripe API: + tweak naming of init flag
2020-07-13 22:52:13 +00:00
// Re-dispatch available payment methods to store.
dispatcher( availablePaymentMethods );
// Note: some payment methods use the `canMakePayment` callback to initialize / setup.
// Example: Stripe CC, Stripe Payment Request.
// That's why we track "is initialised" state here.
setIsInitialized( true );
Show payment gateways in correct (merchant-configured) order (https://github.com/woocommerce/woocommerce-blocks/pull/2934) * enqueue order of payment gateways as script data * use configured gateway order for payment method tabs * clarify name of payment gateway sort order setting * fix formatting Co-authored-by: Darren Ethier <darren@roughsmootheng.in> * fix bug - express payment methods not working due to ordering logic: - move ordering code to payment methods in usePaymentMethods hook; - this only applies to standard (non express) payment methods - also any code that uses payment methods will get them in correct order * why did this formatting not happen pre-commit? * move method ordering into refreshPaymentMethods to avoid infinite loop: - pass keys of express payment methods so they work correctly (show up) - refreshPaymentMethods dispatches availablePaymentMethods to redux store; I suspect this was causing infinite loop as the callback depends on registeredPaymentMethods - handle case when a payment method is not in PAYMENT_GATEWAY_SORT_ORDER - this happens with COD when dependent on shipping * fix formatting * use shallow equal to prevent refreshCanMakePayments infinite loop * use native Set instead of lodash.union for unique gateway names * code formatting * check to ensure we register paymentGatewaySortOrder asset once only * fix COD tab showing out of order if not available at page load: - return ALL gateways in sort order array - note this includes gateways that are not enabled by merchant * reinstate return bool from usePaymentMethods hook (broken in refactor) * add basic typedefs for payment methods hooks Co-authored-by: Darren Ethier <darren@roughsmootheng.in>
2020-08-05 01:56:33 +00:00
}, [
dispatcher,
isEditor,
registeredPaymentMethods,
paymentMethodsOrder,
] );
allow payment methods to disable based on shipping (API change) (https://github.com/woocommerce/woocommerce-blocks/pull/2840) * allow payment methods to disable based on shipping or other factors: - renamed 'initialized' array 'available' to match primary purpose of `canMakePayment` api - whether payment method should be available - trigger refresh of available payment methods when shopper chooses different shipping method - rename resolveCanMakePayments => refreshCanMakePayments - tweaked some variable names and scope for clarity - added comments to clarify things Note this should not affect behaviour yet - no existing payment methods use this new feature. COD payment method will need this - woocommerce/woocommerce-blocks#2831 * optimise refreshCanMakePayments: - useShallowEqual to avoid unnecessary call when shipping methods have not actually changed (but object value has) * replace ("set") payment methods in store, was appending: - payment methods may come and go depending on cart/checkout state - the previous SET action appended provided payment methods to the collection - this prevents dynamic payment methods e.g. COD from being able to hide i.e. disable * cache test payment request to avoid unnecessary stripe API calls: - in the canMakePayment callback there's a test payment to determine if chrome pay/apple pay is set up and available - canMakePayment is now called multiple times as checkout state changes - now the results of the test payment are stored in variable, and returned on subsequent calls * set init flag to avoid additional attempts to init stripe API: + tweak naming of init flag
2020-07-13 22:52:13 +00:00
// Determine which payment methods are available initially and whenever
// shipping methods change.
// Some payment methods (e.g. COD) can be disabled for specific shipping methods.
useEffect( () => {
allow payment methods to disable based on shipping (API change) (https://github.com/woocommerce/woocommerce-blocks/pull/2840) * allow payment methods to disable based on shipping or other factors: - renamed 'initialized' array 'available' to match primary purpose of `canMakePayment` api - whether payment method should be available - trigger refresh of available payment methods when shopper chooses different shipping method - rename resolveCanMakePayments => refreshCanMakePayments - tweaked some variable names and scope for clarity - added comments to clarify things Note this should not affect behaviour yet - no existing payment methods use this new feature. COD payment method will need this - woocommerce/woocommerce-blocks#2831 * optimise refreshCanMakePayments: - useShallowEqual to avoid unnecessary call when shipping methods have not actually changed (but object value has) * replace ("set") payment methods in store, was appending: - payment methods may come and go depending on cart/checkout state - the previous SET action appended provided payment methods to the collection - this prevents dynamic payment methods e.g. COD from being able to hide i.e. disable * cache test payment request to avoid unnecessary stripe API calls: - in the canMakePayment callback there's a test payment to determine if chrome pay/apple pay is set up and available - canMakePayment is now called multiple times as checkout state changes - now the results of the test payment are stored in variable, and returned on subsequent calls * set init flag to avoid additional attempts to init stripe API: + tweak naming of init flag
2020-07-13 22:52:13 +00:00
refreshCanMakePayments();
}, [ refreshCanMakePayments, selectedShippingMethods ] );
return isInitialized;
};
Show payment gateways in correct (merchant-configured) order (https://github.com/woocommerce/woocommerce-blocks/pull/2934) * enqueue order of payment gateways as script data * use configured gateway order for payment method tabs * clarify name of payment gateway sort order setting * fix formatting Co-authored-by: Darren Ethier <darren@roughsmootheng.in> * fix bug - express payment methods not working due to ordering logic: - move ordering code to payment methods in usePaymentMethods hook; - this only applies to standard (non express) payment methods - also any code that uses payment methods will get them in correct order * why did this formatting not happen pre-commit? * move method ordering into refreshPaymentMethods to avoid infinite loop: - pass keys of express payment methods so they work correctly (show up) - refreshPaymentMethods dispatches availablePaymentMethods to redux store; I suspect this was causing infinite loop as the callback depends on registeredPaymentMethods - handle case when a payment method is not in PAYMENT_GATEWAY_SORT_ORDER - this happens with COD when dependent on shipping * fix formatting * use shallow equal to prevent refreshCanMakePayments infinite loop * use native Set instead of lodash.union for unique gateway names * code formatting * check to ensure we register paymentGatewaySortOrder asset once only * fix COD tab showing out of order if not available at page load: - return ALL gateways in sort order array - note this includes gateways that are not enabled by merchant * reinstate return bool from usePaymentMethods hook (broken in refactor) * add basic typedefs for payment methods hooks Co-authored-by: Darren Ethier <darren@roughsmootheng.in>
2020-08-05 01:56:33 +00:00
/**
* Custom hook for setting up payment methods (standard, non-express).
*
* @param {function(Object):undefined} dispatcher
*
* @return {boolean} True when standard payment methods have been initialized.
*/
export const usePaymentMethods = ( dispatcher ) => {
const standardMethods = getPaymentMethods();
// Ensure all methods are present in order.
// Some payment methods may not be present in PAYMENT_GATEWAY_SORT_ORDER if they
// depend on state, e.g. COD can depend on shipping method.
const displayOrder = new Set( [
...PAYMENT_GATEWAY_SORT_ORDER,
...Object.keys( standardMethods ),
] );
return usePaymentMethodRegistration(
dispatcher,
standardMethods,
Array.from( displayOrder )
);
};
/**
* Custom hook for setting up express payment methods.
*
* @param {function(Object):undefined} dispatcher
*
* @return {boolean} True when express payment methods have been initialized.
*/
export const useExpressPaymentMethods = ( dispatcher ) => {
const expressMethods = getExpressPaymentMethods();
return usePaymentMethodRegistration(
dispatcher,
expressMethods,
Object.keys( expressMethods )
);
};