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:
Bianca Widstam
2025-06-24 13:38:30 +00:00
parent eb77241a4e
commit 5c3b30ea93
10 changed files with 136 additions and 23 deletions

View File

@@ -8,6 +8,7 @@ import TrackingSDK from "@/components/TrackingSDK"
import useLang from "@/hooks/useLang"
import { useSearchHistory } from "@/hooks/useSearchHistory"
import { clearPaymentInfoSessionStorage } from "../../EnterDetails/Payment/helpers"
import { getTracking } from "./tracking"
import type { Room } from "@/types/stores/booking-confirmation"
@@ -37,20 +38,31 @@ export default function Tracking({
const searchHistory = useSearchHistory()
const searchTerm = searchHistory.searchHistory[0]?.name
if (!bookingRooms.every(Boolean)) {
return null
}
let trackingData = null
const rooms = bookingRooms.filter((room): room is Room => !!room)
const { hotelsTrackingData, pageTrackingData, paymentInfo, ancillaries } =
getTracking(
if (bookingRooms.every(Boolean)) {
const rooms = bookingRooms.filter((room): room is Room => !!room)
trackingData = getTracking(
lang,
bookingConfirmation.booking,
bookingConfirmation.hotel,
rooms,
searchTerm
)
}
useEffect(() => {
if (trackingData?.paymentInfo) {
clearPaymentInfoSessionStorage()
}
}, [trackingData])
if (!trackingData) {
return null
}
const { hotelsTrackingData, pageTrackingData, paymentInfo, ancillaries } =
trackingData
return (
<TrackingSDK

View File

@@ -2,6 +2,7 @@ import { differenceInCalendarDays, format, isWeekend } from "date-fns"
import { CancellationRuleEnum } from "@/constants/booking"
import { readPaymentInfoFromSessionStorage } from "@/components/HotelReservation/EnterDetails/Payment/helpers"
import { getSpecialRoomType } from "@/utils/specialRoomType"
import { invertedBedTypeMap } from "../../utils"
@@ -66,6 +67,7 @@ export function getTracking(
) {
const arrivalDate = new Date(booking.checkInDate)
const departureDate = new Date(booking.checkOutDate)
const paymentInfoSessionData = readPaymentInfoFromSessionStorage()
const pageTrackingData: TrackingSDKPageData = {
channel: TrackingChannelEnum.hotelreservation,
@@ -177,9 +179,7 @@ export function getTracking(
? "glacardsaveconfirmed"
: undefined,
type:
booking.guaranteeInfo && isFlexBooking
? booking.guaranteeInfo.cardType
: undefined,
booking.guaranteeInfo?.cardType ?? paymentInfoSessionData?.paymentMethod,
}
return {

View File

@@ -11,6 +11,10 @@ import { trackPaymentEvent } from "@/utils/tracking"
import { trackEvent } from "@/utils/tracking/base"
import { serializeBookingSearchParams } from "@/utils/url"
import {
clearPaymentInfoSessionStorage,
readPaymentInfoFromSessionStorage,
} from "../helpers"
import { clearGlaSessionStorage, readGlaFromSessionStorage } from "./helpers"
import type { PersistedState } from "@/types/stores/enter-details"
@@ -41,6 +45,7 @@ export default function HandleErrorCallback({
)
const glaSessionData = readGlaFromSessionStorage()
const paymentInfoSessionData = readPaymentInfoFromSessionStorage()
if (status === PaymentCallbackStatusEnum.Cancel) {
if (glaSessionData) {
@@ -54,6 +59,8 @@ export default function HandleErrorCallback({
paymentInfo: {
hotelId: glaSessionData.hotelId,
status: "glacardsavecancelled",
type: glaSessionData.paymentMethod,
isSavedCreditCard: glaSessionData.isSavedCreditCard,
},
})
} else {
@@ -61,6 +68,8 @@ export default function HandleErrorCallback({
event: "paymentCancel",
hotelId: detailsStorage.booking.hotelId,
status: "cancelled",
method: paymentInfoSessionData?.paymentMethod,
isSavedCreditCard: paymentInfoSessionData?.isSavedCreditCard,
})
}
}
@@ -76,6 +85,8 @@ export default function HandleErrorCallback({
paymentInfo: {
hotelId: glaSessionData.hotelId,
status: "glacardsavefailed",
type: glaSessionData.paymentMethod,
isSavedCreditCard: glaSessionData.isSavedCreditCard,
},
})
} else {
@@ -84,10 +95,13 @@ export default function HandleErrorCallback({
hotelId: detailsStorage.booking.hotelId,
errorMessage,
status: "failed",
method: paymentInfoSessionData?.paymentMethod,
isSavedCreditCard: paymentInfoSessionData?.isSavedCreditCard,
})
}
}
clearGlaSessionStorage()
clearPaymentInfoSessionStorage()
if (searchParams.size > 0) {
router.replace(`${returnUrl}?${searchParams.toString()}`)

View File

@@ -66,6 +66,11 @@ export default function HandleSuccessCallback({
hotelId: glaSessionData.hotelId,
guaranteedProduct: "room",
},
paymentInfo: {
hotelId: glaSessionData.hotelId,
type: glaSessionData.paymentMethod,
isSavedCreditCard: glaSessionData.isSavedCreditCard,
},
})
clearGlaSessionStorage()
}

View File

@@ -5,6 +5,8 @@ export const glaStorageName = "gla-storage"
type GlaSessionData = {
lateArrivalGuarantee: string
hotelId: string
paymentMethod?: string
isSavedCreditCard?: boolean
}
export function readGlaFromSessionStorage(): GlaSessionData | null {
@@ -20,12 +22,19 @@ export function readGlaFromSessionStorage(): GlaSessionData | null {
export function writeGlaToSessionStorage(
lateArrivalGuarantee: string,
hotelId: string
hotelId: string,
paymentMethod: string,
isSavedCreditCard: boolean
) {
try {
sessionStorage.setItem(
glaStorageName,
JSON.stringify({ lateArrivalGuarantee, hotelId })
JSON.stringify({
lateArrivalGuarantee,
hotelId,
paymentMethod,
isSavedCreditCard,
})
)
} catch (error) {
console.error("Error writing to session storage:", error)

View File

@@ -43,7 +43,12 @@ import PriceChangeDialog from "../PriceChangeDialog"
import { writeGlaToSessionStorage } from "./PaymentCallback/helpers"
import BookingAlert from "./BookingAlert"
import GuaranteeDetails from "./GuaranteeDetails"
import { hasFlexibleRate, hasPrepaidRate, isPaymentMethodEnum } from "./helpers"
import {
hasFlexibleRate,
hasPrepaidRate,
isPaymentMethodEnum,
writePaymentInfoToSessionStorage,
} from "./helpers"
import MixedRatePaymentBreakdown from "./MixedRatePaymentBreakdown"
import PaymentOptionsGroup from "./PaymentOptionsGroup"
import { type PaymentFormData, paymentSchema } from "./schema"
@@ -216,10 +221,12 @@ export default function PaymentClient({
const currentPaymentMethod = methods.getValues("paymentMethod")
const smsEnable = methods.getValues("smsConfirmation")
const guarantee = methods.getValues("guarantee")
const isSavedCreditCard = savedCreditCards?.some(
const savedCreditCard = savedCreditCards?.find(
(card) => card.id === currentPaymentMethod
)
const isSavedCreditCard = !!savedCreditCard
if (guarantee || (bookingMustBeGuaranteed && hasOnlyFlexRates)) {
const lateArrivalGuarantee = guarantee ? "yes" : "mandatory"
trackEvent({
@@ -233,13 +240,14 @@ export default function PaymentClient({
isSavedCreditCard,
hotelId,
status: "glacardsavefailed",
type: savedCreditCard ? savedCreditCard.type : currentPaymentMethod,
},
})
} else {
trackPaymentEvent({
event: "paymentFail",
hotelId,
method: currentPaymentMethod,
method: savedCreditCard ? savedCreditCard.type : currentPaymentMethod,
isSavedCreditCard,
smsEnable,
errorMessage,
@@ -355,21 +363,29 @@ export default function PaymentClient({
cancel: `${paymentRedirectUrl}/cancel`,
}
: undefined
const paymentMethodType = savedCreditCard
? savedCreditCard.type
: paymentMethod
if (guarantee || (bookingMustBeGuaranteed && hasOnlyFlexRates)) {
const lateArrivalGuarantee = guarantee ? "yes" : "mandatory"
writeGlaToSessionStorage(lateArrivalGuarantee, hotelId)
writeGlaToSessionStorage(
lateArrivalGuarantee,
hotelId,
paymentMethodType,
!!savedCreditCard
)
trackGlaSaveCardAttempt(hotelId, savedCreditCard, lateArrivalGuarantee)
} else if (!hasOnlyFlexRates) {
trackPaymentEvent({
event: "paymentAttemptStart",
hotelId,
method: savedCreditCard ? savedCreditCard.type : paymentMethod,
method: paymentMethodType,
isSavedCreditCard: !!savedCreditCard,
smsEnable: data.smsConfirmation,
status: "attempt",
})
}
writePaymentInfoToSessionStorage(paymentMethodType, !!savedCreditCard)
const payload = {
checkInDate: fromDate,

View File

@@ -45,3 +45,46 @@ export function calculateTotalRoomPrice(
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)
}

View File

@@ -80,7 +80,13 @@ export default function Form() {
cardType: savedCreditCard.cardType,
}
: undefined
writeGlaToSessionStorage("yes", hotelId)
const lateArrivalGuarantee = "yes"
writeGlaToSessionStorage(
lateArrivalGuarantee,
hotelId,
savedCreditCard ? savedCreditCard.type : PaymentMethodEnum.card,
!!savedCreditCard
)
guaranteeBooking.mutate({
refId,
language: lang,

View File

@@ -57,16 +57,18 @@ export default function TrackGuarantee({
}
const trackGuaranteePaymentEvent = (event: string, status: string) => {
const glaHotelInfo = readGlaFromSessionStorage()
const glaSessionData = readGlaFromSessionStorage()
trackEvent({
event,
hotelInfo: {
hotelId: glaHotelInfo?.hotelId,
hotelId: glaSessionData?.hotelId,
lateArrivalGuarantee: "yes",
guaranteedProduct: "room",
},
paymentInfo: {
status,
type: glaSessionData?.paymentMethod,
isSavedCreditCard: glaSessionData?.isSavedCreditCard,
...(errorMessage && { errorMessage }),
},
})
@@ -75,14 +77,19 @@ export default function TrackGuarantee({
switch (status) {
case PaymentCallbackStatusEnum.Success:
const glaHotelInfo = readGlaFromSessionStorage()
const glaSessionData = readGlaFromSessionStorage()
trackEvent({
event: "guaranteeBookingSuccess",
hotelInfo: {
hotelId: glaHotelInfo?.hotelId,
hotelId: glaSessionData?.hotelId,
lateArrivalGuarantee: "yes",
guaranteedProduct: "room",
},
paymentInfo: {
type: glaSessionData?.paymentMethod,
hotelId: glaSessionData?.hotelId,
isSavedCreditCard: glaSessionData?.isSavedCreditCard,
},
})
clearGlaSessionStorage()
break