sylius/refund-plugin
Sylius Refund Plugin adds refund management to Sylius e-commerce stores. Administrators can create and process order and payment refunds, track refund states and items, and integrate refund workflows with Sylius resources and admin UI.
Architecture fit — poor to conditional. sylius/refund-plugin is not a generic PHP refund library; it is a Sylius plugin. Sylius is a Symfony-based e-commerce stack built on Doctrine ORM, Symfony DI/service tagging, Sylius ResourceBundle, and Winzou/Messenger-driven state machines. Every extension point it uses — RefundResource, grid/CRUD definitions, state machine callbacks on sylius_order_payment transitions, resource repositories, form types, and Twig/Admin UI hooks — has no analogue in Laravel. There is no composer-level interop: the package's service providers are Symfony compiler passes, not Laravel service providers, and its entities extend Sylius core models rather than Eloquent. For a Laravel codebase the realistic "integration" is zero code reuse — at best it serves as a reference implementation of refund domain modelling.
Integration feasibility.
| Scenario | Feasibility | Notes |
|---|---|---|
| Existing Sylius 1.x store | High | Add via Composer, run migrations, wire refund payment methods; this is the intended path |
| Laravel app, headless Sylius as a separate backend | Low | Would require running a second runtime, syncing orders/customers, and proxying refund state — cost far exceeds writing the refund domain natively |
| Laravel app wanting refund logic | None directly | Port the concepts (Refund, RefundPayment, CreditMemo, state transitions) into Eloquent/domain services |
| Non-Sylius Symfony app | Low | Doctrine/state-machine parts portable only with substantial rework |
Technical risk.
Key questions for the requester.
Stack fit. Assume a Laravel/PHP target unless told otherwise. Score this package as not integrable and reclassify it as a design reference. The core entities worth mirroring are: Refund (aggregate root, tied to a Payment/Order, amount, currency, state), RefundPayment (the actual money movement, with gateway reference and idempotency key), and CreditMemo (the accounting document, often a generated PDF with sequential numbering). The valuable part is the state machine: requested → accepted/rejected → completed/failed, with units split per payment method.
Migration path.
composer require sylius/refund-plugin, enable the bundle, run Doctrine migrations, configure refund payment methods, and assign the refund-related state machine transitions and admin permissions.symfony/workflow is usable standalone, or use spatie/laravel-model-states), and backfill historical refunds.Compatibility. Pin explicitly. Check PHP version, Sylius minor version, Symfony major, and Doctrine DBAL. If the 2026 release date is inaccurate, determine the actual latest tag and its Sylius constraint before scoping any work. Assume no compatibility with PHP 8.4 / Symfony 7 unless the composer.json says so.
Sequencing (Laravel-native build, recommended).
refunds, refund_lines (per order item / per payment), refund_transactions, credit_notes. Unique constraint on (payment_id, idempotency_key).RefundGateway::refund(amount, currency, reference)) with adapters per PSP; persist raw request/response payloads.pending.Maintenance. If you fork or vendor this plugin, you inherit a Sylius-version treadmill: every Sylius minor upgrade requires a plugin compatibility bump, and you are maintaining Symfony DI wiring for a codebase your team may not know. On the Laravel-native path, maintenance is ordinary application code your team already owns — materially lower long-term cost, which is the strongest argument against adopting the package outside Sylius.
Support. No vendor support; MIT with best-effort maintainer attention. The Sylius org gives it some legitimacy, but 73 stars and 0 dependents means community troubleshooting is scarce. Budget for reading source rather than finding answers. If the plugin is business-critical (it touches money), assume you will be the maintainer of last resort.
Scaling. Refund volume is a small fraction of order volume, so throughput is not the concern — consistency is. Watch: DB transactions spanning refund state and gateway calls (never hold a transaction open across an HTTP call), queue-based processing with retries, and a reconciliation job that tolerates PSP eventual consistency. Sylius's resource/Doctrine layer is fine here; the failure risk is in the money movement, not the ORM.
Failure modes to design for.
(payment_id, gateway_refund_id).max()+1.Ramp-up. On Sylius: a Symfony-comfortable developer needs roughly 1–2 weeks to be productive, plus time to learn the Sylius resource/state-machine conventions (the real cost). A Laravel-only team would need weeks of Symfony context switching for a package they cannot use anyway — not justified. On the Laravel-native path, a mid-level developer with the gateway docs can ship the core refund flow in 1–2 weeks, with credit notes and reconciliation adding another 1–2 weeks. Either way, allocate explicit time for finance/accounting review, which historically consumes more calendar time than the engineering.
Bottom line. For a Laravel stack: do not adopt. Use it as a checklist for domain completeness and build natively against your PSP SDKs. For a Sylius stack: viable and probably the path of least resistance, contingent on verifying the actual latest release and its Sylius version constraint, since the reported release date is not credible as given.
How can I help you explore Laravel packages today?