# Invoice Dunning Sequence

Run a staged outreach sequence against overdue invoices, escalating tone from a friendly nudge to a firm reminder to a final escalation, while remembering what has already been sent to each customer.

## When to use

- A batch of invoices has gone past due and customers need reminders without duplicate or overly aggressive messages.
- You need consistent, staged follow-up (nudge, firm, escalate) tracked per customer over time.
- Someone needs a heads-up that an account is heading toward collections or requires a manual call.
- Recurring, unattended dunning runs are needed on a schedule (e.g., daily).

## Tools

- `http-get`
- `send-email`
- `schedule-task`
- `update-memory`
- `create-task`

## Playbook

1. Use `http-get` to pull the current overdue invoice list from the billing system, e.g. `GET https://api.billingprovider.com/v1/invoices?status=overdue`. Auth is injected by the org's Integration row for this host — never ask for, echo, or hardcode credentials. On 401/403 or missing Integration, stop and `send-message` a human naming the service and scopes.
2. For each overdue invoice, check prior contact history using `update-memory` (read the per-customer dunning record: last stage sent, last sent date, days overdue at last contact).
3. Determine the correct stage: no prior contact or invoice 1-15 days overdue -> "nudge"; already nudged and 16-30 days overdue -> "firm"; already firm and 30+ days overdue -> "escalate".
4. Draft the stage-appropriate message and send it with `send-email` to the customer's billing contact. Nudge is friendly and brief; firm restates the amount, due date, and days overdue; escalate states that the account may be sent to collections or paused and asks for immediate payment or contact.
5. Immediately after sending, call `update-memory` to record the customer, invoice ID, stage sent, and timestamp, so the next run does not repeat or skip a stage.
6. If a customer reaches the "escalate" stage and does not respond within 5 business days, use `create-task` titled "APPROVAL: escalate account to collections for [customer]" so a human decides whether to pause service, refer to collections, or write off — do not take that action autonomously.
7. If the customer disputes a charge, or asks for a payment plan, adjustment, or refund, do not negotiate terms yourself: use `create-task` titled "APPROVAL: [action] for invoice [ID]" describing the request, and route it to a human for a decision. Never execute a payment, refund, credit, or journal entry directly — those actions are always staged as an approval task, never performed autonomously.
8. Use `schedule-task` to queue the next check for this customer (e.g., re-check in 7 days) so the sequence continues without a person re-triggering it each time.
9. If the billing system needs any correction (e.g., marking an invoice as "in dispute" or updating a due date), use `http-request` for the PATCH/PUT call rather than assuming `http-get`/`send-email` can do it, and confirm the Integration scope covers writes before calling.

## Failure modes

- Sending a repeat "nudge" or "firm" message because the per-customer memory record was not checked or updated — always read and write `update-memory` around every send.
- Escalating a customer who already paid: cross-check the invoice status via `http-get` immediately before sending, since stale data causes wrongful escalation.
- Treating a dispute or payment-plan request as routine and resolving it yourself instead of creating a human "APPROVAL" task — this app never executes financial changes.
- Missing Integration auth on the billing host causing silent failures; always stop and `send-message` a human rather than retrying with guessed credentials.

## Done when

- Every overdue invoice for the run has received the correct stage message (or none, if already contacted and not yet due for the next stage) and its memory record is updated.
- All disputes, payment-plan requests, and collections decisions are sitting as open "APPROVAL" tasks for a human, none executed autonomously.
- The next check is scheduled via `schedule-task` for each customer still in an active dunning cycle.