What
Settlement mails are accounting documents — they should carry the on-chain evidence that supports the "paid" claim. Both currently fall short for multi-payment invoices.
Client receipt (InvoicePaidReceiptMail)
`resources/views/mail/invoice-paid.blade.php` renders a single `$invoice->txid` in the body. Per `Invoice::refreshPaymentLedger` (`app/Models/Invoice.php` lines 476–487), `$invoice->txid` stores only the latest confirmed payment's txid:
```php
$selectedPayment = $latestConfirmed ?? $latestDetected;
…
$this->txid = $selectedPayment->txid;
```
So an invoice paid via 3 partial transactions ships a receipt listing only the third txid. The other two confirmed payments that contributed to the settlement are silently dropped from the receipt body.
Issuer paid notice (`InvoiceIssuerPaidNoticeMail`)
`resources/views/mail/invoice-issuer-paid.blade.php` includes no txid at all. The issuer's accounting evidence is just `Client / Amount / Paid at` — they have to click through to the invoice page to find any txids.
Where
- `resources/views/mail/invoice-paid.blade.php` (client receipt body)
- `resources/views/mail/invoice-issuer-paid.blade.php` (issuer paid notice body)
- Both Mailables already pass `$invoice` to the view; payment data is available via `$invoice->payments` / `$invoice->activePayments()` etc.
Fix direction
Iterate confirmed payments contributing to settlement and render a list, one row per payment, in both templates:
- txid (full, monospace, with
word-break: break-all for narrow viewports — same pattern the current receipt uses for its single txid)
- sats received + fiat amount at detection (the locked-at-detection-time values, per spec §5.12.4 /
PARTIAL_PAYMENTS.md:73-74)
- Optional: confirmed at timestamp per payment
For single-payment invoices the list renders one row — same readability as today. For multi-payment invoices it surfaces the full settlement history.
Filter to confirmed, non-ignored payments only ($invoice->payments()->whereNotNull('confirmed_at')->whereNull('ignored_at') or via activeOnChainPayments()).
Test plan
- Feature test: create an invoice with 2+ confirmed payments contributing to a paid settlement; render
InvoicePaidReceiptMail and InvoiceIssuerPaidNoticeMail; assert every payment's txid appears in the rendered body.
- Single-payment invoice still renders cleanly (one row, no awkward "1 of 1" framing).
- Re-fire both mails against an existing §5.x invoice with the new templates; eyeball QA confirms the list reads as an accounting record, not noise.
Tracked in
docs/strategies/19.1_NOTIFICATION_COVERAGE_AUDIT.md §5.3 (settlement-mail verification).
What
Settlement mails are accounting documents — they should carry the on-chain evidence that supports the "paid" claim. Both currently fall short for multi-payment invoices.
Client receipt (
InvoicePaidReceiptMail)`resources/views/mail/invoice-paid.blade.php` renders a single `$invoice->txid` in the body. Per `Invoice::refreshPaymentLedger` (`app/Models/Invoice.php` lines 476–487), `$invoice->txid` stores only the latest confirmed payment's txid:
```php
$selectedPayment = $latestConfirmed ?? $latestDetected;
…
$this->txid = $selectedPayment->txid;
```
So an invoice paid via 3 partial transactions ships a receipt listing only the third txid. The other two confirmed payments that contributed to the settlement are silently dropped from the receipt body.
Issuer paid notice (`InvoiceIssuerPaidNoticeMail`)
`resources/views/mail/invoice-issuer-paid.blade.php` includes no txid at all. The issuer's accounting evidence is just `Client / Amount / Paid at` — they have to click through to the invoice page to find any txids.
Where
Fix direction
Iterate confirmed payments contributing to settlement and render a list, one row per payment, in both templates:
word-break: break-allfor narrow viewports — same pattern the current receipt uses for its single txid)PARTIAL_PAYMENTS.md:73-74)For single-payment invoices the list renders one row — same readability as today. For multi-payment invoices it surfaces the full settlement history.
Filter to confirmed, non-ignored payments only (
$invoice->payments()->whereNotNull('confirmed_at')->whereNull('ignored_at')or viaactiveOnChainPayments()).Test plan
InvoicePaidReceiptMailandInvoiceIssuerPaidNoticeMail; assert every payment's txid appears in the rendered body.Tracked in
docs/strategies/19.1_NOTIFICATION_COVERAGE_AUDIT.md§5.3 (settlement-mail verification).