Merged in fix/SW-3020-paymentInfo-tracking (pull request #2403)
fix(SW-3020): add correct paymentInfo in booking flow and ancillary flow * fix(SW-3020): add correct paymentInfo in booking flow and ancillary flow * fix(SW-3020): fix pr comments Approved-by: Tobias Johansson
This commit is contained in:
@@ -8,6 +8,7 @@ import TrackingSDK from "@/components/TrackingSDK"
|
|||||||
import useLang from "@/hooks/useLang"
|
import useLang from "@/hooks/useLang"
|
||||||
import { useSearchHistory } from "@/hooks/useSearchHistory"
|
import { useSearchHistory } from "@/hooks/useSearchHistory"
|
||||||
|
|
||||||
|
import { clearPaymentInfoSessionStorage } from "../../EnterDetails/Payment/helpers"
|
||||||
import { getTracking } from "./tracking"
|
import { getTracking } from "./tracking"
|
||||||
|
|
||||||
import type { Room } from "@/types/stores/booking-confirmation"
|
import type { Room } from "@/types/stores/booking-confirmation"
|
||||||
@@ -37,20 +38,31 @@ export default function Tracking({
|
|||||||
const searchHistory = useSearchHistory()
|
const searchHistory = useSearchHistory()
|
||||||
const searchTerm = searchHistory.searchHistory[0]?.name
|
const searchTerm = searchHistory.searchHistory[0]?.name
|
||||||
|
|
||||||
if (!bookingRooms.every(Boolean)) {
|
let trackingData = null
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (bookingRooms.every(Boolean)) {
|
||||||
const rooms = bookingRooms.filter((room): room is Room => !!room)
|
const rooms = bookingRooms.filter((room): room is Room => !!room)
|
||||||
|
trackingData = getTracking(
|
||||||
const { hotelsTrackingData, pageTrackingData, paymentInfo, ancillaries } =
|
|
||||||
getTracking(
|
|
||||||
lang,
|
lang,
|
||||||
bookingConfirmation.booking,
|
bookingConfirmation.booking,
|
||||||
bookingConfirmation.hotel,
|
bookingConfirmation.hotel,
|
||||||
rooms,
|
rooms,
|
||||||
searchTerm
|
searchTerm
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (trackingData?.paymentInfo) {
|
||||||
|
clearPaymentInfoSessionStorage()
|
||||||
|
}
|
||||||
|
}, [trackingData])
|
||||||
|
|
||||||
|
if (!trackingData) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const { hotelsTrackingData, pageTrackingData, paymentInfo, ancillaries } =
|
||||||
|
trackingData
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TrackingSDK
|
<TrackingSDK
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { differenceInCalendarDays, format, isWeekend } from "date-fns"
|
|||||||
|
|
||||||
import { CancellationRuleEnum } from "@/constants/booking"
|
import { CancellationRuleEnum } from "@/constants/booking"
|
||||||
|
|
||||||
|
import { readPaymentInfoFromSessionStorage } from "@/components/HotelReservation/EnterDetails/Payment/helpers"
|
||||||
import { getSpecialRoomType } from "@/utils/specialRoomType"
|
import { getSpecialRoomType } from "@/utils/specialRoomType"
|
||||||
|
|
||||||
import { invertedBedTypeMap } from "../../utils"
|
import { invertedBedTypeMap } from "../../utils"
|
||||||
@@ -66,6 +67,7 @@ export function getTracking(
|
|||||||
) {
|
) {
|
||||||
const arrivalDate = new Date(booking.checkInDate)
|
const arrivalDate = new Date(booking.checkInDate)
|
||||||
const departureDate = new Date(booking.checkOutDate)
|
const departureDate = new Date(booking.checkOutDate)
|
||||||
|
const paymentInfoSessionData = readPaymentInfoFromSessionStorage()
|
||||||
|
|
||||||
const pageTrackingData: TrackingSDKPageData = {
|
const pageTrackingData: TrackingSDKPageData = {
|
||||||
channel: TrackingChannelEnum.hotelreservation,
|
channel: TrackingChannelEnum.hotelreservation,
|
||||||
@@ -177,9 +179,7 @@ export function getTracking(
|
|||||||
? "glacardsaveconfirmed"
|
? "glacardsaveconfirmed"
|
||||||
: undefined,
|
: undefined,
|
||||||
type:
|
type:
|
||||||
booking.guaranteeInfo && isFlexBooking
|
booking.guaranteeInfo?.cardType ?? paymentInfoSessionData?.paymentMethod,
|
||||||
? booking.guaranteeInfo.cardType
|
|
||||||
: undefined,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ import { trackPaymentEvent } from "@/utils/tracking"
|
|||||||
import { trackEvent } from "@/utils/tracking/base"
|
import { trackEvent } from "@/utils/tracking/base"
|
||||||
import { serializeBookingSearchParams } from "@/utils/url"
|
import { serializeBookingSearchParams } from "@/utils/url"
|
||||||
|
|
||||||
|
import {
|
||||||
|
clearPaymentInfoSessionStorage,
|
||||||
|
readPaymentInfoFromSessionStorage,
|
||||||
|
} from "../helpers"
|
||||||
import { clearGlaSessionStorage, readGlaFromSessionStorage } from "./helpers"
|
import { clearGlaSessionStorage, readGlaFromSessionStorage } from "./helpers"
|
||||||
|
|
||||||
import type { PersistedState } from "@/types/stores/enter-details"
|
import type { PersistedState } from "@/types/stores/enter-details"
|
||||||
@@ -41,6 +45,7 @@ export default function HandleErrorCallback({
|
|||||||
)
|
)
|
||||||
|
|
||||||
const glaSessionData = readGlaFromSessionStorage()
|
const glaSessionData = readGlaFromSessionStorage()
|
||||||
|
const paymentInfoSessionData = readPaymentInfoFromSessionStorage()
|
||||||
|
|
||||||
if (status === PaymentCallbackStatusEnum.Cancel) {
|
if (status === PaymentCallbackStatusEnum.Cancel) {
|
||||||
if (glaSessionData) {
|
if (glaSessionData) {
|
||||||
@@ -54,6 +59,8 @@ export default function HandleErrorCallback({
|
|||||||
paymentInfo: {
|
paymentInfo: {
|
||||||
hotelId: glaSessionData.hotelId,
|
hotelId: glaSessionData.hotelId,
|
||||||
status: "glacardsavecancelled",
|
status: "glacardsavecancelled",
|
||||||
|
type: glaSessionData.paymentMethod,
|
||||||
|
isSavedCreditCard: glaSessionData.isSavedCreditCard,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@@ -61,6 +68,8 @@ export default function HandleErrorCallback({
|
|||||||
event: "paymentCancel",
|
event: "paymentCancel",
|
||||||
hotelId: detailsStorage.booking.hotelId,
|
hotelId: detailsStorage.booking.hotelId,
|
||||||
status: "cancelled",
|
status: "cancelled",
|
||||||
|
method: paymentInfoSessionData?.paymentMethod,
|
||||||
|
isSavedCreditCard: paymentInfoSessionData?.isSavedCreditCard,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,6 +85,8 @@ export default function HandleErrorCallback({
|
|||||||
paymentInfo: {
|
paymentInfo: {
|
||||||
hotelId: glaSessionData.hotelId,
|
hotelId: glaSessionData.hotelId,
|
||||||
status: "glacardsavefailed",
|
status: "glacardsavefailed",
|
||||||
|
type: glaSessionData.paymentMethod,
|
||||||
|
isSavedCreditCard: glaSessionData.isSavedCreditCard,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@@ -84,10 +95,13 @@ export default function HandleErrorCallback({
|
|||||||
hotelId: detailsStorage.booking.hotelId,
|
hotelId: detailsStorage.booking.hotelId,
|
||||||
errorMessage,
|
errorMessage,
|
||||||
status: "failed",
|
status: "failed",
|
||||||
|
method: paymentInfoSessionData?.paymentMethod,
|
||||||
|
isSavedCreditCard: paymentInfoSessionData?.isSavedCreditCard,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clearGlaSessionStorage()
|
clearGlaSessionStorage()
|
||||||
|
clearPaymentInfoSessionStorage()
|
||||||
|
|
||||||
if (searchParams.size > 0) {
|
if (searchParams.size > 0) {
|
||||||
router.replace(`${returnUrl}?${searchParams.toString()}`)
|
router.replace(`${returnUrl}?${searchParams.toString()}`)
|
||||||
|
|||||||
@@ -66,6 +66,11 @@ export default function HandleSuccessCallback({
|
|||||||
hotelId: glaSessionData.hotelId,
|
hotelId: glaSessionData.hotelId,
|
||||||
guaranteedProduct: "room",
|
guaranteedProduct: "room",
|
||||||
},
|
},
|
||||||
|
paymentInfo: {
|
||||||
|
hotelId: glaSessionData.hotelId,
|
||||||
|
type: glaSessionData.paymentMethod,
|
||||||
|
isSavedCreditCard: glaSessionData.isSavedCreditCard,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
clearGlaSessionStorage()
|
clearGlaSessionStorage()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ export const glaStorageName = "gla-storage"
|
|||||||
type GlaSessionData = {
|
type GlaSessionData = {
|
||||||
lateArrivalGuarantee: string
|
lateArrivalGuarantee: string
|
||||||
hotelId: string
|
hotelId: string
|
||||||
|
paymentMethod?: string
|
||||||
|
isSavedCreditCard?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export function readGlaFromSessionStorage(): GlaSessionData | null {
|
export function readGlaFromSessionStorage(): GlaSessionData | null {
|
||||||
@@ -20,12 +22,19 @@ export function readGlaFromSessionStorage(): GlaSessionData | null {
|
|||||||
|
|
||||||
export function writeGlaToSessionStorage(
|
export function writeGlaToSessionStorage(
|
||||||
lateArrivalGuarantee: string,
|
lateArrivalGuarantee: string,
|
||||||
hotelId: string
|
hotelId: string,
|
||||||
|
paymentMethod: string,
|
||||||
|
isSavedCreditCard: boolean
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
sessionStorage.setItem(
|
sessionStorage.setItem(
|
||||||
glaStorageName,
|
glaStorageName,
|
||||||
JSON.stringify({ lateArrivalGuarantee, hotelId })
|
JSON.stringify({
|
||||||
|
lateArrivalGuarantee,
|
||||||
|
hotelId,
|
||||||
|
paymentMethod,
|
||||||
|
isSavedCreditCard,
|
||||||
|
})
|
||||||
)
|
)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error writing to session storage:", error)
|
console.error("Error writing to session storage:", error)
|
||||||
|
|||||||
@@ -43,7 +43,12 @@ import PriceChangeDialog from "../PriceChangeDialog"
|
|||||||
import { writeGlaToSessionStorage } from "./PaymentCallback/helpers"
|
import { writeGlaToSessionStorage } from "./PaymentCallback/helpers"
|
||||||
import BookingAlert from "./BookingAlert"
|
import BookingAlert from "./BookingAlert"
|
||||||
import GuaranteeDetails from "./GuaranteeDetails"
|
import GuaranteeDetails from "./GuaranteeDetails"
|
||||||
import { hasFlexibleRate, hasPrepaidRate, isPaymentMethodEnum } from "./helpers"
|
import {
|
||||||
|
hasFlexibleRate,
|
||||||
|
hasPrepaidRate,
|
||||||
|
isPaymentMethodEnum,
|
||||||
|
writePaymentInfoToSessionStorage,
|
||||||
|
} from "./helpers"
|
||||||
import MixedRatePaymentBreakdown from "./MixedRatePaymentBreakdown"
|
import MixedRatePaymentBreakdown from "./MixedRatePaymentBreakdown"
|
||||||
import PaymentOptionsGroup from "./PaymentOptionsGroup"
|
import PaymentOptionsGroup from "./PaymentOptionsGroup"
|
||||||
import { type PaymentFormData, paymentSchema } from "./schema"
|
import { type PaymentFormData, paymentSchema } from "./schema"
|
||||||
@@ -216,10 +221,12 @@ export default function PaymentClient({
|
|||||||
const currentPaymentMethod = methods.getValues("paymentMethod")
|
const currentPaymentMethod = methods.getValues("paymentMethod")
|
||||||
const smsEnable = methods.getValues("smsConfirmation")
|
const smsEnable = methods.getValues("smsConfirmation")
|
||||||
const guarantee = methods.getValues("guarantee")
|
const guarantee = methods.getValues("guarantee")
|
||||||
const isSavedCreditCard = savedCreditCards?.some(
|
const savedCreditCard = savedCreditCards?.find(
|
||||||
(card) => card.id === currentPaymentMethod
|
(card) => card.id === currentPaymentMethod
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const isSavedCreditCard = !!savedCreditCard
|
||||||
|
|
||||||
if (guarantee || (bookingMustBeGuaranteed && hasOnlyFlexRates)) {
|
if (guarantee || (bookingMustBeGuaranteed && hasOnlyFlexRates)) {
|
||||||
const lateArrivalGuarantee = guarantee ? "yes" : "mandatory"
|
const lateArrivalGuarantee = guarantee ? "yes" : "mandatory"
|
||||||
trackEvent({
|
trackEvent({
|
||||||
@@ -233,13 +240,14 @@ export default function PaymentClient({
|
|||||||
isSavedCreditCard,
|
isSavedCreditCard,
|
||||||
hotelId,
|
hotelId,
|
||||||
status: "glacardsavefailed",
|
status: "glacardsavefailed",
|
||||||
|
type: savedCreditCard ? savedCreditCard.type : currentPaymentMethod,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
trackPaymentEvent({
|
trackPaymentEvent({
|
||||||
event: "paymentFail",
|
event: "paymentFail",
|
||||||
hotelId,
|
hotelId,
|
||||||
method: currentPaymentMethod,
|
method: savedCreditCard ? savedCreditCard.type : currentPaymentMethod,
|
||||||
isSavedCreditCard,
|
isSavedCreditCard,
|
||||||
smsEnable,
|
smsEnable,
|
||||||
errorMessage,
|
errorMessage,
|
||||||
@@ -355,21 +363,29 @@ export default function PaymentClient({
|
|||||||
cancel: `${paymentRedirectUrl}/cancel`,
|
cancel: `${paymentRedirectUrl}/cancel`,
|
||||||
}
|
}
|
||||||
: undefined
|
: undefined
|
||||||
|
const paymentMethodType = savedCreditCard
|
||||||
|
? savedCreditCard.type
|
||||||
|
: paymentMethod
|
||||||
if (guarantee || (bookingMustBeGuaranteed && hasOnlyFlexRates)) {
|
if (guarantee || (bookingMustBeGuaranteed && hasOnlyFlexRates)) {
|
||||||
const lateArrivalGuarantee = guarantee ? "yes" : "mandatory"
|
const lateArrivalGuarantee = guarantee ? "yes" : "mandatory"
|
||||||
writeGlaToSessionStorage(lateArrivalGuarantee, hotelId)
|
writeGlaToSessionStorage(
|
||||||
|
lateArrivalGuarantee,
|
||||||
|
hotelId,
|
||||||
|
paymentMethodType,
|
||||||
|
!!savedCreditCard
|
||||||
|
)
|
||||||
trackGlaSaveCardAttempt(hotelId, savedCreditCard, lateArrivalGuarantee)
|
trackGlaSaveCardAttempt(hotelId, savedCreditCard, lateArrivalGuarantee)
|
||||||
} else if (!hasOnlyFlexRates) {
|
} else if (!hasOnlyFlexRates) {
|
||||||
trackPaymentEvent({
|
trackPaymentEvent({
|
||||||
event: "paymentAttemptStart",
|
event: "paymentAttemptStart",
|
||||||
hotelId,
|
hotelId,
|
||||||
method: savedCreditCard ? savedCreditCard.type : paymentMethod,
|
method: paymentMethodType,
|
||||||
isSavedCreditCard: !!savedCreditCard,
|
isSavedCreditCard: !!savedCreditCard,
|
||||||
smsEnable: data.smsConfirmation,
|
smsEnable: data.smsConfirmation,
|
||||||
status: "attempt",
|
status: "attempt",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
writePaymentInfoToSessionStorage(paymentMethodType, !!savedCreditCard)
|
||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
checkInDate: fromDate,
|
checkInDate: fromDate,
|
||||||
|
|||||||
@@ -45,3 +45,46 @@ export function calculateTotalRoomPrice(
|
|||||||
comparisonPrice,
|
comparisonPrice,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const paymentInfoStorageName = "payment-info-storage"
|
||||||
|
|
||||||
|
type PaymentInfoSessionData = {
|
||||||
|
paymentMethod: string
|
||||||
|
isSavedCreditCard: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export function readPaymentInfoFromSessionStorage():
|
||||||
|
| PaymentInfoSessionData
|
||||||
|
| undefined {
|
||||||
|
try {
|
||||||
|
const paymentInfoSessionData = sessionStorage.getItem(
|
||||||
|
paymentInfoStorageName
|
||||||
|
)
|
||||||
|
if (!paymentInfoSessionData) return undefined
|
||||||
|
return JSON.parse(paymentInfoSessionData)
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error reading from session storage:", error)
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function writePaymentInfoToSessionStorage(
|
||||||
|
paymentMethod: string,
|
||||||
|
isSavedCreditCard: boolean
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
sessionStorage.setItem(
|
||||||
|
paymentInfoStorageName,
|
||||||
|
JSON.stringify({
|
||||||
|
paymentMethod,
|
||||||
|
isSavedCreditCard,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error writing to session storage:", error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function clearPaymentInfoSessionStorage() {
|
||||||
|
sessionStorage.removeItem(paymentInfoStorageName)
|
||||||
|
}
|
||||||
|
|||||||
@@ -80,7 +80,13 @@ export default function Form() {
|
|||||||
cardType: savedCreditCard.cardType,
|
cardType: savedCreditCard.cardType,
|
||||||
}
|
}
|
||||||
: undefined
|
: undefined
|
||||||
writeGlaToSessionStorage("yes", hotelId)
|
const lateArrivalGuarantee = "yes"
|
||||||
|
writeGlaToSessionStorage(
|
||||||
|
lateArrivalGuarantee,
|
||||||
|
hotelId,
|
||||||
|
savedCreditCard ? savedCreditCard.type : PaymentMethodEnum.card,
|
||||||
|
!!savedCreditCard
|
||||||
|
)
|
||||||
guaranteeBooking.mutate({
|
guaranteeBooking.mutate({
|
||||||
refId,
|
refId,
|
||||||
language: lang,
|
language: lang,
|
||||||
|
|||||||
@@ -57,16 +57,18 @@ export default function TrackGuarantee({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const trackGuaranteePaymentEvent = (event: string, status: string) => {
|
const trackGuaranteePaymentEvent = (event: string, status: string) => {
|
||||||
const glaHotelInfo = readGlaFromSessionStorage()
|
const glaSessionData = readGlaFromSessionStorage()
|
||||||
trackEvent({
|
trackEvent({
|
||||||
event,
|
event,
|
||||||
hotelInfo: {
|
hotelInfo: {
|
||||||
hotelId: glaHotelInfo?.hotelId,
|
hotelId: glaSessionData?.hotelId,
|
||||||
lateArrivalGuarantee: "yes",
|
lateArrivalGuarantee: "yes",
|
||||||
guaranteedProduct: "room",
|
guaranteedProduct: "room",
|
||||||
},
|
},
|
||||||
paymentInfo: {
|
paymentInfo: {
|
||||||
status,
|
status,
|
||||||
|
type: glaSessionData?.paymentMethod,
|
||||||
|
isSavedCreditCard: glaSessionData?.isSavedCreditCard,
|
||||||
...(errorMessage && { errorMessage }),
|
...(errorMessage && { errorMessage }),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@@ -75,14 +77,19 @@ export default function TrackGuarantee({
|
|||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case PaymentCallbackStatusEnum.Success:
|
case PaymentCallbackStatusEnum.Success:
|
||||||
const glaHotelInfo = readGlaFromSessionStorage()
|
const glaSessionData = readGlaFromSessionStorage()
|
||||||
trackEvent({
|
trackEvent({
|
||||||
event: "guaranteeBookingSuccess",
|
event: "guaranteeBookingSuccess",
|
||||||
hotelInfo: {
|
hotelInfo: {
|
||||||
hotelId: glaHotelInfo?.hotelId,
|
hotelId: glaSessionData?.hotelId,
|
||||||
lateArrivalGuarantee: "yes",
|
lateArrivalGuarantee: "yes",
|
||||||
guaranteedProduct: "room",
|
guaranteedProduct: "room",
|
||||||
},
|
},
|
||||||
|
paymentInfo: {
|
||||||
|
type: glaSessionData?.paymentMethod,
|
||||||
|
hotelId: glaSessionData?.hotelId,
|
||||||
|
isSavedCreditCard: glaSessionData?.isSavedCreditCard,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
clearGlaSessionStorage()
|
clearGlaSessionStorage()
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ export function trackGlaSaveCardAttempt(
|
|||||||
},
|
},
|
||||||
paymentInfo: {
|
paymentInfo: {
|
||||||
status: "glacardsaveattempt",
|
status: "glacardsaveattempt",
|
||||||
|
isSavedCreditCard: !!savedCreditCard,
|
||||||
type: savedCreditCard?.cardType,
|
type: savedCreditCard?.cardType,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user