Billing → Clients → Client Summary presents the existing invoice email modal and native SMS/WhatsApp review actions for rows whose type is invoice. The new link actions use the shared row-action API, getPath(), a non-menu Form View and automatic KAS_FORM submission through db_actions. Opening a review page never sends a notification. Existing project email overrides, sender/reply addresses, To/CC/BCC controls and email document behavior retain their existing workflow.
The existing email modal reloads invoice data rather than trusting posted row text. It binds submission to an expiring session review token, active Billing permission and CSRF, and supplies an invoice/customer source and stable intent key to shared tracking. The default template confirms recipient acceptance with wasAccepted() while preserving the mailer's historical send return contracts. The sent flag advances only when the configured sender exposes confirmed acceptance. A project-owned template can still define its own content and document attachment behavior; the default Core template supplies a document link rather than attaching a PDF. The modal keeps its existing response/submission interface for override compatibility.
An active Billing account with current database privilege4 or higher reviews and confirms each new notification. The server reloads the invoice using both INID and its actual customer CLID; posted recipient/name/body fields cannot redirect a send. The review shows invoice number, customer, international destination and the localized transactional message. Customer LANG selects English, Spanish or French. A nonempty CEL is authoritative; otherwise TEL is used. An invalid CEL is never silently replaced with another contact number. Use explicit international country codes; Canada and Mexico follow the same shared phone normalization.
Customer permission and confirmation
The Messaging permissions native action records existing consent or withdrawal separately for SMS and WhatsApp. It requires a10–200-character reference to supporting evidence already held in authorized customer records; the form does not obtain consent from a customer. Records bind the installation/project, customer, channel and normalized destination hash. A changed number requires its own permission. Missing/withdrawn permission or an inactive customer prevents submission. Withdrawal revokes outstanding delivery access for that customer/channel.
Confirmation uses session CSRF plus a server-owned delivery ID. The server rechecks active account access, customer ownership, destination, permission, invoice revision, expiry and sender readiness. A committed dispatch claim and stable shared-message idempotency key prevent repeated clicks, refreshes and reopened forms from sending another message for the same invoice revision/channel. A changed invoice can be reviewed as a new intent. Failed/uncertain submissions require history/reconciliation rather than an automatic resend. This intentionally does not provide a blind new-key retry control.
The native Form View dispatch uses domain actions INVOICE_MESSAGE and INVOICE_PERMISSION before the generic query builder. This is a native submission extension because sending is not an ordinary table INSERT/UPDATE. Generic edits, clone and CSV access to the capability/permission tables are blocked. The existing email modal remains its original independent handler and compatibility contract; these changes do not retrofit arbitrary project overrides.
Customer invoice access
The SMS and WhatsApp messages use an expiring customer link on the installation's trusted HTTPS origin. It grants read-only access to exactly one invoice/customer/project. The recipient does not need a KAS administrator account. An opaque identifier and256-bit capability use a URL fragment; the browser removes that fragment from history and submits it by POST. Only the capability's hash is stored. Ordinary request URLs and referrers contain neither the capability nor an invoice/customer identifier. The capability is still a bearer secret: whoever receives or forwards the message can open that specific invoice until it expires or is revoked. Share it only with the intended customer.
The boundary rejects tampering, expiry, revocation, another project, unsubmitted links and an invoice/customer revision change. It uses no administrator bypass flag and no arbitrary public PDF path. Default validity is seven days; trusted configuration permits five minutes through thirty days. The authorized INVOICE_REVOKE domain action/service can revoke an invoice's links, and channel withdrawal revokes that customer's links. Reusing an expired/revoked intent does not silently create new access.
The public page escapes invoice/customer/item data and provides a PDF generated with the existing document library, with remote resources and embedded PHP disabled. Delivery permits at most500 items and500000 bytes of item descriptions; larger documents require another authorized delivery method rather than truncation. It serves no other invoices, payment credentials, administrator controls or payment operation. Responses use no-store, no-referrer and frame/content restrictions. HTTPS termination must set trusted server HTTPS state. JavaScript is required for fragment-to-POST opening. The public endpoint deliberately validates capability access before the ordinary administrator-session dispatcher. Rotating the protected signing key invalidates existing capabilities.
Message content and evidence
SMS uses a short business-name/invoice-number message and the secure link. It attaches no PDF. WhatsApp uses an approved invoice utility template with three ordered body parameters: business identity, invoice number and the complete secure link. Its language, name and approved category must match the configured template exactly. The initial implementation uses links consistently. The shared media method can send an already uploaded document ID inside an authenticated customer-service window; it does not upload a PDF or substitute a document header into this invoice template.
An example template body for approval is: {{1}}: your invoice {{2}} is available at {{3}}. Supply localized equivalents for each customer language and verify their actual approvals. Approved Business App coexistence and business sender configuration are operational prerequisites. Replies remain in the business's existing phone application under its authorized coexistence setup. KAS provides no employee chat interface and does not migrate/register numbers from this workflow.
The shared lifecycle records invoice/customer source association, recipient, intent, submission outcome and later authenticated delivery evidence. SMS segments remain pending until authoritative positive provider counts arrive. WhatsApp units require confirmed delivery/read of automated messages. Acceptance is not delivery. Simulated messages and manual Business App replies create no automated billable charges. Existing monthly carry-forward and billing behavior remain unchanged. Authorized Message History access retains its separate administrator permission; a Billing role alone does not grant access to BCC history.
Protected server configuration supplies the installation/project identity, trusted public origin, feature enablement, approved sender account, supported language templates, coexistence readiness and expiry policy. Incomplete configuration displays an unavailable message before dispatch. Provider-specific configuration belongs in private operational records; no token belongs in a browser field, ordinary setting, example or message URL.