Merge branch 'develop' into rlsmerge/2026.01.15-to-develop
This commit is contained in:
commit
b5bc983626
5 changed files with 183 additions and 71 deletions
|
|
@ -84,6 +84,21 @@ export function mapAdyenToFmgPaymentMethod(adyenMethod) {
|
|||
return match ?? paymentMethods.CREDIT_CARD;
|
||||
}
|
||||
|
||||
export function mapFmgToAdyenPaymentMethod(fmgMethod) {
|
||||
const paymentMethodMap = {
|
||||
[paymentMethods.CREDIT_CARD]: "scheme",
|
||||
[paymentMethods.AFTERPAY]: "afterpaytouch",
|
||||
[paymentMethods.PAYPAL]: "paypal",
|
||||
[paymentMethods.APPLE_PAY]: "applepay",
|
||||
[paymentMethods.PAY_NOW]: null,
|
||||
[paymentMethods.LATER]: null,
|
||||
};
|
||||
|
||||
const match = paymentMethodMap[fmgMethod];
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
export function generateCcToken(adyenSessionInfo) {
|
||||
const order = store.getters.order;
|
||||
const locationInfo = getLocationInfo(order);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,16 @@
|
|||
<div class="container">
|
||||
<div class="row">
|
||||
<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="payment-container">
|
||||
<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 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";
|
||||
|
|
@ -61,7 +72,7 @@ import { applicationConfig } from "@/constants/application-config";
|
|||
import { paymentMethods } from "@/constants/payment-method-constants";
|
||||
|
||||
import "@adyen/adyen-web/styles/adyen.css";
|
||||
import { mapAdyenToFmgPaymentMethod } from "../../helpers/adyen-helper";
|
||||
import { mapAdyenToFmgPaymentMethod, mapFmgToAdyenPaymentMethod } from "../../helpers/adyen-helper";
|
||||
import { showFmgLoadingModal } from "../../helpers/loading-modal-helper";
|
||||
import cart from "@/fmg-components/cart/cart";
|
||||
import { coverageStatus } from "@/constants/insurance";
|
||||
|
|
@ -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);
|
||||
|
|
@ -270,7 +289,7 @@ export default {
|
|||
|
||||
console.log(checkout);
|
||||
|
||||
const dropin = new Dropin(checkout, {
|
||||
const configuration = {
|
||||
paymentMethodsConfiguration: {
|
||||
ideal: {
|
||||
showImage: true,
|
||||
|
|
@ -292,7 +311,21 @@ export default {
|
|||
name: "Credit or debit card",
|
||||
},
|
||||
},
|
||||
}).mount("#adyen-container");
|
||||
};
|
||||
|
||||
const adyenPaymentType = mapFmgToAdyenPaymentMethod(this.piaType);
|
||||
|
||||
if (adyenPaymentType) {
|
||||
configuration.openPaymentMethod = {
|
||||
type: adyenPaymentType,
|
||||
};
|
||||
}
|
||||
|
||||
const dropin = new Dropin(checkout, configuration);
|
||||
|
||||
this.dropinComponent = dropin;
|
||||
|
||||
dropin.mount("#adyen-container");
|
||||
},
|
||||
|
||||
async handleCompletedPayment(result) {
|
||||
|
|
@ -382,33 +415,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 +454,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,9 +469,44 @@ 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: {
|
||||
piaType() {
|
||||
return this.$store.getters.order.payment.piaType;
|
||||
},
|
||||
|
||||
adyenInitRequestInfo() {
|
||||
return {
|
||||
sourceSystem: this.sourceSystem,
|
||||
|
|
@ -581,6 +644,7 @@ export default {
|
|||
funnelSubHeader,
|
||||
navbar,
|
||||
cart,
|
||||
alert,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -622,7 +622,10 @@ export default {
|
|||
},
|
||||
},
|
||||
isMobileSelected() {
|
||||
return this.appointmentType == AppointmentTypeStrings.MOBILE;
|
||||
return (
|
||||
this.appointmentType == AppointmentTypeStrings.MOBILE ||
|
||||
(this.isServiceableMobile && !this.isServiceableInshop)
|
||||
);
|
||||
},
|
||||
isServiceableMobile() {
|
||||
if (this.isRecalibrationServiceableMobile !== null) {
|
||||
|
|
@ -1134,30 +1137,7 @@ export default {
|
|||
);
|
||||
}
|
||||
},
|
||||
getTimeSlotInfo() {
|
||||
// Get the current date
|
||||
const currentDate = getTodayDate();
|
||||
|
||||
// Add 10 days to the current date
|
||||
currentDate.setDate(currentDate.getDate() + 10);
|
||||
|
||||
// Format the date as yyyy-mm-dd
|
||||
const year = currentDate.getFullYear();
|
||||
const month = String(currentDate.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(currentDate.getDate()).padStart(2, "0");
|
||||
|
||||
const formattedDate = `${year}-${month}-${day}`;
|
||||
|
||||
return {
|
||||
date: formattedDate,
|
||||
endTime: "12:00",
|
||||
jobMaxMinutes: "180",
|
||||
jobMinMinutes: "120",
|
||||
routeCode: "3357I-03357-M-I*20988*AM",
|
||||
startTime: "08:00",
|
||||
};
|
||||
},
|
||||
onShopSelected(shopQuestionPopUpData) {
|
||||
async onShopSelected(shopQuestionPopUpData) {
|
||||
this.resetWaitlist();
|
||||
this.preSelectedDate = null;
|
||||
this.shopProviderData = shopQuestionPopUpData.shopProviderData;
|
||||
|
|
@ -1165,6 +1145,8 @@ export default {
|
|||
const selectedProvider = this.shopProviderData.shopProviders.find((shopProvider) => {
|
||||
return shopProvider.providerNumber === shopQuestionPopUpData.selectedProviderNumber;
|
||||
});
|
||||
const didProviderNumberChange =
|
||||
oldProvider?.providerNumber !== selectedProvider?.providerNumber;
|
||||
|
||||
// No zipCodeData comes back if zip was not changed
|
||||
if (shopQuestionPopUpData.zipCodeData) {
|
||||
|
|
@ -1173,13 +1155,12 @@ export default {
|
|||
selectedProvider
|
||||
);
|
||||
} else {
|
||||
const didProviderNumberChange =
|
||||
oldProvider?.providerNumber !== selectedProvider.providerNumber;
|
||||
if (didProviderNumberChange) {
|
||||
this.updateSelectedProvider(selectedProvider);
|
||||
this.initializeDatePicker();
|
||||
}
|
||||
}
|
||||
await this.initializeDatePicker();
|
||||
this.setSelectedDateToFirstAvailable();
|
||||
},
|
||||
async getMoreScheduleData(startDate, endDate) {
|
||||
// called only when "View more dates" is clicked; not on initial page load
|
||||
|
|
@ -1717,7 +1698,6 @@ export default {
|
|||
this.zipContainsMilitaryBase = newZipCode.containsMilitaryBase;
|
||||
this.selectedDate = null;
|
||||
this.selectedProvider = newProvider;
|
||||
this.initializeDatePicker();
|
||||
},
|
||||
handleAppointmentTypeChange(newAppointmentType) {
|
||||
this.updateFooterButtonText();
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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: {},
|
||||
|
|
|
|||
Loading…
Reference in a new issue