Merged in feat/SW-659-payment-send-query-params (pull request #727)
feat(SW-659): Receive query params from Planet callbacks * feat(SW-659): read confirmation number from url and update callback url if dev * fix(SW-659): moved callback url into env variable Approved-by: Simon.Emanuelsson
This commit is contained in:
@@ -22,9 +22,11 @@ import type { LangParams, PageArgs } from "@/types/params"
|
|||||||
|
|
||||||
export default async function BookingConfirmationPage({
|
export default async function BookingConfirmationPage({
|
||||||
params,
|
params,
|
||||||
}: PageArgs<LangParams>) {
|
searchParams,
|
||||||
|
}: PageArgs<LangParams, { confirmationNumber: string }>) {
|
||||||
|
const confirmationNumber = searchParams.confirmationNumber
|
||||||
const booking = await serverClient().booking.confirmation({
|
const booking = await serverClient().booking.confirmation({
|
||||||
confirmationNumber: "991697377",
|
confirmationNumber,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!booking) {
|
if (!booking) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { NextRequest, NextResponse } from "next/server"
|
import { NextRequest, NextResponse } from "next/server"
|
||||||
import { env } from "process"
|
|
||||||
|
|
||||||
|
import { BOOKING_CONFIRMATION_NUMBER } from "@/constants/booking"
|
||||||
import { Lang } from "@/constants/languages"
|
import { Lang } from "@/constants/languages"
|
||||||
import {
|
import {
|
||||||
bookingConfirmation,
|
bookingConfirmation,
|
||||||
@@ -17,14 +17,24 @@ export async function GET(
|
|||||||
console.log(`[payment-callback] callback started`)
|
console.log(`[payment-callback] callback started`)
|
||||||
const lang = params.lang as Lang
|
const lang = params.lang as Lang
|
||||||
const status = params.status
|
const status = params.status
|
||||||
const returnUrl = new URL(`${publicURL}/${payment[lang]}`)
|
|
||||||
|
|
||||||
if (status === "success") {
|
const queryParams = request.nextUrl.searchParams
|
||||||
|
const confirmationNumber = queryParams.get(BOOKING_CONFIRMATION_NUMBER)
|
||||||
|
|
||||||
|
if (status === "success" && confirmationNumber) {
|
||||||
const confirmationUrl = new URL(`${publicURL}/${bookingConfirmation[lang]}`)
|
const confirmationUrl = new URL(`${publicURL}/${bookingConfirmation[lang]}`)
|
||||||
|
confirmationUrl.searchParams.set(
|
||||||
|
BOOKING_CONFIRMATION_NUMBER,
|
||||||
|
confirmationNumber
|
||||||
|
)
|
||||||
|
|
||||||
console.log(`[payment-callback] redirecting to: ${confirmationUrl}`)
|
console.log(`[payment-callback] redirecting to: ${confirmationUrl}`)
|
||||||
return NextResponse.redirect(confirmationUrl)
|
return NextResponse.redirect(confirmationUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const returnUrl = new URL(`${publicURL}/${payment[lang]}`)
|
||||||
|
returnUrl.search = queryParams.toString()
|
||||||
|
|
||||||
if (status === "cancel") {
|
if (status === "cancel") {
|
||||||
returnUrl.searchParams.set("cancel", "true")
|
returnUrl.searchParams.set("cancel", "true")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod"
|
import { zodResolver } from "@hookform/resolvers/zod"
|
||||||
import { useRouter } from "next/navigation"
|
import { useRouter, useSearchParams } from "next/navigation"
|
||||||
import { useEffect, useState } from "react"
|
import { useEffect, useMemo, useState } from "react"
|
||||||
import { Label as AriaLabel } from "react-aria-components"
|
import { Label as AriaLabel } from "react-aria-components"
|
||||||
import { FormProvider, useForm } from "react-hook-form"
|
import { FormProvider, useForm } from "react-hook-form"
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
BOOKING_CONFIRMATION_NUMBER,
|
|
||||||
BookingStatusEnum,
|
BookingStatusEnum,
|
||||||
PAYMENT_METHOD_TITLES,
|
PAYMENT_METHOD_TITLES,
|
||||||
PaymentMethodEnum,
|
PaymentMethodEnum,
|
||||||
@@ -17,7 +16,9 @@ import {
|
|||||||
bookingTermsAndConditions,
|
bookingTermsAndConditions,
|
||||||
privacyPolicy,
|
privacyPolicy,
|
||||||
} from "@/constants/currentWebHrefs"
|
} from "@/constants/currentWebHrefs"
|
||||||
|
import { env } from "@/env/client"
|
||||||
import { trpc } from "@/lib/trpc/client"
|
import { trpc } from "@/lib/trpc/client"
|
||||||
|
import { useEnterDetailsStore } from "@/stores/enter-details"
|
||||||
|
|
||||||
import LoadingSpinner from "@/components/LoadingSpinner"
|
import LoadingSpinner from "@/components/LoadingSpinner"
|
||||||
import Button from "@/components/TempDesignSystem/Button"
|
import Button from "@/components/TempDesignSystem/Button"
|
||||||
@@ -51,6 +52,9 @@ export default function Payment({
|
|||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const lang = useLang()
|
const lang = useLang()
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
|
const queryParams = useSearchParams()
|
||||||
|
const { firstName, lastName, email, phoneNumber, countryCode } =
|
||||||
|
useEnterDetailsStore((state) => state.data)
|
||||||
const [confirmationNumber, setConfirmationNumber] = useState<string>("")
|
const [confirmationNumber, setConfirmationNumber] = useState<string>("")
|
||||||
|
|
||||||
const methods = useForm<PaymentFormData>({
|
const methods = useForm<PaymentFormData>({
|
||||||
@@ -90,14 +94,15 @@ export default function Payment({
|
|||||||
)
|
)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (confirmationNumber && bookingStatus?.data?.paymentUrl) {
|
if (bookingStatus?.data?.paymentUrl) {
|
||||||
// Planet doesn't support query params so we have to store values in session storage
|
|
||||||
sessionStorage.setItem(BOOKING_CONFIRMATION_NUMBER, confirmationNumber)
|
|
||||||
router.push(bookingStatus.data.paymentUrl)
|
router.push(bookingStatus.data.paymentUrl)
|
||||||
}
|
}
|
||||||
}, [confirmationNumber, bookingStatus, router])
|
}, [bookingStatus, router])
|
||||||
|
|
||||||
function handleSubmit(data: PaymentFormData) {
|
function handleSubmit(data: PaymentFormData) {
|
||||||
|
const allQueryParams =
|
||||||
|
queryParams.size > 0 ? `?${queryParams.toString()}` : ""
|
||||||
|
|
||||||
// set payment method to card if saved card is submitted
|
// set payment method to card if saved card is submitted
|
||||||
const paymentMethod = isPaymentMethodEnum(data.paymentMethod)
|
const paymentMethod = isPaymentMethodEnum(data.paymentMethod)
|
||||||
? data.paymentMethod
|
? data.paymentMethod
|
||||||
@@ -118,13 +123,13 @@ export default function Payment({
|
|||||||
rateCode: "SAVEEU",
|
rateCode: "SAVEEU",
|
||||||
roomTypeCode: "QC",
|
roomTypeCode: "QC",
|
||||||
guest: {
|
guest: {
|
||||||
title: "Mr",
|
title: "Mr", // TODO: do we need title?
|
||||||
firstName: "Test",
|
firstName,
|
||||||
lastName: "User",
|
lastName,
|
||||||
email: "test.user@scandichotels.com",
|
email,
|
||||||
phoneCountryCodePrefix: "string",
|
phoneCountryCodePrefix: phoneNumber.slice(0, 3),
|
||||||
phoneNumber: "string",
|
phoneNumber: phoneNumber.slice(3),
|
||||||
countryCode: "string",
|
countryCode,
|
||||||
},
|
},
|
||||||
packages: {
|
packages: {
|
||||||
breakfast: true,
|
breakfast: true,
|
||||||
@@ -150,9 +155,9 @@ export default function Payment({
|
|||||||
phoneCountryCode: "",
|
phoneCountryCode: "",
|
||||||
phoneSubscriber: "",
|
phoneSubscriber: "",
|
||||||
},
|
},
|
||||||
success: `api/web/payment-callback/${lang}/success`,
|
success: `${env.NEXT_PUBLIC_PAYMENT_CALLBACK_URL}/${lang}/success`,
|
||||||
error: `api/web/payment-callback/${lang}/error`,
|
error: `${env.NEXT_PUBLIC_PAYMENT_CALLBACK_URL}/${lang}/error${allQueryParams}`,
|
||||||
cancel: `api/web/payment-callback/${lang}/cancel`,
|
cancel: `${env.NEXT_PUBLIC_PAYMENT_CALLBACK_URL}/${lang}/cancel${allQueryParams}`,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export enum BedTypeEnum {
|
|||||||
Unknown = "Unknown",
|
Unknown = "Unknown",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BOOKING_CONFIRMATION_NUMBER = "bookingConfirmationNumber"
|
export const BOOKING_CONFIRMATION_NUMBER = "confirmationNumber"
|
||||||
|
|
||||||
export enum PaymentMethodEnum {
|
export enum PaymentMethodEnum {
|
||||||
card = "card",
|
card = "card",
|
||||||
|
|||||||
4
env/client.ts
vendored
4
env/client.ts
vendored
@@ -5,10 +5,14 @@ export const env = createEnv({
|
|||||||
client: {
|
client: {
|
||||||
NEXT_PUBLIC_NODE_ENV: z.enum(["development", "test", "production"]),
|
NEXT_PUBLIC_NODE_ENV: z.enum(["development", "test", "production"]),
|
||||||
NEXT_PUBLIC_PORT: z.string().default("3000"),
|
NEXT_PUBLIC_PORT: z.string().default("3000"),
|
||||||
|
NEXT_PUBLIC_PAYMENT_CALLBACK_URL: z
|
||||||
|
.string()
|
||||||
|
.default("/api/web/payment-callback"),
|
||||||
},
|
},
|
||||||
emptyStringAsUndefined: true,
|
emptyStringAsUndefined: true,
|
||||||
runtimeEnv: {
|
runtimeEnv: {
|
||||||
NEXT_PUBLIC_NODE_ENV: process.env.NODE_ENV,
|
NEXT_PUBLIC_NODE_ENV: process.env.NODE_ENV,
|
||||||
NEXT_PUBLIC_PORT: process.env.NEXT_PUBLIC_PORT,
|
NEXT_PUBLIC_PORT: process.env.NEXT_PUBLIC_PORT,
|
||||||
|
NEXT_PUBLIC_PAYMENT_CALLBACK_URL: `${process.env.NODE_ENV === "development" ? `http://localhost:${process.env.NEXT_PUBLIC_PORT}` : ""}/api/web/payment-callback`,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user