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:
Tobias Johansson
2024-10-23 11:51:44 +00:00
parent d2817c5f8c
commit 025c5c8291
5 changed files with 44 additions and 23 deletions

View File

@@ -22,9 +22,11 @@ import type { LangParams, PageArgs } from "@/types/params"
export default async function BookingConfirmationPage({
params,
}: PageArgs<LangParams>) {
searchParams,
}: PageArgs<LangParams, { confirmationNumber: string }>) {
const confirmationNumber = searchParams.confirmationNumber
const booking = await serverClient().booking.confirmation({
confirmationNumber: "991697377",
confirmationNumber,
})
if (!booking) {

View File

@@ -1,6 +1,6 @@
import { NextRequest, NextResponse } from "next/server"
import { env } from "process"
import { BOOKING_CONFIRMATION_NUMBER } from "@/constants/booking"
import { Lang } from "@/constants/languages"
import {
bookingConfirmation,
@@ -17,14 +17,24 @@ export async function GET(
console.log(`[payment-callback] callback started`)
const lang = params.lang as Lang
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]}`)
confirmationUrl.searchParams.set(
BOOKING_CONFIRMATION_NUMBER,
confirmationNumber
)
console.log(`[payment-callback] redirecting to: ${confirmationUrl}`)
return NextResponse.redirect(confirmationUrl)
}
const returnUrl = new URL(`${publicURL}/${payment[lang]}`)
returnUrl.search = queryParams.toString()
if (status === "cancel") {
returnUrl.searchParams.set("cancel", "true")
}

View File

@@ -1,14 +1,13 @@
"use client"
import { zodResolver } from "@hookform/resolvers/zod"
import { useRouter } from "next/navigation"
import { useEffect, useState } from "react"
import { useRouter, useSearchParams } from "next/navigation"
import { useEffect, useMemo, useState } from "react"
import { Label as AriaLabel } from "react-aria-components"
import { FormProvider, useForm } from "react-hook-form"
import { useIntl } from "react-intl"
import {
BOOKING_CONFIRMATION_NUMBER,
BookingStatusEnum,
PAYMENT_METHOD_TITLES,
PaymentMethodEnum,
@@ -17,7 +16,9 @@ import {
bookingTermsAndConditions,
privacyPolicy,
} from "@/constants/currentWebHrefs"
import { env } from "@/env/client"
import { trpc } from "@/lib/trpc/client"
import { useEnterDetailsStore } from "@/stores/enter-details"
import LoadingSpinner from "@/components/LoadingSpinner"
import Button from "@/components/TempDesignSystem/Button"
@@ -51,6 +52,9 @@ export default function Payment({
const router = useRouter()
const lang = useLang()
const intl = useIntl()
const queryParams = useSearchParams()
const { firstName, lastName, email, phoneNumber, countryCode } =
useEnterDetailsStore((state) => state.data)
const [confirmationNumber, setConfirmationNumber] = useState<string>("")
const methods = useForm<PaymentFormData>({
@@ -90,14 +94,15 @@ export default function Payment({
)
useEffect(() => {
if (confirmationNumber && bookingStatus?.data?.paymentUrl) {
// Planet doesn't support query params so we have to store values in session storage
sessionStorage.setItem(BOOKING_CONFIRMATION_NUMBER, confirmationNumber)
if (bookingStatus?.data?.paymentUrl) {
router.push(bookingStatus.data.paymentUrl)
}
}, [confirmationNumber, bookingStatus, router])
}, [bookingStatus, router])
function handleSubmit(data: PaymentFormData) {
const allQueryParams =
queryParams.size > 0 ? `?${queryParams.toString()}` : ""
// set payment method to card if saved card is submitted
const paymentMethod = isPaymentMethodEnum(data.paymentMethod)
? data.paymentMethod
@@ -118,13 +123,13 @@ export default function Payment({
rateCode: "SAVEEU",
roomTypeCode: "QC",
guest: {
title: "Mr",
firstName: "Test",
lastName: "User",
email: "test.user@scandichotels.com",
phoneCountryCodePrefix: "string",
phoneNumber: "string",
countryCode: "string",
title: "Mr", // TODO: do we need title?
firstName,
lastName,
email,
phoneCountryCodePrefix: phoneNumber.slice(0, 3),
phoneNumber: phoneNumber.slice(3),
countryCode,
},
packages: {
breakfast: true,
@@ -150,9 +155,9 @@ export default function Payment({
phoneCountryCode: "",
phoneSubscriber: "",
},
success: `api/web/payment-callback/${lang}/success`,
error: `api/web/payment-callback/${lang}/error`,
cancel: `api/web/payment-callback/${lang}/cancel`,
success: `${env.NEXT_PUBLIC_PAYMENT_CALLBACK_URL}/${lang}/success`,
error: `${env.NEXT_PUBLIC_PAYMENT_CALLBACK_URL}/${lang}/error${allQueryParams}`,
cancel: `${env.NEXT_PUBLIC_PAYMENT_CALLBACK_URL}/${lang}/cancel${allQueryParams}`,
},
})
}

View File

@@ -11,7 +11,7 @@ export enum BedTypeEnum {
Unknown = "Unknown",
}
export const BOOKING_CONFIRMATION_NUMBER = "bookingConfirmationNumber"
export const BOOKING_CONFIRMATION_NUMBER = "confirmationNumber"
export enum PaymentMethodEnum {
card = "card",

4
env/client.ts vendored
View File

@@ -5,10 +5,14 @@ export const env = createEnv({
client: {
NEXT_PUBLIC_NODE_ENV: z.enum(["development", "test", "production"]),
NEXT_PUBLIC_PORT: z.string().default("3000"),
NEXT_PUBLIC_PAYMENT_CALLBACK_URL: z
.string()
.default("/api/web/payment-callback"),
},
emptyStringAsUndefined: true,
runtimeEnv: {
NEXT_PUBLIC_NODE_ENV: process.env.NODE_ENV,
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`,
},
})