Skip to content

feat: invoice email sending, view tracking & BullMQ payment reminders#124

Merged
0xdevcollins merged 1 commit intomainfrom
feat/invoice-email-reminders
Apr 4, 2026
Merged

feat: invoice email sending, view tracking & BullMQ payment reminders#124
0xdevcollins merged 1 commit intomainfrom
feat/invoice-email-reminders

Conversation

@0xdevcollins
Copy link
Copy Markdown
Owner

Closes #66

Summary

  • POST /v1/invoices/:id/send — sends branded invoice email (merchant logo, brand colour, optional custom message, Pay Now CTA) and schedules automatic reminders
  • GET /v1/invoices/:id/track — public pixel endpoint embedded in the email; when the customer opens the email their client loads this pixel, transitioning the invoice SENT → VIEWED and firing the invoice.viewed webhook
  • 3 BullMQ reminder jobs scheduled automatically on send (relative to due date)
  • New webhook events: invoice.sent, invoice.viewed
  • invoice.overdue and invoice.paid webhooks now fired correctly per invoice

Reminder schedule

Job Fires Action
before_due −3 days Reminder email to customer
on_due Due date Reminder email to customer
after_due +3 days Mark OVERDUE + invoice.overdue webhook + reminder email

Webhook events

Event Trigger
invoice.sent POST /:id/send
invoice.viewed Customer opens email (pixel fires)
invoice.paid Full payment recorded
invoice.overdue after_due reminder job or bulk cron

Test plan

  • POST /v1/invoices/:id/send with { "message": "Please pay by end of month" } — email received with custom message and branding
  • Open the email — GET /:id/track fires, status changes to VIEWED, invoice.viewed webhook delivered
  • Verify 3 BullMQ jobs queued in Redis (invoice-reminders queue) after send
  • POST /v1/invoices/:id/payments with full amount — invoice.paid webhook fired
  • Invoice without due date — send still works, no reminder jobs scheduled
  • API_URL env var set correctly so tracking pixel URL resolves

🤖 Generated with Claude Code

Closes #66

- POST /v1/invoices/:id/send now sends branded email via Resend with
  merchant logo, brand colour, optional custom message, Pay Now CTA,
  and an embedded 1×1 tracking pixel
- GET /v1/invoices/:id/track — public pixel endpoint; loading it
  transitions invoice SENT → VIEWED and fires invoice.viewed webhook
- Three BullMQ reminder jobs auto-scheduled on send (3 days before due,
  on due date, 3 days after due date which also marks OVERDUE)
- Webhook events added: invoice.sent, invoice.viewed
- invoice.overdue webhook now fired per-invoice (bulk cron + reminder processor)
- invoice.paid webhook fired on full payment via recordPayment()
- Notification templates updated with merchant branding and contextual
  due-date colouring (red when overdue)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@0xdevcollins 0xdevcollins merged commit c57b2fa into main Apr 4, 2026
2 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

API: Invoice CRUD Endpoints & PDF Generation

1 participant