mirror of
https://github.com/xtr-dev/payload-billing.git
synced 2025-12-10 02:43:24 +00:00
feat: add automatic payment/invoice status sync and invoice view page
Core Plugin Enhancements: - Add afterChange hook to payments collection to auto-update linked invoice status to 'paid' when payment succeeds - Add afterChange hook to invoices collection for bidirectional payment-invoice relationship management - Add invoice status sync when manually marked as paid - Update plugin config types to support collection extension options Demo Application Features: - Add professional invoice view page with print-friendly layout (/invoice/[id]) - Add custom message field to payment creation form - Add invoice API endpoint to fetch complete invoice data with customer info - Add payment API endpoint to retrieve payment with invoice relationship - Update payment success page with "View Invoice" button - Implement beforeChange hook to copy custom message from payment metadata to invoice - Remove customer collection dependency - use direct customerInfo fields instead Documentation: - Update README with automatic status synchronization section - Add collection extension examples to demo README - Document new features: bidirectional relationships, status sync, invoice view Technical Improvements: - Fix total calculation in invoice API (use 'amount' field instead of 'total') - Add proper TypeScript types with CollectionSlug casting - Implement Next.js 15 async params pattern in API routes - Add customer name/email/company fields to payment creation form 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -2,13 +2,31 @@
|
||||
|
||||
import Link from 'next/link'
|
||||
import { useSearchParams } from 'next/navigation'
|
||||
import { Suspense } from 'react'
|
||||
import { Suspense, useEffect, useState } from 'react'
|
||||
|
||||
function PaymentSuccessContent() {
|
||||
const searchParams = useSearchParams()
|
||||
const paymentId = searchParams.get('paymentId')
|
||||
const amount = searchParams.get('amount')
|
||||
const currency = searchParams.get('currency')
|
||||
const [invoiceId, setInvoiceId] = useState<string | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
// Fetch the payment to get the invoice ID
|
||||
if (paymentId) {
|
||||
fetch(`/api/demo/payment/${paymentId}`)
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
if (data.success && data.payment?.invoice) {
|
||||
const invId = typeof data.payment.invoice === 'object' ? data.payment.invoice.id : data.payment.invoice
|
||||
setInvoiceId(invId)
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('Failed to fetch payment invoice:', err)
|
||||
})
|
||||
}
|
||||
}, [paymentId])
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gradient-to-br from-green-600 to-emerald-700 flex items-center justify-center p-4">
|
||||
@@ -76,6 +94,35 @@ function PaymentSuccessContent() {
|
||||
<h3 className="font-semibold text-slate-800 text-lg">What's Next?</h3>
|
||||
|
||||
<div className="grid gap-3">
|
||||
{invoiceId && (
|
||||
<Link
|
||||
href={`/invoice/${invoiceId}`}
|
||||
className="flex items-center justify-between p-4 border-2 border-green-500 bg-green-50 rounded-lg hover:bg-green-100 transition-all group cursor-pointer"
|
||||
>
|
||||
<div>
|
||||
<div className="font-semibold text-green-800 group-hover:text-green-900">
|
||||
📄 View Invoice
|
||||
</div>
|
||||
<div className="text-sm text-green-700">
|
||||
See your invoice with custom message
|
||||
</div>
|
||||
</div>
|
||||
<svg
|
||||
className="w-5 h-5 text-green-600 group-hover:text-green-800"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M9 5l7 7-7 7"
|
||||
/>
|
||||
</svg>
|
||||
</Link>
|
||||
)}
|
||||
|
||||
<Link
|
||||
href="/"
|
||||
className="flex items-center justify-between p-4 border-2 border-slate-200 rounded-lg hover:border-green-500 hover:bg-green-50 transition-all group cursor-pointer"
|
||||
|
||||
Reference in New Issue
Block a user