Merge pull request #3006 from Safelite/feature/CASH-1722
Adyen - Update Error Scenarios
This commit is contained in:
commit
6c845aaaa5
3 changed files with 143 additions and 40 deletions
|
|
@ -4,6 +4,16 @@
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
|
<div>
|
||||||
|
<alert
|
||||||
|
ref="piaErrorAlert"
|
||||||
|
class="my-4"
|
||||||
|
v-if="hasPaymentFailureError"
|
||||||
|
cmsWidgetName="PIAErrorAlertWidget"
|
||||||
|
alertClass="alert-danger"
|
||||||
|
@textLinkClicked="paymentFailedPayLater"
|
||||||
|
v-bind:isDismissible="false" />
|
||||||
|
</div>
|
||||||
<div id="card-container">
|
<div id="card-container">
|
||||||
<div id="payment-container">
|
<div id="payment-container">
|
||||||
<funnelSubHeader class="py-5" cmsWidgetName="FunnelSubHeaderWidget" />
|
<funnelSubHeader class="py-5" cmsWidgetName="FunnelSubHeaderWidget" />
|
||||||
|
|
@ -45,6 +55,7 @@ import Form from "vee-validate";
|
||||||
import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
|
import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
|
||||||
import navbar from "@/fmg-components/nav-bar/nav-bar";
|
import navbar from "@/fmg-components/nav-bar/nav-bar";
|
||||||
import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header";
|
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 { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
import { settleAllPromises } from "@/helpers/layout-helper";
|
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||||
|
|
@ -75,6 +86,8 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
sessionId: String,
|
sessionId: String,
|
||||||
|
dropinComponent: null,
|
||||||
|
hasPaymentFailureError: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -92,9 +105,15 @@ export default {
|
||||||
|
|
||||||
const resultMap = await settleAllPromises(promiseResultMap);
|
const resultMap = await settleAllPromises(promiseResultMap);
|
||||||
|
|
||||||
|
const hasExistingPiaError = to.query?.piaFailure;
|
||||||
|
|
||||||
// Hydrate page with results
|
// Hydrate page with results
|
||||||
next(async (vm) => {
|
next(async (vm) => {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
|
|
||||||
|
if (hasExistingPiaError) {
|
||||||
|
vm.hasPaymentFailureError = true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -184,9 +203,9 @@ export default {
|
||||||
debugLog("providerLocation.city:", providerLocation.city, !preReqResult);
|
debugLog("providerLocation.city:", providerLocation.city, !preReqResult);
|
||||||
debugLog("providerLocation.state:", providerLocation.state, !preReqResult);
|
debugLog("providerLocation.state:", providerLocation.state, !preReqResult);
|
||||||
debugLog("providerLocation.zipCode:", providerLocation.zipCode, !preReqResult);
|
debugLog("providerLocation.zipCode:", providerLocation.zipCode, !preReqResult);
|
||||||
|
|
||||||
debugLog("", null, !preReqResult);
|
debugLog("", null, !preReqResult);
|
||||||
|
|
||||||
debugLog("isInsuranceSet:", isInsuranceSet, !preReqResult);
|
debugLog("isInsuranceSet:", isInsuranceSet, !preReqResult);
|
||||||
|
|
||||||
debugLog("", null, !preReqResult);
|
debugLog("", null, !preReqResult);
|
||||||
|
|
@ -197,7 +216,7 @@ export default {
|
||||||
debugLog("schedule.endTime:", schedule.endTime, !preReqResult);
|
debugLog("schedule.endTime:", schedule.endTime, !preReqResult);
|
||||||
debugLog("schedule.jobMaxMinutes:", schedule.jobMaxMinutes, !preReqResult);
|
debugLog("schedule.jobMaxMinutes:", schedule.jobMaxMinutes, !preReqResult);
|
||||||
debugLog("schedule.jobMinMinutes:", schedule.jobMinMinutes, !preReqResult);
|
debugLog("schedule.jobMinMinutes:", schedule.jobMinMinutes, !preReqResult);
|
||||||
|
|
||||||
debugLog("", null, !preReqResult);
|
debugLog("", null, !preReqResult);
|
||||||
|
|
||||||
debugLog("customerReqs:", customerReqs, !preReqResult);
|
debugLog("customerReqs:", customerReqs, !preReqResult);
|
||||||
|
|
@ -205,7 +224,7 @@ export default {
|
||||||
debugLog("customer.lastName:", customer.lastName, !preReqResult);
|
debugLog("customer.lastName:", customer.lastName, !preReqResult);
|
||||||
debugLog("customer.phoneNumber:", customer.phoneNumber, !preReqResult);
|
debugLog("customer.phoneNumber:", customer.phoneNumber, !preReqResult);
|
||||||
debugLog("customer.emailAddress:", customer.emailAddress, !preReqResult);
|
debugLog("customer.emailAddress:", customer.emailAddress, !preReqResult);
|
||||||
|
|
||||||
debugLog("", null, !preReqResult);
|
debugLog("", null, !preReqResult);
|
||||||
|
|
||||||
debugLog("paymentMethodReqs:", paymentMethodReqs, !preReqResult);
|
debugLog("paymentMethodReqs:", paymentMethodReqs, !preReqResult);
|
||||||
|
|
@ -292,7 +311,11 @@ export default {
|
||||||
name: "Credit or debit card",
|
name: "Credit or debit card",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}).mount("#adyen-container");
|
});
|
||||||
|
|
||||||
|
this.dropinComponent = dropin;
|
||||||
|
|
||||||
|
dropin.mount("#adyen-container");
|
||||||
},
|
},
|
||||||
|
|
||||||
async handleCompletedPayment(result) {
|
async handleCompletedPayment(result) {
|
||||||
|
|
@ -382,33 +405,33 @@ export default {
|
||||||
console.log(`Result =`);
|
console.log(`Result =`);
|
||||||
console.log(result);
|
console.log(result);
|
||||||
|
|
||||||
// Fetch session info
|
const wasPaymentCancelled = result?.resultCode === "Cancelled";
|
||||||
const paymentSessionRequest = {
|
|
||||||
zipCodeCtu: this.locationInfo.zipCodeCtu,
|
|
||||||
workOrderNumber: this.workOrderNumberLastSixDigits,
|
|
||||||
sourceSystem: this.sourceSystem,
|
|
||||||
sessionId: this.sessionId,
|
|
||||||
sessionResult: result?.sessionResult,
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log(`Get session payload =`);
|
if (!wasPaymentCancelled) {
|
||||||
console.log(paymentSessionRequest);
|
const stringToLog = `ADYEN PAYMENT NOT AUTHORIZED. Code = ${result?.resultCode}. Id = ${this.sessionId}`;
|
||||||
|
|
||||||
try {
|
await global.$logger.logError(stringToLog);
|
||||||
const response = await globalMethods.callHttpClient({
|
|
||||||
method: endpoints.GetAdyenSessionResult.method,
|
|
||||||
endpoint: endpoints.GetAdyenSessionResult.url,
|
|
||||||
payload: paymentSessionRequest,
|
|
||||||
logApiCall: true,
|
|
||||||
pageNameToLog: "payment-adyen",
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(response);
|
this.hasPaymentFailureError = true;
|
||||||
} catch (error) {
|
|
||||||
console.log(`Error getting session info after failure.`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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() {
|
async saveAndSubmitWorkOrder() {
|
||||||
// Work order submission after successful payment.
|
// Work order submission after successful payment.
|
||||||
|
|
@ -421,15 +444,10 @@ export default {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(`error: response from submit work order: ${error.message}`);
|
console.log(`error: response from submit work order: ${error.message}`);
|
||||||
|
|
||||||
// navigate to error page
|
this.$router.navigateWithoutSaving(
|
||||||
const errorPayload = {
|
this.navigationScenarios.PIA_ERROR,
|
||||||
cause: `Error while submitting work order after Adyen payment.`,
|
this.pageName
|
||||||
currentPage: this.pageName,
|
);
|
||||||
sessionId: this.sessionId,
|
|
||||||
idempotencyKey: this.idempotencyKey,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.$router.handleSoftError(errorPayload);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -441,6 +459,37 @@ export default {
|
||||||
this.pageName
|
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: {
|
computed: {
|
||||||
|
|
@ -581,6 +630,7 @@ export default {
|
||||||
funnelSubHeader,
|
funnelSubHeader,
|
||||||
navbar,
|
navbar,
|
||||||
cart,
|
cart,
|
||||||
|
alert,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -578,6 +578,13 @@ const routingTable = function () {
|
||||||
scenario: navigationScenarios.CLICKED_FORWARD,
|
scenario: navigationScenarios.CLICKED_FORWARD,
|
||||||
destinationPageData: routeData.CONFIRMATION,
|
destinationPageData: routeData.CONFIRMATION,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
scenario: navigationScenarios.PIA_ERROR,
|
||||||
|
destinationPageData: routeData.PAYMENT_METHOD,
|
||||||
|
params: {
|
||||||
|
piaError: "true",
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,30 @@ export async function adyenReturnBeforeEnter(to, from) {
|
||||||
const redirectResult = to?.query?.redirectResult;
|
const redirectResult = to?.query?.redirectResult;
|
||||||
|
|
||||||
if (sessionId && 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(`Out of promise`);
|
||||||
console.log(result);
|
console.log(result);
|
||||||
|
|
||||||
|
|
@ -59,7 +82,10 @@ export async function adyenReturnBeforeEnter(to, from) {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
return {
|
return {
|
||||||
name: routeData.ERROR.name,
|
name: routeData.PAYMENT_METHOD.name,
|
||||||
|
query: {
|
||||||
|
piaError: "true",
|
||||||
|
},
|
||||||
replace: true,
|
replace: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -93,12 +119,32 @@ function finalizeAdyenPayment(sessionId, redirectResult) {
|
||||||
onPaymentFailed: (result, component) => {
|
onPaymentFailed: (result, component) => {
|
||||||
console.log(`Payment failed`);
|
console.log(`Payment failed`);
|
||||||
console.log(result);
|
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) => {
|
onError: (error, component) => {
|
||||||
console.log(`Error occured`);
|
console.log(`Error occured`);
|
||||||
console.log(error);
|
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: {},
|
options: {},
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue