From 09084dab48818bcfa09333bbd5e98cdcc9b1df84 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 8 Jan 2026 13:59:26 -0500 Subject: [PATCH 1/8] Simplify + Add logging --- src/layouts/payment-adyen/payment-adyen.vue | 34 +++++---------------- 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/src/layouts/payment-adyen/payment-adyen.vue b/src/layouts/payment-adyen/payment-adyen.vue index b407f9d55..45bdc4961 100644 --- a/src/layouts/payment-adyen/payment-adyen.vue +++ b/src/layouts/payment-adyen/payment-adyen.vue @@ -378,37 +378,19 @@ export default { await this.saveAndSubmitWorkOrder(); }, - async handleFailedPayment(result) { + handleFailedPayment(result) { 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 stringToLog = `ADYEN PAYMENT NOT AUTHORIZED. Code = ${result?.resultCode}. Id = ${this.sessionId}`; - console.log(`Get session payload =`); - console.log(paymentSessionRequest); - - try { - const response = await globalMethods.callHttpClient({ - method: endpoints.GetAdyenSessionResult.method, - endpoint: endpoints.GetAdyenSessionResult.url, - payload: paymentSessionRequest, - logApiCall: true, - pageNameToLog: "payment-adyen", - }); - - console.log(response); - } catch (error) { - console.log(`Error getting session info after failure.`); - } + global.$logger.logError(stringToLog); + }, + handleError(error) { + const stringToLog = `ADYEN ERROR. Name = ${error.name}. Details = ${error.message}.`; + + global.$logger.logError(stringToLog); }, - handleError(error) {}, async saveAndSubmitWorkOrder() { // Work order submission after successful payment. From 6534b06238bb296b245491a33d26d3ece3591f86 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 8 Jan 2026 16:40:43 -0500 Subject: [PATCH 2/8] Parity experience for failed payments. --- src/layouts/payment-adyen/payment-adyen.vue | 59 +++++++++++++++++++-- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/src/layouts/payment-adyen/payment-adyen.vue b/src/layouts/payment-adyen/payment-adyen.vue index 45bdc4961..4ea759e2c 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, }; }, @@ -292,7 +305,11 @@ export default { name: "Credit or debit card", }, }, - }).mount("#adyen-container"); + }); + + this.dropinComponent = dropin; + + dropin.mount("#adyen-container"); }, async handleCompletedPayment(result) { @@ -378,13 +395,17 @@ export default { await this.saveAndSubmitWorkOrder(); }, - handleFailedPayment(result) { + async handleFailedPayment(result) { console.log(`Result =`); console.log(result); const stringToLog = `ADYEN PAYMENT NOT AUTHORIZED. Code = ${result?.resultCode}. Id = ${this.sessionId}`; - global.$logger.logError(stringToLog); + await global.$logger.logError(stringToLog); + + this.hasPaymentFailureError = true; + + this.dropinComponent?.update(); }, handleError(error) { const stringToLog = `ADYEN ERROR. Name = ${error.name}. Details = ${error.message}.`; @@ -423,6 +444,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: { @@ -563,6 +615,7 @@ export default { funnelSubHeader, navbar, cart, + alert, }, }; From 6aa8d3434cb6c1890b8dd303147368bfafed037a Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 8 Jan 2026 17:30:49 -0500 Subject: [PATCH 3/8] Parity for adyen failures in redirect flow --- src/layouts/payment-adyen/payment-adyen.vue | 6 +++++ .../methods/route-logic/adyen-return.js | 26 ++++++++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/layouts/payment-adyen/payment-adyen.vue b/src/layouts/payment-adyen/payment-adyen.vue index 4ea759e2c..262614235 100644 --- a/src/layouts/payment-adyen/payment-adyen.vue +++ b/src/layouts/payment-adyen/payment-adyen.vue @@ -105,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; + } }); }, diff --git a/src/router/methods/route-logic/adyen-return.js b/src/router/methods/route-logic/adyen-return.js index d94de4c38..1e423e056 100644 --- a/src/router/methods/route-logic/adyen-return.js +++ b/src/router/methods/route-logic/adyen-return.js @@ -15,7 +15,21 @@ 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 (error) { + // 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); @@ -93,12 +107,18 @@ function finalizeAdyenPayment(sessionId, redirectResult) { onPaymentFailed: (result, component) => { console.log(`Payment failed`); console.log(result); - reject("Payment failed from Adyen"); + reject({ + paymentFailure: true, + message: "Payment failed from Adyen", + }); }, onError: (error, component) => { console.log(`Error occured`); console.log(error); - reject("Error from Adyen"); + reject({ + paymentFailure: false, + message: "Error from Adyen", + }); }, }, options: {}, From fa5ff6b58bf9b50d08aa669bc8231538ee613ac1 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Mon, 12 Jan 2026 13:26:38 -0500 Subject: [PATCH 4/8] Handle cancellation and payment errors. --- src/layouts/payment-adyen/payment-adyen.vue | 36 +++++++++++++------ .../methods/route-logic/adyen-return.js | 15 ++++++-- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/layouts/payment-adyen/payment-adyen.vue b/src/layouts/payment-adyen/payment-adyen.vue index 262614235..d71c13a38 100644 --- a/src/layouts/payment-adyen/payment-adyen.vue +++ b/src/layouts/payment-adyen/payment-adyen.vue @@ -111,7 +111,7 @@ export default { next(async (vm) => { vm.setCmsContent(resultMap.cmsContent); - if(hasExistingPiaError) { + if (hasExistingPiaError) { vm.hasPaymentFailureError = true; } }); @@ -203,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); @@ -216,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); @@ -224,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); @@ -405,18 +405,32 @@ export default { console.log(`Result =`); console.log(result); - const stringToLog = `ADYEN PAYMENT NOT AUTHORIZED. Code = ${result?.resultCode}. Id = ${this.sessionId}`; + const wasPaymentCancelled = result?.resultCode === "Cancelled"; - await global.$logger.logError(stringToLog); + if (!wasPaymentCancelled) { + const stringToLog = `ADYEN PAYMENT NOT AUTHORIZED. Code = ${result?.resultCode}. Id = ${this.sessionId}`; - this.hasPaymentFailureError = true; + await global.$logger.logError(stringToLog); + + this.hasPaymentFailureError = true; + } this.dropinComponent?.update(); }, - handleError(error) { - const stringToLog = `ADYEN ERROR. Name = ${error.name}. Details = ${error.message}.`; + async handleError(error) { + console.log(error); - global.$logger.logError(stringToLog); + 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(); }, async saveAndSubmitWorkOrder() { diff --git a/src/router/methods/route-logic/adyen-return.js b/src/router/methods/route-logic/adyen-return.js index 1e423e056..e7a901c2e 100644 --- a/src/router/methods/route-logic/adyen-return.js +++ b/src/router/methods/route-logic/adyen-return.js @@ -19,7 +19,16 @@ export async function adyenReturnBeforeEnter(to, from) { try { result = await finalizeAdyenPayment(sessionId, redirectResult); - } catch (error) { + } catch (unexpectedResult) { + // If user cancelled payment, handle without error message + if (unexpectedResult.code === "Cancelled") { + 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, @@ -108,7 +117,7 @@ function finalizeAdyenPayment(sessionId, redirectResult) { console.log(`Payment failed`); console.log(result); reject({ - paymentFailure: true, + code: result?.resultCode, message: "Payment failed from Adyen", }); }, @@ -116,7 +125,7 @@ function finalizeAdyenPayment(sessionId, redirectResult) { console.log(`Error occured`); console.log(error); reject({ - paymentFailure: false, + code: "Error", message: "Error from Adyen", }); }, From 3bfe0b2b4391531e87ece25b74f25fe24b8ba070 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Tue, 13 Jan 2026 10:08:59 -0500 Subject: [PATCH 5/8] Align error on final order submission --- src/layouts/payment-adyen/payment-adyen.vue | 13 ++++--------- src/router/constants/routing-table.js | 7 +++++++ src/router/methods/route-logic/adyen-return.js | 5 ++++- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/layouts/payment-adyen/payment-adyen.vue b/src/layouts/payment-adyen/payment-adyen.vue index d71c13a38..d47187760 100644 --- a/src/layouts/payment-adyen/payment-adyen.vue +++ b/src/layouts/payment-adyen/payment-adyen.vue @@ -444,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; } 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 e7a901c2e..3db4fda99 100644 --- a/src/router/methods/route-logic/adyen-return.js +++ b/src/router/methods/route-logic/adyen-return.js @@ -82,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, }; } From 6ab6932fc57d9bda65a2fe0093a90001f664ae02 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Tue, 13 Jan 2026 10:26:43 -0500 Subject: [PATCH 6/8] Optional chaining --- src/layouts/payment-adyen/payment-adyen.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/payment-adyen/payment-adyen.vue b/src/layouts/payment-adyen/payment-adyen.vue index d47187760..ab5f69be6 100644 --- a/src/layouts/payment-adyen/payment-adyen.vue +++ b/src/layouts/payment-adyen/payment-adyen.vue @@ -423,7 +423,7 @@ export default { const wasPaymentCancelled = error?.name === "CANCEL"; if (!wasPaymentCancelled) { - const stringToLog = `ADYEN ERROR. Name = ${error.name}. Details = ${error.message}.`; + const stringToLog = `ADYEN ERROR. Name = ${error?.name}. Details = ${error?.message}.`; await global.$logger.logError(stringToLog); From 516ba215b8d313e660cf12848a5214db9d5314b9 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Tue, 13 Jan 2026 11:11:25 -0500 Subject: [PATCH 7/8] Nits on redirect flow --- src/router/methods/route-logic/adyen-return.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/router/methods/route-logic/adyen-return.js b/src/router/methods/route-logic/adyen-return.js index 3db4fda99..f15168861 100644 --- a/src/router/methods/route-logic/adyen-return.js +++ b/src/router/methods/route-logic/adyen-return.js @@ -21,7 +21,7 @@ export async function adyenReturnBeforeEnter(to, from) { result = await finalizeAdyenPayment(sessionId, redirectResult); } catch (unexpectedResult) { // If user cancelled payment, handle without error message - if (unexpectedResult.code === "Cancelled") { + if (unexpectedResult.code === "Cancelled" || unexpectedResult.code === "CANCEL") { return { name: routeData.PAYMENT_ADYEN.name, replace: true, @@ -119,6 +119,13 @@ function finalizeAdyenPayment(sessionId, redirectResult) { onPaymentFailed: (result, component) => { console.log(`Payment failed`); console.log(result); + + 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", @@ -127,8 +134,15 @@ function finalizeAdyenPayment(sessionId, redirectResult) { onError: (error, component) => { console.log(`Error occured`); console.log(error); + + if (error?.name !== "CANCEL") { + const stringToLog = `ADYEN ERROR. Name = ${error?.name}. Details = ${error?.message}.`; + + global.$logger.logError(stringToLog); + } + reject({ - code: "Error", + code: error?.name, message: "Error from Adyen", }); }, From a68e0ad43144b0bac74ea0bc8ce8560fd1b2f81b Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Tue, 13 Jan 2026 12:16:11 -0500 Subject: [PATCH 8/8] Typo --- src/layouts/payment-adyen/payment-adyen.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/payment-adyen/payment-adyen.vue b/src/layouts/payment-adyen/payment-adyen.vue index ab5f69be6..bbdf33719 100644 --- a/src/layouts/payment-adyen/payment-adyen.vue +++ b/src/layouts/payment-adyen/payment-adyen.vue @@ -12,7 +12,7 @@ cmsWidgetName="PIAErrorAlertWidget" alertClass="alert-danger" @textLinkClicked="paymentFailedPayLater" - v-bind:isDismissable="false" /> + v-bind:isDismissible="false" />