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

Laravel Mesomb Laravel Package

malico/laravel-mesomb

A Laravel integration for the MeSomb payment API, offering straightforward configuration, service bindings, and convenient helpers for initiating mobile money payments and handling transactions in Laravel applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Read this first: release 1.6 is the final release of this package. It has been superseded by hachther/laravel-mesomb, which is maintained by the MeSomb team directly. New projects should start on the successor package; existing projects should treat 1.6 as a frozen dependency and budget a migration. Everything below applies equally well to both packages since the underlying MeSomb HTTP API and the general shape of the wrapper are the same.

Install and configure

  1. composer require <vendor>/laravel-mesomb (pin to 1.6.* — no further releases are coming).
  2. Publish the config: php artisan vendor:publish --tag=mesomb-config (tag name varies; check the service provider's publishes() call).
  3. Set the credentials in .env:
    • application key / API key
    • API secret / secret key
    • MESOMB_SANDBOX=true for development, false in production
  4. Clear cached config after editing: php artisan config:clear (a stale config:cache is the single most common "my keys aren't being picked up" cause).

Where to look first

  • config/mesomb.php — the canonical list of options, base URI, and credential names. Match your .env keys against this file rather than the README, which may lag behind.
  • The package's service provider — confirms which facade alias and which singleton binding are registered, and therefore what you can type-hint or app()->make().
  • The HTTP client class — this is where retries, timeouts, and error mapping live (or don't). Read it before you trust it in production.
  • README + CHANGELOG — 1.6 is the terminal entry; everything above it is your effective spec.
  • The package's tests/ directory (if present) — the fastest way to see real request/response payload shapes.

First use case

The archetypal first integration is a collection: request a payment from a customer's mobile money wallet (MTN MoMo / Orange Money) and reconcile the result. A minimal flow:

$response = Mesomb::makeCollect(
    amount: 1000,
    service: 'MTN',            // or 'ORANGE'
    payer: '2376XXXXXXXX',     // MSISDN with country code
    nonce: $payment->reference // your idempotency key
);

Then persist the returned transaction reference/id and immediately decide: do you trust the synchronous response, or do you poll getStatus() / wait for a webhook? For anything involving money, treat the synchronous response as acceptance, not settlement — see Gotchas.

Implementation Patterns

Wrap the package behind your own interface. This is the pattern that makes the 1.6 EOL announcement a non-event. Define a small contract in your app (PaymentGateway with collect(), disburse(), status()), bind the package-backed implementation in a service provider, and never reference the facade outside that one class. When you move to hachther/laravel-mesomb, you rewrite one adapter and nothing else.

Persist a local transaction record before you call out. Table with reference (your own UUID), provider_id, amount, currency, service, status, raw_response. Write the row first, then call the API, then update. This gives you idempotency, an audit trail, and a queue of "pending" transactions to reconcile after a crash or timeout.

Use your own nonce/reference for idempotency. Pass a stable per-attempt identifier rather than letting the package or the API generate one. If a request times out, you can safely re-query status by your reference instead of re-issuing a charge.

Reconcile asynchronously. Production pattern: controller creates the intent, dispatches a job, the job calls the gateway, then a scheduled command sweeps pending transactions older than N minutes and calls status() on each. This covers the very common case where MeSomb accepted the request but the customer never entered their PIN.

Webhooks (if the package exposes a handler). Point the callback route at a controller that: (1) locates the local transaction by reference, (2) re-fetches status from the API rather than trusting the payload body, (3) updates state inside a DB transaction, (4) returns 200 fast and does the rest on a queue. Always make webhook handling idempotent — providers retry.

Multi-environment config. Keep sandbox and live credentials in separate .env blocks and drive them via config('mesomb.sandbox') / a services entry. Never branch on app()->environment() inside business logic; branch on config so tests can flip it.

Testing. Http::fake() around the client is the cheapest approach: assert the outgoing payload shape and stub the response. Combined with the adapter interface, you can also bind a FakePaymentGateway for feature tests and keep the suite fully offline. Do not hit the sandbox in CI.

Migration path to the successor. Both packages wrap the same API, so the mapping is mostly mechanical: install hachther/laravel-mesomb, re-publish its config, copy credentials across, re-point your adapter, run your existing tests against Http::fake() stubs updated to the new namespace. Do it behind a feature flag so you can flip back per-environment.

Gotchas and Tips

EOL is the headline gotcha. 1.6 receives no security patches, no PHP/Laravel compatibility updates, and no bug fixes. Pin the version in composer.json, add a README/ticket noting the migration, and do not build new features on it. If you're on Laravel 12+ or PHP 8.4+, verify installability before committing — a dead package will not be updated for the next framework major.

Amounts are integers in minor-ish units. XAF has no decimal subdivision, but sending 10.00 or a float will produce confusing validation errors or silently wrong charges. Always pass int, and validate at the edge ($request->validate(['amount' => 'required|integer|min:100'])).

Phone numbers must be MSISDN with country code, typically 2376XXXXXXXX for Cameroon, no +, no spaces. A number that works in the sandbox with one format may fail live. Normalize in a single helper.

Never blindly retry a collection. A timeout does not mean failure — it means unknown. Retrying with a fresh nonce can double-charge the customer. Retry only status lookups; for charges, reconcile by reference.

Set explicit HTTP timeouts. Package defaults are often generous or absent. Wrap calls in ->timeout(...), and make sure your queue worker's --timeout exceeds it, otherwise the job is killed mid-request and you get an orphaned charge with no local record.

Error handling is inconsistent between transport and business failures. A network error throws; a declined payment often returns a 200 with a non-success status/code in the body. Handle both: catch transport exceptions and inspect the response object. Don't rely on HTTP status alone.

The synchronous response is not settlement. Treat SUCCESS on the initial call as "request accepted." Only your status check or webhook flips the transaction to paid.

Webhook payloads may not be signed in packages of this vintage. If there's no signature verification, the safe pattern is verify-by-refetch: on callback, call status() for that reference and use that answer. Also make sure the callback route is POST, excluded from CSRF, and not behind auth middleware.

Local webhook development requires a public URL (ngrok, expose, or Laravel Valet's share command). Document it in the team README — this trips up every new developer. Fall back to the status-sweep command while developing.

Sensitive data in logs. The package may log full request/response payloads including keys and phone numbers at debug level. Check config/logging.php in production and consider a redacting tap or setting the package's log channel to a null driver.

Config caching bites. After any .env or config/mesomb.php change: php artisan config:clear. In Docker, verify the env vars actually reach the container — env() calls inside package config files return null once config is cached.

Extension points worth knowing: the base URI is usually configurable (useful for pointing at a mock server in tests), the underlying Guzzle/HTTP client can be swapped via container binding if the package resolves it through the container, and the facade is typically a thin proxy — so Mesomb::shouldReceive(...) mocks work, but prefer the adapter interface over facade mocking to keep tests resilient.

Watch the fork, not this repo. Set a reminder to check hachther/laravel-mesomb's releases before your next major upgrade cycle; that's where fixes for anything you hit here will land.

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.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
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
adachsoft/php-code-style