import { useState, useEffect } from 'react'; import { useParams, useSearchParams } from 'react-router-dom'; import PageLoader from '../components/PageLoader'; const supabaseUrl = import.meta.env.VITE_SUPABASE_URL; const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY; const currencyFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', }); export default function PayInvoice() { const { id } = useParams(); const [searchParams] = useSearchParams(); const success = searchParams.get('success') === '1'; const cancelled = searchParams.get('cancelled') === '1'; const [invoice, setInvoice] = useState(null); const [company, setCompany] = useState(null); const [loading, setLoading] = useState(true); const [paying, setPaying] = useState(false); const [error, setError] = useState(''); const totalLabel = currencyFormatter.format(Number(invoice?.total || 0)); useEffect(() => { async function load() { try { const response = await fetch(`${supabaseUrl}/functions/v1/get-public-invoice`, { method: 'POST', headers: { 'Content-Type': 'application/json', apikey: supabaseAnonKey, }, body: JSON.stringify({ invoice_ref: id }), }); const body = await response.json(); if (!response.ok || !body?.invoice) { setLoading(false); return; } setInvoice(body.invoice); setCompany(body.invoice.companies || null); } catch (err) { console.error('PayInvoice load failed:', err); } finally { setLoading(false); } } load(); }, [id]); const handlePay = async () => { setPaying(true); setError(''); try { const response = await fetch(`${supabaseUrl}/functions/v1/create-checkout-session`, { method: 'POST', headers: { 'Content-Type': 'application/json', apikey: supabaseAnonKey, }, body: JSON.stringify({ invoice_ref: id }), }); const body = await response.json(); if (!response.ok || !body?.url) throw new Error(body?.error || 'Could not create payment session.'); window.location.href = body.url; } catch (err) { setError(err.message); setPaying(false); } }; return (
{loading ? : null}
{/* Logo */}
Fourge Branding
{!invoice ? (
Invoice not found
This payment link may be invalid or expired.
) : success || invoice.status === 'paid' ? (
Payment received
{invoice.invoice_number}
{totalLabel}
Charged in USD
Thank you for your payment. We'll be in touch!
) : (
Invoice
{invoice.invoice_number}
{invoice.bill_to || company?.name}
Invoice Date
{new Date(invoice.invoice_date).toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' })}
Due Date
{new Date(invoice.due_date).toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' })}
Total Due
{totalLabel}
{cancelled && (
Payment was cancelled. You can try again below.
)} {error && (
{error}
)}
Secured by Stripe · Charged in USD · hello@fourgebranding.com
)}
); }