Email workspaceBill-payment transfer review alert — direct internal send
Source: resources/views/mails/payment_limit.blade.php, extending mailtemplate::emails.default. It is rendered directly by billsController::payonline, app/Http/Controllers/Expenses/billsController.php:559/:684. It is **not** App\Mail\PaymentLimit, whose separate emails.invoice.paymentLimit view has no discovered construction and remains apparently unused.
Native subjects and portable values
Preserve the existing caller-selected $this->title. Low provider balance: Vendor pay transfer failed. check superadmin for action. Failed transfer response: Payment for bill with number {bill.bill_id} (online payment) followed by the existing trailing space. The second subject has no period added. Suggested preheader: the same caller subject. These are states of one directly rendered notification, not two Mailables.
| Token | Existing source / derivation | Handling |
|---|---|---|
| {{provider_message}} | data.description = balance_response.message or res.message | Required escaped multiline original provider text, including empty/0; no raw HTML or invented error explanation. |
| {{transfer_amount}} | data.currency.symbol . number_format(data.amount, 2), where data.amount = request.amount_paid | Required full original symbol/format, preserving zero/sign. Do not use request.total_amount, minor-unit request amount_togo or the bill total. |
| {{business_name}} | data.business.name = current_business.name | Required original business identity, escaped. |
| {{document_reference}} | isset(invoice) ? invoice.invoice_number : 'bill' | Required complete original expression. Both current direct callers omit invoice, so use literal bill. Do not invent a body bill number merely because a local $bill exists or the subject includes it. If another actual view caller supplies invoice, preserve its original invoice_number, including null/empty semantics. |
| {{provider_dashboard_url}} | Fixed https://dashboard.paystack.com/#/dashboard | Required complete original general provider dashboard URL, validated separately. It is not transaction-specific and does not retry a transfer. |
| {{preheader}} | Existing caller-selected title | Escaped text; not a new settlement guarantee. |
Header-only adapter input notice_subject is the exact original $this->title, including caller bill-ID formatting/trailing space. It is not a new body token. Preserve configured native From/Reply-To and the fixed internal recipient in each Mail::send closure. No subject should be inferred from a Mailable class. The default logo/optional {{logo_url}} plus actual CID/approved HTTPS shared badges follow [shared-footer](../shared-footer.md).
There are no optional business sections or legacy duplicate action-link fields in this body. The invoice fallback is a value-mapping condition, not an invented extra active invoice email type. Keep all rows, even if a provider message is supplied empty. Required missing data needs an explicit target-project decision rather than an invented reference/amount/provider reason.
Two failure branches and accounting distinction
Route POST paybillonline at routes/api.php:961 calls payonline. The caller finds current business and Bill, reads provider balance, and compares request.amount_paid * 100. In the low-balance branch it creates VendorPayFail, prepares currency/business/amount/description, sets the first subject and directly sends the view at :559. In the transfer-response branch it invokes the provider and, when res.status is false, creates VendorPayFail, uses res.message and the second subject, then sends the same view at :684. This library does not invoke those requests or change any guards/error handling/accounting/notification order.
The source continues ledger/payment-history/paid-status work despite failed onward transfer. Do not borrow PaymentError's invoice-payment prerequisite or label this bill unpaid/refunded/settled. The original body says collection to Built succeeded but onward transfer failed; this view does not independently verify collection in either caller. The draft retains that as **reported** collection context rather than claiming verified settlement. The message-above-is-from-Paystack explanation remains, and its existing dashboard link becomes Open Paystack dashboard with provider-review context.
Both direct calls are synchronous Laravel Mail::send(view, data, closure), not queue() or the unused PaymentLimit Mailable. Preserve native transport/outbox behavior. Neither closure configures business PDF/attachment, CC/BCC or Reply-To; the common inline badge-image requirements are separate. The old package layout is a rendering dependency, not another project notification type; a full standalone HTML view should replace nesting in that layout during separately authorized integration.
Native integration and safety
Keep the direct Mail::send caller/closure, data and exact subject routing; provide a complete HTML view and proposed plain-text alternative through Laravel's native supported view mechanism. Portable {{placeholder_name}} tokens are not automatically Blade. Do not add a new templating framework, Mailable/sender migration or finance/retry behavior as part of HTML integration.
Escape all provider text, identifiers, amounts and attributes. Validate the approved provider dashboard/image HTTPS destinations separately and use one pass for replacement. Source diagnostics may need an explicitly authorized production redaction policy; do not copy actual provider payloads/recipients/banking data into fixtures or logs. No live provider dashboard or transfer is opened here.
Five fictional states cover low balance, failed provider response, supplied zero/empty values, original view-level invoice context as a mapping check and long fields. The invoice-context fixture does not establish that a current direct bill caller supplies invoice; only the two current bill calls were traced. Files: public/ready/bill-transfer-failure.html/.txt and previews/bill-transfer-failure-*.html/.txt. No separate project-owned plain-text alternative found. Browser rendering does not establish collection/transfer truth, retry safety, client compatibility, CID delivery or production sending.