Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Omnipay Bundle Laravel Package

sylius/omnipay-bundle

Sylius Omnipay Bundle integrates the Omnipay PHP payment library with Sylius, letting stores configure multiple payment gateways through one unified API. It provides gateway factories, configuration, and payment handling for Sylius checkout.

View on GitHub
Deep Wiki
Context7

Getting Started

Read this first: the bundle is archived and READ-ONLY. It is a Symfony 2 / Sylius 1.x integration layer for Omnipay. composer require sylius/omnipay-bundle inside a Laravel app will not register anything useful — there is no Laravel service provider, no facade, and its Symfony/PHP constraints will fight a modern composer.json. Do not adopt it for new work. The assessment below is written for a Laravel developer who either inherits a legacy Symfony/Sylius app or who wants to lift the pattern into Laravel using league/omnipay directly.

If you inherited a legacy Symfony/Sylius application that already depends on it:

  1. composer require sylius/omnipay-bundle (expect to pin old Symfony/Omnipay versions — check the composer.json require block before guessing).
  2. Register new Sylius\Bundle\OmnipayBundle\SyliusOmnipayBundle() in app/AppKernel.php.
  3. Where to look first:
    • DependencyInjection/Configuration.php — the authoritative schema for the sylius_omnipay.gateways config tree. Read this before writing any YAML.
    • Resources/config/services.xml — tells you which services are public/injectable and what the gateway service IDs look like.
    • GatewayFactory in the bundle — the seam between config and Omnipay gateway objects.
  4. Minimal config: one gateway entry per provider, using the Omnipay factory short name plus its parameters:
sylius_omnipay:
    gateways:
        paypal_express:
            factory: PayPal_Express
            parameters:
                username: "%paypal_user%"
                password: "%paypal_password%"
                signature: "%paypal_signature%"
                testMode: true

First use case: a single purchase() charge. Pull the configured gateway, call purchase() with amount, currency, and card/token data, then branch on the response (isSuccessful(), isRedirect(), isPending()). Persist the gateway transaction reference immediately on return.

The Laravel equivalent (what most readers actually want):

composer require league/omnipay omnipay/stripe omnipay/paypal
// app/Providers/PaymentServiceProvider.php
$this->app->singleton(GatewayInterface::class, function () {
    return Omnipay::create(config('services.stripe.gateway'))
        ->initialize([
            'apiKey'    => config('services.stripe.secret'),
            'testMode'  => app()->environment() !== 'production',
        ]);
});

That is functionally what the bundle does for Symfony — nothing more.

Implementation Patterns

  • Config-driven gateway registry. Keep one entry per provider, with credentials from env/parameters, never committed YAML. The bundle's only job is turning that config into injectable Omnipay gateway objects. In Laravel this is a config/payments.php file plus a service-provider binding per gateway.
  • Inject the gateway, not the container. Wrap each provider in a thin PaymentService that normalizes parameter names (Stripe's token vs PayPal's token, amount units, returnUrl shape). This is the one class that lets you swap providers or swap Omnipay for a first-party SDK without touching checkout controllers.
  • Authorize/capture for delayed capture. Use authorize() at checkout and capture() at fulfillment; refund() with the stored transactionReference. Not every gateway supports all three — check the gateway class' capabilities before exposing an admin button.
  • Offsite redirect flow. purchase() on PayPal/redirect gateways returns a response exposing a redirect (getRedirectResponse() or getRedirectUrl() depending on gateway version). Redirect the user, persist transactionId before leaving your app, and on return call completePurchase() with the same identifying parameters. A redirect is a normal outcome — branch on isRedirect(), do not treat it as an error.
  • Normalize the order → Omnipay mapping once. Keep a single mapper covering amount (in minor units), currency, transactionId, returnUrl, cancelUrl, card/token. Scattering this across controllers is the #1 source of "works for Stripe, breaks for PayPal" bugs.
  • Webhooks as a separate path. Handle async notifications in their own controller/job, verify signatures where the provider supports it, and make handlers idempotent keyed on the gateway transaction id. In Laravel: a dedicated route outside auth middleware, a VerifyWebhookSignature middleware, and a queued ProcessPaymentWebhook job.
  • Testing. Use Omnipay's Mock gateway (Omnipay::create('Mock')) or MockGateway subclasses to assert on outbound request parameters and return canned responses with no network. Set testMode: true and hit provider sandboxes for integration checks. In Laravel, bind the mock in a Testing service provider or via $this->mock(GatewayInterface::class).
  • Event dispatch on outcome. PaymentSucceeded / PaymentFailed / PaymentPending from the PaymentService keeps order state, emails, and analytics out of payment code. This mirrors the Symfony event dispatcher usage the bundle relied on.
  • One provider per service, one interface for all. A GatewayInterface (Omnipay's own) or your own PaymentGateway contract means checkout code never names a provider — exactly the abstraction the bundle provided for Sylius.

Gotchas and Tips

  • Archived status is the top risk. No security patches, no Omnipay/Symfony compatibility updates, zero dependents. Treat it as frozen code: pin the version, vendor or fork if you must keep it, and put a dated retirement on it.
  • Omnipay v2 vs v3 namespaces differ. v2 uses Omnipay\Common\GatewayFactory; v3 uses Omnipay\Omnipay::create(). Check composer.lock before copy-pasting a snippet from GitHub — half the available examples are v2.
  • Amount units are gateway-specific. Most Omnipay gateways expect minor units (cents) as integers; some (older PayPal Express) expect decimal strings. Encode this in your mapper with a per-gateway converter, not at call sites.
  • isSuccessful() is not "money moved." Authorize returns successful with funds only held. Check getTransactionReference() is non-null and record the mode (purchase vs authorize) alongside it, or reconciliation will be ambiguous later.
  • Config cache in Symfony is unforgiving. Changing sylius_omnipay.gateways requires bin/console cache:clear, and the container caches gateway service definitions. In Laravel, the equivalent trap is php artisan config:cache after editing config/payments.php.
  • Parameter keys are passed straight through to the Omnipay gateway. The bundle does not validate them. Misspell signature and you get a runtime gateway exception, not a config error — validate gateway params in your own bootstrapping if you control the config.
  • testMode must be environment-driven. Hard-coding testMode: true in a config file that gets promoted is a classic legacy-app incident. Bind it from APP_ENV.
  • Extension points are thin but present. You can register custom Omnipay gateways by tagging a service or extending the gateway factory, but with the bundle archived you are on your own if the seam moves. Prefer to wrap the bundle behind your own PaymentGateway interface so the extension point you actually rely on is yours, not the bundle's.
  • Debugging gateway failures. Log the Omnipay request object (minus PAN/CVC) and the full getMessage() + getCode()) from failed responses; most "silent" failures are gateway-side validation errors surfaced only there. Never log card, cvv, or full request bodies.
  • Redirect return URLs are absolute and whitelisted. If checkout is on a different host or subdomain than the callback route, gateways will reject or the user lands on 404. Configure returnUrl/cancelUrl from url() in Laravel, and whitelist them in the provider dashboard.
  • Do not couple the payment upgrade to a framework upgrade. If you are exiting this bundle, introduce an internal PaymentGateway interface first, migrate one provider at a time behind it, and only then remove the dependency. That seam is the only durable thing you get from this exercise — the bundle itself is replaceable glue, and so is Omnipay.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log