Invoices
Invoices
The Invoices module handles the full billing lifecycle — from creating an invoice through to payment reconciliation. Invoices can be paid manually or via Stripe online payments. Overdue and recurring invoices are managed automatically by scheduled cron jobs.
Creating an Invoice
- Navigate to Invoices in the left sidebar.
- Click + New Invoice.
- Fill in the invoice form:
| Field | Required | Notes |
|---|---|---|
| Client | Yes | Select from existing client records |
| Invoice Number | Auto | Generated automatically; can be overridden |
| Issue Date | Yes | Defaults to today |
| Due Date | Yes | Payment deadline |
| Notes / Payment Terms | No | e.g. "Payment due within 30 days of issue" |
- Click Create Invoice to save the draft and open the line items editor.
Adding line items
| Field | Required | Notes |
|---|---|---|
| Description | Yes | Service or deliverable name |
| Quantity | Yes | Number of units |
| Unit Price | Yes | Price per unit in display currency |
The subtotal (subtotal_cents in the database) is calculated as the sum of all line item totals.
Internally, all monetary amounts are stored in cents (e.g. £1,500.00 is stored as 150000). The UI handles this conversion automatically — always enter amounts in your display currency.
Sending an Invoice
Once the invoice is ready:
- Open the invoice.
- Review all line items and the total.
- Click Send Invoice.
- Confirm the recipient email.
- Click Send.
What happens:
- The invoice status changes from
drafttosent. - The client receives an email via Resend with a link to view the invoice in their portal.
- The invoice shows a Pay Now button if Stripe is configured.
Marking an Invoice as Paid (Manual)
If a client pays by bank transfer, cheque, or another method outside Stripe:
- Open the invoice.
- Click Mark as Paid.
- Optionally enter a payment reference or note.
- Click Confirm.
The invoice status changes to paid and the payment date is recorded.
Stripe Integration
When Stripe is configured (see Settings), clients can pay invoices online.
How it works
- The client opens the invoice in their portal and clicks Pay Now.
- They are redirected to a Stripe Checkout page for secure card payment.
- On successful payment, Stripe sends a
payment_intent.succeededwebhook to the CRM. - The webhook handler automatically marks the invoice as
paidand records the payment timestamp.
Stripe webhook
The webhook endpoint is: /api/webhooks/stripe
The STRIPE_WEBHOOK_SECRET environment variable validates that events are genuinely from Stripe. This is configured in Vercel and does not require any manual setup.
If a client has paid via Stripe, the webhook will mark it paid automatically within seconds. Manually marking it paid before the webhook fires can cause duplicate payment records. Wait for the webhook, or check Stripe dashboard to confirm payment before acting.
Overdue Invoices
The CRM runs a cron job daily at 02:00 UTC to identify overdue invoices.
What the cron does
- Queries all invoices in
sentstatus wheredue_date < today. - Updates their status to
overdue. - Sends a reminder email to the client.
- Sends an admin notification.
The overdue cron runs at /api/admin/appointments/cron and is protected by the CRON_SECRET environment variable. It is triggered by Vercel Cron — no manual action is needed.
Manual overdue handling
If you want to flag an invoice as overdue before the cron runs:
- Open the invoice.
- Click the Actions menu.
- Select Mark as Overdue.
- Optionally send a manual reminder email from the same menu.
Recurring Invoices
Invoices can be set to recur automatically at a defined interval. The cron runs daily at 03:00 UTC to generate due recurring invoices.
Setting up a recurring invoice
- Create or open an invoice.
- In the invoice settings, enable Recurring.
- Select the interval:
| Interval | Description |
|---|---|
monthly |
New invoice generated each month on the same date |
quarterly |
New invoice generated every 3 months |
annual |
New invoice generated once a year |
- Save the invoice.
How recurring invoices work
When the cron fires:
- It identifies recurring invoices where the next generation date has passed.
- It creates a new invoice with the same client, line items, and settings.
- It sets the new invoice's issue date to today and calculates a new due date.
- The new invoice is created in
draftstatus — you must send it manually, or enable Auto-Send in the recurring settings.
Even with auto-send enabled, check your recurring invoice list monthly to ensure the amounts and line items are still current. If your service rates change, update the source recurring invoice.
Downloading an Invoice PDF
- Open the invoice.
- Click Download PDF.
- A PDF is generated with your company branding, client details, line items, and payment instructions.
The PDF uses the company name, logo, and address configured in Settings → Company Info. Ensure these are up to date before sending invoices.
Invoice Statuses
| Status | Meaning |
|---|---|
draft |
Created but not yet sent to the client |
sent |
Delivered to the client; payment not yet received |
paid |
Payment received (manual or Stripe) |
overdue |
Due date has passed without payment |