2020-03-10 13:39:21 +00:00
|
|
|
/**
|
|
|
|
* Internal dependencies
|
|
|
|
*/
|
|
|
|
import { TYPES, DEFAULT_STATE, STATUS } from './constants';
|
|
|
|
|
|
|
|
const {
|
|
|
|
SET_PRISTINE,
|
2020-04-14 16:52:23 +00:00
|
|
|
SET_IDLE,
|
2020-03-10 13:39:21 +00:00
|
|
|
SET_PROCESSING,
|
2020-04-14 16:52:23 +00:00
|
|
|
SET_BEFORE_PROCESSING,
|
|
|
|
SET_AFTER_PROCESSING,
|
|
|
|
SET_PROCESSING_RESPONSE,
|
2020-03-10 13:39:21 +00:00
|
|
|
SET_REDIRECT_URL,
|
|
|
|
SET_COMPLETE,
|
|
|
|
SET_HAS_ERROR,
|
|
|
|
SET_NO_ERROR,
|
|
|
|
INCREMENT_CALCULATING,
|
|
|
|
DECREMENT_CALCULATING,
|
2020-03-30 14:32:23 +00:00
|
|
|
SET_ORDER_ID,
|
2020-03-10 13:39:21 +00:00
|
|
|
} = TYPES;
|
|
|
|
|
2020-04-14 16:52:23 +00:00
|
|
|
const {
|
|
|
|
PRISTINE,
|
|
|
|
IDLE,
|
|
|
|
PROCESSING,
|
|
|
|
BEFORE_PROCESSING,
|
|
|
|
AFTER_PROCESSING,
|
|
|
|
COMPLETE,
|
|
|
|
} = STATUS;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Prepares the payment_result data from the server checkout endpoint response.
|
|
|
|
*
|
|
|
|
* @param {Object} data The value of `payment_result` from the checkout
|
|
|
|
* processing endpoint response.
|
2020-04-16 14:39:46 +00:00
|
|
|
* @param {string} data.message If there was a general error message it will appear
|
|
|
|
* on this property.
|
2020-04-14 16:52:23 +00:00
|
|
|
* @param {string} data.payment_status The payment status. One of 'success', 'failure',
|
|
|
|
* 'pending', 'error'.
|
|
|
|
* @param {Array<Object>} data.payment_details An array of Objects with a 'key' property that is a
|
|
|
|
* string and value property that is a string. These are
|
|
|
|
* converted to a flat object where the key becomes the
|
|
|
|
* object property and value the property value.
|
|
|
|
*
|
|
|
|
* @return {Object} A new object with 'paymentStatus', and 'paymentDetails' as the properties.
|
|
|
|
*/
|
|
|
|
export const prepareResponseData = ( data ) => {
|
|
|
|
const responseData = {
|
2020-04-16 14:39:46 +00:00
|
|
|
message: data?.message || '',
|
2020-04-14 16:52:23 +00:00
|
|
|
paymentStatus: data.payment_status,
|
|
|
|
paymentDetails: {},
|
|
|
|
};
|
|
|
|
if ( Array.isArray( data.payment_details ) ) {
|
|
|
|
data.payment_details.forEach( ( { key, value } ) => {
|
|
|
|
responseData.paymentDetails[ key ] = value;
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
return responseData;
|
|
|
|
};
|
2020-03-10 13:39:21 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Reducer for the checkout state
|
|
|
|
*
|
|
|
|
* @param {Object} state Current state.
|
|
|
|
* @param {Object} action Incoming action object.
|
|
|
|
*/
|
2020-04-14 16:52:23 +00:00
|
|
|
export const reducer = (
|
|
|
|
state = DEFAULT_STATE,
|
|
|
|
{ url, type, orderId, data }
|
|
|
|
) => {
|
2020-04-08 15:46:34 +00:00
|
|
|
let newState;
|
2020-03-10 13:39:21 +00:00
|
|
|
switch ( type ) {
|
|
|
|
case SET_PRISTINE:
|
|
|
|
newState = DEFAULT_STATE;
|
|
|
|
break;
|
2020-04-14 16:52:23 +00:00
|
|
|
case SET_IDLE:
|
|
|
|
newState =
|
2020-07-29 11:00:26 +00:00
|
|
|
state.status !== IDLE
|
2020-04-14 16:52:23 +00:00
|
|
|
? {
|
|
|
|
...state,
|
|
|
|
status: IDLE,
|
|
|
|
}
|
|
|
|
: state;
|
|
|
|
break;
|
2020-03-10 13:39:21 +00:00
|
|
|
case SET_REDIRECT_URL:
|
|
|
|
newState =
|
|
|
|
url !== state.url
|
|
|
|
? {
|
|
|
|
...state,
|
|
|
|
redirectUrl: url,
|
|
|
|
}
|
|
|
|
: state;
|
|
|
|
break;
|
2020-04-14 16:52:23 +00:00
|
|
|
case SET_PROCESSING_RESPONSE:
|
|
|
|
newState = {
|
|
|
|
...state,
|
|
|
|
processingResponse: data,
|
|
|
|
};
|
|
|
|
break;
|
|
|
|
|
2020-03-10 13:39:21 +00:00
|
|
|
case SET_COMPLETE:
|
|
|
|
newState =
|
2020-04-08 15:46:34 +00:00
|
|
|
state.status !== COMPLETE
|
2020-03-10 13:39:21 +00:00
|
|
|
? {
|
|
|
|
...state,
|
2020-04-08 15:46:34 +00:00
|
|
|
status: COMPLETE,
|
2020-04-15 15:43:03 +00:00
|
|
|
redirectUrl: data?.redirectUrl || state.redirectUrl,
|
2020-03-10 13:39:21 +00:00
|
|
|
}
|
|
|
|
: state;
|
|
|
|
break;
|
|
|
|
case SET_PROCESSING:
|
|
|
|
newState =
|
2020-04-08 15:46:34 +00:00
|
|
|
state.status !== PROCESSING
|
2020-03-10 13:39:21 +00:00
|
|
|
? {
|
|
|
|
...state,
|
2020-04-08 15:46:34 +00:00
|
|
|
status: PROCESSING,
|
2020-03-10 13:39:21 +00:00
|
|
|
hasError: false,
|
|
|
|
}
|
|
|
|
: state;
|
|
|
|
// clear any error state.
|
|
|
|
newState =
|
|
|
|
newState.hasError === false
|
|
|
|
? newState
|
|
|
|
: { ...newState, hasError: false };
|
|
|
|
break;
|
2020-04-14 16:52:23 +00:00
|
|
|
case SET_BEFORE_PROCESSING:
|
2020-04-03 11:50:54 +00:00
|
|
|
newState =
|
2020-04-14 16:52:23 +00:00
|
|
|
state.status !== BEFORE_PROCESSING
|
2020-04-03 11:50:54 +00:00
|
|
|
? {
|
|
|
|
...state,
|
2020-04-14 16:52:23 +00:00
|
|
|
status: BEFORE_PROCESSING,
|
2020-04-03 11:50:54 +00:00
|
|
|
hasError: false,
|
|
|
|
}
|
|
|
|
: state;
|
|
|
|
break;
|
2020-04-14 16:52:23 +00:00
|
|
|
case SET_AFTER_PROCESSING:
|
|
|
|
newState =
|
|
|
|
state.status !== AFTER_PROCESSING
|
|
|
|
? {
|
|
|
|
...state,
|
|
|
|
status: AFTER_PROCESSING,
|
|
|
|
}
|
|
|
|
: state;
|
|
|
|
break;
|
2020-03-10 13:39:21 +00:00
|
|
|
case SET_HAS_ERROR:
|
|
|
|
newState = state.hasError
|
|
|
|
? state
|
|
|
|
: {
|
|
|
|
...state,
|
|
|
|
hasError: true,
|
|
|
|
};
|
|
|
|
newState =
|
2020-04-03 11:50:54 +00:00
|
|
|
state.status === PROCESSING ||
|
2020-04-14 16:52:23 +00:00
|
|
|
state.status === BEFORE_PROCESSING
|
2020-03-10 13:39:21 +00:00
|
|
|
? {
|
|
|
|
...newState,
|
|
|
|
status: IDLE,
|
|
|
|
}
|
|
|
|
: newState;
|
|
|
|
break;
|
|
|
|
case SET_NO_ERROR:
|
|
|
|
newState = state.hasError
|
|
|
|
? {
|
|
|
|
...state,
|
|
|
|
hasError: false,
|
|
|
|
}
|
|
|
|
: state;
|
|
|
|
break;
|
|
|
|
case INCREMENT_CALCULATING:
|
|
|
|
newState = {
|
|
|
|
...state,
|
|
|
|
calculatingCount: state.calculatingCount + 1,
|
|
|
|
};
|
|
|
|
break;
|
|
|
|
case DECREMENT_CALCULATING:
|
|
|
|
newState = {
|
|
|
|
...state,
|
|
|
|
calculatingCount: Math.max( 0, state.calculatingCount - 1 ),
|
|
|
|
};
|
|
|
|
break;
|
2020-03-30 14:32:23 +00:00
|
|
|
case SET_ORDER_ID:
|
|
|
|
newState = {
|
|
|
|
...state,
|
|
|
|
orderId,
|
|
|
|
};
|
|
|
|
break;
|
2020-03-10 13:39:21 +00:00
|
|
|
}
|
|
|
|
// automatically update state to idle from pristine as soon as it
|
|
|
|
// initially changes.
|
|
|
|
if (
|
|
|
|
newState !== state &&
|
|
|
|
type !== SET_PRISTINE &&
|
|
|
|
newState.status === PRISTINE
|
|
|
|
) {
|
|
|
|
newState.status = IDLE;
|
|
|
|
}
|
|
|
|
return newState;
|
|
|
|
};
|