rikudou/euqrpayment
Generate EU QR payment codes (EPC/SEPA) for invoices and payment slips. This Laravel/PHP package builds compliant QR payloads with IBAN, BIC, amount and remittance data, plus validation helpers and simple Blade rendering.
Architecture fit. This is not a Laravel package in any meaningful sense — no service provider, no config file, no facade, no published assets. It is a framework-agnostic PHP value/payload builder. Its role is narrow and honest: take domain data (IBAN, BIC, recipient, amount, remittance info) and emit an EPC069-12 v2 formatted string that a QR renderer can encode. It does not initiate, transmit, confirm, or reconcile payments. It fits one slot well — "pay by bank transfer" surfaces on invoices, PDFs, statements, email, and checkout — and fits nothing else.
Critically, it is a complement to a PSP, not a substitute. If any stakeholder expects "did the customer pay?", this library answers nothing. That expectation gap is the most likely source of product disappointment.
Integration feasibility. High. Composer-installable, PSR-4 autoloaded, zero runtime dependencies, zero infrastructure. A competent PHP developer can spike it in a day. The friction is not integration, it is conformance verification.
Technical risk. Concentrated in maintenance and correctness, not architecture:
Key questions to answer in the spike: Is the IBAN mod-97 checksum validated? Is BIC correctly omitted (not blanked) for non-SEPA countries? Is the EPC character repertoire enforced, with transliteration for diacritics? Is the 331-byte payload cap enforced? Is the amount formatted with . and exactly two decimals within 0.01–999999999.99? Is field order, version header, and trailing newline exactly per spec? Does it support strict_types and modern PHP? Is there a test suite, and who owns the fork if we adopt?
Stack fit. Any Laravel 9–11 app on PHP 8.1+. No queue, cache, database, or scheduled job required.
Pattern. Do not call the vendor class from controllers or Blade. Introduce our own boundary — an EpcQrPayloadGenerator interface bound in our service provider — that owns validation, character sanitization, amount normalization, and returns a typed DTO with toPayload(). The vendor class never leaks past that boundary, so swapping to a fork or an in-house rewrite is a one-file change.
Migration path. Greenfield; no data migration. If the product currently prints raw IBAN/BIC blocks, ship the QR alongside for one release behind a feature flag, retain the text fallback for apps and users that don't scan, then measure scan rates before removing anything.
Compatibility. Pin the exact version, commit the lockfile, and — given dormancy — vendor the source into the repo or a private VCS fork rather than relying on Packagist availability. Add a visible note that upstream is unmaintained so no one mistakes it for a supported dependency.
Sequencing:
Fallback. Budget 2–3 developer-days to reimplement directly from EPC069-12 if the spike reveals spec gaps. Given the small surface, this is a credible primary option, not just a contingency.
Maintenance. Near-zero runtime footprint, non-trivial ownership burden. Assume we own the code: fork under our org, preserve MIT headers, add CI with a PHP version matrix and the conformance fixtures, and review the EPC spec annually.
Support. Failures arrive as user complaints ("the app says the QR is invalid"), never as logs. Write a runbook, and persist the exact generated payload string against each invoice — that makes disputes debuggable and allows re-rendering without recomputation.
Scaling. A non-issue. Pure string manipulation, sub-millisecond, trivially cacheable per invoice. The only material cost is QR image generation; cache the PNG.
Failure modes to instrument: payload exceeding 331 bytes; non-repertoire characters (Czech, German, Polish names; &, *, accented remittance text); amount rounding divergent from the invoice total — a one-cent mismatch is a reconciliation incident; missing BIC where the receiving bank requires it; renderer missing GD/Imagick; print resolution too low to scan reliably.
Security. The QR is an unsigned payment instruction. Generate it exclusively server-side; never accept IBAN or amount from the client when rendering, and never expose a generic render endpoint — that is a ready-made phishing primitive. Bind each payload to an invoice ID and log generation.
Reconciliation gap. No confirmation, no webhook, no status. Finance still matches incoming SEPA credits (camt.053 or bank API) against invoices, and the remittance field is the only join key. Constrain and validate it, keep it short and machine-parseable within the 140-character limit, and treat it as a data contract, not free text.
Ramp-up. A PHP developer is productive in half a day. The real ramp is spec literacy — designate one owner to read EPC069-12 v2 and maintain the fixtures. The low opportunity score (35) and composite 0.27 accurately describe a small, stable, marginally useful utility with no momentum: adopt it for a thin, non-core feature, wrap it defensively, and do not build a product bet on top of it.
How can I help you explore Laravel packages today?