softsolutions4u/orocommerce-invoice
A Laravel/PHP package for integrating OroCommerce invoicing, offering tools to generate, sync, and manage invoices between your application and OroCommerce. Streamline invoice workflows with a simple, framework-friendly API.
Heads-up before anything else: despite the framing, this is not a Laravel package. softsolutions4u/orocommerce-invoice is a Symfony 7.4 bundle built for OroCommerce CE 7.0.3 on PHP 8.5. It will not composer require into a Laravel app in any usable way — no service provider, no config publish, no Blade views. Treat this assessment as "if you're working in an OroCommerce codebase," not "if you're working in Laravel."
Minimal steps:
composer require softsolutions4u/orocommerce-invoice
php bin/console oro:platform:update --force
php bin/console oro:assets:install
Then, in order:
MAILER_DSN pointed at Mailpit/Papercut.Where to look first: the README's configuration section (auto-invoicing toggle, branding, bank-transfer details, demo data), then the bundle's Resources/config/oro/acls.yml, Resources/config/oro/system_configuration.yml, and its email template directory. The lifecycle is the core mental model — Draft → Posted → Open → Partially Paid / Overdue → Paid, with Cancelled reachable — so read the workflow definition before writing anything that reacts to invoice status.
First realistic use case: replacing a manual/manual-plus-spreadsheet invoicing flow for Payment Term orders — create the invoice from the order, let the PDF and reminder emails handle the paperwork, and have an admin confirm the bank transfer when it lands.
Also: confirm your runtime first. PHP 8.5 only, and pinned to OroCommerce 7.0.3. If you're on PHP 8.3 or an older Oro, this is a non-starter until you upgrade.
Order → invoice is the spine. Two entry points: an admin creating an invoice from an order in the backoffice, and the optional auto-invoicing for Payment Term orders. For the automated path, make sure the setting is enabled per organization/website scope, not just globally, and test it against a real checkout rather than a fixture.
Lifecycle as an integration surface. Anything you build around this package should key off invoice status and payment state, not off order state — invoices move independently once posted. If you need downstream behaviour (fulfilment gating, accounting sync, ERP push), hook invoice transitions rather than order transitions.
Payments: three distinct paths.
Partial payments are the pattern most likely to expose edge cases; build a test case for 3 × 33.33 against a 100.00 invoice and check the final status flips to Paid cleanly.
Permissions per role, per action. The bundle advertises role-based permissions for every action. In practice: create a ROLE_INVOICE_CLERK (view + confirm payments) and a ROLE_INVOICE_MANAGER (everything including cancel), assign via Oro's standard role UI, and verify the storefront permissions separately — customer-facing ACLs live in a different tree from backoffice ones. Audit who can cancel, because that's the destructive one.
Email and branding customization. Four templates, EN/DE out of the box. Override them the Oro way rather than editing vendor files — bundle-level template overrides, then a translation file for any additional locale. Company branding for the PDF (logo, address, bank details) is configuration; get it set before you demo, because the PDF is the artefact the customer actually sees.
Bank-transfer reference is your reconciliation key. The storefront surfaces a unique reference per invoice. Whatever finance process you have downstream should match on that reference, not on customer name or amount — partial payments make amounts ambiguous.
Recommended rollout sequence: enable on a staging copy of production data, create ~20 invoices across all lifecycle paths, run a full reminder cycle (which means waiting for or manually triggering the Overdue check), then enable for one customer group before going wide.
"No core overrides" is the headline risk-reducer, and also easy to break. The bundle is self-contained, which makes upgrades safer — but the moment you override its templates or extend its services in your own bundle, you own the merge on every update. Keep overrides in one clearly-named project bundle and document them.
oro:platform:update --force runs schema migrations. --force skips the confirmation prompt. Snapshot the database and know your rollback path before running it in anything resembling production. This is the single most common way people break an Oro instance.
oro:assets:install is not optional. Skip it and you get broken storefront styling, missing icons, possibly a non-rendering PDF logo. If the storefront looks subtly wrong after install, this is the first thing to re-run — with the cache clear that follows it.
Nothing time-based happens without cron and consumers. Automatic Overdue transitions and payment reminders almost certainly ride on Oro's cron/message-queue infrastructure. If your oro:cron job and message consumers aren't running, invoices never go Overdue and reminders never send — and it fails silently, with no error, just a status that never changes. When debugging "the reminder didn't fire," check cron and the message queue before you check configuration. Then check var/logs/ for the consumer.
Rounding on partial payments. Verify how the bundle allocates partial payments against the invoice total and what it does with the residual cent. This determines whether your books reconcile. Test with awkward amounts deliberately.
PDF generation is the usual performance cliff. Large invoices, many line items, high-resolution logos, and a cold Symfony cache can push memory and time limits. Generate a batch of invoices in staging and watch the worker; if you're emailing PDFs at volume, make sure that happens asynchronously rather than in the request cycle.
ACLs may not backfill to existing roles. New permissions typically need to be granted explicitly after install — existing non-admin roles will have the menu item but no access, or worse, access without visibility. Audit the role grid post-install rather than assuming.
Locale coverage is EN/DE only. If your customer base isn't, you're writing translations. Missing translations in Oro usually fall back silently to the default locale, so a French customer gets English rather than an error — easy to miss until a customer complains.
Debugging checklist, in order: var/logs/ (prod and dev) → clear cache (rm -rf var/cache/* or cache:clear) → confirm ACLs → confirm cron/consumers → re-run oro:assets:install. That sequence resolves the large majority of "it's installed but not working" reports.
v1.0.0 means no upgrade history. There's no track record of how the maintainer handles breaking changes, and the PHP 8.5 / Oro 7.0.3 pin is narrow enough that the next patch of either could strand you. If this becomes load-bearing for revenue, either budget for the possibility of maintaining a fork, or keep your invoicing logic thin enough to swap out.
Extension points worth confirming early: whether invoice transitions dispatch events you can subscribe to cleanly, and whether the payment-confirmation action is exposed as a service you can call from your own console command. If it isn't, and you need ERP-driven confirmation, you're screen-scraping the backoffice — which is the point at which you'd reconsider the build-vs-buy call.
How can I help you explore Laravel packages today?