SSR-1081 handling payment return info from hop

This commit is contained in:
Matt Caimi 2024-02-27 16:46:34 -05:00 committed by Bill Richardson
parent bc7947187a
commit 8e9302df40
8 changed files with 261 additions and 21 deletions

View file

@ -1,5 +1,20 @@
const queryStrings = Object.freeze({
ISS_PAGE: 'issPage'
ISS_PAGE: 'issPage',
ERROR: 'error',
SUBSCRIPTIONID: 'subscriptionid',
REFERRAL_SEQ_NUM: 'referralseqnum',
CARD_EXPIRATION_MONTH: 'card_expirationmonth',
CARD_EXPIRATION_YEAR: 'card_expirationyear',
CARD_TYPE: 'sgcardtype',
BILL_TO_POSTAL_CODE: 'billto_postalcode',
BILL_TO_FIRST_NAME: 'billto_firstname',
BILL_TO_LAST_NAME: 'billto_lastname',
REFERENCE_NUMBER: 'req_reference_number',
AUTH_CODE: 'auth_code',
TRANSACTION_ID: 'transaction_id',
TRANS_REFERENCE_NUMBER: 'auth_trans_ref_no',
LAST_FOUR: 'last_four',
DISPLAY_PAY_IN_ADVANCE_ALERT: 'displayPayInAdvanceAlert'
});
export default queryStrings;

View file

@ -0,0 +1,5 @@
const webStorageConstants = Object.freeze({
SUBMITTED_ORDER: 'submittedOrder'
});
export default webStorageConstants;

View file

@ -0,0 +1,11 @@
export default function getQuerystringParameter(key) {
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
const lowerCaseParams = new URLSearchParams();
urlParams.forEach((value, name) => {
lowerCaseParams.append(name.toLowerCase(), value);
});
return lowerCaseParams.get(key.toLowerCase());
}

View file

@ -460,15 +460,11 @@ export default {
computed: {
payInAdvanceResponseUrl() {
const { protocol, host } = window.location;
return `${protocol}//${host}/?issPage=${
issPageValues.PAYMENT_RETURN
}&src=iss-nextgen`;
return `${protocol}//${host}/?issPage=${issPageValues.PAYMENT_RETURN}&src=iss-nextgen`;
},
payInAdvanceCancelUrl() {
const { protocol, host } = window.location;
return `${protocol}//${host}/?issPage=${
issPageValues.PAYMENT_METHOD
}&src=iss-nextgen`;
return `${protocol}//${host}/?issPage=${issPageValues.PAYMENT_METHOD}&src=iss-nextgen`;
},
dynamicCSSUrl() {
const { protocol, hostname, port } = window.location;

View file

@ -0,0 +1,145 @@
<template>
<Form
ref="theForm"
@submit="onSubmit"
@invalidSubmit="onInvalidSubmit">
</Form>
</template>
<script>
import { Form } from 'vee-validate';
import BaseFormMixin from '@/mixins/base-form-mixin.js';
import { useMainStore } from '@/store/index.js';
import queryStrings from '@/constants/query-strings';
import getQuerystringParameter from '@/helpers/querystring-helper.js';
import { paymentMethods } from '@/constants/payment-method-constants.js';
export default {
name: 'payment-return',
components: {
// eslint-disable-next-line vue/no-reserved-component-names
Form
},
mixins: [BaseFormMixin],
async mounted() {
const payInAdvanceError = getQuerystringParameter(queryStrings.ERROR);
const { payInAdvanceType } = useMainStore().order.payment;
if (payInAdvanceError) {
console.error(`Error during payment: ${payInAdvanceError}`);
const paymentPageNavScenario =
payInAdvanceType === paymentMethods.CREDIT_CARD
|| payInAdvanceType === paymentMethods.AFTERPAY;
if (paymentPageNavScenario) {
this.$router.navigate(
this.navigationScenarios.PAY_IN_ADVANCE_CREDIT_CARD_ERROR,
this.$route,
{
[queryStrings.DISPLAY_PAY_IN_ADVANCE_ALERT]: payInAdvanceType
}
);
} else {
this.$router.navigate(
this.navigationScenarios.PAY_IN_ADVANCE_ERROR,
this.$route,
{
[queryStrings.DISPLAY_PAY_IN_ADVANCE_ALERT]: true
}
);
}
} else {
switch (payInAdvanceType) {
case paymentMethods.CREDIT_CARD:
case paymentMethods.AFTERPAY:
await this.processCreditCardResponse();
break;
case paymentMethods.PAYPAL:
break;
default:
console.log(`Unknown pay in advance type: ${payInAdvanceType}`);
this.$router.navigate(
this.navigationScenarios.PAY_IN_ADVANCE_ERROR,
this.$route,
{
[queryStrings.DISPLAY_PAY_IN_ADVANCE_ALERT]: true
}
);
}
}
},
methods: {
arePagePrerequisitesValid() {
return true;
},
async processCreditCardResponse() {
const subscriptionId = getQuerystringParameter(queryStrings.SUBSCRIPTIONID);
const referralSeqNum = getQuerystringParameter(queryStrings.REFERRAL_SEQ_NUM);
if (referralSeqNum !== useMainStore().order.referralSequenceNumber) {
console.error(`error: unknown ref:${referralSeqNum} ${useMainStore().order.referralSequenceNumber}`);
this.$router.navigate(
this.navigationScenarios.PAY_IN_ADVANCE_ERROR,
this.$route,
{
[queryStrings.DISPLAY_PAY_IN_ADVANCE_ALERT]: true
}
);
} else {
const expMonth = getQuerystringParameter(queryStrings.CARD_EXPIRATION_MONTH);
const expYear = getQuerystringParameter(queryStrings.CARD_EXPIRATION_YEAR);
const cardType = getQuerystringParameter(queryStrings.CARD_TYPE);
const billToPostalCode = getQuerystringParameter(queryStrings.BILL_TO_POSTAL_CODE);
const billToFirstName = getQuerystringParameter(queryStrings.BILL_TO_FIRST_NAME);
const billToLastName = getQuerystringParameter(queryStrings.BILL_TO_LAST_NAME);
const referenceNumber = getQuerystringParameter(queryStrings.REFERENCE_NUMBER);
const authCode = getQuerystringParameter(queryStrings.AUTH_CODE);
const transactionId = getQuerystringParameter(queryStrings.TRANSACTION_ID);
const transReferenceNumber = getQuerystringParameter(queryStrings.TRANS_REFERENCE_NUMBER);
const lastFour = getQuerystringParameter(queryStrings.LAST_FOUR);
const ccToken = {
subscriptionId,
expMonth,
expYear,
cardType,
billToPostalCode,
billToFirstName,
billToLastName,
referenceNumber,
authCode,
transactionId,
transReferenceNumber,
lastFour
};
useMainStore().updateCCToken(ccToken);
await this.saveAndSubmitWorkOrder();
}
},
async saveAndSubmitWorkOrder() {
// Final work order submit after returning from pay in advance.
useMainStore().resetSubmittedOrder();
try {
// do we have a function to submit a work order,
// perhaps built into saveSession?
// we need to submit the work order here
} catch (error) {
console.error(`error: response from submit work order:${error.message}`);
this.$router.navigate(
this.navigationScenarios.PAY_IN_ADVANCE_ERROR,
this.$route,
{
[queryStrings.DISPLAY_PAY_IN_ADVANCE_ALERT]: true
}
);
return;
}
useMainStore().createSubmittedOrder();
this.$router.navigate(
this.navigationScenarios.PAY_IN_ADVANCE_SUCCESS,
this.$route
);
}
}
};
</script>

View file

@ -96,6 +96,9 @@ const navigationScenarios = Object.freeze({
// Payment
CLICKED_PAY_NOW: 'CLICKED_PAY_NOW',
PAY_IN_ADVANCE_ERROR: 'PAY_IN_ADVANCE_ERROR',
PAY_IN_ADVANCE_CREDIT_CARD_ERROR: 'PAY_IN_ADVANCE_CREDIT_CARD_ERROR',
PAY_IN_ADVANCE_SUCCESS: 'PAY_IN_ADVANCE_SUCCESS',
// Bailout
CLICKED_FORWARD_WITH_BAILOUT: 'CLICKED_FORWARD_WITH_BAILOUT'

View file

@ -641,6 +641,23 @@ const routingTable = () => [
}
]
},
{
issPageValue: issPageValues.PAYMENT_RETURN,
maps: [
{
scenario: navigationScenarios.PAY_IN_ADVANCE_ERROR,
destinationIssPageValue: issPageValues.PAYMENT_METHOD
},
{
scenario: navigationScenarios.PAY_IN_ADVANCE_CREDIT_CARD_ERROR,
destinationIssPageValue: issPageValues.PAYMENT_PAGE
},
{
scenario: navigationScenarios.PAY_IN_ADVANCE_SUCCESS,
destinationIssPageValue: issPageValues.CONFIRMATION
},
]
},
{
issPageValue: issPageValues.TPA_CONFIRMATION,
maps: [

View file

@ -19,6 +19,7 @@ import {
noCoverageForSelectedVehicle,
repairWaivedForSelectedVehicle
} from '@/helpers/policy-vehicle-helper';
import webStorageConstants from '@/constants/web-storage-constants';
const storeId = 'main';
@ -155,7 +156,21 @@ const getDefaultState = () => ({
},
parentAccountNumber: 0,
isPayInAdvance: null,
payInAdvanceType: null
payInAdvanceType: null,
ccToken: {
subscriptionId: null,
expMonth: null,
expYear: null,
cardType: null,
billToPostalCode: null,
billToFirstName: null,
billToLastName: null,
referenceNumber: null,
authCode: null,
transactionId: null,
transReferenceNumber: null,
lastFour: null
}
},
contactInfo: {
firstName: null,
@ -934,18 +949,6 @@ export const useMainStore = defineStore({
});
},
getCarrierAccountInfo() {
return new Promise((resolve, reject) => {
globalMethods.callHttpClient({
method: endpoints.GetAccountInfo.method,
endpoint: endpoints.GetAccountInfo.url + this.issConfig.parentAccountNumber
}).then((response) => {
this.order.carrierPhoneNumber = response.data.phoneNumber;
return resolve(response.data);
}).catch((error) => reject(error));
});
},
async getSupportingItems() {
const { glassParts } = this.lineItems;
const { carId } = this.vehicle;
@ -1383,6 +1386,10 @@ export const useMainStore = defineStore({
this.order.serviceLocation.searchFilter = serviceLocationInfo.searchFilter;
},
resetState() {
Object.assign(this, getDefaultState());
},
resetRegistrationState() {
this.order.vehicle.registration.licensePlate = null;
this.order.vehicle.registration.address = null;
@ -2135,7 +2142,48 @@ export const useMainStore = defineStore({
method: endpoints.GetPaymentSignature.method,
endpoint: endpoints.GetPaymentSignature.url
});
}
},
updateCCToken(ccToken) {
this.order.payment.ccToken.subscriptionId = ccToken.subscriptionId;
this.order.payment.ccToken.expMonth = ccToken.expMonth;
this.order.payment.ccToken.expYear = ccToken.expYear;
this.order.payment.ccToken.cardType = ccToken.cardType;
this.order.payment.ccToken.billToPostalCode = ccToken.billToPostalCode;
this.order.payment.ccToken.billToFirstName = ccToken.billToFirstName;
this.order.payment.ccToken.billToLastName = ccToken.billToLastName;
this.order.payment.ccToken.referenceNumber = ccToken.referenceNumber;
this.order.payment.ccToken.authCode = ccToken.authCode;
this.order.payment.ccToken.transactionId = ccToken.transactionId;
this.order.payment.ccToken.transReferenceNumber = ccToken.transReferenceNumber;
this.order.payment.ccToken.lastFour = ccToken.lastFour;
},
hasSubmittedOrder() {
return window.sessionStorage.getItem(webStorageConstants.SUBMITTED_ORDER) !== null;
},
createSubmittedOrder() {
if (this.hasSubmittedOrder()) {
return;
}
const submittedOrder = this.order;
const { experiments } = this.applicationUser;
// set to local storage
window.sessionStorage.setItem(webStorageConstants.SUBMITTED_ORDER, JSON.stringify(submittedOrder));
// clear vuex
this.resetState();
// restore user's experiments
this.applicationUser.experiments = experiments;
},
resetSubmittedOrder() {
// clear from local storage
window.sessionStorage.removeItem(webStorageConstants.SUBMITTED_ORDER);
},
},
persist: true