Download the PHP package gowelle/flutterwave-php without Composer
On this page you can find all versions of the php package gowelle/flutterwave-php. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download gowelle/flutterwave-php
More information about gowelle/flutterwave-php
Files in gowelle/flutterwave-php
Package flutterwave-php
Short Description Modern Laravel package for Flutterwave v4 API integration
License MIT
Informations about the package flutterwave-php
Flutterwave - Laravel Wrapper
A comprehensive Laravel wrapper for Flutterwave Services API v4. This package provides a type-safe, feature-rich integration for Flutterwave payment processing with automatic retry logic, rate limiting, webhook verification, and comprehensive error handling.
Table of Contents
- Features
- Requirements
- Installation
- Quick Start
- Configuration
- Usage
- Direct Charges
- Payments
- Payment Methods
- Customers
- Orders
- Refunds
- Transfers/Payouts
- Settlements
- Banks
- Mobile Networks
- Virtual Accounts
- Wallets
- Chargebacks
- Fees
- UI Components
- Livewire Components
- Vue Components
- Localization
- Charge Sessions
- Events & Listeners
- Webhooks
- Error Handling
- Card Encryption
- Advanced Usage
- Retry Logic
- Rate Limiting
- Testing
- Troubleshooting
- Static Analysis
- Code Style
- Contributing
- License
- Support
- Changelog
Features
- Complete Flutterwave v4 API Support - Full coverage of Flutterwave's v4 API including payments, refunds, transfers, settlements, virtual accounts, wallets, and more
- Direct Charge Orchestrator - Simplified payment flow that combines customer, payment method, and charge creation in a single request
- Payment Methods Management - Create, list, and manage payment methods for customers
- Orders API - Complete order management with create, read, update, and list operations
- Bank Operations - Get banks by country, resolve bank accounts, and retrieve bank branches
- Mobile Networks Support - List mobile money networks by country for mobile payments
- Virtual Accounts - Create and manage virtual bank accounts for receiving payments with multi-currency support
- Wallets API - Resolve wallet accounts, retrieve transaction statements with pagination, and query balances for single or multiple currencies
- Charge Session Tracking - Database-backed tracking of charge sessions with automatic status updates via webhooks
- Event System - Laravel events for direct charge lifecycle and webhook processing
- Automatic Retry Logic - Exponential backoff for transient failures (5xx errors, rate limits, timeouts)
- Rate Limiting - Configurable per-request rate limiting to prevent API quota exhaustion
- Webhook Verification - Secure webhook signature validation with automatic event dispatching
- Type-Safe DTOs - Full TypeScript-like typing with PHP 8.3+ for better IDE support and fewer runtime errors
- Comprehensive Error Handling - Detailed error messages with categorization (validation, authentication, API errors)
- Database Migrations - Built-in migrations for charge session tracking
- Testing Ready - Full test suite with Pest framework and HTTP faking support
- Laravel Integration - Service provider, facade, and comprehensive configuration system
- UI Components - Pre-built Livewire and Vue/Inertia components for payment forms, PIN/OTP input, status display, and saved payment methods
Requirements
- PHP 8.3 or higher
- Laravel 11.0, 12.0, or 13.0
- Composer
- Flutterwave account with API credentials
Installation
Install the package via Composer:
The package will automatically register its service provider and facade.
Quick Start
- Publish the configuration file:
Or publish all package assets:
-
Configure your Flutterwave credentials in
.env: -
Verify your credentials:
- Retrieve your encryption key:
Get your encryption key from your Flutterwave dashboard under API Settings. You'll need this to encrypt card data before sending requests.
-
Run migrations (if using charge sessions):
- Start using the package:
Important: When making card charge requests, card data must be encrypted using AES-256-GCM encryption. See the Flutterwave Encryption Documentation for encryption requirements and PHP examples.
Configuration
The package is configured via config/flutterwave.php. After publishing, you can customize all settings:
API Credentials
Your Flutterwave API credentials can be found in your Flutterwave dashboard under Settings > API.
Environment
Set to 'staging' for testing or 'production' for live transactions.
API Settings
Rate Limiting
Configure rate limiting to prevent hitting Flutterwave API limits. The default allows 100 requests per 60 seconds.
Logging
Control logging behavior. Enable log_requests and log_responses for debugging API interactions.
Webhook Settings
Configure webhook handling. The package automatically registers a webhook route that verifies signatures and dispatches events.
Default Currency
Set the default currency for transactions if not specified in the request.
Charge Sessions
Configure charge session tracking:
enabled: Enable/disable charge session trackingauto_create: Automatically create sessions when direct charges are createdcleanup_after_days: Days before old sessions are cleaned upmax_polls: Maximum polling attempts for charge status
Cache Settings
Configure caching for frequently accessed data like access tokens, bank lists, and mobile networks.
Model Classes
Configure the model classes used by the ChargeSession model for relationships. These should be the fully qualified class names of your application's User and Payment models.
Environment Variables Reference
| Variable | Description | Default |
|---|---|---|
FLUTTERWAVE_CLIENT_ID |
Your Flutterwave client ID | - |
FLUTTERWAVE_CLIENT_SECRET |
Your Flutterwave client secret | - |
FLUTTERWAVE_SECRET_HASH |
Your webhook secret hash | - |
FLUTTERWAVE_ENCRYPTION_KEY |
Encryption key for card data | - |
FLUTTERWAVE_ENVIRONMENT |
Environment: staging or production |
staging |
FLUTTERWAVE_DEBUG |
Enable debug logging (dev only) | false |
FLUTTERWAVE_TIMEOUT |
Request timeout in seconds | 30 |
FLUTTERWAVE_MAX_RETRIES |
Maximum retry attempts | 3 |
FLUTTERWAVE_RETRY_DELAY |
Retry delay in milliseconds | 1000 |
FLUTTERWAVE_RATE_LIMIT_ENABLED |
Enable rate limiting | true |
FLUTTERWAVE_RATE_LIMIT_MAX |
Max requests per window | 100 |
FLUTTERWAVE_RATE_LIMIT_WINDOW |
Time window in seconds | 60 |
FLUTTERWAVE_LOGGING_ENABLED |
Enable logging | true |
FLUTTERWAVE_LOG_CHANNEL |
Log channel | stack |
FLUTTERWAVE_LOG_LEVEL |
Log level | info |
FLUTTERWAVE_LOG_REQUESTS |
Log API requests | false |
FLUTTERWAVE_LOG_RESPONSES |
Log API responses | false |
FLUTTERWAVE_WEBHOOK_VERIFY |
Verify webhook signatures | true |
FLUTTERWAVE_WEBHOOK_PATH |
Webhook route path | webhooks/flutterwave |
FLUTTERWAVE_DEFAULT_CURRENCY |
Default currency code | TZS |
FLUTTERWAVE_SESSION_CLEANUP_DAYS |
Days before session cleanup | 30 |
FLUTTERWAVE_SESSION_AUTO_CREATE |
Auto-create charge sessions | false |
FLUTTERWAVE_SESSION_MAX_POLLS |
Max polling attempts | 60 |
FLUTTERWAVE_CACHE_ENABLED |
Enable caching | true |
FLUTTERWAVE_USER_MODEL |
User model class | App\Models\User |
FLUTTERWAVE_PAYMENT_MODEL |
Payment model class | App\Domain\Payment\Models\Payment |
Usage
Direct Charges
The Direct Charge service uses Flutterwave's orchestrator endpoint to simplify the payment flow by combining customer, payment method, and charge creation in a single request.
Important: When making card charge requests, you must encrypt the card information before sending the request. Card data (card number, CVV, expiry month, expiry year) must be encrypted using AES-256-GCM encryption. See the Flutterwave Encryption Documentation for detailed encryption requirements and examples.
Creating a Direct Charge
Using DTO (type-safe):
Updating Charge Authorization
When a charge requires additional authorization (PIN, OTP, AVS), submit the authorization data:
Sandbox Scenario Keys for Authorization
In non-production environments, each AuthorizationData factory method accepts an optional scenarioKey parameter. Pass it to simulate specific authorization outcomes in the sandbox:
The scenario_key is forwarded as a header on the authorization request. It has no effect in production — only in staging/sandbox environments.
Checking Charge Status
Payments
The Payments service handles the traditional charge flow where you create customers and payment methods separately.
Processing a Payment
Payment Methods
Manage payment methods for customers.
List Payment Methods
Create Payment Method
Important: Card data must be encrypted using AES-256-GCM encryption before sending. See the Flutterwave Encryption Documentation for encryption requirements.
Get Payment Method
Customers
Manage customer records.
Create Customer
Per v4: Only
name,phone, andaddressare optional.phonemust be an object withcountry_code(ISO 3166 alpha-3) andnumber(7–10 digits without country code).
Using DTO (type-safe, v4-aligned):
Per Flutterwave v4, only email is required; name, phone, and address are optional. phone must be an object with country_code (ISO 3166 alpha-3) and number (7–10 digits without country code).
Update Customer
Per Flutterwave v4, only email is required.
Search Customer
Get Customer
List Customers
Orders
Manage orders for tracking purchases and payments. The Order API supports both a simple creation method (using existing customer and payment method IDs) and an orchestrator method (with inline customer and payment details).
Create Order (Simple)
Create an order using existing customer and payment method IDs:
Using DTO (type-safe):
Create Order with Orchestrator
Create an order with inline customer and payment method details:
Get Order
List Orders
List orders with optional filtering and pagination:
Available Order Statuses:
Update Order
Update order metadata or perform actions (void/capture):
Convenience methods:
Refunds
Process refunds for completed charges with type-safe DTOs and filtering.
Create Refund
Get Refund
List Refunds
List all refunds with optional pagination and date filtering:
Refund Reasons
The RefundReason enum provides type-safe reason values:
Refund Status
The RefundStatus enum tracks refund state:
Transfers/Payouts
Send money to bank accounts, mobile money wallets, or Flutterwave wallets.
Bank Transfer (Orchestrator)
The recommended approach - creates the recipient inline:
Mobile Money Transfer (Orchestrator)
Get Transfer
List Transfers
Retry Failed Transfer
Create Recipient
For the general flow, pre-create recipients. The SDK provides factory methods for all Flutterwave recipient types.
Simple Bank Recipients (account number + bank code only):
African Bank Recipients (with name):
African Bank Recipients (with name + branch):
International Bank Recipients (full KYC required):
Mobile Money Recipients (ETB, GHS, KES, RWF, TZS, UGX, XAF, XOF, ZMW):
Custom/New Types (use constructor directly):
Create Sender
The SDK supports all Flutterwave sender types:
Generic Sender (for most transfers):
GBP/EUR Bank Sender (requires full KYC for international transfers):
Delete Sender
Get Transfer Rate
General Flow Transfer
For the general flow, use pre-created recipient and sender IDs:
Settlements
Retrieve settlement information (read-only).
Get Settlement
List Settlements
Banks
Get bank information and resolve account details.
Get Banks by Country
Get Bank Branches
Resolve Bank Account
The bank account lookup payload varies by documented variant. The wrapper exposes explicit methods and DTO constructors for each supported schema.
NGN
USD bank account look up for NG accounts
GBP corporate
GBP individual
Using DTOs
Mobile Networks
Get mobile money networks by country.
List Mobile Networks
Wallets
Manage Flutterwave wallet operations including account lookup, statement retrieval, and balance queries.
Resolve Wallet Account
Verify wallet account information for a customer:
Get Wallet Statement
Retrieve wallet transaction statement with pagination and filtering:
Get Wallet Balance (Single Currency)
Fetch the available balance for a specific currency:
Get Wallet Balances (Multiple Currencies)
Fetch available balances for all currencies:
Virtual Accounts
Create and manage virtual bank accounts for receiving payments. Virtual account operations are now integrated into the Banks service for a unified banking experience.
Create Virtual Account
Create a virtual account for a specific customer using type-safe DTOs:
Retrieve Virtual Account
Get details of a specific virtual account:
List Virtual Accounts
List all virtual accounts:
List Virtual Accounts with Filters
List virtual accounts with pagination and filtering using DTOs:
Update Virtual Account
Update account status or BVN using DTOs:
Supported Currencies
Virtual accounts support the following currencies:
- NGN - Nigerian Naira
- GHS - Ghanaian Cedi
- EGP - Egyptian Pound (requires
customer_account_number) - KES - Kenyan Shilling (requires
customer_account_number) - MAD - Moroccan Dirham
- ZAR - South African Rand
Account Types
- STATIC - Permanent account that can be reused (amount should be 0)
- DYNAMIC - Temporary account for specific transaction (expires after configured duration)
Example: Complete Virtual Account Flow
Chargebacks
Manage dispute lifecycles including creating, retrieving, accepting, and declining chargebacks raised against charges.
List Chargebacks
Create a Chargeback
Accept a Chargeback
Decline a Chargeback
Retrieve a Chargeback
Fees
Fetch accurate fee information to predict transaction costs across paths and card brands.
Calculate Fees
UI Components
This package includes pre-built UI components for both Laravel Livewire and Vue/Inertia applications, enabling rapid payment form integration with client-side encryption.
Publishing Assets
Livewire Components
The package includes 5 Livewire components that are automatically registered when Livewire is installed.
Payment Form
A complete card payment form with client-side encryption:
Props:
amount(int) - Payment amount in minor unitscurrency(string) - 3-letter currency code (e.g., "TZS", "NGN", "KES")customer(array) - Customer details withemail,firstName,lastName,phoneredirectUrl(string) - Callback URL after payment
Events:
payment-success- Payment completed successfullypayment-error- Payment failedauthorization-required- PIN/OTP/redirect needed
PIN Input
Secure PIN authorization input with masked fields:
Props:
chargeId(string) - Direct charge ID requiring authorizationpinLength(int) - Number of PIN digits (default: 4)
OTP Input
OTP verification with resend countdown:
Props:
chargeId(string) - Direct charge ID requiring OTPlength(int) - OTP length (default: 6)resendCountdown(int) - Seconds before resend allowed (default: 60)
Payment Status
Real-time payment status display with polling:
Props:
chargeId(string) - Direct charge ID to monitorpollInterval(int) - Polling interval in milliseconds (default: 3000)autoPoll(bool) - Start polling automatically (default: true)
Payment Methods
List and manage saved payment methods:
Props:
customerId(string) - Customer ID to fetch methods forcurrency(string) - Currency to filter methods
Complete Livewire Payment Flow Example
Here's how to implement a complete payment flow in a Livewire component:
Blade Template:
Livewire Events Reference
All Livewire components dispatch events that you can listen to in parent components:
| Component | Event | Payload |
|---|---|---|
flutterwave-payment-form |
payment-success |
['id' => string, 'reference' => string, 'status' => string] |
flutterwave-payment-form |
payment-error |
string (error message) |
flutterwave-payment-form |
authorization-required |
['chargeId' => string, 'type' => string, 'redirectUrl' => ?string] |
flutterwave-pin-input |
pin-submitted |
['nonce' => string, 'encrypted_pin' => string] |
flutterwave-pin-input |
cancelled |
- |
flutterwave-otp-input |
otp-submitted |
string (OTP code) |
flutterwave-otp-input |
otp-resent |
- |
flutterwave-otp-input |
cancelled |
- |
flutterwave-payment-status |
status-updated |
['status' => string, 'charge' => array] |
flutterwave-payment-status |
payment-complete |
array (charge data) |
flutterwave-payment-methods |
method-selected |
string (method ID) |
flutterwave-payment-methods |
add-new-clicked |
- |
Vue Components
For Vue/Inertia applications, publish the components and import them:
Components will be published to resources/js/vendor/flutterwave/.
Payment Form (Vue)
PIN Input (Vue)
OTP Input (Vue)
Payment Status (Vue)
Payment Methods (Vue)
Client-Side Encryption
The Vue components include encryption utilities for secure card data handling:
Backend API Setup
The Vue components communicate with your backend via API endpoints. Add these routes to handle payment processing:
Example Controller:
Complete Payment Flow Example
Here's how to implement a complete payment flow using the Vue components together:
Detailed Props & Events Reference
PaymentForm Props
| Prop | Type | Default | Description |
|---|---|---|---|
amount |
number |
required | Payment amount in minor units |
currency |
string |
'TZS' |
3-letter ISO currency code |
reference |
string |
auto-generated | Unique payment reference |
redirectUrl |
string |
'' |
Callback URL after 3DS authorization |
customer |
object |
{} |
Pre-filled customer data |
meta |
object |
{} |
Custom metadata to attach |
encryptionKey |
string |
required | Flutterwave encryption key |
labels |
object |
{} |
Custom label overrides for i18n |
PaymentForm Events
| Event | Payload | Description |
|---|---|---|
success |
DirectChargeResponse |
Payment completed successfully |
failed |
DirectChargeResponse |
Payment failed/cancelled/timeout |
error |
string |
Error message for display |
requires-pin |
chargeId: string |
Card requires PIN |
requires-otp |
chargeId: string |
Card requires OTP |
requires-redirect |
url, chargeId |
Redirect needed for 3DS |
PinInput Props
| Prop | Type | Default | Description |
|---|---|---|---|
chargeId |
string |
required | Charge ID |
pinLength |
number |
4 |
PIN digit count |
encryptionKey |
string |
required | Encryption key |
labels |
object |
{} |
Label overrides |
OtpInput Props
| Prop | Type | Default | Description |
|---|---|---|---|
chargeId |
string |
required | Charge ID |
otpLength |
number |
6 |
OTP digit count |
maskedPhone |
string |
'' |
Phone to display |
labels |
object |
{} |
Label overrides |
PaymentStatus Props
| Prop | Type | Default | Description |
|---|---|---|---|
chargeId |
string |
required | Charge ID to monitor |
startPolling |
boolean |
false |
Start polling on mount |
pollInterval |
number |
3000 |
Poll interval (ms) |
maxPolls |
number |
60 |
Max attempts before timeout |
useFlutterwave Composable
For custom payment implementations, use the useFlutterwave composable:
Styling & Customization
All components use scoped CSS with .flw- prefixed class names.
Key CSS Classes:
| Class | Element |
|---|---|
.flw-payment-form |
Form container |
.flw-input |
Input fields |
.flw-btn-primary |
Primary buttons |
.flw-alert-error |
Error messages |
.flw-pin-box |
PIN digit inputs |
.flw-otp-box |
OTP digit inputs |
Override Example:
Localization
The package includes built-in support for multiple languages. Currently supported languages:
- English (
en) - Default - Swahili (
sw) - French (
fr)
Publishing Translations
To customize the translation strings, publish the language files:
This will publish the files to resources/lang/vendor/flutterwave.
Using in Vue Components
All Vue components accept a labels prop to override specific text:
Charge Sessions
Charge Sessions provide database-backed tracking of direct charge transactions. This feature is particularly useful for tracking charges that require multiple authorization steps (PIN, OTP, redirects).
Features
- Automatic status updates via webhooks
- Event-driven session creation and updates
- Relationship tracking with User and Payment models
- Metadata storage for custom data
- Automatic cleanup of old sessions
Enabling Charge Sessions
-
Publish and run the migration:
- Configure in
config/flutterwave.php:
Using Charge Sessions
Automatic Creation
When auto_create is enabled, sessions are automatically created when direct charges are created:
Manual Creation
You can also create sessions manually:
Querying Sessions
Updating Sessions
Sessions are automatically updated via webhooks when enabled is true. You can also update them manually:
Session Cleanup
Run the cleanup command to remove old sessions:
Or schedule it in your app/Console/Kernel.php:
Events & Listeners
The package dispatches Laravel events for important actions, allowing you to hook into the payment flow.
Available Events
FlutterwaveChargeCreated
Dispatched when a direct charge is created:
FlutterwaveChargeUpdated
Dispatched when charge authorization is submitted:
FlutterwaveTransferCreated
Dispatched when a transfer is created (bank, mobile money, or wallet):
FlutterwaveWebhookReceived
Dispatched when a webhook is received and verified:
Built-in Listeners
The package includes built-in listeners that are automatically registered:
- CreateChargeSession - Creates charge sessions when
auto_createis enabled - UpdateChargeSession - Updates charge sessions when authorization is submitted
- UpdateChargeSessionFromWebhook - Updates charge sessions from webhook events
You can disable these by setting the appropriate configuration options.
Custom Event Listeners
Create your own event listeners:
Register in app/Providers/EventServiceProvider.php:
Webhooks
The package includes automatic webhook handling with signature verification and event dispatching.
Using the Built-in Webhook Route
The package automatically registers a webhook route at /webhooks/flutterwave (configurable via FLUTTERWAVE_WEBHOOK_PATH). This route:
- Verifies the webhook signature
- Dispatches the
FlutterwaveWebhookReceivedevent - Returns a 200 response
Configure the webhook URL in your Flutterwave dashboard to point to:
Listening to Webhook Events
You can listen to webhook events and process them based on the event type. The package provides both string-based and enum-based methods for type safety.
Using String Event Types (Backward Compatible)
Using WebhookEventType Enum (Recommended)
For better type safety, use the WebhookEventType enum:
WebhookEventType Enum
The WebhookEventType enum provides type-safe webhook event handling with helper methods:
Available Event Types:
CHARGE_COMPLETED- Charge completed eventCHARGE_FAILED- Charge failed eventCHARGE_SUCCESSFUL- Charge successful eventPAYMENT_COMPLETED- Payment completed eventPAYMENT_FAILED- Payment failed eventPAYMENT_SUCCESSFUL- Payment successful eventTRANSFER_COMPLETED- Transfer completed event
Helper Methods:
fromString(?string $event): ?self- Convert string to enum (returns null for unknown types)isPaymentEvent(): bool- Check if event is payment-related (charge. or payment.)isTransferEvent(): bool- Check if event is transfer-related (transfer.*)isChargeEvent(): bool- Check if event is charge-related (charge.*)isSuccessful(): bool- Check if event indicates success
Example Usage:
Manual Webhook Verification
If you need to verify webhooks manually (e.g., in a custom route):
Note: Flutterwave sends the signature in the flutterwave-signature header, which is automatically handled by the verifyRequest method.
Error Handling
All API calls throw FlutterwaveException on error. The exception provides detailed information about the error:
Error Types
- ValidationError - Invalid request data (400)
- AuthenticationError - Invalid credentials (401)
- RateLimitError - Too many requests (429)
- ApiError - Other API errors (500, 502, 503, etc.)
Card Encryption
Critical: When making card charge requests, you must encrypt all card data using AES-256-GCM encryption before sending to Flutterwave.
Encryption Implementation Guide
For a complete encryption implementation guide with examples, security best practices, and integration patterns, see ENCRYPTION_IMPLEMENTATION.md.
Quick Start - Using ChargeRequestBuilder
The simplest way to handle card encryption is using the ChargeRequestBuilder. It returns a type-safe DirectChargeRequestDTO:
Using ChargeRequestBuilder with Different Payment Methods
The builder supports multiple payment methods:
Card Payments:
Mobile Money:
Bank Account:
With Additional Options:
Manual Encryption
For more control, use the EncryptionService directly:
Type-Safe DTOs
The ChargeRequestBuilder returns a DirectChargeRequestDTO for type safety:
Available DTOs:
- DirectChargeRequestDTO - Direct charge orchestrator requests
- ChargeRequestDTO - Traditional charge flow requests
Key Features
- AES-256-GCM Encryption - Industry-standard authenticated encryption
- Automatic Nonce Generation - Cryptographically secure 12-character nonces
- Input Validation - Validates card data before encryption
- Base64 Encoding - Safe transmission of binary data
- Zero Plaintext - Card data never exposed in request payloads
For detailed documentation including security best practices, error handling, and advanced usage, see ENCRYPTION_IMPLEMENTATION.md.
Advanced Usage
Card Data Encryption (Advanced)
Critical: When making card charge requests, you must encrypt all card data (card number, CVV, expiry month, expiry year) using AES-256-GCM encryption before sending the request to Flutterwave.
Encryption Requirements
- Retrieve your encryption key from your Flutterwave dashboard under API Settings
- Use AES-256-GCM encryption with a 12-character nonce
- Base64 encode the encrypted data
- Include the nonce in your request
Encryption Process
- Generate a cryptographically secure random 12-character nonce (alphanumeric)
- Encrypt each card field (card number, CVV, expiry month, expiry year) using:
- Algorithm: AES-256-GCM
- Key: Your encryption key from Flutterwave dashboard (base64 decoded)
- IV/Nonce: The 12-character nonce
- Base64 encode the encrypted result
- Include both the nonce and encrypted fields in your request
Example Request Structure
PHP Encryption Example
For PHP, you can use OpenSSL or libsodium. Here's a basic example using OpenSSL:
Reference: For detailed encryption documentation, examples, and best practices, see the Flutterwave Encryption Documentation.
Error Handling
If you send unencrypted or improperly encrypted card details, Flutterwave will return a 422 error:
Idempotency Keys
Use idempotency keys to safely retry requests:
For charge requests, if you omit idempotency_key, the package uses order_id when present. If neither value is provided, a UUID is generated automatically.
Trace IDs
Trace IDs help track requests across systems:
Custom Retry Strategies
The package automatically retries on transient failures. You can customize retry behavior:
Rate Limiting Customization
Adjust rate limiting based on your needs:
Direct Service Access
Access services directly without the facade:
Dependency Injection
Inject services into your classes:
Retry Logic
The package automatically retries failed requests with exponential backoff for:
- 5xx server errors
- 429 rate limit errors
- 408 timeout errors
- 503 service unavailable
Configuration
Configure retry behavior in .env:
The retry delay doubles with each attempt (exponential backoff).
Rate Limiting
Rate limiting prevents hitting Flutterwave API quotas. It's enabled by default and limits requests per time window.
Configuration
When the limit is reached, requests will wait until the window resets or throw a RateLimitException.
Testing
The package is fully testable using Laravel's HTTP faking capabilities.
Running Tests
Example Test
Testing Webhooks
Troubleshooting
Common Issues
Authentication Errors
Problem: 401 Unauthorized errors
Solutions:
- Verify your
FLUTTERWAVE_CLIENT_IDandFLUTTERWAVE_CLIENT_SECRETare correct - Check that credentials match your environment (staging vs production)
- Ensure credentials haven't been rotated in Flutterwave dashboard
Webhook Verification Failures
Problem: Webhook signature verification fails
Solutions:
- Verify
FLUTTERWAVE_SECRET_HASHmatches your webhook secret in Flutterwave dashboard - Ensure the webhook route is accessible (not behind authentication)
- Check that the
flutterwave-signatureheader is being received
Rate Limit Errors
Problem: 429 Too Many Requests errors
Solutions:
- Increase
FLUTTERWAVE_RATE_LIMIT_MAX_REQUESTSif you have higher quotas - Implement request queuing for high-volume operations
- Use caching for frequently accessed data (banks, networks)
Charge Status Not Updating
Problem: Charge sessions not updating from webhooks
Solutions:
- Verify
charge_sessions.enabledistruein config - Check that webhook route is properly configured
- Ensure webhook events are being received (check logs)
- Verify database migrations have been run
Timeout Errors
Problem: Requests timing out
Solutions:
- Increase
FLUTTERWAVE_TIMEOUTvalue - Check network connectivity to Flutterwave API
- Verify firewall rules allow outbound connections
Debugging
Enable detailed logging:
Check logs in storage/logs/laravel.log for detailed API interactions.
Testing in Different Environments
Always test in staging before moving to production:
Sandbox Scenario Keys
Flutterwave's sandbox API uses scenario_key headers to simulate different charge outcomes without needing real card data. No scenario key is applied by default — you must pass one explicitly when you want to control the sandbox outcome.
For charge authorization, pass scenarioKey to any AuthorizationData factory method:
For the initial charge request, pass scenario_key in the data array:
Note: Scenario keys are ignored in production environments.
Static Analysis
Run PHPStan for type checking:
For lower-resource systems, adjust the memory limit:
Code Style
Format code with Laravel Pint:
Contributing
Contributions are welcome! Please ensure:
- Tests pass:
vendor/bin/pest - Code style:
vendor/bin/pint - Type safety:
vendor/bin/phpstan analyse
License
MIT License. See LICENSE file for details.
Support
For issues and questions, please visit GitHub Issues.
Changelog
See CHANGELOG.md for detailed version history.
All versions of flutterwave-php with dependencies
illuminate/contracts Version ^11.0|^12.0|^13.0
illuminate/database Version ^11.0|^12.0|^13.0
illuminate/http Version ^11.0|^12.0|^13.0
illuminate/support Version ^11.0|^12.0|^13.0
illuminate/validation Version ^11.0|^12.0|^13.0
spatie/laravel-package-tools Version ^1.93