woocommerce/packages/woocommerce-blocks/assets/js/payment-method-extensions/payment-methods/stripe/credit-card/use-payment-intents.js
2021-12-10 12:03:04 +00:00

105 lines
2.9 KiB
JavaScript

/**
* External dependencies
*/
import { useEffect } from '@wordpress/element';
/**
* @typedef {import('@woocommerce/type-defs/registered-payment-method-props').EmitResponseProps} EmitResponseProps
* @typedef {import('../stripe-utils/type-defs').Stripe} Stripe
*/
/**
* Opens the modal for PaymentIntent authorizations.
*
* @param {Object} params Params object.
* @param {Stripe} params.stripe The stripe object.
* @param {Object} params.paymentDetails The payment details from the
* server after checkout processing.
* @param {string} params.errorContext Context where errors will be added.
* @param {string} params.errorType Type of error responses.
* @param {string} params.successType Type of success responses.
*/
const openIntentModal = ( {
stripe,
paymentDetails,
errorContext,
errorType,
successType,
} ) => {
const checkoutResponse = { type: successType };
if (
! paymentDetails.setup_intent &&
! paymentDetails.payment_intent_secret
) {
return checkoutResponse;
}
const isSetupIntent = !! paymentDetails.setupIntent;
const verificationUrl = paymentDetails.verification_endpoint;
const intentSecret = isSetupIntent
? paymentDetails.setup_intent
: paymentDetails.payment_intent_secret;
return stripe[ isSetupIntent ? 'confirmCardSetup' : 'confirmCardPayment' ](
intentSecret
)
.then( function ( response ) {
if ( response.error ) {
throw response.error;
}
const intent =
response[ isSetupIntent ? 'setupIntent' : 'paymentIntent' ];
if (
intent.status !== 'requires_capture' &&
intent.status !== 'succeeded'
) {
return checkoutResponse;
}
checkoutResponse.redirectUrl = verificationUrl;
return checkoutResponse;
} )
.catch( function ( error ) {
checkoutResponse.type = errorType;
checkoutResponse.message = error.message;
checkoutResponse.retry = true;
checkoutResponse.messageContext = errorContext;
// Reports back to the server.
window.fetch( verificationUrl + '&is_ajax' );
return checkoutResponse;
} );
};
export const usePaymentIntents = (
stripe,
subscriber,
setSourceId,
emitResponse
) => {
useEffect( () => {
const unsubscribe = subscriber( async ( { processingResponse } ) => {
const paymentDetails = processingResponse.paymentDetails || {};
const response = await openIntentModal( {
stripe,
paymentDetails,
errorContext: emitResponse.noticeContexts.PAYMENTS,
errorType: emitResponse.responseTypes.ERROR,
successType: emitResponse.responseTypes.SUCCESS,
} );
if (
response.type === emitResponse.responseTypes.ERROR &&
response.retry
) {
setSourceId( '0' );
}
return response;
} );
return () => unsubscribe();
}, [
subscriber,
emitResponse.noticeContexts.PAYMENTS,
emitResponse.responseTypes.ERROR,
emitResponse.responseTypes.SUCCESS,
setSourceId,
stripe,
] );
};