Merge branch 'master' into feat/tracking-payment

This commit is contained in:
Linus Flood
2025-01-10 11:37:22 +01:00
4 changed files with 51 additions and 29 deletions

View File

@@ -47,10 +47,14 @@ export default async function PaymentCallbackPage({
const bookingStatus = await serverClient().booking.status({ const bookingStatus = await serverClient().booking.status({
confirmationNumber, confirmationNumber,
}) })
// TODO: how to handle errors for multiple rooms?
const error = bookingStatus.errors.find((e) => e.errorCode)
searchObject.set( searchObject.set(
"errorCode", "errorCode",
bookingStatus?.metadata?.errorCode error
? bookingStatus.metadata.errorCode.toString() ? error.errorCode.toString()
: PaymentErrorCodeEnum.Failed.toString() : PaymentErrorCodeEnum.Failed.toString()
) )
trackPaymentEvent({ trackPaymentEvent({

View File

@@ -76,7 +76,7 @@ export default function PaymentClient({
(state) => state.actions.setIsSubmittingDisabled (state) => state.actions.setIsSubmittingDisabled
) )
const [confirmationNumber, setConfirmationNumber] = useState<string>("") const [bookingNumber, setBookingNumber] = useState<string>("")
const [isPollingForBookingStatus, setIsPollingForBookingStatus] = const [isPollingForBookingStatus, setIsPollingForBookingStatus] =
useState(false) useState(false)
@@ -106,13 +106,17 @@ export default function PaymentClient({
const initiateBooking = trpc.booking.create.useMutation({ const initiateBooking = trpc.booking.create.useMutation({
onSuccess: (result) => { onSuccess: (result) => {
if (result?.confirmationNumber) { if (result) {
setConfirmationNumber(result.confirmationNumber) setBookingNumber(result.id)
if (result.metadata?.priceChangedMetadata) { const priceChange = result.rooms.find(
(r) => r.priceChangedMetadata
)?.priceChangedMetadata
if (priceChange) {
setPriceChangeData({ setPriceChangeData({
oldPrice: roomPrice.publicPrice, oldPrice: roomPrice.publicPrice,
newPrice: result.metadata.priceChangedMetadata.totalPrice, newPrice: priceChange.totalPrice,
}) })
} else { } else {
setIsPollingForBookingStatus(true) setIsPollingForBookingStatus(true)
@@ -129,7 +133,7 @@ export default function PaymentClient({
const priceChange = trpc.booking.priceChange.useMutation({ const priceChange = trpc.booking.priceChange.useMutation({
onSuccess: (result) => { onSuccess: (result) => {
if (result?.confirmationNumber) { if (result?.id) {
setIsPollingForBookingStatus(true) setIsPollingForBookingStatus(true)
} else { } else {
handlePaymentError("No confirmation number") handlePaymentError("No confirmation number")
@@ -145,7 +149,7 @@ export default function PaymentClient({
}) })
const bookingStatus = useHandleBookingStatus({ const bookingStatus = useHandleBookingStatus({
confirmationNumber, confirmationNumber: bookingNumber,
expectedStatus: BookingStatusEnum.BookingCompleted, expectedStatus: BookingStatusEnum.BookingCompleted,
maxRetries, maxRetries,
retryInterval, retryInterval,
@@ -452,7 +456,9 @@ export default function PaymentClient({
: "" : ""
router.push(`${selectRate(lang)}${allSearchParams}`) router.push(`${selectRate(lang)}${allSearchParams}`)
}} }}
onAccept={() => priceChange.mutate({ confirmationNumber })} onAccept={() =>
priceChange.mutate({ confirmationNumber: bookingNumber })
}
/> />
) : null} ) : null}
</> </>

View File

@@ -11,14 +11,13 @@ export const createBookingSchema = z
.object({ .object({
data: z.object({ data: z.object({
attributes: z.object({ attributes: z.object({
confirmationNumber: z.string(),
cancellationNumber: z.string().nullable(),
reservationStatus: z.string(), reservationStatus: z.string(),
paymentUrl: z.string().nullable(), paymentUrl: z.string().nullable(),
metadata: z rooms: z
.object({ .array(
errorCode: z.number().nullable().optional(), z.object({
errorMessage: z.string().nullable().optional(), confirmationNumber: z.string(),
cancellationNumber: z.string().nullable(),
priceChangedMetadata: z priceChangedMetadata: z
.object({ .object({
roomPrice: z.number(), roomPrice: z.number(),
@@ -27,7 +26,21 @@ export const createBookingSchema = z
.nullable() .nullable()
.optional(), .optional(),
}) })
.nullable(), )
.default([]),
errors: z
.array(
z.object({
confirmationNumber: z.string(),
errorCode: z.string(),
description: z.string(),
meta: z
.record(z.string(), z.union([z.string(), z.number()]))
.nullable()
.optional(),
})
)
.default([]),
}), }),
type: z.string(), type: z.string(),
id: z.string(), id: z.string(),
@@ -45,11 +58,10 @@ export const createBookingSchema = z
id: d.data.id, id: d.data.id,
links: d.data.links, links: d.data.links,
type: d.data.type, type: d.data.type,
confirmationNumber: d.data.attributes.confirmationNumber,
cancellationNumber: d.data.attributes.cancellationNumber,
reservationStatus: d.data.attributes.reservationStatus, reservationStatus: d.data.attributes.reservationStatus,
paymentUrl: d.data.attributes.paymentUrl, paymentUrl: d.data.attributes.paymentUrl,
metadata: d.data.attributes.metadata, rooms: d.data.attributes.rooms,
errors: d.data.attributes.errors,
})) }))
// QUERY // QUERY

View File

@@ -199,7 +199,7 @@ const CouponReward = z.object({
title: z.string().optional(), title: z.string().optional(),
id: z.string().optional(), id: z.string().optional(),
rewardId: z.string().optional(), rewardId: z.string().optional(),
rewardType: z.enum(["Surprise", "Campaign"]), rewardType: z.enum(["Surprise", "Campaign", "Member-voucher"]),
redeemLocation: z.string().optional(), redeemLocation: z.string().optional(),
operaRewardId: z.string().default(""), operaRewardId: z.string().default(""),
status: z.string().optional(), status: z.string().optional(),