diff --git a/src/layouts/payment-adyen/payment-adyen.vue b/src/layouts/payment-adyen/payment-adyen.vue index b407f9d55..bbdf33719 100644 --- a/src/layouts/payment-adyen/payment-adyen.vue +++ b/src/layouts/payment-adyen/payment-adyen.vue @@ -4,6 +4,16 @@
+
+ +
@@ -45,6 +55,7 @@ import Form from "vee-validate"; import funnelHeader from "@/fmg-components/funnel-header/funnel-header"; import navbar from "@/fmg-components/nav-bar/nav-bar"; import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header"; +import alert from "@/ux-components/alert/alert"; import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; import { settleAllPromises } from "@/helpers/layout-helper"; @@ -75,6 +86,8 @@ export default { data() { return { sessionId: String, + dropinComponent: null, + hasPaymentFailureError: false, }; }, @@ -92,9 +105,15 @@ export default { const resultMap = await settleAllPromises(promiseResultMap); + const hasExistingPiaError = to.query?.piaFailure; + // Hydrate page with results next(async (vm) => { vm.setCmsContent(resultMap.cmsContent); + + if (hasExistingPiaError) { + vm.hasPaymentFailureError = true; + } }); }, @@ -184,9 +203,9 @@ export default { debugLog("providerLocation.city:", providerLocation.city, !preReqResult); debugLog("providerLocation.state:", providerLocation.state, !preReqResult); debugLog("providerLocation.zipCode:", providerLocation.zipCode, !preReqResult); - + debugLog("", null, !preReqResult); - + debugLog("isInsuranceSet:", isInsuranceSet, !preReqResult); debugLog("", null, !preReqResult); @@ -197,7 +216,7 @@ export default { debugLog("schedule.endTime:", schedule.endTime, !preReqResult); debugLog("schedule.jobMaxMinutes:", schedule.jobMaxMinutes, !preReqResult); debugLog("schedule.jobMinMinutes:", schedule.jobMinMinutes, !preReqResult); - + debugLog("", null, !preReqResult); debugLog("customerReqs:", customerReqs, !preReqResult); @@ -205,7 +224,7 @@ export default { debugLog("customer.lastName:", customer.lastName, !preReqResult); debugLog("customer.phoneNumber:", customer.phoneNumber, !preReqResult); debugLog("customer.emailAddress:", customer.emailAddress, !preReqResult); - + debugLog("", null, !preReqResult); debugLog("paymentMethodReqs:", paymentMethodReqs, !preReqResult); @@ -292,7 +311,11 @@ export default { name: "Credit or debit card", }, }, - }).mount("#adyen-container"); + }); + + this.dropinComponent = dropin; + + dropin.mount("#adyen-container"); }, async handleCompletedPayment(result) { @@ -382,33 +405,33 @@ export default { console.log(`Result =`); console.log(result); - // Fetch session info - const paymentSessionRequest = { - zipCodeCtu: this.locationInfo.zipCodeCtu, - workOrderNumber: this.workOrderNumberLastSixDigits, - sourceSystem: this.sourceSystem, - sessionId: this.sessionId, - sessionResult: result?.sessionResult, - }; + const wasPaymentCancelled = result?.resultCode === "Cancelled"; - console.log(`Get session payload =`); - console.log(paymentSessionRequest); + if (!wasPaymentCancelled) { + const stringToLog = `ADYEN PAYMENT NOT AUTHORIZED. Code = ${result?.resultCode}. Id = ${this.sessionId}`; - try { - const response = await globalMethods.callHttpClient({ - method: endpoints.GetAdyenSessionResult.method, - endpoint: endpoints.GetAdyenSessionResult.url, - payload: paymentSessionRequest, - logApiCall: true, - pageNameToLog: "payment-adyen", - }); + await global.$logger.logError(stringToLog); - console.log(response); - } catch (error) { - console.log(`Error getting session info after failure.`); + this.hasPaymentFailureError = true; } + + this.dropinComponent?.update(); + }, + async handleError(error) { + console.log(error); + + const wasPaymentCancelled = error?.name === "CANCEL"; + + if (!wasPaymentCancelled) { + const stringToLog = `ADYEN ERROR. Name = ${error?.name}. Details = ${error?.message}.`; + + await global.$logger.logError(stringToLog); + + this.hasPaymentFailureError = true; + } + + this.dropinComponent?.update(); }, - handleError(error) {}, async saveAndSubmitWorkOrder() { // Work order submission after successful payment. @@ -421,15 +444,10 @@ export default { } catch (error) { console.log(`error: response from submit work order: ${error.message}`); - // navigate to error page - const errorPayload = { - cause: `Error while submitting work order after Adyen payment.`, - currentPage: this.pageName, - sessionId: this.sessionId, - idempotencyKey: this.idempotencyKey, - }; - - this.$router.handleSoftError(errorPayload); + this.$router.navigateWithoutSaving( + this.navigationScenarios.PIA_ERROR, + this.pageName + ); return; } @@ -441,6 +459,37 @@ export default { this.pageName ); }, + + async paymentFailedPayLater() { + console.log(`Doing final work order submission...`); + showFmgLoadingModal(true); + + await this.dispatchStoreAction( + storeActions.SAVE_PAYMENT_METHOD_CHOICE, + paymentMethods.PAY_LATER, + false + ); + + await this.dispatchStoreAction(storeActions.RESET_SAVE_SESSION_PROMISE); + + try { + await submitWorkOrder({ + pageNameToLog: this.pageName, + submitAfterSave: true, + }); + + await baseMixin.methods.dispatchStoreAction(storeActions.CREATE_SUBMITTED_STATE); + + this.$router.navigateWithoutSaving( + this.navigationScenarios.CLICKED_FORWARD, + this.pageName + ); + } catch (error) { + console.log(`Final submission failed after failed payment.`); + this.$router.handleSoftError(); + return; + } + }, }, computed: { @@ -581,6 +630,7 @@ export default { funnelSubHeader, navbar, cart, + alert, }, }; diff --git a/src/router/constants/routing-table.js b/src/router/constants/routing-table.js index 192e1572e..48cd49b3f 100644 --- a/src/router/constants/routing-table.js +++ b/src/router/constants/routing-table.js @@ -578,6 +578,13 @@ const routingTable = function () { scenario: navigationScenarios.CLICKED_FORWARD, destinationPageData: routeData.CONFIRMATION, }, + { + scenario: navigationScenarios.PIA_ERROR, + destinationPageData: routeData.PAYMENT_METHOD, + params: { + piaError: "true", + }, + }, ], }, { diff --git a/src/router/methods/route-logic/adyen-return.js b/src/router/methods/route-logic/adyen-return.js index d94de4c38..f15168861 100644 --- a/src/router/methods/route-logic/adyen-return.js +++ b/src/router/methods/route-logic/adyen-return.js @@ -15,7 +15,30 @@ export async function adyenReturnBeforeEnter(to, from) { const redirectResult = to?.query?.redirectResult; if (sessionId && redirectResult) { - const result = await finalizeAdyenPayment(sessionId, redirectResult); + let result = null; + + try { + result = await finalizeAdyenPayment(sessionId, redirectResult); + } catch (unexpectedResult) { + // If user cancelled payment, handle without error message + if (unexpectedResult.code === "Cancelled" || unexpectedResult.code === "CANCEL") { + return { + name: routeData.PAYMENT_ADYEN.name, + replace: true, + }; + } + + // Otherwise, failure scenario. + // Payment fails, so return user to payment-adyen screen to try again or pay later. + return { + name: routeData.PAYMENT_ADYEN.name, + query: { + piaFailure: true, + }, + replace: true, + }; + } + console.log(`Out of promise`); console.log(result); @@ -59,7 +82,10 @@ export async function adyenReturnBeforeEnter(to, from) { } catch (error) { console.log(error); return { - name: routeData.ERROR.name, + name: routeData.PAYMENT_METHOD.name, + query: { + piaError: "true", + }, replace: true, }; } @@ -93,12 +119,32 @@ function finalizeAdyenPayment(sessionId, redirectResult) { onPaymentFailed: (result, component) => { console.log(`Payment failed`); console.log(result); - reject("Payment failed from Adyen"); + + if (result?.resultCode !== "Cancelled") { + const stringToLog = `ADYEN PAYMENT NOT AUTHORIZED. Code = ${result?.resultCode}. Id = ${sessionId}`; + + global.$logger.logError(stringToLog); + } + + reject({ + code: result?.resultCode, + message: "Payment failed from Adyen", + }); }, onError: (error, component) => { console.log(`Error occured`); console.log(error); - reject("Error from Adyen"); + + if (error?.name !== "CANCEL") { + const stringToLog = `ADYEN ERROR. Name = ${error?.name}. Details = ${error?.message}.`; + + global.$logger.logError(stringToLog); + } + + reject({ + code: error?.name, + message: "Error from Adyen", + }); }, }, options: {},