woocommerce/plugins/woocommerce-blocks/assets/js/payment-method-extensions/payment-methods/stripe/credit-card/use-payment-intents.js

72 lines
2.3 KiB
JavaScript
Raw Normal View History

Refactor checkout status and event emitters to support stripe intents and more complex payment methods. (https://github.com/woocommerce/woocommerce-blocks/pull/2189) * initial mapping out of stripe payment intents * rename checkout processing statuses to be clearer * Add new status and refactor checkout complete behaviour. * Make sure payment result data is included in checkout processing response * add payment intent handling Still testing * make sure promise is returned * include site url with endpoint * modify setComplete status to optionally receive redirectUrl for changing in state at the same time as setting status * fix typo in property retrieval * add error handling for after checkout processing event * add notices area for payment methods * implement error handling for stripe intents * hook into stripe error processing and include error in payment response * clear notices so they don’t show in block and merge payment details * add notice handling to payment context * modify error processing in checkout processor * handle errors with fallback in checkout state context * hook into after processing for stripe cc error handling * set checkout to idle status if before processing emitters result in error * Add emit response type-defs and normalize expectations for observer responses * improve doc block * switch checkoutIsComplete check to checkoutAfterProcessing for payment complete status change * remove unneeded event emitters and consolidate some logic * fix idle status set logic
2020-04-14 16:52:23 +00:00
/**
* 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 {Stripe} stripe The stripe object.
* @param {Object} paymentDetails The payment details from the server after checkout
* processing.
* @param {EmitResponseProps} emitResponse Various helpers for usage with observer response
* objects.
*/
const openIntentModal = ( stripe, paymentDetails, emitResponse ) => {
const checkoutResponse = { type: emitResponse.responseTypes.SUCCESS };
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 = emitResponse.responseTypes.ERROR;
checkoutResponse.message = error.message;
checkoutResponse.retry = true;
checkoutResponse.messageContext =
emitResponse.noticeContexts.PAYMENTS;
// Reports back to the server.
window.fetch( verificationUrl + '&is_ajax' );
return checkoutResponse;
} );
};
export const usePaymentIntents = ( stripe, subscriber, emitResponse ) => {
useEffect( () => {
const unsubscribe = subscriber( ( { processingResponse } ) => {
const paymentDetails = processingResponse.paymentDetails || {};
return openIntentModal( stripe, paymentDetails, emitResponse );
} );
return () => unsubscribe();
}, [ subscriber, stripe ] );
};