> For the complete documentation index, see [llms.txt](https://acoservice.gitbook.io/acoservice-documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://acoservice.gitbook.io/acoservice-documentation/discord-integration/notifications.md).

# Notifications and DMs

What the bot direct-messages members, when it sends each kind, and how a member turns them off.

The bot sends every member notification as a Discord DM. It never emails members. Each attempt is written to an audit log with its outcome, so "did they get it?" is a question with an answer rather than a guess.

Preferences live on the site, not in Discord — there is no slash command to mute the bot.

## What the bot sends

| Type                   | Sent when                                                                                                                                                                               | Contains                                                                                                                |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| Checkout success       | The feed captures a successful checkout matched to the member                                                                                                                           | Product, store, order details from the parsed embed                                                                     |
| Checkout decline       | The feed captures a decline or a cancellation                                                                                                                                           | The decline or cancellation reason as the checkout bot reported it                                                      |
| Review hold            | The feed captures a checkout the retailer flagged for review                                                                                                                            | Same as a success, marked as possibly cancelling                                                                        |
| Invoice                | An admin runs `/billing send` or `/billing send-all`, or auto-billing fires                                                                                                             | Amount, due date, payment methods, a live Pay button, and the **Zelle memo code** when Zelle is on                      |
| Zelle payment received | The payments inbox matches a member's Zelle payment to their invoice                                                                                                                    | The amount, the memo code, and that the invoice is paid                                                                 |
| Payment reminder       | The reminder loop runs (every 6 hours) and today is a configured reminder day, or the tab is overdue                                                                                    | Number of unpaid items, total, and a relative due date                                                                  |
| Billing scheduled      | A "bill after the drop" window is armed, a drop lands, and the run is scheduled                                                                                                         | The date and time the auto-billing run will fire, so the member can pay before it does                                  |
| Operator alert         | An invoice is paid or expires, a new Zelle claim arrives, a payments inbox email needs a look, an order or shipment signal needs a human, or a drop-billing window expires with no drop | A short line naming the member and what happened, posted to the invoice log channel or sent to the ACO's operator by DM |
| Test                   | A member presses "Send test DM" on their settings page                                                                                                                                  | One line confirming DMs reach them                                                                                      |

**Who receives what.** Checkout DMs, invoices, reminders and the billing scheduled heads-up go to the member they concern. Operator alerts go to your staff instead — posted to the invoice log channel configured with `/billing set-log-channel`, or sent to the ACO's operator by DM. The test DM goes to whoever pressed the button.

## How delivery works

Checkout DMs, the billing scheduled heads-up, and the tab summaries posted to a member's ticket channel are queued and delivered by a background worker rather than sent inline. Each queued message:

1. is delivered through the same audited sender as every other DM, so the member's preferences apply;
2. is retried on a failure with a growing wait between attempts, up to five attempts;
3. if a DM still cannot be delivered and the member has a ticket channel mapped with `/tab set-ticket`, falls back to posting the same message in that channel, mentioning them;
4. is recorded as failed with the reason if neither the DM nor the fallback lands.

Queued messages survive a bot restart — nothing is lost because the bot went down mid-delivery. Invoice DMs and payment reminders are sent directly through the same audited sender (and an invoice DM's Pay button keeps working after a restart, because the bot re-registers it).

## Reminders, in detail

The reminder loop runs every six hours and walks every tenant's tabs. A member gets a reminder when all of these hold:

* their tab has a due date
* they haven't already been reminded today
* they have unpaid or invoiced entries
* today is one of the configured reminder days (`/billing set-reminders`, default 3, 1 and 0 days before due) — or the tab is already overdue, in which case a reminder goes out daily until it's cleared

The "not already reminded today" check is what keeps the six-hourly loop from sending four reminders a day: a member gets at most one, no matter how many times the loop runs.

An overdue reminder is titled **OVERDUE — Payment Reminder** rather than **Payment Reminder**. Tenants can disable reminders entirely, or disable billing altogether, via feature flags; the loop skips those tenants.

## What members can switch off

Four toggles, on the member's [Settings](/acoservice-documentation/for-members/settings.md) page.

| Toggle            | Covers                                                 |
| ----------------- | ------------------------------------------------------ |
| Master switch     | Every DM from the bot. Off means nothing gets through. |
| Checkout alerts   | Successful, declined and review-hold checkouts         |
| Invoice alerts    | Invoice DMs, and the "auto-billing runs at…" heads-up  |
| Payment reminders | Reminders before and after the due date                |

Turning the master switch off greys out and disables the other three — they're irrelevant once nothing is being sent.

<figure><img src="https://2779061473-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FpaLOMxupLGH6cNeNBpOr%2Fuploads%2Fgit-blob-a03df6094fb6e51afbd85787078acb1bf56f8cc5%2Fsettings.png?alt=media" alt="The member settings page showing the four Discord notification toggles and a Send test DM button"><figcaption><p>The toggles, the Send test DM button, and the sticky save bar that appears only when something is unsaved.</p></figcaption></figure>

Changes are not saved as you flip them. A save bar sticks to the bottom of the page with **Discard** and **Save changes** while anything is unsaved; when nothing is, the page shows "All changes saved" instead.

An admin can also switch some of these off for the whole ACO, on [Features](/acoservice-documentation/for-tenant-admins/features.md#automations) under Automations:

* **Order tracker** off: no order update DMs (shipped, delivered, cancelled).
* **Cancel email alerts** off: no "order cancelled" DM and no ops alert when a cancellation email matches a checkout.
* The **Post** switches only hide checkout feed posts. Checkout DMs still go out.

{% hint style="info" %}
Operator alerts and test DMs deliberately ignore these preferences, and so does a manual retry of a failed notification. Everything a member actually receives as a notification respects them.
{% endhint %}

## Testing delivery

**Send test DM** on the settings page asks the bot to DM the member one line immediately, bypassing their preferences. It is the fastest way to separate "the bot isn't sending" from "Discord isn't delivering".

* Success: a toast saying the DM was sent, and the message appears in Discord.
* Failure: the error Discord returned, usually meaning DM privacy is closed or there is no server in common with the bot.

If a member's last notification failed, a red banner sits above the toggles naming the notification type, the error and when it happened, with a reminder to retry the test DM after fixing DM privacy. The member's Billing page carries the same kind of banner for a failed invoice DM and links across to Settings, where the **Resend** button re-sends the original message.

## Why DMs fail

The bot fetches the user and sends. Anything Discord raises is caught and recorded — a failed DM never crashes a checkout, an invoice or a reminder.

| Symptom                                            | Cause                                                                                                     |
| -------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| 403 Forbidden (Discord's code 50007 in the detail) | The member has DMs from server members turned off, has blocked the bot, or shares no server with your bot |
| 404                                                | The Discord account no longer exists                                                                      |
| Other HTTP errors                                  | Transient Discord problems or rate limiting                                                               |
| Nothing sent at all, for anyone                    | The bot is not online — most often because the bot token was never supplied                               |

A member whose DMs keep failing and who has a ticket channel mapped will still receive queued checkout notices and the billing heads-up there. Invoice DMs and reminders do not have that fallback — if the DM fails, the member needs to fix their privacy settings and press Resend on their Settings page (or ask an admin to re-send). See [Members not getting DMs](/acoservice-documentation/troubleshooting/dms-not-arriving.md).

{% hint style="warning" %}
If **no** member in your server receives any DM, check the bot before checking anyone's privacy settings. A tenant configured with only a Client ID and Client Secret has a working site and no running bot, and a bot that isn't running sends nothing. See [Your Discord application](/acoservice-documentation/setting-up-your-tenant/discord-application.md) and [The bot is offline or missing](/acoservice-documentation/troubleshooting/bot-unresponsive.md).
{% endhint %}

## The audit log

Every attempt the bot decides to make is recorded before it is made, then updated with what happened. A member can see their own recent attempts from the bell in the site's top bar, and the last failure on their Settings page.

| Field                               | Meaning                                                        |
| ----------------------------------- | -------------------------------------------------------------- |
| Status                              | `pending` while in flight, then `sent`, `failed`, or `skipped` |
| Attempts                            | Incremented on each try, including retries                     |
| Error code                          | The HTTP status Discord returned, e.g. 403 or 404              |
| Error message                       | Discord's text                                                 |
| Last attempt / Sent at / Created at | Timestamps                                                     |

One deliberate gap: for the high-volume sends (checkout DMs, reminders), a member who has opted out does **not** accumulate a log row for each message they were never going to get — the preference check runs before the log write. Their log looks empty because nothing was attempted, not because something was lost. A few deliberate, low-volume sends do record a `skipped` row so the member can see that the bot chose not to send.

**Retrying a failed notification replays the exact message the member missed** — the same embed, and for an invoice the same live Pay button — from the copy kept with the audit entry. A manual retry also goes out even if the member's preferences say no.

## Messages that are not DMs

Two channels of communication sit outside the preference system entirely, because they are channel posts rather than direct messages:

* **Ticket channel posts.** If a member is mapped to a ticket channel with `/tab set-ticket`, tab additions and payment reminders are also posted there, and the queued fallback delivers a checkout notice there when a DM cannot land. A member who has switched off DMs will still be pinged in their ticket.
* **The public feed channel.** Successful checkouts are posted there by design. Whether the member is named in the feed post is a tenant-wide setting, not a per-member one.

Tab additions posted to a ticket channel are batched, not sent one per checkout. The bot buffers them during an active drop and flushes one consolidated message per member after five minutes of quiet, splitting it across several messages if it would exceed Discord's length limit. During a busy drop, expect one tidy summary rather than forty pings.

## Related

* [Settings and notifications](/acoservice-documentation/for-members/settings.md) — the member-side page
* [Members not getting DMs](/acoservice-documentation/troubleshooting/dms-not-arriving.md)
* [Checkout feed sources](/acoservice-documentation/discord-integration/feed-sources.md) — what has to parse correctly before a checkout DM exists at all
* [Billing and invoices](/acoservice-documentation/for-tenant-admins/billing.md)
