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 Payment Laravel Package

abraham-flutterwave/laravel-payment

Laravel package for Flutterwave for Business v3 APIs, simplifying payments integration in Laravel apps. Supports card, account, mobile money, bank transfers, USSD, Barter, and NQR collections with quick API calls.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

This package is a thin, conventional Laravel integration: a service provider, a Flutterwave facade, a publishable config/flutterwave.php, a Blade view for the inline modal, and a set of pre-registered routes (checkout, callback, success, failed, cancel, webhook). It wraps Flutterwave for Business (F4B) v3 REST endpoints and exposes them as static facade calls plus convenience helpers (generateTransactionReference(), render('inline'|'standard', $payload), use('transactions'), use('webhooks')).

It fits a server-rendered Laravel monolith or a Blade-based checkout flow well. It fits poorly in three scenarios worth flagging up front:

  1. SPA / headless front ends. The inline modal is delivered as a Blade view (flutterwave::modal), so a Vue/React/Next front end can't consume it directly. Those teams would use render('standard') to redirect to a hosted Flutterwave page, or bypass the package and call the API directly — at which point the package's value drops to just webhook signature verification.
  2. Multi-tenant or multi-market SaaS. Business name, logo, country, currency, and enabled payment methods live in a single global config file. Per-tenant branding or per-market currency/rail selection requires runtime config mutation, which is fragile. This is the largest architectural constraint for a platform play.
  3. Laravel Octane / Swoole / RoadRunner. The documented webhook pattern uses Flutterwave::use('webhooks') followed by $webhook->getHook() — i.e., state stashed on a container singleton and read back in a second call. Under a long-lived worker, request-scoped state on singletons is a classic cross-request leak vector. Needs validation before any Octane migration.

A genuine positive: the package does not impose a schema. No migrations, no models, no transaction tables. Your order and ledger state stays yours. That is the right design for a payments wrapper and materially lowers lock-in.

Integration feasibility

Installation is a one-liner (composer require abraham-flutterwave/laravel-payment), config publish, four env vars, then a working sandbox checkout. For a competent Laravel developer, first successful sandbox payment is a 1–3 day task. Production-grade is not: realistically 2–4 weeks once you add idempotent webhook ingestion, amount/currency validation, reconciliation, refunds, and observability.

Feasibility blockers to resolve before committing:

  • Provenance of the "Official" claim. Packagist vendor is abraham-flutterwave, but the repository resolves to a personal GitHub account (bajoski34/Laravel) with 8 stars and 0 dependents. The README's support channels point to Flutterwave DX. This is consistent with a maintainer-rebranded community package rather than a first-party deliverable. Confirm canonical status with Flutterwave DX (email/Slack in README) before it appears in an architecture decision record.
  • vendor/ is committed to the repo. The README states this is intentional "for those who do not have composer installed." That is a reproducibility and supply-chain smell: committed vendor trees drift from composer.json, bloat clones, and defeat vulnerability scanning. It also implies the maintainer's CI is not standard.
  • Tests are not hermetic. The README instructs you to change account_number / account_bank / business email if subaccount tests fail, and warns tests may fail on OTP validation "depending on whether the service is down." These tests hit the live Flutterwave API. They cannot run in your CI, which means you get zero upstream regression signal on version bumps — every upgrade is a manual sandbox regression.
  • Release metadata anomaly. The last release is stamped 2026-10-15. Verify the tag actually exists on the repo and is signed/corresponds to the Packagist artifact; treat future-dated or mismatched provenance as a gate, not a footnote.

Technical risk register

Risk Severity Why Mitigation
Provenance / supply chain High Personal-account repo, no first-party confirmation, committed vendor dir Confirm with Flutterwave DX; pin commit SHA; mirror internally
Bus factor ≈ 1 High 8 stars, 0 dependents, single maintainer Fork under MIT; budget internal ownership
Webhook trust without amount validation High README sample validates signature + tx_ref + status only, not amount or currency Server-side compare amount/currency/customer to your order record before fulfilment
PCI scope ambiguity Medium FLW_ENCRYPTION_KEY implies direct card charge capability; inline modal keeps card data off your servers Decide SAQ A-EP (modal only) vs. full scope; do not store/transmit PANs
Non-hermetic test suite Medium No CI-grade signal; every bump is manual QA Build your own contract tests against sandbox
Octane/singleton state Medium use()/getHook() pattern holds per-request state Verify or forbid Octane on payment paths
Route registration Low–Med Package registers public routes by default (configurable since 2.1.0) Override all routes; apply auth, CSRF, rate-limit middleware explicitly
Refund/dispute tooling Medium Refunds exist in the API surface; no chargeback/dispute workflow, no console commands (listed as TODO) Build refund ops in-app; manage disputes in Flutterwave dashboard
Feature gaps Medium TODO list still names card, transfer, subaccount, plans, momo — i.e., payouts/marketplace/subscriptions are not shipped Scope to collections-only; plan marketplace payouts separately

Key questions for the maintainer / vendor

  1. Is this the canonical first-party Laravel SDK, and will bajoski34/Laravel be migrated into a Flutterwave-owned org with release signing?
  2. Which Laravel and PHP versions are actually tested in CI, and is there a published support matrix?
  3. Does the package use Illuminate\Support\Facades\Http (mockable via Http::fake) or raw Guzzle? This determines whether we can write hermetic tests.
  4. Is singleton state reset between requests, and is Octane supported?
  5. What is the deprecation/breaking-change policy for the v3 API sunset, and is there a v4 migration plan?
  6. Are refunds, partial refunds, and multi-currency settlement exposed, and are they covered by tests?
  7. What is the support SLA, if any, versus community-only Slack?

Integration Approach

Stack fit

Dimension Assessment
Framework Laravel 6+ through 12 (Laravel 12 added in 2.1.1); not validated for Lumen or Symfony standalone
PHP Floor of 7.3 (EOL Nov 2021) — treat as "runs on 8.1–8.3" and verify on your runtime
Front end Blade/modal-friendly; SPA requires hosted-link mode or direct API
Data layer No migrations shipped — your schema, your ledger
Async None shipped; queueing, retries, and reconciliation are your build
Observability A dedicated flutterwave log channel is documented; no metrics, no health checks
Multi-tenancy Weak — global config for branding, country, currency

Migration path

If you already run flutterwavedev/flutterwave-v3, kingflamez/laravelrave, or a hand-rolled Guzzle client, this is not a drop-in replacement. Different namespaces, different facade surface, different payload assembly, different webhook verification API. Plan a parallel-run cutover per rail, not a swap.

If you are greenfield, the sequencing below is the recommended path regardless — the adapter layer is what makes the choice reversible.

Reference architecture — always via an adapter

interface PaymentGateway {
    public function createCheckout(array $order): CheckoutSession;
    public function verify(string $reference): PaymentResult;
    public function refund(string $reference, int $amountMinor): RefundResult;
    public function handleWebhook(Request $request): WebhookEvent;
}

The package's facade is static, which means any direct call site is welded to it. Wrap it behind this interface so (a) domain code never imports Flutterwave\Payments\*, (b) you can add Paystack/Stripe for non-African markets without touching order logic, and (c) a fork or replacement is a single class change. This is the highest-leverage TPM decision in the whole evaluation.

Compatibility constraints to lock down

  • Pin an exact version ("abraham-flutterwave/laravel-payment": "2.1.1"), not a caret range. With a low release cadence and no upstream CI signal, minor bumps should be deliberate, tested events.
  • Confirm PHPUnit compatibility for your test runner — the upstream suite targets an unspecified PHPUnit version and live APIs.
  • Verify CSRF and middleware behavior on the package's POST checkout route, and confirm route overrides (2.1.0 feature) work as documented before relying on them.
  • Confirm sandbox vs. production switching via FLW_ENVIRONMENT is a hard boundary — mixed keys are a common cause of silent test-mode charges in production.

Sequencing and gates

Phase Work Exit criteria Est.
0. Due diligence Confirm provenance with Flutterwave DX; audit license, tags, vendor dir; review code for HTTP client and state handling Written approval in ADR; commit SHA pinned 3–5 days
1. Spike Sandbox integration on a throwaway branch; card + one mobile-money rail; inline and standard modal Successful end-to-end payment + webhook received and verified 1 week
2. Adapter PaymentGateway interface, FlutterwaveGateway, order/transaction state machine, idempotency table Domain code has zero direct package imports 1–2 weeks
3. Trust boundary Signature verification, replay/duplicate suppression, amount + currency + customer reconciliation against order, async job dispatch Pen-test-style adversarial cases pass (wrong amount, replayed payload, forged signature) 1 week
4. Resilience Reconciliation poller for missed webhooks, PENDING-state handling for USSD/mobile money, alerting on signature failures Documented recovery from dropped webhook without manual intervention 1 week
5. Pilot One market, one product line, capped volume, canary cohort 30 days clean; zero un-reconciled transactions; MTTR measured 4 weeks

Gate between 1 and 2: if due diligence fails or the spike reveals un-mockable HTTP or Octane incompatibility, fall back to direct F4B v3 integration and keep only the webhook-verification logic. The package's abstraction saves days, not months — do not treat it as load-bearing.


Operational Impact

Maintenance

Assign a named internal owner. Ongoing cost is modest but non-zero: roughly 2–4 days per quarter for version bumps, sandbox regression runs, and incident review. The maintenance signal is mixed — 2.1.1 adding Laravel 12 support shows someone is watching framework compatibility, but the TODO list (subaccounts, payouts, plans, console commands) reads as a roadmap that hasn't moved, and the vendor/-committed convention suggests non-standard release engineering. Assume you are the maintainer of last resort. MIT licensing makes an internal fork viable; budget for it in the business case rather than treating it as a contingency.

Support

Two distinct support surfaces, frequently conflated:

  • Package support — community Slack/email from the README, no SLA, thin community (8 stars). Response quality is unproven.
  • Merchant support — settlement delays, chargebacks, compliance/KYC holds, API outages. This is Flutterwave account-manager territory and is entirely independent of this package's health. Negotiate a commercial agreement with Flutterwave directly; the package confers no support entitlement.

Build an internal runbook covering: key rotation, sandbox/production key separation, webhook replay, manual reconciliation, refund execution, and escalation contacts. That runbook is worth more than the package.

Scaling

The SDK itself is not the bottleneck; the surrounding control plane is.

  • Webhook bursts — payment events arrive in spikes. Ingest fast (verify signature, persist raw payload, return 200), then process in a queued job. Never call verifyTransactionReference() synchronously inside the webhook handler as the README sample implies; that adds a third-party round-trip to your webhook latency and invites Flutterwave-side retries.
  • Idempotency store — dedupe on (tx_ref, flw_id). Plan archival; this table grows with every payment forever.
  • Verification API rate limits — reconciliation polling multiplies calls. Batch, back off, and index tx_ref.
  • Multi-currency — the config holds one default currency. Genuine multi-market support requires per-request currency and per-market rail enablement, which the package does not model. Confirm before promising multi-country in a roadmap.
  • Modal latency — inline mode adds a Blade render plus Flutterwave JS bootstrap; measure on low-bandwidth mobile networks, which is precisely the target demographic for mobile-money rails.

Failure modes

Failure Detection Blast radius Mitigation
Webhook never delivered Reconciliation job finds pending orders past TTL Orders stuck unfulfilled Poll verifyTransactionReference with backoff; alert on age
Duplicate webhook delivery Idempotency key collision Double fulfilment / double credit Unique constraint on (tx_ref, flw_id) + idempotent job
Signature mismatch verifySignature() returns false → 401 Flutterwave retries; events delayed Alert on 401 rate; verify raw body (not parsed JSON) against header
Amount/currency tampering Server-side comparison to order fails Revenue loss on underpriced fulfilment Hard-fail order if amount or currency ≠ expected
Callback races webhook Both paths attempt fulfilment Double processing Single idempotent fulfilment path shared by both
Mobile-money PENDING never resolves Status stuck for hours Unfulfilled high-intent orders Explicit pending state, customer comms, automated follow-up poll
Sandbox/live key mixup Test-mode charge in production logs Real revenue silently not collected Environment assertion at boot; separate credentials per environment
Route hijack / unauth access Unexpected POSTs to /flutterwave/payment/checkout Forged checkout initiations Override routes; auth, CSRF, rate-limit middleware
Upstream API outage 5xx / timeouts Checkout unavailable Circuit breaker, graceful degradation message, retry queue
Maintainer abandonment No release for N months Frozen framework compatibility Fork trigger defined in advance (e.g., no release in 9 months)

Ramp-up

Developer ramp-up is genuinely fast — Laravel devs read facades fluently and the README covers the happy path in ~200 lines. Expect 1–2 days to first payment. The real learning curve is payments domain literacy, not this package: idempotency, reconciliation, PCI scope, settlement vs. authorization, chargeback handling, and the fact that a signed webhook is a claim to be verified, not a fact. The README's sample webhook handler, which verifies signature and status but never compares the amount to the order, is the single most likely production incident source for a team that copies it.

Production-readiness checklist (definition of done before the first real naira/dollar):

  • Adapter layer in place; zero direct Flutterwave\Payments\* imports outside it
  • All package routes overridden with explicit middleware
  • Amount, currency, and customer reconciled against the order on every fulfilment
  • Idempotent, queued webhook ingestion with raw-body signature verification
  • Reconciliation poller for missed/pending webhooks, with alerting
  • Refund path implemented and tested (package exposes it; ops workflow does not)
  • Sandbox/production key separation asserted at boot
  • Log channel wired, signature-failure and reconciliation-gap alerts live
  • Runbook written; named owner assigned; fork trigger agreed
  • Contract tests in CI (mock HTTP layer) so version bumps are verifiable without live keys

TPM recommendation: conditionally adopt for a collections-only, single-market pilot with the adapter layer as a hard prerequisite. Do not standardize it as a platform dependency, do not use it for marketplace payouts or subscription plans (both still on the TODO list), and do not adopt it at all until Flutterwave DX confirms canonical ownership. The effort saved is real but measured in days; the bus-factor and provenance risk are measured in quarters.

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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin