diff --git a/packages/app-store/alby/components/AlbyPaymentComponent.tsx b/packages/app-store/alby/components/AlbyPaymentComponent.tsx
index bd8a414554..0d99643f3a 100644
--- a/packages/app-store/alby/components/AlbyPaymentComponent.tsx
+++ b/packages/app-store/alby/components/AlbyPaymentComponent.tsx
@@ -1,10 +1,16 @@
import Link from "next/link";
-import { useState } from "react";
+import { useSearchParams } from "next/navigation";
+import { useEffect, useState } from "react";
import QRCode from "react-qr-code";
import z from "zod";
+import type { PaymentPageProps } from "@calcom/features/ee/payments/pages/payment";
+import { useBookingSuccessRedirect } from "@calcom/lib/bookingSuccessRedirect";
import { useCopy } from "@calcom/lib/hooks/useCopy";
+import { useLocale } from "@calcom/lib/hooks/useLocale";
+import { trpc } from "@calcom/trpc/react";
import { Button } from "@calcom/ui";
+import { showToast } from "@calcom/ui";
import { ClipboardCheck, Clipboard } from "@calcom/ui/components/icon";
import { Spinner } from "@calcom/ui/components/icon/Spinner";
@@ -13,6 +19,7 @@ interface IAlbyPaymentComponentProps {
// Will be parsed on render
data: unknown;
};
+ paymentPageProps: PaymentPageProps;
}
// Create zod schema for data
@@ -21,8 +28,7 @@ const PaymentAlbyDataSchema = z.object({
.object({
paymentRequest: z.string(),
})
- .optional(),
- capture: z.object({}).optional(),
+ .required(),
});
export const AlbyPaymentComponent = (props: IAlbyPaymentComponentProps) => {
@@ -45,6 +51,7 @@ export const AlbyPaymentComponent = (props: IAlbyPaymentComponentProps) => {
return (
+
{isPaying &&
}
{!isPaying && (
<>
@@ -58,6 +65,9 @@ export const AlbyPaymentComponent = (props: IAlbyPaymentComponentProps) => {
);
};
+
+type PaymentCheckerProps = PaymentPageProps;
+
+function PaymentChecker(props: PaymentCheckerProps) {
+ // This effect checks if the booking status has changed to "ACCEPTED"
+ // then reload the page to show the new payment status
+ // FIXME: subscribe to the exact payment instead of polling bookings
+ // FIXME: booking success is copied from packages/features/ee/payments/components/Payment.tsx
+ const searchParams = useSearchParams();
+ const bookingSuccessRedirect = useBookingSuccessRedirect();
+ const utils = trpc.useContext();
+ const { t } = useLocale();
+ useEffect(() => {
+ const interval = setInterval(() => {
+ (async () => {
+ if (props.booking.status === "ACCEPTED") {
+ return;
+ }
+ const bookingsResult = await utils.viewer.bookings.get.fetch({
+ filters: {
+ status: "upcoming",
+ eventTypeIds: [props.eventType.id],
+ },
+ });
+ // TODO: is there a better way than reloading the whole page?
+ // currently props.booking comes from SSR
+ if (
+ bookingsResult.bookings.some(
+ (booking) => booking.id === props.booking.id && booking.status === "ACCEPTED"
+ )
+ ) {
+ showToast("Payment successful", "success");
+
+ const params: {
+ [k: string]: any;
+ } = {
+ uid: props.booking.uid,
+ email: searchParams.get("email"),
+ location: t("web_conferencing_details_to_follow"),
+ };
+
+ bookingSuccessRedirect({
+ successRedirectUrl: props.eventType.successRedirectUrl,
+ query: params,
+ booking: props.booking,
+ });
+ }
+ })();
+ }, 1000);
+ return () => clearInterval(interval);
+ }, [
+ bookingSuccessRedirect,
+ props.booking,
+ props.booking.id,
+ props.booking.status,
+ props.eventType.id,
+ props.eventType.successRedirectUrl,
+ props.payment.success,
+ searchParams,
+ t,
+ utils.viewer.bookings,
+ ]);
+ return null;
+}
diff --git a/packages/features/ee/payments/components/PaymentPage.tsx b/packages/features/ee/payments/components/PaymentPage.tsx
index f329e1900a..478b2dd9a0 100644
--- a/packages/features/ee/payments/components/PaymentPage.tsx
+++ b/packages/features/ee/payments/components/PaymentPage.tsx
@@ -152,7 +152,7 @@ const PaymentPage: FC = (props) => {
)}
{props.payment.appId === "alby" && !props.payment.success && (
-
+
)}
{props.payment.refunded && (
{t("refunded")}