'use client'; import { AlertCircle, CreditCard, Loader2, Smartphone, Wallet } from 'lucide-react'; import { useCallback, useState } from 'react'; import { ComponentErrorBoundary } from '@/components/error-boundary'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { formatVND } from '@/lib/currency'; import { paymentApi, type CreatePaymentPayload, } from '@/lib/payment-api'; import { subscriptionApi, type PlanDto } from '@/lib/subscription-api'; import { cn } from '@/lib/utils'; // --------------------------------------------------------------------------- // Types // --------------------------------------------------------------------------- type PaymentProvider = CreatePaymentPayload['provider']; interface CheckoutModalProps { open: boolean; onOpenChange: (open: boolean) => void; plan: PlanDto | null; billingCycle: 'monthly' | 'yearly'; /** If true, this is an upgrade from an existing subscription */ isUpgrade?: boolean; /** Current plan tier — used for display context during upgrade */ currentTier?: string; } // --------------------------------------------------------------------------- // Constants // --------------------------------------------------------------------------- const PAYMENT_PROVIDERS: { id: PaymentProvider; label: string; icon: React.ReactNode; description: string; }[] = [ { id: 'VNPAY', label: 'VNPay', icon: , description: 'Thẻ ATM, Visa, MasterCard, QR Code', }, { id: 'MOMO', label: 'MoMo', icon: , description: 'Ví MoMo', }, { id: 'ZALOPAY', label: 'ZaloPay', icon: , description: 'Ví ZaloPay, thẻ ngân hàng', }, ]; const PLAN_TIER_LABELS: Record = { FREE: 'Miễn phí', AGENT_PRO: 'Môi giới Pro', INVESTOR: 'Nhà đầu tư', ENTERPRISE: 'Doanh nghiệp', }; // --------------------------------------------------------------------------- // Component // --------------------------------------------------------------------------- export function CheckoutModal(props: CheckoutModalProps) { return ( ); } function CheckoutModalInner({ open, onOpenChange, plan, billingCycle, isUpgrade = false, currentTier, }: CheckoutModalProps) { const [provider, setProvider] = useState('VNPAY'); const [processing, setProcessing] = useState(false); const [error, setError] = useState(null); const price = plan ? billingCycle === 'monthly' ? plan.priceMonthlyVND : plan.priceYearlyVND : '0'; const handleCheckout = useCallback(async () => { if (!plan || Number(price) === 0) return; setProcessing(true); setError(null); try { // Step 1: Create or upgrade subscription if (isUpgrade) { await subscriptionApi.upgradeSubscription(plan.tier); } else { await subscriptionApi.createSubscription(plan.tier, billingCycle); } // Step 2: Create payment and redirect to gateway const localeMatch = window.location.pathname.match(/^\/(vi|en)(\/|$)/); const localePrefix = localeMatch?.[1] ? `/${localeMatch[1]}` : ''; const returnUrl = `${window.location.origin}${localePrefix}/payment/return`; const idempotencyKey = `sub-${plan.tier}-${billingCycle}-${Date.now()}`; const result = await paymentApi.createPayment({ provider, type: 'SUBSCRIPTION', amountVND: Number(price), description: `${isUpgrade ? 'Nâng cấp' : 'Đăng ký'} gói ${PLAN_TIER_LABELS[plan.tier] ?? plan.name} — ${billingCycle === 'monthly' ? 'hàng tháng' : 'hàng năm'}`, returnUrl, idempotencyKey, }); // Redirect to payment gateway if (result.paymentUrl) { window.location.href = result.paymentUrl; } } catch (e) { const message = e instanceof Error ? e.message : 'Thanh toán thất bại. Vui lòng thử lại.'; setError(message); setProcessing(false); } }, [plan, price, billingCycle, isUpgrade, provider]); if (!plan) return null; return ( !processing && onOpenChange(o)}> {isUpgrade ? 'Nâng cấp gói dịch vụ' : 'Đăng ký gói dịch vụ'} {isUpgrade && currentTier ? `Nâng cấp từ ${PLAN_TIER_LABELS[currentTier] ?? currentTier} lên ${PLAN_TIER_LABELS[plan.tier] ?? plan.name}` : `Chọn phương thức thanh toán để đăng ký gói ${PLAN_TIER_LABELS[plan.tier] ?? plan.name}`} {/* Order summary */}
Gói dịch vụ {PLAN_TIER_LABELS[plan.tier] ?? plan.name}
Chu kỳ thanh toán
{billingCycle === 'monthly' ? 'Hàng tháng' : 'Hàng năm'} {billingCycle === 'yearly' && ( -17% )}
Tổng cộng {formatVND(price)} /{billingCycle === 'monthly' ? 'tháng' : 'năm'}
{/* Payment method selection */}

Phương thức thanh toán

{PAYMENT_PROVIDERS.map((p) => ( ))}
{/* Error message */} {error && (

{error}

)}
); }