Payment Reminders
Payment reminders automate the process of chasing outstanding payments from clients. NexusRMS uses a polymorphic reminder system that works with invoices, quotes, and payment plan installments, providing automatic escalation from gentle pre-due notices through to urgent final demands with full email engagement tracking.
How reminders work
Each PaymentReminder record is linked to a remindable document through a polymorphic relationship using remindable_type and remindable_id. This means the same reminder system handles:
- Invoice reminders — Chasing unpaid or overdue invoices
- Quote reminders — Following up on quotes awaiting client approval
- Payment plan installment reminders — Notifying clients about upcoming or overdue installment payments
Reminder types
NexusRMS defines eight reminder types through the REMINDER_TYPES constant, each with a configured timing and priority level:
- pre_due — Pre-Due Reminder: sent 7 days before the due date at low priority. A friendly heads-up that payment will be due soon.
- due_today — Due Today: sent on the due date (0 days) at medium priority. A notification that the payment is due today.
- overdue_1 — First Overdue Notice: sent 1 day after the due date at high priority. The first notification that a payment has been missed.
- overdue_2 — Second Overdue Notice: sent 7 days after the due date at high priority. A follow-up emphasising the overdue status.
- overdue_3 — Third Overdue Notice: sent 14 days after the due date at urgent priority. A firmer reminder indicating the account is significantly overdue.
- final_notice — Final Notice: sent 30 days after the due date at urgent priority. The last automated reminder before further action may be taken.
- payment_plan — Payment Plan Installment: sent 3 days before an installment due date at medium priority. Specific to payment plan installments.
- custom — Custom Reminder: sent at a user-defined time at medium priority. Used for one-off reminders outside the standard escalation sequence.
Reminder fields
Each reminder record contains the following key fields:
- client_id — The client being reminded
- discussion_thread_id — Links to a CommunicationThread record for email tracking and conversation history
- reminder_type — One of the eight types listed above
- status — Current delivery status: scheduled, sent, failed, or cancelled
- scheduled_at — When the reminder is scheduled to be sent
- sent_at — When the reminder was actually sent
- email_subject — The subject line of the reminder email
- email_body — The HTML body content of the email
- email_recipients — JSON array containing to, cc, and bcc email addresses
- amount_due — The amount owed at the time of sending
- amount_overdue — The overdue portion of the amount
- days_overdue — Number of days past the due date
Sending reminders
Reminders are sent through one of two methods:
- send() — Dispatches the SendPaymentReminderJob for asynchronous processing. The job creates or uses an existing CommunicationThread (type: invoice), links to the invoice's project for context, and sends via the DiscussionEmailService with open and click tracking. This is the recommended method for production use.
- sendNow() — Dispatches the SendPaymentReminderJob synchronously for immediate delivery. Useful for testing or when the reminder must be sent without delay.
On the invoice detail page, click Send Reminder to create and dispatch a reminder immediately. The invoice's reminder_sent, reminder_sent_at, and reminder_count fields are updated to track how many reminders have been sent.
Delivery status tracking
- markAsSent(emailProviderId) — Called by the email service webhook when delivery is confirmed. Records the sent_at timestamp and the email_provider_id for cross-referencing with Postmark or Mailgun.
- markAsFailed(reason) — Records the failure_reason, increments attempt_count, and updates last_attempt_at. Failed reminders can be retried by dispatching send() again.
Email engagement tracking
NexusRMS tracks email engagement through webhooks from your email provider (Postmark, Mailgun, etc.):
- opened_at — Recorded when the client opens the reminder email, via the markAsOpened() method. Only the first open is tracked.
- clicked_at — Recorded when the client clicks a link in the email (typically the payment link), via the markAsClicked() method. Only the first click is tracked.
- wasOpened() — Returns true if the email has been opened
- wasClicked() — Returns true if a link has been clicked
- getEngagementRate() — Returns a score between 0.0 and 1.0 based on engagement: 0.5 for opened, 0.5 for clicked, 1.0 for both
Escalation
Payment reminders follow an automatic escalation sequence. Each level increases in both urgency and firmness of language:
- pre_due (low priority) — Friendly advance notice
- due_today (medium priority) — Payment due notification
- overdue_1 (high priority) — First overdue notice
- overdue_2 (high priority) — Second overdue notice
- overdue_3 (urgent priority) — Third overdue notice
- final_notice (urgent priority) — Final demand
Use getReminderTypeConfig() to retrieve the full configuration for a reminder type, getReminderTypeName() for the human-readable label, and getPriority() for the priority level (low, medium, high, or urgent).
Payment resolution
When payment is received for an invoice or installment that has active reminders, call markPaymentReceived() on the reminder. This sets payment_received to true and records the payment_received_at timestamp, signalling that no further reminders are needed for this particular document.
Cancelling reminders
To stop a scheduled reminder from being sent, use the cancel(reason, cancelledBy) method. This sets the status to cancelled and records the cancellation_reason and cancelled_by fields. Cancelling is permanent — cancelled reminders cannot be reactivated.
Tips
- Start with pre-due reminders — A gentle reminder 7 days before the due date significantly reduces late payments and maintains positive client relationships.
- Monitor engagement rates — If a client consistently opens but does not click payment links, there may be a payment method issue worth investigating.
- Use custom reminders for special cases — When the standard escalation sequence is not appropriate (e.g., a VIP client), create a custom reminder with tailored messaging.
- Check payment status before sending — Review the payment_received flag on existing reminders to avoid sending a reminder for a payment that has already been received but not yet reconciled.
- Review failed reminders regularly — Failed reminders often indicate invalid email addresses on the client record. Fix the client's contact details and retry.
- Cancel reminders after credit notes — If you issue a credit note that fully resolves an invoice, cancel any remaining scheduled reminders to prevent confusing the client.
Was this article helpful?