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

Monnify Laravel Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package and publish its config:

composer require monnify/monnify-laravel
php artisan vendor:publish --tag=monnify-config

Add your Monnify credentials to .env (MONNIFY_API_KEY, MONNIFY_SECRET_KEY, MONNIFY_CONTRACT_CODE, and the sandbox/base URL). Start by reading the new Quick Start section — it now contains a complete payment-initialisation and callback-verification example, which is the fastest path to a working integration.

Your first use case should be a simple card/transfer checkout: initialise a transaction, redirect the customer to the returned checkout URL, then verify the transaction on the callback route. Once that works end-to-end in sandbox, move on to webhooks (the docs now cover all 12 event types with a full Laravel controller example) so you are not relying solely on browser redirects.

For anything beyond collections, the 1.1.0 Bills Payment support is the next area to explore: browse categories and billers, fetch products, validate a customer, then vend. Use the newly documented sandbox test cards (no-OTP, OTP, 3DS, and failure scenarios) to exercise the unhappy paths before going live.

Implementation Patterns

Payment initialisation and callback verification. Keep initialisation in a dedicated service or action class rather than a controller. Generate your own paymentReference (or persist Monnify's) before redirecting, so you can reconcile callbacks even if the user never returns. On the callback route, verify the transaction server-side with the package before marking an order paid — never trust query-string status alone.

Webhook-first fulfilment. Add a dedicated webhook controller, exclude it from CSRF in bootstrap/app.php (Laravel 11+) or VerifyCsrfToken (Laravel 10), and verify the signature against the raw request body before parsing. The 1.1.0 docs cover signature verification and best practices; follow them exactly. Dispatch a queued job from the webhook and return 200 quickly, so slow order processing does not cause Monnify retries. Make handlers idempotent keyed on paymentReference / transactionReference.

Bills Payment flow. Treat it as a multi-step workflow: categories → billers → products → validate customer → vend → requery. Cache categories and billers (they change infrequently) but always validate the customer immediately before vend, since validation is product- and customer-specific. Persist the vend reference before calling out, and use the requery endpoint for any transaction left in a pending/in-progress state rather than blindly retrying vend.

Bulk transfers. With destinationAccountName now optional in 1.1.0, you can send transaction lists that match the Monnify spec without fabricating names. Still validate the overall payload shape locally (amounts, account numbers, references) before submitting — a partially rejected bulk batch is more painful to reconcile than a pre-flight validation failure.

Response handling. The docs now explain the responseBody nesting convention. Standardise on a small helper or DTO that unwraps responseBody once, so your controllers and jobs do not repeatedly reach through nested arrays. Return your own consistent API responses rather than leaking Monnify's envelope to your frontend.

Integration tips. Bind the package client behind an interface if you plan to fake it in tests; use Http::fake() for feature tests around your own endpoints. Keep all Monnify calls inside jobs or service classes so retries and timeouts are explicit. Log the request reference, response code, and response body on every call — reconciliation during support incidents is dramatically easier.

Gotchas and Tips

  • responseBody nesting. Most confusion for new integrators comes from reading fields at the wrong level. Unwrap once at the boundary and pass clean data inward.
  • CSRF will silently break webhooks. If your webhook route is not excluded, Monnify receives a 419 and retries; you will see duplicate deliveries once fixed. Exclude the route and verify signatures instead.
  • Signature verification needs the raw body. Do not verify against a re-encoded JSON payload — read the raw request content and use the exact header Monnify sends.
  • Sandbox cards are scenario-specific. Use the 1.1.0 test card table deliberately: no-OTP, OTP, 3DS, and failure cards each exercise different branches. Test the failure and 3DS paths before release, not after.
  • Amounts and currency. Confirm whether the package expects major units (naira) or minor units for each endpoint, and be consistent. Off-by-100 errors are the classic Monnify integration bug.
  • Bills vend is not idempotent by default. Always persist your reference before calling, and requery rather than retrying a vend whose response you did not receive.
  • Requery, don't poll aggressively. In-progress transactions can take time; use backoff and stop after a defined window, then flag for manual review.
  • Optional destinationAccountName is optional for the API, not for your UI. If your product requires a beneficiary name for user confirmation, keep that validation in your form request layer.
  • PHP version. The package targets PHP 8.1+ and CI now statically verifies PHP 8.1 compatibility via PHPStan level 6. If you are on 8.1, you are supported; keep composer.lock platform constraints aligned if you deploy across mixed PHP versions.
  • Extension points. Publish and edit the config for base URLs, timeouts, and credentials; prefer config over hardcoding, and override the HTTP client/timeouts if you operate in high-latency environments.
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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console