UNPKG

gapp-payment-method-flow

Version:

Mobile Gapp flow for Payment Method

499 lines (471 loc) 21.7 kB
import { useCallback, useEffect, useState } from 'react'; import { httpRequest } from '../shared/httpRequest'; import axios from 'axios'; /** Initial value for payment method */ const paymentMethodInitialValues = { id: 0, text: '', value: '' }; /** view model of payment method gapp */ function useViewModel(_ref) { var _dataIn$actions5; let { dataLoad, dataIn, dataOut } = _ref; const [paymentMethods, setPaymentMethods] = useState([]); const [newDataLoad, setNewDataLoad] = useState([]); const [tempSelectedPaymentMethod, setTempSelectedPaymentMethod] = useState(paymentMethodInitialValues); const [paymentMethodDataOut, setPaymentMethodDataOut] = useState({ loading: false, paymentMethod: {}, cardDetails: {}, errorResponse: {}, savedCard: {}, defaultCardId: 0, savedCards: (dataLoad === null || dataLoad === void 0 ? void 0 : dataLoad.savedCards) || [] }); const { data: dataLoadData, axios: axiosInstance, cardValidationToken, endpoints, token, baseUrl, validateCardUrl, ...resDataLoad } = dataLoad || {}; const dataLoadType = dataIn.dataLoadType || 'json-stab'; const data = dataLoadType === 'json-stab' ? dataLoadData : [...paymentMethods]; const isCardValidate = (dataIn === null || dataIn === void 0 ? void 0 : dataIn.isCardValidate) || false; const cardFormTrigger = (dataIn === null || dataIn === void 0 ? void 0 : dataIn.cardFormTrigger) || ''; const cardFormTriggerKey = (dataIn === null || dataIn === void 0 ? void 0 : dataIn.cardFormTriggerKey) || 'text'; /** dataIn function to reconstruct the list of payment method */ const constructedData = () => { const newData = data.map(i => { var _i$merchant_processor; return { id: i === null || i === void 0 ? void 0 : i.id, text: i === null || i === void 0 ? void 0 : i.name, value: i === null || i === void 0 ? void 0 : i.name, subText: i.description, descriptionText: '', isExpanded: i.expanded || true, child: (i.merchant_processors || []).length > 0 ? (_i$merchant_processor = i.merchant_processors) === null || _i$merchant_processor === void 0 ? void 0 : _i$merchant_processor.map(d => { var _d$processors, _d$processors2, _d$processors3, _d$processors4; return { id: d === null || d === void 0 ? void 0 : d.id, text: (_d$processors = d.processors) === null || _d$processors === void 0 ? void 0 : _d$processors.name, value: (_d$processors2 = d.processors) === null || _d$processors2 === void 0 ? void 0 : _d$processors2.name, subText: (_d$processors3 = d.processors) === null || _d$processors3 === void 0 ? void 0 : _d$processors3.description, descriptionText: '', imageUri: ((_d$processors4 = d.processors) === null || _d$processors4 === void 0 ? void 0 : _d$processors4.icon_url) || undefined }; }) : undefined }; }); const isNewDataLoad = Array.isArray(newDataLoad) && newDataLoad.length > 0; const dLoad = isNewDataLoad ? newDataLoad : newData; if (dataIn.constructData) { return dataIn.constructData(dLoad, data); } else { return dLoad || []; } }; /** dataOut function of Payment Method MiniApp * like MethodSelection, MethodSelectionAccordion */ const handleSelectPaymentMethod = values => { const newPaymentMethod = (values === null || values === void 0 ? void 0 : values.type) === 'Selected' && values !== null && values !== void 0 && values.value ? values === null || values === void 0 ? void 0 : values.value : values; const newPaymentMethods = (values === null || values === void 0 ? void 0 : values.type) === 'NewDataLoad' && values !== null && values !== void 0 && values.value ? values === null || values === void 0 ? void 0 : values.value : newDataLoad; setPaymentMethodDataOut({ ...paymentMethodDataOut, errorResponse: {}, paymentMethod: newPaymentMethod }); setNewDataLoad(newPaymentMethods); }; /** dataOut function of Payment Method MiniApp * (MethodSelectionAccordionScreen) */ const handleSubmitPaymentMethodAccordion = async values => { var _values$selectedSaved, _paymentMethodDataOut, _values$selectedSaved2, _values$selectedSaved3, _values$selectedSaved4; const newPaymentMethod = values === null || values === void 0 ? void 0 : values.selectedMethod; const newCardDetails = { ...((_values$selectedSaved = values.selectedSavedCard) === null || _values$selectedSaved === void 0 ? void 0 : _values$selectedSaved.value), isSavedCard: true }; const newSavedCard = values === null || values === void 0 ? void 0 : values.selectedSavedCard; const newPaymentMethods = (values === null || values === void 0 ? void 0 : values.newData) || newDataLoad; const hasTokenId = cardFormTrigger === newPaymentMethod[cardFormTriggerKey] && newSavedCard !== null && newSavedCard !== void 0 && newSavedCard.id && (_paymentMethodDataOut = paymentMethodDataOut.cardDetails) !== null && _paymentMethodDataOut !== void 0 && _paymentMethodDataOut.paymentTokenId ? true : false; const validatedCard = hasTokenId ? {} : (values === null || values === void 0 ? void 0 : (_values$selectedSaved2 = values.selectedSavedCard) === null || _values$selectedSaved2 === void 0 ? void 0 : (_values$selectedSaved3 = _values$selectedSaved2.value) === null || _values$selectedSaved3 === void 0 ? void 0 : _values$selectedSaved3.cardNumber) && (await validateCreditDebitCard(values === null || values === void 0 ? void 0 : (_values$selectedSaved4 = values.selectedSavedCard) === null || _values$selectedSaved4 === void 0 ? void 0 : _values$selectedSaved4.value)); setPaymentMethodDataOut({ ...paymentMethodDataOut, errorResponse: {}, cardDetails: Object.assign(newCardDetails, validatedCard), paymentMethod: newPaymentMethod, savedCard: newSavedCard }); setNewDataLoad(newPaymentMethods); }; const handleCardFormTrigger = methodValues => { var _dataIn$actions; setTempSelectedPaymentMethod(methodValues); if (dataIn !== null && dataIn !== void 0 && (_dataIn$actions = dataIn.actions) !== null && _dataIn$actions !== void 0 && _dataIn$actions.handleCardFormTrigger && methodValues[cardFormTriggerKey] === cardFormTrigger) { var _dataIn$actions2; dataIn === null || dataIn === void 0 ? void 0 : (_dataIn$actions2 = dataIn.actions) === null || _dataIn$actions2 === void 0 ? void 0 : _dataIn$actions2.handleCardFormTrigger(methodValues); } }; const handleAddNewCard = methodValues => { var _dataIn$actions3; setTempSelectedPaymentMethod(methodValues); if (dataIn !== null && dataIn !== void 0 && (_dataIn$actions3 = dataIn.actions) !== null && _dataIn$actions3 !== void 0 && _dataIn$actions3.handleAddNewCard) { var _dataIn$actions4; dataIn === null || dataIn === void 0 ? void 0 : (_dataIn$actions4 = dataIn.actions) === null || _dataIn$actions4 === void 0 ? void 0 : _dataIn$actions4.handleAddNewCard(methodValues); } }; const validateCreditDebitCard = async values => { try { var _values$cardNumber; let validatedCard = {}; const cardPayload = { card: { number: values === null || values === void 0 ? void 0 : (_values$cardNumber = values.cardNumber) === null || _values$cardNumber === void 0 ? void 0 : _values$cardNumber.replace(/-/g, ''), expMonth: values.mm, expYear: values.yy, cvc: values.cvv } }; setPaymentMethodDataOut({ ...paymentMethodDataOut, loading: true }); const networkServiceCondition1 = dataLoadType === 'network-service-config' && validateCardUrl && cardValidationToken; const networkServiceCondition2 = dataLoadType === 'network-service' && cardValidationToken && validateCardUrl; if (isCardValidate) { if (networkServiceCondition1) { const validateRes = await httpRequest({ tokenType: 'Basic', ...resDataLoad, url: `${validateCardUrl}`, method: 'POST', bearerToken: cardValidationToken, requestPostData: cardPayload }); const res = (validateRes === null || validateRes === void 0 ? void 0 : validateRes.data) || validateRes; validatedCard = { paymentTokenId: res === null || res === void 0 ? void 0 : res.paymentTokenId, state: res === null || res === void 0 ? void 0 : res.state }; } else if (networkServiceCondition2) { const validateRes = await axios.post(validateCardUrl, cardPayload, { headers: { 'Accept': 'application/json', 'Content-type': 'application/json;charset=utf-8', 'Authorization': `${(resDataLoad === null || resDataLoad === void 0 ? void 0 : resDataLoad.tokenType) || 'Basic'} ${cardValidationToken}` } }); const res = (validateRes === null || validateRes === void 0 ? void 0 : validateRes.data) || validateRes; validatedCard = { paymentTokenId: res === null || res === void 0 ? void 0 : res.paymentTokenId, state: res === null || res === void 0 ? void 0 : res.state }; } } return validatedCard; } catch (err) { var _err$response; const error = (err === null || err === void 0 ? void 0 : (_err$response = err.response) === null || _err$response === void 0 ? void 0 : _err$response.data) || (err === null || err === void 0 ? void 0 : err.data) || err; console.error('error at validating card form located on payment method gapp', error); setPaymentMethodDataOut({ ...paymentMethodDataOut, errorResponse: (err === null || err === void 0 ? void 0 : err.response) || err, loading: false }); } }; // @ts-ignore const verifyCardNumberType = numberCard => { const cardTypes = { 'Electron': /^(4026|417500|4405|4508|4844|4913|4917)\d+$/, 'Maestro': /^(5018|5020|5038|5612|5893|6304|6759|6761|6762|6763|0604|6390)\d+$/, 'Dankort': /^(5019)\d+$/, 'Interpayment': /^(636)\d+$/, 'Union Pay': /^(62|88)\d+$/, // Visa card numbers start with a 4. 'Visa': /^4[0-9]{6,}$/g, // MasterCard numbers start with the numbers 51 through 55, // but this will only detect MasterCard credit cards; // there are other cards issued using the MasterCard system that // do not fall into this IIN range. In 2016, they will add numbers // in the range (222100-272099). 'Master Card': /^5[1-5][0-9]{5,}|222[1-9][0-9]{3,}|22[3-9][0-9]{4,}|2[3-6][0-9]{5,}|27[01][0-9]{4,}|2720[0-9]{3,}$/g, // American Express card numbers start with 34 or 37. 'American Express': /^3[47][0-9]{5,}$/g, // Diners Club card numbers begin with 300 through 305, 36 or 38. There are Diners Club cards that begin with 5 and have 16 digits. These are a joint venture between Diners Club and MasterCard and should be processed like a MasterCard. 'Diner Club': /^3(?:0[0-5]|[68][0-9])[0-9]{4,}$/g, // Discover card numbers begin with 6011 or 65. 'Discover': /^6(?:011|5[0-9]{2})[0-9]{3,}$/g, // JCB cards begin with 2131, 1800 or 35. 'JCB': /^(?:2131|1800|35[0-9]{3})[0-9]{3,}$/g }; for (const nType in cardTypes) { if (cardTypes[nType].test(numberCard)) { return nType; } } }; /** handle dataOut of CardForm */ const handleCardFormDataOut = async values => { try { const validatedCard = await validateCreditDebitCard(values); // if (typeof values?.isSavedCard === 'boolean') { setPaymentMethodDataOut({ ...paymentMethodDataOut, loading: false, errorResponse: {}, paymentMethod: tempSelectedPaymentMethod, cardDetails: Object.assign(values, validatedCard) }); // } else { // setPaymentMethodDataOut({ // ...paymentMethodDataOut, // loading: false, // errorResponse: {}, // cardDetails: Object.assign(values, validatedCard), // }); // } } catch (err) { var _err$response2; const error = (err === null || err === void 0 ? void 0 : (_err$response2 = err.response) === null || _err$response2 === void 0 ? void 0 : _err$response2.data) || (err === null || err === void 0 ? void 0 : err.data) || err; console.error('error at submitting card details located on payment method gapp', error); setPaymentMethodDataOut({ ...paymentMethodDataOut, errorResponse: (err === null || err === void 0 ? void 0 : err.response) || err, loading: false }); } }; /** handle dataOut of CardForm */ // const handleCardFormDataOut2 = async (values: any) => { // try { // setPaymentMethodDataOut({ // ...paymentMethodDataOut, // loading: true, // }); // const validatedCard: any = await validateCreditDebitCard(values); // const numberCard: string = (values?.cardNumber || '')?.replace( // /(-)*/g, // '' // ); // const cardDetailsValue = { // cardNumber: numberCard, // '5123-4567-8901-2346', // cvv: values?.cvv, // mm: values?.mm, // name: values?.name, // yy: values?.yy, // }; // if (typeof values?.isSavedCard === 'boolean') { // const privacyCardNumber = numberCard?.replace(/.{12}/g, '**********'); // const savedCardsLength: number = ( // paymentMethodDataOut?.savedCards || [] // )?.length; // // const hasSavedCards: boolean = savedCardsLength > 0; // const savedCardNewId: number = savedCardsLength + 1; // const savedCardDetails = { // id: savedCardNewId, // name: verifyCardNumberType(numberCard) || '', // card_number: privacyCardNumber, // '**********2346', // promo: '', // value: cardDetailsValue, // }; // const cards = paymentMethodDataOut?.savedCards?.concat([ // savedCardDetails, // ]); // setPaymentMethodDataOut({ // ...paymentMethodDataOut, // loading: false, // errorResponse: {}, // paymentMethod: tempSelectedPaymentMethod, // cardDetails: Object.assign(values, cardDetailsValue, validatedCard), // defaultCardId: values?.isSavedCard // ? values.id // : paymentMethodDataOut?.defaultCardId, // savedCards: values?.isSavedCard // ? cards // : paymentMethodDataOut?.savedCards, // }); // } else { // setPaymentMethodDataOut({ // ...paymentMethodDataOut, // loading: false, // errorResponse: {}, // cardDetails: Object.assign(values, cardDetailsValue, validatedCard), // }); // } // } catch (err: any) { // const error = err?.response?.data || err?.data || err; // console.error( // 'error at submitting card details located on payment method gapp', // error // ); // setPaymentMethodDataOut({ // ...paymentMethodDataOut, // errorResponse: err?.response || err, // loading: false, // }); // } // }; // const handleSavedCardScreenDataOut = async ({ // defaultId, // newData, // newSelected, // }: { // defaultId?: number | string; // newData: any; // newSelected: any; // }) => { // const cardDefaultID = newData.filter((n: any) => n.id === defaultId); // const cardNotDefaultID = newData.filter((n: any) => n.id !== defaultId); // setPaymentMethodDataOut({ // ...paymentMethodDataOut, // defaultCardId: cardDefaultID?.length === 1 ? defaultId : 0, // savedCards: cardDefaultID.concat(cardNotDefaultID), // savedCard: newSelected, // }); // }; // api request and set to state action (case 1 - network-service-config) const fetchItems = useCallback(async () => { try { const networkServiceCondition1 = dataLoadType === 'network-service-config' && (endpoints === null || endpoints === void 0 ? void 0 : endpoints.getAll); const networkServiceCondition2 = dataLoadType === 'network-service' && (endpoints === null || endpoints === void 0 ? void 0 : endpoints.getAll) && axiosInstance; if (networkServiceCondition1) { var _res$data; setPaymentMethodDataOut({ ...paymentMethodDataOut, errorResponse: {}, loading: true }); const res = await httpRequest({ url: `${baseUrl}${endpoints === null || endpoints === void 0 ? void 0 : endpoints.getAll}`, method: 'GET', bearerToken: token, tokenType: 'Bearer', ...resDataLoad }); setPaymentMethods((res === null || res === void 0 ? void 0 : (_res$data = res.data) === null || _res$data === void 0 ? void 0 : _res$data.data) || (res === null || res === void 0 ? void 0 : res.data) || []); setPaymentMethodDataOut({ ...paymentMethodDataOut, errorResponse: {}, loading: false }); } else if (networkServiceCondition2) { var _res$data2; setPaymentMethodDataOut({ ...paymentMethodDataOut, errorResponse: {}, loading: true }); const res = await axiosInstance.get(endpoints === null || endpoints === void 0 ? void 0 : endpoints.getAll); setPaymentMethods((res === null || res === void 0 ? void 0 : (_res$data2 = res.data) === null || _res$data2 === void 0 ? void 0 : _res$data2.data) || (res === null || res === void 0 ? void 0 : res.data) || []); setPaymentMethodDataOut({ ...paymentMethodDataOut, errorResponse: {}, loading: false }); } } catch (err) { const error = (err === null || err === void 0 ? void 0 : err.response) || err; console.error('error at fetching payment method list located on payment method gapp', error); setPaymentMethodDataOut({ ...paymentMethodDataOut, loading: false, errorResponse: error }); } }, []); // life-cycle method to run api request useEffect(() => { fetchItems(); }, [endpoints === null || endpoints === void 0 ? void 0 : endpoints.getAll]); // life-cycle method to dataOut (your GApp) useEffect(() => { dataOut(paymentMethodDataOut); }, [paymentMethodDataOut]); // useEffect(() => { // if (Array.isArray(dataLoad?.savedCards)) { // setPaymentMethodDataOut({ // ...paymentMethodDataOut, // savedCards: dataLoad?.savedCards, // }); // console.log('render dataLoad Saved cards', dataLoad?.savedCards); // } // }, [JSON.stringify(dataLoad?.savedCards)]); return { /** mini-app/screen key (compatible to: MethodSelection) */ 'payment-method': { dataLoad: constructedData() }, /** mini-app/screen key (compatible to: MethodSelectionAccordion) */ 'payment-method-accordion-list': { dataLoad: constructedData(), dataIn: { selectedPaymentMethod: paymentMethodDataOut.paymentMethod[cardFormTriggerKey] === cardFormTrigger ? paymentMethodInitialValues : paymentMethodDataOut.paymentMethod }, dataOut: handleSelectPaymentMethod }, /** mini-app/screen key (compatible to: MethodSelectionAccordionScreen) */ 'payment-method-accordion-screen': { dataLoad: constructedData(), dataIn: { selectedPaymentMethod: paymentMethodDataOut.paymentMethod[cardFormTriggerKey] === cardFormTrigger ? paymentMethodInitialValues : paymentMethodDataOut.paymentMethod, cardFormTrigger, handleCardFormTrigger, savedCards: dataLoad === null || dataLoad === void 0 ? void 0 : dataLoad.savedCards, onPressNewCard: handleAddNewCard, onPressManageCard: dataIn === null || dataIn === void 0 ? void 0 : (_dataIn$actions5 = dataIn.actions) === null || _dataIn$actions5 === void 0 ? void 0 : _dataIn$actions5.handleManageCard }, dataOut: handleSubmitPaymentMethodAccordion }, /** mini-app/screen key (compatible to: MethodSelectionAccordionScreen) */ // 'payment-method-accordion-screen2': { // dataLoad: constructedData(), // dataIn: { // selectedPaymentMethod: // paymentMethodDataOut.paymentMethod?.text === cardFormTrigger // ? paymentMethodInitialValues // : paymentMethodDataOut.paymentMethod, // cardFormTrigger, // handleCardFormTrigger, // savedCards: paymentMethodDataOut?.savedCards, // onPressNewCard: handleAddNewCard, // onPressManageCard: dataIn?.actions?.handleManageCard, // }, // dataOut: handleSubmitPaymentMethodAccordion, // }, /** mini-app/screen key (compatible to: CardForm) */ 'card-form-details': { dataOut: handleCardFormDataOut }, /** mini-app/screen key (compatible to: CardForm) */ // 'card-form-details2': { // dataOut: handleCardFormDataOut2, // }, /** mini-app/screen key (compatible to: SavedCardScreen) */ 'saved-card-screen': { dataLoad: { data: dataLoad === null || dataLoad === void 0 ? void 0 : dataLoad.savedCards } } // 'saved-card-screen-2': { // dataLoad: { // data: paymentMethodDataOut?.savedCards, // }, // dataOut: handleSavedCardScreenDataOut, // }, }; } export default useViewModel; //# sourceMappingURL=useViewModel.js.map