Skip to content

[Invoices]: Render SEPA EPC (Girocode) payment QR on invoice PDFs #664

Description

@nielsdrost7

v1 renders a scan-to-pay SEPA EPC QR on invoice PDFs (application/libraries/QrCode.php, using endroid/qr-code + smhg/sepa-qr-data): payload = recipient, IBAN, BIC, currency, remittance text, open balance as amount. Recipient resolves settings→user_company→user_name; IBAN/BIC/remittance prefer the invoice user's own fields (user_iban, user_bic, user_remittance_textapplication/modules/users/views/form.php:255-262) with settings fallback; remittance is tag-parsed via parse_template(). The template guards rendering: only when qr_code is enabled, IBAN+BIC present, and 0 < balance < 10e9 (application/views/invoice_templates/pdf/InvoicePlane.php:17,329-345). v2 has the settings fields (unconsumed — Modules/Core/Filament/Admin/Pages/Settings.php:417+, tracked as #256) but zero QR generation code. Related: #256 (settings), #375 (Swiss QR-bill variant).

Specific

Add an EPC069-12 ("Girocode") QR block to the invoice PDF template: build the EPC payload from company settings (qr_code_recipient, qr_code_iban, qr_code_bic, qr_code_remittance_text, currency) with per-user overrides, amount = invoice balance, encoded via endroid/qr-code (medium error correction, as the EPC standard requires) and embedded as a data-URI image in the PDF HTML. Render only when the #256 toggle is on, IBAN and BIC resolve non-empty, and the balance is positive and below the EPC ceiling.

Measurable

  • With settings configured and a positive balance, the generated invoice PDF contains a QR image whose decoded payload is valid EPC069-12 (BCD/002/1/SCT, name, IBAN, BIC, EUR<amount>, remittance).
  • Toggle off, missing IBAN/BIC, or zero/negative balance → no QR block.
  • Amount always equals the balance, not the total.

Achievable

  1. Add endroid/qr-code (+ smhg/sepa-qr-data or equivalent EPC payload builder) to composer.
  2. New Modules/Invoices/Services/EpcQrService.php (forInvoice(Invoice): ?string returning a data URI, null when guards fail) — settings via the [Settings]: Invoices — QR Code Settings #256 keys.
  3. Include in invoices::pdf.invoice (and the Report Builder template as a QR brick once PR [IP-130]: Report Builder — bands + bricks (IP-130, Phases 1-4 + Browsershot driver) #608 merges).

Relevant

Scan-to-pay QR codes materially speed up payment in SEPA countries and are existing v1 functionality; the settings UI already promises it.

Time-Bound

After #256 (settings persistence) — the renderer consumes those keys.

Arrange

Company settings rows for qr_code=1, IBAN DE89370400440532013000, BIC, recipient, remittance; invoice with balance 100.00; second invoice fully paid.

Act

Call EpcQrService::forInvoice() for both; render the first invoice's HTML via InvoiceService::renderHtml().

Assert

  • Service returns a data:image/png;base64,... URI for the open invoice; decoding the QR yields an EPC payload with the configured IBAN and amount 100.00.
  • Service returns null for the paid invoice and when qr_code=0 or IBAN missing.
  • Rendered invoice HTML contains the QR <img> only in the enabled case.
  • Per-user IBAN/BIC override the company settings when present.

Metadata

Metadata

Assignees

No one assigned

    Labels

    refinedRefined with SMART plan / test suggestions

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions