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

Mpay24 Bundle Laravel Package

netbull/mpay24-bundle

Symfony bundle for integrating the mPAY24 payment gateway, helping you add mPAY24 payment processing to your Symfony application through a configurable service-based setup.

View on GitHub
Deep Wiki
Context7

Getting Started

First, the framework check. This is a Symfony bundle, not a Laravel package. There is no service provider, no facade, no config/mpay24.php. If your application is Laravel, you cannot composer require this and expect it to work — the bundle assumes a Symfony kernel, DI container, and configuration tree. The honest Laravel path is to skip the bundle entirely and depend on the underlying SDK directly:

composer require mpay24/mpay24-php

…wrapped in your own Mpay24Gateway class bound to a PaymentGateway interface in a service provider. Use this bundle's source only as a reference implementation for how the Mpay24 client is meant to be configured (merchant ID, SOAP password, test vs. live endpoint).

If you are on Symfony, install and let Flex register it:

composer require netbull/mpay24-bundle

On older Symfony versions, add Netbull\Mpay24Bundle\NetbullMpay24Bundle to config/bundles.php manually.

Read DependencyInjection/Configuration.php before anything else. With a 2-star package the README is not authoritative; the config tree is the only reliable list of keys. Expect something shaped like:

# config/packages/netbull_mpay24.yaml
netbull_mpay24:
    merchant_id: '%env(MPAY24_MERCHANT_ID)%'
    soap_password: '%env(MPAY24_SOAP_PASSWORD)%'
    test_mode: true

Confirm the real names with:

bin/console config:dump-reference netbull_mpay24

First use case — one sandbox card payment, end to end. The flow you want working before touching production credentials:

  1. Build a payment: amount, currency, order reference, success/error/callback URLs.
  2. Call the API through the injected client service.
  3. Redirect the user to the returned payment-page Location.
  4. Handle the return trip (and the async notification) in a second action.
  5. Query transaction status to confirm — never trust the redirect alone.

Where to look, in order: DependencyInjection/Configuration.php (what you can configure) → DependencyInjection/*Extension.php (which service IDs exist and what's injected) → Services/ or Api/ (the client wrapper you'll actually use) → Event/ (if it dispatches Symfony events on notification, that's your integration seam, not the controller). Ramp-up on the code is hours; the real cost is Mpay24 domain knowledge — status model, settlement cycles, chargebacks, and the payment-method matrix for your target countries.

Implementation Patterns

Inject the configured client, don't construct it. The bundle's entire value is wiring credentials and endpoint selection into a ready-made service. Find the service ID in the extension and inject it by type-hint:

public function __construct(private Mpay24Client $mpay24) {}

If you find yourself new-ing the SDK client yourself, you've bypassed the only thing the bundle provides — at that point drop the bundle and use the SDK behind your own interface.

Initiate → redirect → confirm, in three separate requests. Never treat the success-URL hit as proof of payment. Pattern:

// 1. Checkout action
$payment = $this->mpay24->createPayment($order, $successUrl, $errorUrl, $callbackUrl);
return $this->redirect($payment->getLocation());

// 2. Return action — display only
// 3. Status action (also called from the notification handler) — the source of truth
$status = $this->mpay24->getTransactionStatus($order->getReference());

Make step 3 idempotent and call it from both the user redirect and the server-side notification, so a lost notification or a user closing the tab doesn't strand an order.

Put a gateway interface in front of it. This is the highest-leverage pattern given the package's maturity signals. Define your own contract (authorize, capture, refund, status, handleNotification) and implement a thin Mpay24Gateway inside it. Business logic — checkout, order state machine, reconciliation — talks to the interface, never to Mpay24Client. Swapping PSPs later then costs an adapter, not a rewrite.

Notification handling as a Symfony event or dedicated controller. If the bundle dispatches events on callback, subscribe to them and keep the subscriber thin: validate, map the Mpay24 status to an internal order state, persist, return 200 quickly. Do not do heavy work (emails, invoices, ERP sync) in the request cycle — queue it. If there is no event, point the callback URL at your own controller and re-query status; don't rely on the bundle's opinion.

Config through env, one credential pair per environment. Bind MPAY24_MERCHANT_ID / MPAY24_SOAP_PASSWORD via .env and use test_mode for sandbox. Keep sandbox and live credentials in different secret stores with different names — a .env that "just works" locally is exactly how live keys end up in a test run and vice versa.

Feature-flag the rollout. Put the payment method behind a flag, go live on a small traffic slice, and reconcile the first settlement cycles by hand against Mpay24's payout report before trusting the status mapping.

Gotchas and Tips

The framework mismatch is the first gotcha. On Laravel, this is not a dependency option — don't bridge a Symfony kernel into Laravel to run a thin SOAP wrapper. Use mpay24/mpay24-php directly, or reconsider the PSP on commercial grounds.

Check composer.json constraints before committing. Symfony has moved through 5.x/6.x/7.x and PHP 7.4→8.3 while a bundle like this typically goes stale. If it pins Symfony ≤5 or PHP <8.1, it's dead on arrival for a current stack — verify against your actual versions, not the description.

Treat it as unmaintained. 2 stars, 0 dependents, no issue triage velocity, no SLA. Budget for a fork or a repositories entry pointing at your own copy, plus a periodic review against Symfony/PHP upgrades. The security advisories you'll need to watch are on the transitive SDK, not the bundle.

SOAP-era SDKs break silently. Legacy Mpay24 clients have gone stale against updated endpoints without throwing a clear error. Run the full flow against the live sandbox in a disposable environment before trusting anything, and re-run it after any SDK bump.

Amount and currency formatting. Payment gateways commonly want minor units (cents) as integers. Confirm what the wrapper expects — a 19.99 vs 1999 mix-up is a real-money bug that unit tests won't catch unless you assert on the serialized request.

Idempotency is on you. Retried requests without idempotency keys produce duplicate captures. Key every init/capture on your order reference and enforce a uniqueness constraint at the database level, not just in application code.

Never trust the redirect, always poll. The user-facing return can be lost (closed tab, mobile browser, strict referrer policy killing the flow). Poll status as a backstop and reconcile against settlement files. Orders stuck in pending are the classic symptom of notification-only designs.

Misconfiguration should fail fast. A bundle that silently falls back to test mode, or vice versa, is how you ship a store that takes no money. Add a small boot-time check (or a health endpoint) asserting the merchant ID is non-empty and the endpoint matches the environment.

Clear the config cache after changing YAML (bin/console cache:clear). DI config changes in a bundle are invisible until the container is rebuilt — a surprisingly common hour lost.

Log with correlation IDs. Add the order reference to every outbound request and response log. When reconciliation breaks, the difference between a ten-minute and a two-day investigation is whether you can grep the transaction through your own logs.

Test the ugly paths explicitly: declined card, 3DS challenge abandoned on mobile, duplicate notification replayed twice, notification arriving before the user returns, and PSP timeout. Those are the cases that actually page someone at 2 a.m. — a happy-path sandbox payment proves almost nothing.

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.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib