fix(SW-3551): Fix issue with BookingConfigProvider in RSC * wip move config to pages * Move config providing to pages
161 lines
4.7 KiB
TypeScript
161 lines
4.7 KiB
TypeScript
import { notFound } from "next/navigation"
|
|
|
|
import { PaymentCallbackStatusEnum } from "@scandic-hotels/common/constants/paymentCallbackStatusEnum"
|
|
import {
|
|
bookingConfirmation,
|
|
details,
|
|
} from "@scandic-hotels/common/constants/routes/hotelReservation"
|
|
import { logger } from "@scandic-hotels/common/logger"
|
|
import { getServiceToken } from "@scandic-hotels/common/tokenManager"
|
|
import { BookingErrorCodeEnum } from "@scandic-hotels/trpc/enums/bookingErrorCode"
|
|
import { getBooking } from "@scandic-hotels/trpc/routers/booking/utils"
|
|
import { encrypt } from "@scandic-hotels/trpc/utils/encryption"
|
|
|
|
import { BookingFlowConfig } from "../bookingFlowConfig/bookingFlowConfig"
|
|
import { HandleErrorCallback } from "../components/EnterDetails/Payment/PaymentCallback/HandleErrorCallback"
|
|
import { HandleSuccessCallback } from "../components/EnterDetails/Payment/PaymentCallback/HandleSuccessCallback"
|
|
import { serverClient } from "../trpc"
|
|
|
|
import type { Lang } from "@scandic-hotels/common/constants/language"
|
|
|
|
import type { NextSearchParams } from "../types"
|
|
|
|
type PaymentCallbackPageProps = {
|
|
lang: Lang
|
|
searchParams: NextSearchParams
|
|
userAccessToken: string | null
|
|
status: PaymentCallbackStatusEnum
|
|
config: BookingFlowConfig
|
|
}
|
|
export async function PaymentCallbackPage({
|
|
lang,
|
|
userAccessToken,
|
|
searchParams,
|
|
status,
|
|
config,
|
|
}: PaymentCallbackPageProps) {
|
|
const { confirmationNumber } = searchParams
|
|
|
|
if (
|
|
!status ||
|
|
!confirmationNumber ||
|
|
typeof confirmationNumber !== "string"
|
|
) {
|
|
logger.error(
|
|
`[payment-callback] missing status or confirmationNumber in search params`
|
|
)
|
|
notFound()
|
|
}
|
|
|
|
const returnUrl = details(lang)
|
|
const searchObject = new URLSearchParams()
|
|
let errorMessage = undefined
|
|
|
|
if (status === PaymentCallbackStatusEnum.Cancel) {
|
|
searchObject.set("errorCode", BookingErrorCodeEnum.TransactionCancelled)
|
|
return (
|
|
<BookingFlowConfig config={config}>
|
|
<HandleErrorCallback
|
|
returnUrl={returnUrl.toString()}
|
|
searchObject={searchObject}
|
|
status={status}
|
|
errorMessage={errorMessage}
|
|
/>
|
|
</BookingFlowConfig>
|
|
)
|
|
}
|
|
|
|
let token = userAccessToken
|
|
if (!token) {
|
|
const serviceToken = await getServiceToken()
|
|
if (serviceToken) {
|
|
token = serviceToken.access_token
|
|
}
|
|
}
|
|
|
|
if (!token) {
|
|
logger.error(
|
|
`[payment-callback] no token found for user, cannot fetch booking`
|
|
)
|
|
notFound()
|
|
}
|
|
|
|
const booking = await getBooking(confirmationNumber, lang, token)
|
|
|
|
const refId = booking?.refId
|
|
|
|
if (
|
|
status === PaymentCallbackStatusEnum.Success &&
|
|
confirmationNumber &&
|
|
refId
|
|
) {
|
|
const expire = Math.floor(Date.now() / 1000) + 60
|
|
const sig = encrypt(expire.toString())
|
|
const confirmationUrl = `${bookingConfirmation(lang)}?RefId=${encodeURIComponent(refId)}`
|
|
logger.debug(
|
|
`[payment-callback] rendering success callback with confirmation number: ${confirmationNumber}`
|
|
)
|
|
|
|
return (
|
|
<BookingFlowConfig config={config}>
|
|
<HandleSuccessCallback
|
|
refId={refId}
|
|
sig={sig}
|
|
successRedirectUrl={confirmationUrl}
|
|
cardType={booking.guaranteeInfo?.cardType}
|
|
/>
|
|
</BookingFlowConfig>
|
|
)
|
|
}
|
|
|
|
if (refId) {
|
|
try {
|
|
const caller = await serverClient()
|
|
const bookingStatus = await caller.booking.status({
|
|
refId,
|
|
})
|
|
|
|
const { booking } = bookingStatus
|
|
|
|
// TODO: how to handle errors for multiple rooms?
|
|
const error = booking.errors.find((e) => e.errorCode)
|
|
|
|
errorMessage =
|
|
error?.description ??
|
|
`No error message found for booking ${confirmationNumber}, status: ${status}`
|
|
|
|
searchObject.set(
|
|
"errorCode",
|
|
error
|
|
? error.errorCode.toString()
|
|
: BookingErrorCodeEnum.TransactionFailed
|
|
)
|
|
} catch {
|
|
logger.error(
|
|
`[payment-callback] failed to get booking status for ${confirmationNumber}, status: ${status}`
|
|
)
|
|
searchObject.set("errorCode", BookingErrorCodeEnum.TransactionFailed)
|
|
errorMessage = `Failed to get booking status for ${confirmationNumber}, status: ${status}`
|
|
}
|
|
}
|
|
|
|
if (status === PaymentCallbackStatusEnum.Error) {
|
|
logger.error(
|
|
`[payment-callback] error status received for ${confirmationNumber}, status: ${status}`
|
|
)
|
|
searchObject.set("errorCode", BookingErrorCodeEnum.TransactionFailed)
|
|
errorMessage = `Failed to get booking status for ${confirmationNumber}, status: ${status}`
|
|
}
|
|
|
|
return (
|
|
<BookingFlowConfig config={config}>
|
|
<HandleErrorCallback
|
|
returnUrl={returnUrl.toString()}
|
|
searchObject={searchObject}
|
|
status={status}
|
|
errorMessage={errorMessage}
|
|
/>
|
|
</BookingFlowConfig>
|
|
)
|
|
}
|