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

Sylius Quickpay Plugin Laravel Package

setono/sylius-quickpay-plugin

Sylius plugin that integrates the Quickpay payment gateway, letting stores offer Quickpay checkout and payment methods through Sylius's native payment workflow. Configure credentials and payment methods in the admin, then accept card payments at checkout.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a small, single-maintainer Sylius plugin (3 stars, no dependents, last release dated in the future relative to typical release cadences — verify the tag actually exists on Packagist). Treat it as a starting point you will likely fork or patch, not a drop-in appliance.

Install

composer require setono/sylius-quickpay-plugin

Register the bundle in config/bundles.php:

Setono\SyliusQuickpayPlugin\SetonoSyliusQuickpayPlugin::class => ['all' => true],

Wire routing and services — import the plugin's config/routes.yaml (typically under a /quickpay prefix for the callback endpoint) and config/services.yaml from your app config. Most Setono Sylius plugins follow the standard Resources/config layout; check the package's src/Resources/config/ for the exact filenames before assuming.

Where to look first, in order

  1. src/DependencyInjection/ — the extension and configuration tree. This tells you the exact config keys and whether credentials live in config/packages/ or in the Sylius admin gateway config form.
  2. src/Resources/config/services.xml (or .yaml) — look for the GatewayFactory service and its payum gateway name. Note the factory code; you'll need it when creating the payment method.
  3. src/QuickpayGatewayFactory.php and the associated Action/ or Bridge/ classes — this is where the actual Quickpay API calls (authorize, capture, refund, cancel) live.
  4. The callback controller — this is where reliability issues usually hide.

Credentials

Quickpay needs an API key and a private key (for callback checksum verification), plus an agreement ID if you use Quickpay's own subscription/agreement flow. Set these in the Sylius admin under Payment methods → your Quickpay method → gateway config, or, if the plugin exposes it, via environment variables in config/packages/setono_sylius_quickpay.yaml. Confirm which by reading the Configuration class — don't guess, because getting it wrong silently produces a gateway that never authenticates.

First use case

Create a payment method in the Sylius admin using the plugin's gateway factory, set it to Quickpay's test mode credentials, attach it to a channel, and run a single order through checkout. This exercises the whole chain — factory instantiation, authorize action, redirect to Quickpay, callback handling, state machine transition — in about ten minutes and surfaces 90% of integration problems immediately.

Implementation Patterns

Per-channel payment method configuration. Quickpay credentials are gateway config, so the natural pattern is one payment method per channel (or per currency, if you settle in multiple). Create them in fixtures rather than by hand so they're reproducible:

$paymentMethod = $this->getFactory()->createWithGateway('quickpay');
$paymentMethod
    ->setCode('quickpay_dkk')
    ->setName('Quickpay')
    ->setEnabled(true)
    ->setGatewayConfig($this->getGatewayConfigFactory()->create([
        'api_key'    => '%env(QUICKPAY_API_KEY)%',
        'private_key'=> '%env(QUICKPAY_PRIVATE_KEY)%',
        'test_mode'  => true,
    ]));

Verify the exact gateway config array keys against the plugin's Configuration class — they must match the form type's field names exactly or they're silently dropped.

Admin-driven capture/refund. The value of the plugin is that Sylius' payment state machine gets hooked into Quickpay's operations. The pattern: authorize at checkout (authorized state), then capture or refund from Admin → Order → Payments. Each transition dispatches a Payum action that calls Quickpay. Because Quickpay supports both authorize+capture and autocapture, decide which you want before going live — switching later means reconciling in-flight payments. Look for an autocapture config flag; if the plugin doesn't expose one, you'll be capturing manually from admin, which is fine for low volume but a support burden at scale.

Callback/webhook handling. Quickpay posts back to a URL the plugin registers per payment. The controller must:

  • Accept the callback without CSRF or auth (exclude the route in security.yaml).
  • Verify the Quickpay-Checksum-Sha256 header against the private key.
  • Be idempotent — Quickpay retries. Look up the payment by its generated identifier and no-op if it's already in a terminal state.
  • Update the payment via the state machine (sylius_payment transitions), not by setting status directly.

If you write your own controller instead, mirror this exactly. The failure mode is a callback that fires twice and double-captures.

Decorating for custom behaviour. Because the ecosystem is thin, plan on extending. The clean extension points in a Sylius/Payum plugin are:

  • Decorate the Payum action services (sylius.quickpay.action.capture or similar — grep for the service ID) to add order notes, logging, or ERP notifications after a successful capture.
  • Override the gateway factory's form type to add config fields.
  • Add a WinzouStateMachine callback on sylius_payment transitions for side effects, keeping the plugin itself untouched.

Prefer state machine callbacks over action decoration where possible — they survive plugin upgrades.

Testing. Mock at the HTTP boundary, not the service boundary — the plugin's actions will call Quickpay over Guzzle/HttpClient. Use HttpClient's mock response in a functional test and assert the payment transitions to authorized. For unit tests, use Sylius' PaymentMethod factory helpers so you don't hand-construct gateway config arrays.

Gotchas and Tips

The callback URL must be publicly reachable. Local development will not receive callbacks from Quickpay. Use ngrok/Expose and set the base URL, or you will spend hours debugging "payment stuck in processing" — which is almost always "callback never arrived," not a plugin bug.

Checksum verification is not optional. Quickpay signs callbacks. If the plugin's controller doesn't verify the checksum, that's a security hole and a reason to fork. Check the callback controller source before going live. Also confirm the private_key you configured is what the controller reads — mismatches produce rejected callbacks with a generic 403 that's hard to diagnose.

Amounts and currencies. Quickpay takes amounts in the currency's minor unit (øre). Sylius stores the same. This usually lines up, but verify a zero-decimal currency (JPY) if you support one — off-by-100 bugs here are silent and expensive.

Test mode is a config flag, not a separate gateway. If the plugin's only toggle is a test_mode boolean, the credential set is shared. Ensure your production deployment can never inherit test credentials — put them in separate env vars per environment and fail loudly if unset.

Version constraints. A 3-star plugin with no dependents has a narrow tested matrix. Pin it and check the composer.json require against your Sylius version before upgrading Sylius. Expect that a minor Sylius bump breaks it. Budget for reading the diff, not just running composer update.

Last release date is suspicious. The listed release date is in the future. Verify on Packagist what tags actually exist and whether the default branch has unreleased fixes you need. If the fix you need is unreleased, use a VCS repository entry rather than a fork if you can.

Debugging flow when a payment misbehaves:

  1. Quickpay dashboard first — the transaction is either there or it isn't. That separates "our request failed" from "callback handling failed."
  2. var/log/dev.log filtered on quickpay (case-insensitive; logging may be inconsistent).
  3. Check the payment's details JSON column in the sylius_payment table — Payum stores the Quickpay transaction ID and raw response there.
  4. Only then read the plugin source.

The details blob is your best debugging tool. SELECT details FROM sylius_payment WHERE id = ? will show you exactly what Quickpay returned. Most "the plugin is broken" reports resolve to a declined card, a currency mismatch, or a missing agreement ID, all visible there.

Missing features you'll likely need to add: partial refunds (check whether the refund action accepts an amount), multiple captures, and order-status sync after a delayed callback. Confirm each in the source before promising it to stakeholders — the README for a 3-star plugin tends to describe intent more than reality.

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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo