"use client" import { useEffect, useState } from "react" import { useRouter, useSearchParams } from "next/navigation" import { useActiveUser } from "@/hooks/useActiveUser" import { Card, CardContent, CardDescription, CardHeader, CardTitle, CardFooter } from "@/components/ui/card" import { Button } from "@/components/ui/button" import { Loader2, ShieldCheck, ArrowLeft, CheckCircle2 } from "lucide-react" import Link from "next/link" declare global { interface Window { Razorpay: any } } import { Suspense } from "react" export default function CheckoutPage() { return ( }> ) } function CheckoutContent() { const router = useRouter() const searchParams = useSearchParams() const tier = searchParams.get("tier") || "Pro" const { userId, loading: userLoading, user } = useActiveUser() const [address, setAddress] = useState("") const [phone, setPhone] = useState("") const [processing, setProcessing] = useState(false) const [success, setSuccess] = useState(false) const [error, setError] = useState("") const paymentGateway = process.env.NEXT_PUBLIC_PAYMENT_GATEWAY || "razorpay" // Ensure Gateway scripts are loaded useEffect(() => { if (paymentGateway === "razorpay") { const script = document.createElement("script") script.src = "https://checkout.razorpay.com/v1/checkout.js" script.async = true document.body.appendChild(script) return () => { document.body.removeChild(script) } } else if (paymentGateway === "stripe") { // Load Stripe.js if using stripe // const script = document.createElement("script") // script.src = "https://js.stripe.com/v3/" // document.body.appendChild(script) } // PhonePe usually relies on S2S redirection, so no client SDK needed }, [paymentGateway]) // If user is definitely not logged in after loading, redirect to login useEffect(() => { if (!userLoading && !userId) { router.push(`/login?redirect=/checkout?tier=${tier}`) } }, [userId, userLoading, router, tier]) const amount = tier === "Al_Coach" ? 11999 : 3499 const handlePayment = async () => { if (!address.trim() || !phone.trim() || phone.length < 10) { setError("Please provide a valid address and 10-digit phone number.") return } setError("") setProcessing(true) try { // 1. Create order on backend (Passing gateway to abstract logic) const orderRes = await fetch(`/api/billing/create-order?user_id=${userId}&plan_tier=${tier}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ gateway: paymentGateway }) }) if (!orderRes.ok) { throw new Error("Failed to create order. Please try again.") } const orderData = await orderRes.json() if (paymentGateway === "razorpay") { // 2a. Open Razorpay Checkout const options = { key: process.env.NEXT_PUBLIC_RAZORPAY_KEY_ID || "rzp_test_local_sandbox", amount: orderData.amount, currency: "INR", name: "PragatiVeer", description: `Upgrade to ${tier} Tier`, image: "/icon.svg", // Logo order_id: orderData.id, handler: async function (response: any) { try { const verifyRes = await fetch("/api/billing/verify-payment", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ gateway: "razorpay", razorpay_order_id: response.razorpay_order_id, razorpay_payment_id: response.razorpay_payment_id, razorpay_signature: response.razorpay_signature, user_id: userId, tier: tier }) }) const verifyData = await verifyRes.json() if (verifyData.success) { setSuccess(true) setTimeout(() => { window.location.href = "/dashboard" }, 2000) } else { setError("Payment verification failed. If money was deducted, please contact support.") setProcessing(false) } } catch (err) { setError("Failed to verify payment with server.") setProcessing(false) } }, prefill: { name: user?.name || "", email: user?.email || "", contact: phone }, notes: { address: address }, theme: { color: "var(--cyan-ai)" } } const rzp = new window.Razorpay(options) rzp.on('payment.failed', function (response: any) { setError(`Payment Failed: ${response.error.description}`) setProcessing(false) }) rzp.open() } else if (paymentGateway === "phonepe") { // 2b. PhonePe Redirection logic console.log("Redirecting to PhonePe Gateway...") // window.location.href = orderData.redirect_url alert("PhonePe Gateway Logic would trigger here.") setProcessing(false) } else if (paymentGateway === "stripe") { // 2c. Stripe Checkout logic console.log("Redirecting to Stripe Checkout...") alert("Stripe SDK logic would trigger here.") setProcessing(false) } } catch (err: any) { setError(err.message) setProcessing(false) } } if (userLoading || !userId) { return (
) } if (success) { return (

Payment Successful!

Your account has been upgraded to the {tier} tier.

Redirecting to dashboard...
) } return (
Back to Plans
{/* Billing Details */}

Checkout

Billing Details Please enter your details to complete the purchase.
setPhone(e.target.value.replace(/[^0-9]/g, ''))} maxLength={10} placeholder="9876543210" className="w-full bg-background border border-border rounded-xl px-4 py-3 text-sm focus:outline-none focus:ring-2 focus:ring-[var(--cyan-ai)] focus:border-transparent transition-all" />