Adyen POC 0.0

This commit is contained in:
Chloe Herd 2025-12-10 16:12:58 -05:00
parent fdf1db3a25
commit a212894a26
6 changed files with 349 additions and 1 deletions

View file

@ -216,6 +216,14 @@ const endpoints = {
url: "/order/api/v1/order/add-donation-part",
method: "POST",
},
InitializeAdyenPayment: {
url: "/order/api/v1/order/payment/session/initialize-session",
method: "POST",
},
GetAdyenSessionResult: {
url: "/order/api/v1/order/payment/session/session-result",
method: "POST",
},
};
export { endpoints };

View file

@ -0,0 +1,319 @@
<template>
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm">
<div class="container-fluid">
<div class="row justify-content-center">
<div class="col-md-6">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4">
<funnelSubHeader class="pb-4" cmsWidgetName="FunnelSubHeaderWidget" />
<!--
... Page code goes here.
-->
<div id="adyen-container"></div>
<navbar
cmsWidgetName="FunnelFooterWidget"
ref="navbar"
isForwardActionDisabled="true"
isSubmitHidden="true"
@back-clicked="backButtonAction" />
</div>
</div>
</div>
<component
:is="'script'"
src="https://checkoutshopper-test.adyen.com/checkoutshopper/sdk/6.21.0/adyen.js"
@load="initializeAdyen"></component>
<link
rel="stylesheet"
href="https://checkoutshopper-test.adyen.com/checkoutshopper/sdk/6.21.0/adyen.css" />
</Form>
</template>
<script>
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 { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { settleAllPromises } from "@/helpers/layout-helper";
import globalMethods from "@/global-methods";
import { endpoints } from "../../constants/endpoints";
import { AppointmentTypeStrings } from "../../constants/schedule-constants";
export default {
name: "payment-adyen",
mixins: [],
data() {
return {
sessionId: String,
};
},
async beforeRouteEnter(to, from, next) {
// Call APIs
const cmsContentPromise = fetchCmsContentForPage(to.name);
// Settle API calls in parallel before handling results.
const promiseResultMap = [
{
resultKey: "cmsContent",
promise: cmsContentPromise,
},
];
const resultMap = await settleAllPromises(promiseResultMap);
// Hydrate page with results
next(async (vm) => {
vm.setCmsContent(resultMap.cmsContent);
});
},
methods: {
async backButtonAction() {
// Stub, for navigating back via nav-bar.
},
async forwardButtonAction() {
// Stub, for navigating forward via nav-bar
},
arePagePrerequisitesValid() {
// Stub, for checking if application is capable of entering this page
// And/or, is all information required for this page present?
// To prevent sequence-breaking from the end-user.
return true;
},
async initializeAdyen() {
const requestBody = this.adyenInitRequestInfo;
console.log(`Calling with:`);
console.log(requestBody);
const response = await globalMethods.callHttpClient({
method: endpoints.InitializeAdyenPayment.method,
endpoint: endpoints.InitializeAdyenPayment.url,
payload: requestBody,
logApiCall: true,
pageNameToLog: "payment-adyen",
});
const responseJson = response?.data;
console.log(`Got data:`);
console.log(responseJson);
const session = {
id: responseJson.sessionId,
sessionData: responseJson.sessionData,
};
this.sessionId = responseJson.sessionId;
const configuration = {
session: session,
clientKey: "test_WYGT4F5ZT5BRRL5MPWHK6QLYOIXZXROD",
environment: "test",
amount: {
value: this.adyenPriceTotal,
currency: "USD",
},
locale: "en-US",
countryCode: "US",
showPayButton: true,
translations: {
"en-US": {
"creditCard.securityCode.label": "CVV/CVC",
},
},
onPaymentCompleted: (result, component) => {
console.log(`Payment completed from Adyen.`);
this.handleCompletedPayment(result);
},
onPaymentFailed: (result, component) => {
console.log(`Payment failed from Adyen`);
this.handleFailedPayment(result);
},
onError: (error, component) => {
console.log(`Error from Adyen`);
this.handleError(error);
},
};
console.log(`Configuration =`);
console.log(configuration);
// eslint-disable-next-line
const checkOut = await AdyenWeb.AdyenCheckout(configuration);
window.checkout = checkOut;
// eslint-disable-next-line
const dropin = new AdyenWeb.Dropin(checkOut, {
paymentMethodsConfiguration: {
card: {
showBrandIcon: true, // when false not showing the brand logo
hasHolderName: true, // show holder name
holderNameRequired: true, // make holder name mandatory
billingAddressRequired: true,
billingAddressAllowedCountries: ["US"],
// configure placeholders
placeholders: {
cardNumber: "1234 5678 9012 3456",
expiryDate: "MM/YY",
securityCodeThreeDigits: "123",
securityCodeFourDigits: "1234",
holderName: "J. Smith",
},
},
},
}).mount("#adyen-container");
},
async handleCompletedPayment(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,
};
console.log(`Get session payload =`);
console.log(paymentSessionRequest);
const response = await globalMethods.callHttpClient({
method: endpoints.GetAdyenSessionResult.method,
endpoint: endpoints.GetAdyenSessionResult.url,
payload: paymentSessionRequest,
logApiCall: true,
pageNameToLog: "payment-adyen",
});
const responseJson = response?.data;
console.log(`Session response =`);
console.log(responseJson);
const ccToken = {
subscriptionId: responseJson?.storedToken,
expMonth: responseJson?.cardExpiryMonth,
expYear: responseJson?.cardExpiryYear,
cardType: responseJson?.cardType,
billToPostalCode: this.locationInfo.zipCode, // TODO
billToFirstName: this.$store.getters.order.customer.firstName, // TODO
billToLastName: this.$store.getters.order.customer.lastName, // TODO
referenceNumber: responseJson?.workOrderNumber,
authCode: responseJson?.authCode,
transactionId: responseJson?.transactionReference, // TODO
transReferenceNumber: responseJson?.transactionReference,
lastFour: responseJson?.last4DigitsOfCard,
};
console.log(`CC Token generated =`);
console.log(ccToken);
},
handleFailedPayment(result) {},
handleError(error) {},
},
computed: {
adyenInitRequestInfo() {
return {
sourceSystem: this.sourceSystem,
referralSequenceNumber: this.$store.getters.order.referralSequenceNumber,
workOrderNumber: this.workOrderNumberLastSixDigits,
zipCodeCtu: this.locationInfo.zipCodeCtu,
amount: this.adyenPriceTotal, // TODO
city: this.locationInfo.city,
houseNumberOrName: this.splitStreetAddress.number,
street: this.splitStreetAddress.street,
zipCode: this.locationInfo.zipCode,
stateOrProvince: this.locationInfo.state,
returnUrl: "localhost:8080/fmg/confirmation",
email: this.$store.getters.order.customer.emailAddress,
IP: "127.0.0.1", // TODO
firstName: this.$store.getters.order.customer.firstName,
lastName: this.$store.getters.order.customer.lastName,
idempotencyKey: `${this.$store.getters.order.referralCorrelationId}-${this.sourceSystem}`,
};
},
workOrderNumberLastSixDigits() {
const workOrderNumber = this.$store.getters.order.workOrderNumber ?? "";
const tokens = workOrderNumber.split("-");
const lastSegment = tokens[tokens.length - 1] ?? "";
const numDigits = lastSegment.length;
const numZeroes = 6 - numDigits;
let result = "";
for (let i = 0; i < numZeroes; i++) {
result += "0";
}
result += lastSegment;
return result;
},
locationInfo() {
const serviceLocation = this.$store.getters.order.serviceLocation;
const isMobile = serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE;
if (isMobile) {
return {
address: serviceLocation.address,
address2: serviceLocation.address2,
city: serviceLocation.city,
state: serviceLocation.state,
zipCode: serviceLocation.zipCode,
zipCodeCtu: serviceLocation.zipCodeCtu,
};
} else {
const providerInfo = serviceLocation.provider.address;
return {
address: providerInfo.streetAddress,
address2: "",
city: providerInfo.city,
state: providerInfo.state,
zipCode: providerInfo.zipCode,
zipCodeCtu: providerInfo.zipCodeCtu,
};
}
},
splitStreetAddress() {
const address = this.locationInfo.address;
const tokens = address.split(" ") ?? [""];
const number = tokens[0];
const street = tokens.slice(1).reduce((prev, next) => `${prev} ${next}`);
return {
number: number ?? "",
street: street ?? "",
};
},
sourceSystem() {
return "FMG-2.0";
},
adyenPriceTotal() {
return 10000;
},
},
components: {
Form,
funnelHeader,
funnelSubHeader,
navbar,
},
};
</script>

View file

@ -156,6 +156,9 @@ export default {
lastFour: lastFour,
};
console.log(`CCToken =`);
console.log(ccToken);
baseMixin.methods.dispatchStoreAction(storeActions.SAVE_CCTOKEN, ccToken, false);
baseMixin.methods.dispatchStoreAction(
storeActions.SAVE_NEXTGEN_SETTLED_AMOUNT,

View file

@ -89,6 +89,10 @@ export const routeData = {
name: "payment-pia-return",
path: "/payment-pia-return",
},
PAYMENT_ADYEN: {
name: "payment-adyen",
path: "/payment-adyen",
},
CONFIRMATION: {
name: "confirmation",
path: "/confirmation",

View file

@ -535,7 +535,7 @@ const routingTable = function () {
},
{
scenario: navigationScenarios.CLICKED_PAY_NOW,
destinationPageData: routeData.PAYMENT,
destinationPageData: routeData.PAYMENT_ADYEN,
},
{
scenario: navigationScenarios.CLICKED_INSURANCE,
@ -563,6 +563,19 @@ const routingTable = function () {
},
],
},
{
pageName: routeData.PAYMENT_ADYEN.name,
maps: [
{
scenario: navigationScenarios.CLICKED_BACK,
destinationPageData: routeData.PAYMENT_METHOD,
},
{
scenario: navigationScenarios.CLICKED_FORWARD,
destinationPageData: routeData.CONFIRMATION,
},
],
},
{
pageName: routeData.PAYMENT_PIA_RETURN.name,
maps: [

View file

@ -36,6 +36,7 @@ export const routes = [
createRoute(routeData.PAYMENT_METHOD, paymentMethodBeforeEnter),
createRoute(routeData.PAYMENT, paymentBeforeEnter),
createRoute(routeData.PAYMENT_PIA_RETURN),
createRoute(routeData.PAYMENT_ADYEN),
createRoute(routeData.CONFIRMATION),
createRoute(routeData.RETURN_USER),
createRoute(routeData.MOBILE_DETAILS),