sylius/payment-bundle
SyliusPaymentBundle integrates the Payments component into Symfony eCommerce applications, providing the payment foundation used across the Sylius ecosystem. MIT licensed, documented at docs.sylius.com, and maintained by the Sylius community.
Architecture fit — poor (2/10 for a Laravel stack). sylius/payment-bundle is a Symfony bundle, not a framework-agnostic PHP library. Its deliverables are Symfony-specific artifacts: a SyliusPaymentBundle class extending Symfony\Component\HttpKernel\Bundle\Bundle, a DependencyInjection extension, YAML/XML service definitions, route and fixture loaders, form types, and Twig templates. Laravel has no bundle/DI-extension concept, so none of the package's actual surface area can be booted. The only reusable asset underneath is the sylius/payment component (Payment, PaymentMethod, PaymentGateway, PaymentTransitions), which is a thin domain model — roughly a few hundred lines of interfaces, enums, and a static state-machine graph definition. The commercial value here is the design, not the code.
Integration feasibility — not feasible as a dependency. This is a Symfony2-era split repo. Expect constraints in the neighborhood of php ~5.5|7.0, symfony/symfony ~2.7|~3.0, and Doctrine ORM 2.4.x. On Laravel 10/11 with PHP 8.2+ those constraints are unsatisfiable; Composer will refuse to resolve. Forcing with --ignore-platform-reqs yields classes that load but cannot be wired, because the state machine, repository mappings, and gateway configuration all depend on Symfony's container and symfony/workflow. There is no shim that makes this a Laravel package.
Technical risk — high, and concentrated in the worst place. The repo is marked READ-ONLY, has 22 stars, zero dependents, and "readme" maturity — the profile of an archived split that was folded back into the Sylius monorepo around the 1.x consolidation. There is no upstream security response, no CVE triage, and no maintainer to escalate to. Placing archived code in a payment authorization/capture/refund path creates an audit finding regardless of whether card data ever touches it. The domain logic also predates idempotency keys, webhook signature verification, and Payment Request abstractions that modern gateways assume.
Key questions before any spend:
symfony/workflow inside a Laravel app purely for state transitions? That is a second framework's machinery for one feature.Verdict: the package's 0.53 score and 34.97 opportunity score are consistent with what the code says — this is a naming-collision risk, not an adoption candidate. The correct move is to harvest the payment state model (new → processing → authorized → captured → refunded, with failure transitions) as a design reference and implement it natively.
Stack fit — incompatible by construction. Target is Laravel 10/11, PHP 8.2/8.3, Eloquent, queues on Redis/SQS. The bundle requires Symfony kernel boot, Doctrine ORM entity mapping, and Symfony Workflow service configuration. Introducing Doctrine DBAL alongside Eloquent to satisfy mapping metadata is a durable architectural smell and doubles the migration story for zero functional gain.
Three viable paths, ranked:
league/omnipay (framework-agnostic, actively maintained, Laravel-friendly) plus a native state machine using spatie/laravel-model-states or backed enums with guarded transitions. We reproduce the ~15 transitions this package defines in a day, with Eloquent models we already know how to operate.composer require sylius/payment symfony/workflow directly — the components, not the bundle — then write Eloquent-backed implementations of the repository/payment interfaces plus an adapter for the workflow graph. This is a genuine option technically because sylius/payment is comparatively light. It is not a good option commercially: we would own a fork of a domain model whose evolution we cannot follow, wrapped around a state machine we could have written in a week.Migration path. There is no incremental path from Laravel into this bundle. Note also that even within Symfony, this split repo is not the current integration point — modern Sylius ships the payment bundle inside the Sylius/Sylius monorepo with PaymentRequest and gateway-config abstractions. Adopting the split repo means adopting a superseded API surface with no upgrade route to current Sylius.
Compatibility checklist if path 2 is seriously considered:
doctrine/collections.Sequencing (2–3 day spike, hard gate): install sylius/payment + symfony/workflow into a throwaway Laravel app, define the payment graph from the bundle's state config, drive one order through authorize → capture → refund against a Stripe test account, and measure lines of adapter code. If the adapter exceeds ~500 lines, stop and take path 1. Run this before committing any roadmap capacity.
Maintenance — we inherit 100% of it, immediately. The repo is archived: no dependency bumps, no PHP 8.x fixes, no security patches. Forking means our name on the CVE response for a payment-path library. Realistically that is one engineer-day per quarter of pure tax plus unbounded exposure when a transitive Symfony or Doctrine advisory lands. Compare against Omnipay, which has active maintainers and a disclosure process.
Support — effectively zero. Documentation points at docs.sylius.com for a Sylius version we will not be running; issue tracker is closed to the split repo and redirects to the monorepo, where our fork's problems are out of scope. Escalation path is "read the source." Sylius does offer commercial support, but only for Sylius applications — not for a Laravel integration of an archived component.
Scaling — the package is not the constraint, and that is the problem. The payment engine itself is near-stateless; throughput is bounded by gateway rate limits, webhook ingestion, and reconciliation jobs. This package provides none of that operational machinery — no idempotency keys, no webhook signature verification, no retry/backoff semantics, no ledger or settlement reconciliation. Those are 80% of the actual payment-integration effort and we would build them regardless of which package we pick, so the bundle's contribution to scale is nil.
Failure modes to design around (all unaddressed upstream):
payment_events audit table.pending_verification state and an operator runbook.Ramp-up. Team is Laravel-fluent, Sylius-naive. Budget 2–3 weeks for a mid-level engineer to become productive in the Sylius payment domain model, plus ongoing context loss because Sylius ecommerce experience is rare in a Laravel hiring pool and the knowledge will not transfer to future hires. Path 1 requires near-zero ramp-up: Omnipay and spatie/laravel-model-states are idiomatic to the team already.
Recommendation to stakeholders: do not adopt sylius/payment-bundle. Fund the 2–3 day spike only if someone insists, with a pre-agreed kill criterion (~500 lines of adapter). Default plan: Omnipay for gateway abstraction, a native enum-driven payment state machine, an idempotent webhook handler, and a nightly reconciliation job — roughly two engineer-weeks, fully owned, idiomatic, and auditable.
How can I help you explore Laravel packages today?