-
- }
- >
-
-
- );
-}
+"use client";
+
+import Link from "next/link";
+import { useSearchParams } from "next/navigation";
+import { Suspense, useEffect, useState } from "react";
+import Navbar from "@/components/Navbar";
+import Footer from "@/components/Footer";
+
+const LOOKUP_URL = process.env.NEXT_PUBLIC_LOOKUP_URL || "https://licenses.dashcaddy.net/api/checkout/session";
+
+interface LookupResult {
+ status: "delivered" | "pending_email" | "processing" | "not_found" | "expired";
+ code?: string;
+ codeId?: string;
+ productId?: string;
+ durationDays?: number;
+ deliveredVia?: string;
+}
+
+function SuccessContent() {
+ const searchParams = useSearchParams();
+ const sessionId = searchParams.get("session_id");
+
+ const [result, setResult] = useState(null);
+ const [loading, setLoading] = useState(true);
+ const [copied, setCopied] = useState(false);
+ const [sessionCopied, setSessionCopied] = useState(false);
+ const [error, setError] = useState(null);
+
+ useEffect(() => {
+ setResult(null);
+ setError(null);
+ setLoading(true);
+ setCopied(false);
+ setSessionCopied(false);
+ if (!sessionId) {
+ setLoading(false);
+ setError("This page is missing the Stripe checkout session ID. Open the link from your Stripe confirmation or contact support.");
+ return;
+ }
+ if (!/^cs_[A-Za-z0-9_]{3,252}$/.test(sessionId)) {
+ setLoading(false);
+ setError("The Stripe checkout session ID is invalid. Open the confirmation link again or contact support.");
+ return;
+ }
+ let cancelled = false;
+ let activeRequest: AbortController | null = null;
+ let timer: ReturnType | null = null;
+ let attempts = 0;
+ const fetchOnce = async () => {
+ attempts += 1;
+ activeRequest = new AbortController();
+ const requestTimeout = setTimeout(() => activeRequest?.abort(), 10000);
+ try {
+ const r = await fetch(`${LOOKUP_URL}/${encodeURIComponent(sessionId)}`, {
+ cache: "no-store",
+ signal: activeRequest.signal,
+ });
+ if (cancelled) return;
+ if (r.ok) {
+ let j: LookupResult;
+ try {
+ j = (await r.json()) as LookupResult;
+ } catch {
+ setError("The billing server returned malformed data. Check your Stripe or email receipt, then contact support.");
+ setLoading(false);
+ return;
+ }
+ const allowedStatuses = new Set(["delivered", "pending_email", "processing", "not_found", "expired"]);
+ if (!j || typeof j !== "object") {
+ setError("The billing server returned an invalid response. Check your Stripe or email receipt, then contact support.");
+ setLoading(false);
+ return;
+ }
+ const optionalFieldsValid =
+ (j.code === undefined || typeof j.code === "string") &&
+ (j.codeId === undefined || typeof j.codeId === "string") &&
+ (j.productId === undefined || typeof j.productId === "string") &&
+ (j.durationDays === undefined || (Number.isInteger(j.durationDays) && j.durationDays > 0)) &&
+ (j.deliveredVia === undefined || typeof j.deliveredVia === "string");
+ if (typeof j.status !== "string" || !allowedStatuses.has(j.status) || !optionalFieldsValid) {
+ setError("The billing server returned an invalid response. Check your Stripe or email receipt, then contact support.");
+ setLoading(false);
+ return;
+ }
+ if ((j.status === "delivered" || j.status === "pending_email") &&
+ (typeof j.code !== "string" || j.code.trim().length === 0)) {
+ setError("Payment was confirmed, but the license key was not returned. Please contact support with the session ID below.");
+ setLoading(false);
+ return;
+ }
+ if (j.status === "processing" || j.status === "not_found") {
+ if (attempts >= 40) {
+ if (j.status === "not_found") setResult({ status: "not_found" });
+ else setError("Stripe confirmation is taking longer than expected. Check your Stripe or email receipt, then contact support if needed.");
+ setLoading(false);
+ return;
+ }
+ timer = setTimeout(fetchOnce, 3000);
+ return;
+ }
+ setResult(j);
+ if (j.status === "expired") {
+ setError("This checkout session has expired. If you were charged, contact support with the session ID below.");
+ }
+ setLoading(false);
+ } else if (r.status === 404) {
+ if (attempts >= 40) {
+ setResult({ status: "not_found" });
+ setLoading(false);
+ } else {
+ timer = setTimeout(fetchOnce, 3000);
+ }
+ } else if (r.status === 408 || r.status === 429 || r.status >= 500) {
+ if (attempts >= 40) {
+ setError(`The billing server remained unavailable (HTTP ${r.status}). Check your Stripe or email receipt, then contact support.`);
+ setLoading(false);
+ } else {
+ timer = setTimeout(fetchOnce, 3000);
+ }
+ } else {
+ setError(`The billing server is temporarily unavailable (HTTP ${r.status}). Check your Stripe or email receipt, then try again.`);
+ setLoading(false);
+ }
+ } catch {
+ if (!cancelled) {
+ if (attempts >= 40) {
+ setError("The billing request repeatedly timed out or could not reach the server. Check your Stripe or email receipt, then contact support.");
+ setLoading(false);
+ } else {
+ timer = setTimeout(fetchOnce, 3000);
+ }
+ }
+ } finally {
+ clearTimeout(requestTimeout);
+ }
+ };
+ fetchOnce();
+ return () => {
+ cancelled = true;
+ activeRequest?.abort();
+ if (timer) clearTimeout(timer);
+ };
+ }, [sessionId]);
+
+ const copyCode = async () => {
+ if (!result?.code) return;
+ try {
+ await navigator.clipboard.writeText(result.code);
+ setCopied(true);
+ setTimeout(() => setCopied(false), 2000);
+ } catch {
+ /* noop */
+ }
+ };
+
+ const copySessionId = async () => {
+ if (!sessionId) return;
+ try {
+ await navigator.clipboard.writeText(sessionId);
+ setSessionCopied(true);
+ setTimeout(() => setSessionCopied(false), 2000);
+ } catch {
+ /* noop */
+ }
+ };
+
+ const productLabel =
+ result?.productId === "pro-30d"
+ ? "1 month"
+ : result?.productId === "pro-90d"
+ ? "3 months"
+ : result?.productId === "pro-180d"
+ ? "6 months"
+ : result?.productId === "pro-365d"
+ ? "12 months"
+ : null;
+ const confirmed = Boolean(result?.code) && (result?.status === "delivered" || result?.status === "pending_email");
+ const failed = Boolean(error) || result?.status === "not_found" || result?.status === "expired";
+
+ return (
+ <>
+
+
+
+ {/* Order status icon */}
+
+
+
+
+
+ {confirmed ? "Welcome to DashCaddy Premium!" : failed ? "We couldn't confirm your DashCaddy order" : "Confirming your DashCaddy order"}
+
+
+ {error
+ ? "Automatic confirmation has stopped. Try again below or contact support with the session ID."
+ : result?.status === "delivered" || result?.status === "pending_email"
+ ? "Your purchase is complete. Here's your license key:"
+ : "Your license key will appear here once Stripe confirms payment."}
+
+
+ {/* License key panel — only shown once the bridge returns the code */}
+ {!loading && result && (result.status === "delivered" || result.status === "pending_email") && result.code && (
+
+ Email delivery didn't complete, but the license code above is valid now.
+
+ )}
+
+ )}
+
+ {/* Loading state */}
+ {loading && (
+
+
+
+ Confirming payment and preparing your license…
+
+
+ )}
+
+ {!loading && error && (
+
+
We couldn't finish loading this order
+
{error}
+
+
+ )}
+
+ {/* Not-found state (no session_id passed or session unknown) */}
+ {!loading && result && result.status === "not_found" && (
+
+
+ We couldn't find that session
+
+
+ Stripe did not confirm this session within the confirmation window. If you were charged,
+ keep the session ID below and contact{" "}
+
+ support
+
+ .
+