132 lines
3.5 KiB
TypeScript
132 lines
3.5 KiB
TypeScript
/**
|
|
* External dependencies
|
|
*/
|
|
import type { CheckoutResponse } from '@woocommerce/types';
|
|
import { store as noticesStore } from '@wordpress/notices';
|
|
|
|
/**
|
|
* Internal dependencies
|
|
*/
|
|
import { removeNoticesByStatus } from '../../utils/notices';
|
|
import {
|
|
getPaymentResultFromCheckoutResponse,
|
|
runCheckoutAfterProcessingWithErrorObservers,
|
|
runCheckoutAfterProcessingWithSuccessObservers,
|
|
} from './utils';
|
|
import {
|
|
EVENTS,
|
|
emitEvent,
|
|
emitEventWithAbort,
|
|
} from '../../base/context/providers/cart-checkout/checkout-events/event-emit';
|
|
import type {
|
|
emitValidateEventType,
|
|
emitAfterProcessingEventsType,
|
|
} from './types';
|
|
import type { DispatchFromMap } from '../mapped-types';
|
|
import * as actions from './actions';
|
|
|
|
/**
|
|
* Based on the result of the payment, update the redirect url,
|
|
* set the payment processing response in the checkout data store
|
|
* and change the status to AFTER_PROCESSING
|
|
*/
|
|
export const processCheckoutResponse = ( response: CheckoutResponse ) => {
|
|
return ( {
|
|
dispatch,
|
|
}: {
|
|
dispatch: DispatchFromMap< typeof actions >;
|
|
} ) => {
|
|
const paymentResult = getPaymentResultFromCheckoutResponse( response );
|
|
dispatch.setRedirectUrl( paymentResult?.redirectUrl || '' );
|
|
dispatch.setPaymentResult( paymentResult );
|
|
dispatch.setAfterProcessing();
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Emit the CHECKOUT_VALIDATION_BEFORE_PROCESSING event and process all
|
|
* registered observers
|
|
*/
|
|
export const emitValidateEvent: emitValidateEventType = ( {
|
|
observers,
|
|
setValidationErrors, // TODO: Fix this type after we move to validation store
|
|
} ) => {
|
|
return ( { dispatch, registry } ) => {
|
|
const { createErrorNotice } = registry.dispatch( noticesStore );
|
|
removeNoticesByStatus( 'error' );
|
|
emitEvent(
|
|
observers,
|
|
EVENTS.CHECKOUT_VALIDATION_BEFORE_PROCESSING,
|
|
{}
|
|
).then( ( response ) => {
|
|
if ( response !== true ) {
|
|
if ( Array.isArray( response ) ) {
|
|
response.forEach(
|
|
( { errorMessage, validationErrors } ) => {
|
|
createErrorNotice( errorMessage, {
|
|
context: 'wc/checkout',
|
|
} );
|
|
setValidationErrors( validationErrors );
|
|
}
|
|
);
|
|
}
|
|
dispatch.setIdle();
|
|
dispatch.setHasError();
|
|
} else {
|
|
dispatch.setProcessing();
|
|
}
|
|
} );
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Emit the CHECKOUT_AFTER_PROCESSING_WITH_ERROR if the checkout contains an error,
|
|
* or the CHECKOUT_AFTER_PROCESSING_WITH_SUCCESS if not. Set checkout errors according
|
|
* to the observer responses
|
|
*/
|
|
export const emitAfterProcessingEvents: emitAfterProcessingEventsType = ( {
|
|
observers,
|
|
notices,
|
|
} ) => {
|
|
return ( { select, dispatch, registry } ) => {
|
|
const { createErrorNotice } = registry.dispatch( noticesStore );
|
|
const state = select.getCheckoutState();
|
|
const data = {
|
|
redirectUrl: state.redirectUrl,
|
|
orderId: state.orderId,
|
|
customerId: state.customerId,
|
|
orderNotes: state.orderNotes,
|
|
processingResponse: state.paymentResult,
|
|
};
|
|
if ( state.hasError ) {
|
|
// allow payment methods or other things to customize the error
|
|
// with a fallback if nothing customizes it.
|
|
emitEventWithAbort(
|
|
observers,
|
|
EVENTS.CHECKOUT_AFTER_PROCESSING_WITH_ERROR,
|
|
data
|
|
).then( ( observerResponses ) => {
|
|
runCheckoutAfterProcessingWithErrorObservers( {
|
|
observerResponses,
|
|
notices,
|
|
dispatch,
|
|
createErrorNotice,
|
|
data,
|
|
} );
|
|
} );
|
|
} else {
|
|
emitEventWithAbort(
|
|
observers,
|
|
EVENTS.CHECKOUT_AFTER_PROCESSING_WITH_SUCCESS,
|
|
data
|
|
).then( ( observerResponses: unknown[] ) => {
|
|
runCheckoutAfterProcessingWithSuccessObservers( {
|
|
observerResponses,
|
|
dispatch,
|
|
createErrorNotice,
|
|
} );
|
|
} );
|
|
}
|
|
};
|
|
};
|