diff --git a/client/payment-request/blocks/index.js b/client/payment-request/blocks/index.js index 0ec5b11a2d2..6e44c416c77 100644 --- a/client/payment-request/blocks/index.js +++ b/client/payment-request/blocks/index.js @@ -5,7 +5,6 @@ import { PAYMENT_METHOD_NAME_PAYMENT_REQUEST } from '../../checkout/constants'; import { PaymentRequestExpress } from './payment-request-express'; import { applePayImage } from './apple-pay-preview'; import { getConfig } from '../../utils/checkout'; -import { getPaymentRequest } from '../utils'; const ApplePayPreview = () => ; @@ -13,30 +12,17 @@ const paymentRequestPaymentMethod = ( api ) => ( { name: PAYMENT_METHOD_NAME_PAYMENT_REQUEST, content: , edit: , - canMakePayment: ( cartData ) => { + canMakePayment: () => { // If in the editor context, always return true to display the `edit` prop preview. // https://github.com/woocommerce/woocommerce-gutenberg-products-block/issues/4101. if ( getConfig( 'is_admin' ) ) { return true; } - if ( 'undefined' === typeof wcpayPaymentRequestParams ) { - return false; - } - - return api.loadStripe().then( ( stripe ) => { - // Create a payment request and check if we can make a payment to determine whether to - // show the Payment Request Button or not. This is necessary because a browser might be - // able to load the Stripe JS object, but not support Payment Requests. - const pr = getPaymentRequest( { - stripe, - total: parseInt( cartData?.cartTotals?.total_price ?? 0, 10 ), - requestShipping: cartData?.cartNeedsShipping, - displayItems: [], - } ); - - return pr.canMakePayment(); - } ); + return ( + !! api.getStripe() && + 'undefined' !== typeof wcpayPaymentRequestParams + ); }, paymentMethodId: PAYMENT_METHOD_NAME_PAYMENT_REQUEST, supports: { diff --git a/client/payment-request/blocks/payment-request-express.js b/client/payment-request/blocks/payment-request-express.js index 4ef21d73e2d..11ec67c203e 100644 --- a/client/payment-request/blocks/payment-request-express.js +++ b/client/payment-request/blocks/payment-request-express.js @@ -33,6 +33,7 @@ const PaymentRequestExpressComponent = ( { paymentRequest, // paymentRequestType, // isProcessing, + canMakePayment, onButtonClick, } = useInitialization( { api, @@ -56,7 +57,7 @@ const PaymentRequestExpressComponent = ( { }, }; - if ( ! paymentRequest ) { + if ( ! canMakePayment || ! paymentRequest ) { return null; } diff --git a/client/payment-request/blocks/use-initialization.js b/client/payment-request/blocks/use-initialization.js index ec29f32dce4..ae35e83f3f5 100644 --- a/client/payment-request/blocks/use-initialization.js +++ b/client/payment-request/blocks/use-initialization.js @@ -16,6 +16,7 @@ import { import { getPaymentRequest, updatePaymentRequest, + canDoPaymentRequest, normalizeLineItems, } from '../utils'; @@ -32,6 +33,7 @@ export const useInitialization = ( { const [ paymentRequest, setPaymentRequest ] = useState( null ); const [ isFinished, setIsFinished ] = useState( false ); const [ isProcessing, setIsProcessing ] = useState( false ); + const [ canMakePayment, setCanMakePayment ] = useState( false ); const [ paymentRequestType, setPaymentRequestType ] = useState( '' ); // Create the initial paymentRequest object. Note, we can't do anything if stripe isn't available yet or we have zero total. @@ -53,17 +55,10 @@ export const useInitialization = ( { displayItems: normalizeLineItems( billing?.cartTotalItems ), } ); - pr.canMakePayment().then( ( result ) => { - if ( result ) { - setPaymentRequest( pr ); - if ( result.applePay ) { - setPaymentRequestType( 'apple_pay' ); - } else if ( result.googlePay ) { - setPaymentRequestType( 'google_pay' ); - } else { - setPaymentRequestType( 'payment_request_api' ); - } - } + canDoPaymentRequest( pr ).then( ( result ) => { + setPaymentRequest( pr ); + setPaymentRequestType( result.requestType || '' ); + setCanMakePayment( result.canPay ); } ); }, [ stripe, paymentRequest ] ); @@ -136,6 +131,7 @@ export const useInitialization = ( { return { paymentRequest, isProcessing, + canMakePayment, onButtonClick, paymentRequestType, }; diff --git a/client/payment-request/index.js b/client/payment-request/index.js index 882a5536d72..b3dde0fc1bb 100644 --- a/client/payment-request/index.js +++ b/client/payment-request/index.js @@ -12,7 +12,11 @@ import { paymentMethodHandler, } from './event-handlers.js'; -import { shouldUseGooglePayBrand, getPaymentRequest } from './utils'; +import { + shouldUseGooglePayBrand, + getPaymentRequest, + canDoPaymentRequest, +} from './utils'; jQuery( ( $ ) => { // Don't load if blocks checkout is being loaded. @@ -181,8 +185,8 @@ jQuery( ( $ ) => { ); // Check the availability of the Payment Request API first. - paymentRequest.canMakePayment().then( ( result ) => { - if ( ! result ) { + canDoPaymentRequest( paymentRequest ).then( ( result ) => { + if ( ! result || ! result.canPay ) { return; } diff --git a/client/payment-request/utils/utils.js b/client/payment-request/utils/utils.js index d756657a6af..92dcb121213 100644 --- a/client/payment-request/utils/utils.js +++ b/client/payment-request/utils/utils.js @@ -80,6 +80,35 @@ export const updatePaymentRequest = ( { } ); }; +/** + * Returns whether or not the current session can make payments and what type of request it uses. + * + * @param {Object} paymentRequest A Stripe PaymentRequest instance. + * + * @return {Promise} Object containing canPay and the requestType, which can be either + * - payment_request_api + * - apple_pay + * - google_pay + */ +export const canDoPaymentRequest = ( paymentRequest ) => { + return new Promise( ( resolve ) => { + paymentRequest.canMakePayment().then( ( result ) => { + if ( result ) { + let paymentRequestType = 'payment_request_api'; + if ( result.applePay ) { + paymentRequestType = 'apple_pay'; + } else if ( result.googlePay ) { + paymentRequestType = 'google_pay'; + } + + resolve( { canPay: true, requestType: paymentRequestType } ); + } else { + resolve( { canPay: false } ); + } + } ); + } ); +}; + /** * Get WC AJAX endpoint URL. *