send_invoice_notification
Notifications · Write · account-scoped · consent-gated
Send the customer the payment link for an open invoice — on the channels they consented to, and no others.
Usage
The pay-link delivery hop: issue_invoice deliberately sends nothing, and this tool closes that gap with the same gates the web applies at issuance (MOT-127). It sends a real message on behalf of the authenticated account's shop; it writes nothing to MOTOR and nothing to Stripe — the invoice is only read, live, before sending.
The safety model is the argument shape. There is no destination parameter. The invoice's own billing email — set when the advisor issued it — is the only candidate address, and it must also hold a signed consent record for this shop: the invoice knowing an address is not permission to message it.
The status gate runs first. The invoice is read live from Stripe; paid or void refuses with InvoiceNotPayable and nothing is sent — a payment reminder to someone who already paid is the exact failure this gate exists to prevent. Never retry around it.
Each requested channel returns its own structured outcome (sent, deferred with resumeAt under quiet hours, or refused with a reason), and every send lands in the shop's notification audit trail under the same idempotency key the web path uses — an MCP send racing a web re-send converges at the provider. The result always includes payUrl, so the advisor can hand it over when sending is refused.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
invoiceId | string | Yes | The invoice to send the pay link for — the Stripe id from an issue_invoice result (starts with "in_") or the printed invoice number. Example: "ALRVAKWA-0001" |
channels | array of "email" | "sms" | Yes | Which channels to send on. Example: ["email"] |
vehicleDescription | string | No | The vehicle line for the email, e.g. from resolve_vehicle. Omit and the email simply skips it. Example: "2010 Honda Civic LX" |
Description advertised to clients
The exact description a fully entitled MCP client discovers — the workflow contracts travel with the tool, so a client with no system prompt still uses it correctly. An account missing a licence for content this tool reaches sees the same text behind a [Licensed content — not enabled on this account] or [Partially available] notice:
Send the customer the payment link for an OPEN invoice, on the channels they have CONSENTED to. THIS TOOL SENDS REAL MESSAGES on behalf of the authenticated account's shop. It writes NOTHING to MOTOR — DaaS stays read-only — and nothing to Stripe: the invoice is only read, live, before sending. There is deliberately NO destination parameter: the invoice's own billing email must ALSO hold a signed consent record for this shop, so this tool cannot message anyone who has not opted in — do not ask for an address to send to, none can be supplied. A paid or voided invoice refuses with a structured reason (invoice-not-payable) — a payment reminder to someone who already paid is the failure this gate exists to prevent; never retry around it. Each requested channel returns a structured outcome: sent, deferred (quiet hours — queued until the stated time), or refused with a reason (no-consent, consent-scope-mismatch when the consent on file covers quotes only, suppressed, sms-transport-unavailable, …). A refusal is the system working; relay the reason. The result includes payUrl either way, which the advisor can always share by hand. The shop is NEVER a parameter: it resolves from the authenticated account, so this tool can only send for the caller's own invoices.
Example — Send the pay link after issuing
Illustrative payload shapes (ids elided); outcomes are the live gates' own words.
Request
{
"invoiceId": "ALRVAKWA-0001",
"channels": [
"email"
],
"vehicleDescription": "2010 Honda Civic LX"
}
Response
{
"notifications": [
{
"channel": "email",
"status": "sent"
}
],
"payUrl": "https://motoradvisor.app/pay/…"
}
A paid invoice refuses with InvoiceNotPayable ("already paid — payment reminders are suppressed") — the same 409 semantics as the web re-send route, as a structured refusal.