Flutterwave

Lightweight, dependency-free, in-memory Flutterwave API v3 fake for testing code that uses the Flutterwave payments API.

Default port: 4874

Quick start

import { FlutterwaveServer } from "./services/flutterwave/src/server.js";

const server = new FlutterwaveServer(4874);
await server.start();
// ... run your app/tests ...
await server.stop();

All API routes require an Authorization: Bearer <secret-key> header (any non-empty value accepted):

const res = await fetch("http://127.0.0.1:4874/v3/payments", {
  method: "POST",
  headers: { Authorization: "Bearer FLWSECK_TEST-parlel", "Content-Type": "application/json" },
  body: JSON.stringify({ tx_ref: "ref-123", amount: 5000, currency: "NGN", customer: { email: "buyer@parlel.dev" } }),
});
// => { status: "success", message: "Hosted Link", data: { link } }

Access via MCP / preview URL

Reachable at its preview URL (http://127.0.0.1:4874) and through the parlel MCP server as the flutterwave tool. Set FLUTTERWAVE_BASE_URL=http://127.0.0.1:4874 and any non-empty FLUTTERWAVE_SECRET_KEY.

Implemented operations

Response envelope

{ "status": "success", "message": "...", "data": { ... } }

Errors use { "status": "error", "message": "...", "data": null }.

Surface coverage

This emulator faithfully replicates the API surface most application code and agents exercise. Anything below the supported lines is either an intentional design choice for a fast, zero-cost local emulator (✓ By design) or a candidate for a future release (⟳ Roadmap) — never a silent inaccuracy.

Legend: ✅ fully supported · ◐ accepted (stored, not strictly enforced) · ✓ by design · ⟳ on the roadmap.

FeatureStatus
Payment initiation (hosted link)✅ Supported
Transaction verification✅ Supported (always successful)
Transfers create / list / get✅ Supported
Banks list✅ Supported
Bearer auth✓ By design — Any non-empty credential is accepted — no real secrets needed
Real charge / settlement / payout processing✓ By design — Always succeeds deterministically — no real funds move
Webhooks / encryption (3DES) / OTP charge flow✓ By design — Always succeeds deterministically — no real funds move

Manifest

See services/flutterwave/manifest.json — name flutterwave, port 4874, protocol http, healthcheck /health, env FLUTTERWAVE_SECRET_KEY, FLUTTERWAVE_BASE_URL.

<!-- parlel:testenv:start -->

Configuration — test.env

Copy these into your test.env (used by the bridge sidecar flow). Tokens are Parlel's seeded test credentials — any non-empty value is accepted by the emulator, so you rarely need to change them. Swap in real credentials only when pointing at the live service in prod.env.

FLUTTERWAVE_SECRET_KEY=parlel
FLUTTERWAVE_BASE_URL=http://parlel-bridge:4874
<!-- parlel:testenv:end -->