monnify/monnify-laravel
A Laravel wrapper for the Monnify payment gateway, making it easy to accept collections, initiate single and bulk transfers, verify transactions, and handle webhooks. Includes configurable credentials, a fluent API, and support for sandbox and live environments.
Architecture fit
monnify-laravel is a thin, opinionated SDK wrapper around Monnify's REST API, packaged in idiomatic Laravel form (service provider, facade, publishable config, env-driven credentials). It slots into the layer of an application that already owns checkout, wallet, or payout flows and wants to avoid hand-rolling HTTP clients, auth token refresh, and signature verification. It is not an abstraction layer — it does not model payments as domain entities, does not persist transactions, and does not provide reconciliation, ledgering, or idempotency stores. Treat it as a transport adapter, not a payments subsystem. Teams expecting a plug-and-play "Laravel Cashier for Monnify" will be disappointed; teams expecting a typed, tested API client will be satisfied.
The 1.1.0 release widens scope from collections (card charge, transfer, refund) into disbursements and bill presentment (biller categories, billers, products, customer validation, vend, requery). That is a meaningful architectural expansion: bills payment introduces multi-step, stateful flows (browse → validate → vend → requery) where failures can occur mid-sequence. The package exposes the steps but leaves orchestration to the application. Budget for that orchestration explicitly.
Integration feasibility
Low friction. composer require plus config publish plus three env vars gets a developer to a working sandbox charge. The new Quick Start (init + callback verification) and the Webhooks section — 12 event types, signature verification, a complete controller example, CSRF exclusion, best practices — remove the two integration steps that historically consume the most TPM time: signature verification correctness and CSRF exclusion misconfiguration. The sandbox test card table (no-OTP / OTP / 3DS / failure) is a concrete, undersung win: it lets QA write deterministic test cases instead of guessing at magic card numbers.
Feasibility risks are mostly informational, not technical: the notes do not state a supported Laravel/PHP version matrix, and PHP 8.1 compatibility is asserted via PHPStan at level 6 targeting the PHP 8.1 API rather than by an actual 8.1 runtime in CI. That is a reasonable proxy but not a guarantee — confirm the matrix in composer.json before committing to a platform baseline.
Technical risk
destinationAccountName change makes a previously required field optional. This is lenient-by-default: payloads that would have failed validation client-side now reach the API. Low blast radius, but it can silently degrade payout records where the beneficiary name was doing reconciliation or fraud-screening duty. Audit any logic that reads that field post-transfer.vend is a money-moving, irreversible operation against third-party billers with their own downtime profiles. The package gives you requery; it does not give you retry policy, deduplication, or a state machine. First-release features in this category deserve a sandbox hardening period before production.checkout@v6, cache@v5, codecov-action@v6); composer.lock platform constraint fixed for PHP 8.2+. Single-maintainer risk is unassessable from the notes alone.Key questions
composer.json?destinationAccountName relaxation accompanied by server-side validation, or does Monnify accept anonymous beneficiaries?vend and transfers, or must the application mint and persist them?Stack fit Best fit: Laravel monolith or modular monolith with server-rendered or Inertia front ends, PHP 8.2+ (per the lock platform fix), using the framework's HTTP client, queue, and event system. Works well behind a queued job for payout and bills flows, where the request/response cycle is decoupled from the provider's latency.
Poor fit: multi-tenant SaaS that needs per-tenant credential isolation without config gymnastics; event-sourced architectures that want a domain-level payment model; polyglot shops where only part of the system is PHP (you would then be integrating Monnify twice, in two languages, with two signature implementations).
Migration path
From v1.0.0 this is a drop-in minor bump. composer update monnify/monnify-laravel — no config republish required, no facade alias changes indicated. The only behavioural delta is the bulk transfer validation relaxation, which is permissive, so existing correct payloads are unaffected. The realistic migration work is adoption, not upgrade: retrofitting bills payment into an existing checkout means new routes, new UI states (biller → product → customer validation → confirm → requery), and new failure-handling paths.
Compatibility
PHPStan targeting the PHP 8.1 API plus a lock constraint aligned to PHP 8.2+ suggests a supported floor of 8.1 with a tested target of 8.2 or later. Laravel version support is unstated and must be verified. The webhook guidance (CSRF exclusion, signature verification) is framework-version-agnostic and portable. Note the CSRF exclusion step in Laravel 11's slimmed middleware config differs from Laravel 10's VerifyCsrfToken — confirm the docs cover the version you run.
Sequencing
composer.lock resolves, run the full application suite. Confirm the Laravel/PHP matrix against your platform.vend reference with its terminal state.destinationAccountName usage; decide whether a missing name is acceptable for reconciliation and screening, and add a fallback if not.Maintenance
Low steady-state burden. Version bumps are infrequent and, on this evidence, minor and non-breaking. The real maintenance cost sits in your code: webhook handlers, requery schedulers, and the bills state machine all need owning. Pin the version and review changelogs on release rather than floating to ^1.1 blindly — future minors may relax or tighten other required fields in the same quiet way.
Support
Upstream support is via GitHub issues and Monnify's merchant support. The documentation uplift in 1.1.0 (Quick Start, webhooks, sandbox cards, responseBody nesting explanation) is the strongest support asset and should shorten internal onboarding considerably. Escalation for settlement disputes, biller outages, and API credential issues runs through Monnify, not the package — make sure your account management relationship is in place before bills payment goes live.
Scaling
The package is stateless; scaling is bounded by Monnify's rate limits and latency, not by PHP. Two practical constraints: (a) token acquisition should be cached, so confirm the package does not re-authenticate per call under load; (b) card charges and vend calls should be dispatched from queued jobs with explicit timeouts, not from the request thread, or you will hold PHP workers open on provider latency. Webhook ingress should be acknowledged fast (return 200) and processed asynchronously, or bursts during biller incidents will back up your web tier.
Failure modes
vend — the classic. The transaction may have succeeded at the biller. Always requery by reference before retrying; never retry blind.destinationAccountName. Downstream reconciliation and any name-based screening must tolerate null.Ramp-up A mid-level Laravel developer with payments-adjacent experience should reach a working sandbox card charge in under a day using the new Quick Start, and a production-grade webhook handler in two to three days using the webhooks section. Bills payment is the longer pole: expect four to six days including the state machine, requery handling, and sandbox edge-case testing — the feature itself is easy, the orchestration around it is not. TPM time is best spent on the webhook event matrix and the idempotency/requery policy, both of which are application responsibilities the package deliberately does not cover.
How can I help you explore Laravel packages today?