PHP code example of gowelle / flutterwave-php
1. Go to this page and download the library: Download gowelle/flutterwave-php library . Choose the download type require .
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
gowelle / flutterwave-php example snippets
use Gowelle\Flutterwave\Facades\Flutterwave;
// Create a direct charge
// NOTE: Card data shown below must be encrypted before sending
// See: https://developer.flutterwave.com/docs/encryption
$charge = Flutterwave::directCharge()->create([
'amount' => 1000,
'currency' => 'TZS',
'reference' => 'ORDER-123',
'customer' => [
'email' => '[email protected] ', // Required
'name' => [
'first' => 'John', // Required
'last' => 'Doe', // Required
],
'phone_number' => '+255123456789', // Required
],
'payment_method' => [
'type' => 'card',
'card' => [
'nonce' => 'RANDOMLY_GENERATED_12_CHAR_NONCE',
'encrypted_card_number' => 'BASE64_ENCRYPTED_CARD_NUMBER',
'encrypted_cvv' => 'BASE64_ENCRYPTED_CVV',
'encrypted_expiry_month' => 'BASE64_ENCRYPTED_EXPIRY_MONTH',
'encrypted_expiry_year' => 'BASE64_ENCRYPTED_EXPIRY_YEAR',
],
],
'redirect_url' => 'https://example.com/callback',
]);
'client_id' => env('FLUTTERWAVE_CLIENT_ID'),
'client_secret' => env('FLUTTERWAVE_CLIENT_SECRET'),
'secret_hash' => env('FLUTTERWAVE_SECRET_HASH'),
'environment' => env('FLUTTERWAVE_ENVIRONMENT', 'staging'),
'timeout' => env('FLUTTERWAVE_TIMEOUT', 30), // Request timeout in seconds
'max_retries' => env('FLUTTERWAVE_MAX_RETRIES', 3), // Maximum retry attempts
'retry_delay' => env('FLUTTERWAVE_RETRY_DELAY', 1000), // Retry delay in milliseconds
'rate_limit' => [
'enabled' => env('FLUTTERWAVE_RATE_LIMIT_ENABLED', true),
'max_requests' => env('FLUTTERWAVE_RATE_LIMIT_MAX', 100),
'per_seconds' => env('FLUTTERWAVE_RATE_LIMIT_WINDOW', 60),
],
'logging' => [
'enabled' => env('FLUTTERWAVE_LOGGING_ENABLED', true),
'channel' => env('FLUTTERWAVE_LOG_CHANNEL', 'stack'),
'level' => env('FLUTTERWAVE_LOG_LEVEL', 'info'),
'log_requests' => env('FLUTTERWAVE_LOG_REQUESTS', false),
'log_responses' => env('FLUTTERWAVE_LOG_RESPONSES', false),
],
'webhook' => [
'verify_signature' => env('FLUTTERWAVE_WEBHOOK_VERIFY', true),
'route_path' => env('FLUTTERWAVE_WEBHOOK_PATH', 'webhooks/flutterwave'),
'route_name' => 'flutterwave.webhook',
'middleware' => ['api'],
],
'default_currency' => env('FLUTTERWAVE_DEFAULT_CURRENCY', 'TZS'),
'charge_sessions' => [
'enabled' => true,
'table_name' => 'flutterwave_charge_sessions',
'cleanup_after_days' => env('FLUTTERWAVE_SESSION_CLEANUP_DAYS', 30),
'auto_create' => env('FLUTTERWAVE_SESSION_AUTO_CREATE', false),
'max_polls' => env('FLUTTERWAVE_SESSION_MAX_POLLS', 60),
],
'cache' => [
'enabled' => env('FLUTTERWAVE_CACHE_ENABLED', true),
'prefix' => 'flutterwave',
'ttl' => [
'access_token' => 3600, // 1 hour (managed by auth service)
'banks' => 86400, // 24 hours
'mobile_networks' => 86400, // 24 hours
],
],
'models' => [
'user' => env('FLUTTERWAVE_USER_MODEL', 'App\Models\User'),
'payment' => env('FLUTTERWAVE_PAYMENT_MODEL', 'App\Domain\Payment\Models\Payment'),
],
use Gowelle\Flutterwave\Facades\Flutterwave;
use Gowelle\Flutterwave\Exceptions\FlutterwaveException;
try {
// IMPORTANT: Card data must be encrypted before sending
// Retrieve your encryption key from Flutterwave dashboard > API Settings
// Use AES-256-GCM encryption with a 12-character nonce
// See: https://developer.flutterwave.com/docs/encryption
$charge = Flutterwave::directCharge()->create([
'amount' => 10000, // Amount in smallest currency unit (e.g., cents)
'currency' => 'TZS', // Currency code
'reference' => 'ORDER-123', // Your unique reference
'customer' => [
'email' => '[email protected] ',
'name' => [
'first' => 'John',
'last' => 'Doe',
],
'phone_number' => '+255123456789',
],
'payment_method' => [
'type' => 'card',
'card' => [
'nonce' => 'RANDOMLY_GENERATED_12_CHAR_NONCE',
'encrypted_card_number' => 'BASE64_ENCRYPTED_CARD_NUMBER',
'encrypted_cvv' => 'BASE64_ENCRYPTED_CVV',
'encrypted_expiry_month' => 'BASE64_ENCRYPTED_EXPIRY_MONTH',
'encrypted_expiry_year' => 'BASE64_ENCRYPTED_EXPIRY_YEAR',
],
],
'redirect_url' => 'https://example.com/callback',
'meta' => [
'order_id' => '12345',
'user_id' => '67890',
],
]);
// Check charge status
if ($charge->status->isSuccessful()) {
// Payment succeeded
} elseif ($charge->status->
use Gowelle\Flutterwave\Data\DirectCharge\CreateDirectChargeRequest;
use Gowelle\Flutterwave\Facades\Flutterwave;
$request = CreateDirectChargeRequest::make(
amount: 10000,
currency: 'NGN',
reference: 'ORDER-' . uniqid(),
customer: [
'email' => '[email protected] ',
'name' => [
'first' => 'John',
'last' => 'Doe',
],
'phone_number' => '+2341234567890',
],
paymentMethod: [
'type' => 'card',
'card' => [
'nonce' => 'RANDOMLY_GENERATED_12_CHAR_NONCE',
'encrypted_card_number' => 'BASE64_ENCRYPTED_CARD_NUMBER',
'encrypted_cvv' => 'BASE64_ENCRYPTED_CVV',
'encrypted_expiry_month' => 'BASE64_ENCRYPTED_EXPIRY_MONTH',
'encrypted_expiry_year' => 'BASE64_ENCRYPTED_EXPIRY_YEAR',
],
],
redirectUrl: 'https://example.com/callback',
meta: ['order_id' => '12345'],
);
$charge = Flutterwave::directCharge()->createFromDto($request);
// Access charge details including new fields
echo $charge->fees; // Transaction fees
echo $charge->settlementId; // Settlement ID
$charge->isSettled(); // Check if settled
$charge->isDisputed(); // Check if disputed
use Gowelle\Flutterwave\Data\AuthorizationData;
use Gowelle\Flutterwave\Enums\NextActionType;
// For PIN authorization
$authorization = AuthorizationData::createPin(
nonce: $nonce, // Nonce from Flutterwave
encryptedPin: $encryptedPin // Encrypted PIN
);
// For OTP authorization
$authorization = AuthorizationData::createOtp(
code: $otpCode // OTP code from customer
);
// For AVS (Address Verification System)
$authorization = AuthorizationData::createAvs([
'line1' => '123 Main St',
'city' => 'Dar es Salaam',
'state' => 'Dar es Salaam',
'country' => 'TZ',
'postal_code' => '11101',
]);
// Submit authorization
$updatedCharge = Flutterwave::directCharge()->updateChargeAuthorization(
chargeId: $charge->id,
authorizationData: $authorization
);
// Check if charge is now complete
if ($updatedCharge->status->isSuccessful()) {
// Payment completed successfully
} elseif ($updatedCharge->status->
// PIN + OTP flow
$authorization = AuthorizationData::createPin(
nonce: $nonce,
encryptedPin: $encryptedPin,
scenarioKey: 'scenario:auth_pin'
);
// OTP-only step (after PIN was submitted)
$authorization = AuthorizationData::createOtp(
code: $otpCode,
scenarioKey: 'scenario:auth_pin'
);
// AVS flow
$authorization = AuthorizationData::createAvs(
address: ['line1' => '123 Main St', 'city' => 'Lagos', 'country' => 'NG'],
scenarioKey: 'scenario:auth_avs'
);
$updatedCharge = Flutterwave::directCharge()->updateChargeAuthorization(
chargeId: $charge->id,
authorizationData: $authorization
);
use Gowelle\Flutterwave\Enums\DirectChargeStatus;
$status = Flutterwave::directCharge()->status('charge-id');
if ($status->isSuccessful()) {
// Payment succeeded
} elseif ($status->isTerminal()) {
// Payment failed, cancelled, or timed out
} else {
// Payment is pending or
use Gowelle\Flutterwave\Facades\Flutterwave;
// Process a payment with callback for trace ID
$payment = Flutterwave::payments()->process([
'amount' => 1000,
'currency' => 'TZS',
'reference' => 'ORDER-123',
'customer_id' => 'CUST-456',
'payment_method_id' => 'PM-789',
'payment_method_type' => 'card',
'redirect_url' => 'https://example.com/callback',
], function ($traceId) {
// Callback executed when charge is successfully created
logger()->info('Charge created', ['trace_id' => $traceId]);
});
// Get payment status
$status = Flutterwave::payments()->status('charge-id');
$methods = Flutterwave::payments()->methods([
'customer_id' => 'CUST-456',
'currency' => 'TZS',
]);
// IMPORTANT: Card data must be encrypted before sending
// Retrieve your encryption key from Flutterwave dashboard > API Settings
// Use AES-256-GCM encryption with a 12-character nonce
// See: https://developer.flutterwave.com/docs/encryption
$paymentMethod = Flutterwave::payments()->createMethod([
'customer_id' => 'CUST-456',
'type' => 'card',
'card' => [
'nonce' => 'RANDOMLY_GENERATED_12_CHAR_NONCE',
'encrypted_card_number' => 'BASE64_ENCRYPTED_CARD_NUMBER',
'encrypted_cvv' => 'BASE64_ENCRYPTED_CVV',
'encrypted_expiry_month' => 'BASE64_ENCRYPTED_EXPIRY_MONTH',
'encrypted_expiry_year' => 'BASE64_ENCRYPTED_EXPIRY_YEAR',
],
]);
$paymentMethod = Flutterwave::payments()->getMethod('payment-method-id');
$customer = Flutterwave::customers()->create([
'email' => '[email protected] ', // Required
'name' => [
'first' => 'John',
'middle' => 'Michael', // Optional
'last' => 'Doe',
],
'phone' => [
'country_code' => 'TZA',
'number' => '712345678',
],
]);
use Gowelle\Flutterwave\Data\Customer\CreateCustomerRequest;
// Minimal (email only)
$request = new CreateCustomerRequest(email: '[email protected] ');
// With name, phone object, and optional address
$request = new CreateCustomerRequest(
email: '[email protected] ',
firstName: 'John',
lastName: 'Doe',
phone: ['country_code' => 'TZA', 'number' => '712345678'],
middleName: 'Michael', // optional
address: [ // optional: line1, line2?, city, state, postal_code, country
'line1' => '221B Baker Street',
'city' => 'London',
'state' => 'England',
'postal_code' => 'NW1 6XE',
'country' => 'GB',
],
);
$customer = Flutterwave::customers()->createFromDto($request);
use Gowelle\Flutterwave\Data\Customer\UpdateCustomerRequest;
$request = new UpdateCustomerRequest(
email: '[email protected] ',
firstName: 'John',
lastName: 'Doe',
phone: ['country_code' => 'TZA', 'number' => '987654321'],
address: [ /* optional */ ],
);
$customer = Flutterwave::customers()->updateFromDto('customer-id', $request);
use Gowelle\Flutterwave\Data\Customer\SearchCustomerRequest;
$request = new SearchCustomerRequest(email: '[email protected] ');
$customer = Flutterwave::customers()->searchFromDto($request);
$customer = Flutterwave::customers()->get('customer-id');
$customers = Flutterwave::customers()->list([
'page' => 1,
'limit' => 20,
]);
use Gowelle\Flutterwave\Facades\Flutterwave;
$order = Flutterwave::orders()->create([
'amount' => 10000,
'currency' => 'NGN',
'reference' => 'ORDER-' . uniqid(), // 6-42 chars, unique
'customer_id' => 'cust_abc123',
'payment_method_id' => 'pm_xyz789',
'meta' => ['order_type' => 'subscription'], // optional
'redirect_url' => 'https://example.com/callback', // optional
]);
use Gowelle\Flutterwave\Data\Order\CreateOrderRequest;
$request = CreateOrderRequest::make(
amount: 10000.00,
currency: 'NGN',
reference: 'ORDER-' . uniqid(),
customerId: 'cust_abc123',
paymentMethodId: 'pm_xyz789',
meta: ['source' => 'api'], // optional
redirectUrl: 'https://example.com/callback', // optional
);
$order = Flutterwave::orders()->createFromDto($request);
use Gowelle\Flutterwave\Data\Order\CreateOrchestratorOrderRequest;
$request = CreateOrchestratorOrderRequest::make(
amount: 10000.00,
currency: 'NGN',
reference: 'ORDER-' . uniqid(),
customer: [
'email' => '[email protected] ',
'name' => [
'first' => 'John',
'last' => 'Doe',
],
'phone' => '+2341234567890',
],
paymentMethod: [
'type' => 'card',
'card' => [
'nonce' => 'RANDOM_12_CHAR',
'encrypted_card_number' => 'ENCRYPTED_DATA',
'encrypted_cvv' => 'ENCRYPTED_DATA',
'encrypted_expiry_month' => 'ENCRYPTED_DATA',
'encrypted_expiry_year' => 'ENCRYPTED_DATA',
],
],
meta: ['order_type' => 'subscription'], // optional
redirectUrl: 'https://example.com/callback', // optional
);
$order = Flutterwave::orders()->createWithOrchestrator($request);
$order = Flutterwave::orders()->retrieve('order-id');
use Gowelle\Flutterwave\Data\Order\ListOrdersRequest;
use Gowelle\Flutterwave\Data\Order\OrderStatus;
// List all orders (default pagination)
$orders = Flutterwave::orders()->list();
// List with filters
$request = new ListOrdersRequest(
status: OrderStatus::Completed, // Filter by status
from: new DateTime('2024-01-01'), // Start date
to: new DateTime('2024-12-31'), // End date
customerId: 'cust_abc123', // Filter by customer
paymentMethodId: 'pm_xyz789', // Filter by payment method
page: 1, // Page number (>=1)
size: 20, // Results per page (10-50)
);
$orders = Flutterwave::orders()->listWithFilters($request);
use Gowelle\Flutterwave\Data\Order\OrderStatus;
OrderStatus::Completed // Order completed successfully
OrderStatus::Pending // Order is pending
OrderStatus::Authorized // Order is authorized, awaiting capture
OrderStatus::PartiallyCompleted // Partially completed
OrderStatus::Voided // Order was voided
OrderStatus::Failed // Order failed
use Gowelle\Flutterwave\Data\Order\UpdateOrderRequest;
use Gowelle\Flutterwave\Data\Order\OrderAction;
// Update with metadata only
$request = UpdateOrderRequest::withMeta(['updated' => true]);
$order = Flutterwave::orders()->updateFromDto('order-id', $request);
// Void an order
$request = UpdateOrderRequest::void(['reason' => 'Customer cancelled']);
$order = Flutterwave::orders()->updateFromDto('order-id', $request);
// Capture an authorized order
$request = UpdateOrderRequest::capture();
$order = Flutterwave::orders()->updateFromDto('order-id', $request);
// Void an order directly
$order = Flutterwave::orders()->void('order-id', ['reason' => 'Cancelled']);
// Capture an authorized order directly
$order = Flutterwave::orders()->capture('order-id');
use Gowelle\Flutterwave\Data\Refund\CreateRefundRequest;
use Gowelle\Flutterwave\Enums\RefundReason;
// Create a refund with DTO (type-safe)
$refund = Flutterwave::refunds()->create(
new CreateRefundRequest(
amount: 500.00,
chargeId: 'charge-123',
reason: RefundReason::REQUESTED_BY_CUSTOMER,
meta: ['note' => 'Customer requested refund'], // optional
)
);
// Check refund status
if ($refund->isSuccessful()) {
// Refund succeeded
} elseif ($refund->isPending()) {
// Refund is processing
}
$refund = Flutterwave::refunds()->get('refund-id');
// Access refund properties with type safety
echo $refund->amountRefunded; // Float
echo $refund->status->value; // String via enum
echo $refund->status->isSuccessful(); // Boolean
use Gowelle\Flutterwave\Data\Refund\ListRefundsRequest;
// List all refunds (default page=1, size=10)
$refunds = Flutterwave::refunds()->list();
// List with custom pagination
$refunds = Flutterwave::refunds()->list(
new ListRefundsRequest(page: 2, size: 20)
);
// List refunds within date range
$refunds = Flutterwave::refunds()->list(
new ListRefundsRequest(
page: 1,
size: 50,
from: now()->subDays(30),
to: now(),
)
);
// Access refund data
foreach ($refunds as $refund) {
echo $refund->id;
echo $refund->chargeId;
echo $refund->amountRefunded;
echo $refund->status->value;
echo $refund->reason;
}
use Gowelle\Flutterwave\Enums\RefundReason;
RefundReason::DUPLICATE // Duplicate charge
RefundReason::FRAUDULENT // Fraudulent transaction
RefundReason::REQUESTED_BY_CUSTOMER // Customer requested
RefundReason::EXPIRED_UNCAPTURED_CHARGE // Expired uncaptured charge
use Gowelle\Flutterwave\Enums\RefundStatus;
RefundStatus::NEW // Refund created, not yet processed
RefundStatus::PENDING // Refund is being processed
RefundStatus::SUCCEEDED // Refund completed successfully
RefundStatus::FAILED // Refund failed
// Use helper methods for type-safe checks
$refund->status->isSuccessful(); // true if SUCCEEDED
$refund->status->isPending(); // true if NEW or PENDING
$refund->status->isTerminal(); // true if SUCCEEDED or FAILED
use Gowelle\Flutterwave\Data\Transfer\BankTransferRequest;
$transfer = Flutterwave::transfers()->bankTransfer(
new BankTransferRequest(
amount: 50000,
sourceCurrency: 'NGN',
destinationCurrency: 'NGN',
accountNumber: '0123456789',
bankCode: '044',
reference: 'PAYOUT-' . uniqid(),
narration: 'Monthly payout', // optional
)
);
use Gowelle\Flutterwave\Data\Transfer\MobileMoneyTransferRequest;
$transfer = Flutterwave::transfers()->mobileMoneyTransfer(
new MobileMoneyTransferRequest(
amount: 1000,
sourceCurrency: 'NGN',
destinationCurrency: 'GHS',
network: 'MTN',
phoneNumber: '2339012345678',
firstName: 'John',
lastName: 'Doe',
reference: 'MOMO-' . uniqid(),
)
);
$transfer = Flutterwave::transfers()->get('transfer-id');
$transfers = Flutterwave::transfers()->list();
use Gowelle\Flutterwave\Data\Transfer\RetryTransferRequest;
$transfer = Flutterwave::transfers()->retry(
new RetryTransferRequest(
action: 'retry',
reference: 'UNIQUE_RETRY_UUID'
)
);
use Gowelle\Flutterwave\Data\Transfer\CreateRecipientRequest;
// Nigerian (NGN) - simplest form
$recipient = Flutterwave::transfers()->createRecipient(
CreateRecipientRequest::bankNgn(
accountNumber: '0123456789',
bankCode: '044',
)
);
// Ethiopian (ETB)
CreateRecipientRequest::bankEtb($accountNumber, $bankCode, $firstName, $lastName);
// Kenyan (KES)
CreateRecipientRequest::bankKes($accountNumber, $bankCode, $firstName, $lastName);
// Malawian (MWK)
CreateRecipientRequest::bankMwk($accountNumber, $bankCode, $firstName, $lastName);
// Rwandan (RWF)
CreateRecipientRequest::bankRwf($accountNumber, $bankCode, $firstName, $lastName);
// Sierra Leonean (SLL)
CreateRecipientRequest::bankSll($accountNumber, $bankCode, $firstName, $lastName);
// Ugandan (UGX)
CreateRecipientRequest::bankUgx($accountNumber, $bankCode, $firstName, $lastName);
// Ghanaian (GHS)
CreateRecipientRequest::bankGhs($accountNumber, $bankCode, $branch, $firstName, $lastName);
// Central African (XAF)
CreateRecipientRequest::bankXaf($accountNumber, $bankCode, $branch, $firstName, $lastName);
// West African (XOF)
CreateRecipientRequest::bankXof($accountNumber, $bankCode, $branch, $firstName, $lastName);
// US (USD) bank recipient
$recipient = Flutterwave::transfers()->createRecipient(
CreateRecipientRequest::bankUsd(
accountNumber: '1234567890',
bankCode: '021000021',
accountType: 'checking', // or 'savings'
routingNumber: '021000021',
swiftCode: 'CHASUS33',
firstName: 'John',
lastName: 'Doe',
phone: ['country_code' => '1', 'number' => '2025551234'],
email: '[email protected] ',
address: [
'city' => 'New York',
'country' => 'US',
'line1' => '123 Main St',
'postal_code' => '10001',
'state' => 'NY',
],
)
);
// UK (GBP) bank recipient
CreateRecipientRequest::bankGbp(
accountNumber: 'GB82WEST12345698765432',
accountType: 'individual', // or 'corporate'
bankName: 'HSBC',
sortCode: '401276',
firstName: 'John',
lastName: 'Doe',
phone: ['country_code' => '44', 'number' => '7911123456'],
email: '[email protected] ',
address: ['city' => 'London', 'country' => 'GB', 'line1' => '123 High St', 'postal_code' => 'EC1A 1BB'],
);
// European (EUR) bank recipient
CreateRecipientRequest::bankEur(
accountNumber: 'DE89370400440532013000',
bankName: 'Deutsche Bank',
swiftCode: 'DEUTDEFF',
firstName: 'Hans',
lastName: 'Mueller',
phone: ['country_code' => '49', 'number' => '1701234567'],
email: '[email protected] ',
address: ['city' => 'Berlin', 'country' => 'DE', 'line1' => 'Alexanderplatz 1', 'postal_code' => '10178'],
);
// South African (ZAR) bank recipient
CreateRecipientRequest::bankZar(
accountNumber: '1234567890',
bankCode: 'ABSAZAJJ',
firstName: 'John',
lastName: 'Doe',
phone: ['country_code' => '27', 'number' => '823456789'],
email: '[email protected] ',
address: ['city' => 'Cape Town', 'country' => 'ZA', 'line1' => '123 Long St', 'postal_code' => '8001'],
);
$recipient = Flutterwave::transfers()->createRecipient(
CreateRecipientRequest::mobileMoney(
currency: 'TZS',
network: 'VODACOM',
phoneNumber: '255123456789',
firstName: 'John',
lastName: 'Doe',
)
);
// For any type not covered by factory methods
$recipient = Flutterwave::transfers()->createRecipient(
new CreateRecipientRequest(
type: 'bank_custom',
bank: ['account_number' => '...', 'code' => '...'],
name: ['first' => 'John', 'last' => 'Doe'],
)
);
use Gowelle\Flutterwave\Data\Transfer\CreateSenderRequest;
// Basic generic sender
$sender = Flutterwave::transfers()->createSender(
CreateSenderRequest::generic(
firstName: 'John',
lastName: 'Doe',
)
);
// Generic sender with full details
$sender = Flutterwave::transfers()->createSender(
CreateSenderRequest::generic(
firstName: 'John',
lastName: 'Doe',
middleName: 'Michael',
phone: ['country_code' => '234', 'number' => '8012345678'],
email: '[email protected] ',
address: [
'city' => 'Lagos',
'country' => 'NG',
'line1' => '123 Main Street',
'postal_code' => '100001',
'state' => 'Lagos',
],
)
);
// GBP sender for UK bank transfers
$sender = Flutterwave::transfers()->createSender(
CreateSenderRequest::bankGbp(
firstName: 'John',
lastName: 'Doe',
phone: ['country_code' => '44', 'number' => '7911123456'],
email: '[email protected] ',
address: [
'city' => 'London',
'country' => 'GB',
'line1' => '123 High Street',
'postal_code' => 'EC1A 1BB',
'state' => 'Greater London',
],
)
);
// EUR sender for European bank transfers
$sender = Flutterwave::transfers()->createSender(
CreateSenderRequest::bankEur(
firstName: 'Hans',
lastName: 'Mueller',
phone: ['country_code' => '49', 'number' => '1701234567'],
email: '[email protected] ',
address: [
'city' => 'Berlin',
'country' => 'DE',
'line1' => 'Alexanderplatz 1',
'postal_code' => '10178',
'state' => 'Berlin',
],
)
);
Flutterwave::transfers()->deleteSender('sender-id');
use Gowelle\Flutterwave\Data\Transfer\GetRateRequest;
$rate = Flutterwave::transfers()->getRate(
new GetRateRequest(
sourceCurrency: 'NGN',
destinationCurrency: 'GHS',
amount: 10000,
)
);
use Gowelle\Flutterwave\Data\Transfer\CreateTransferRequest;
// First, create recipient and sender (see above)
$recipient = Flutterwave::transfers()->createRecipient(...);
$sender = Flutterwave::transfers()->createSender(...);
// Then create the transfer
$transfer = Flutterwave::transfers()->create(
new CreateTransferRequest(
amount: 50000,
sourceCurrency: 'NGN',
destinationCurrency: 'NGN',
recipientId: $recipient->id,
senderId: $sender->id,
reference: 'PAYOUT-' . uniqid(),
)
);
$settlement = Flutterwave::settlements()->get('settlement-id');
$settlements = Flutterwave::settlements()->list([
'page' => 1,
'limit' => 20,
]);
$banks = Flutterwave::banks()->get('NG'); // Country code (e.g., NG, TZ, KE)
$branches = Flutterwave::banks()->branches('bank-id');
$account = Flutterwave::banks()->resolveAccount(
bankCode: '044',
accountNumber: '0123456789',
);
echo $account->accountName;
$account = Flutterwave::banks()->resolveUsdNgAccount(
bankCode: '044',
accountNumber: '0690000031',
);
$account = Flutterwave::banks()->resolveGbpCorporateAccount(
bankCode: '044',
accountNumber: '0690000031',
businessName: 'Ajadi & Sons Ltd.',
);
$account = Flutterwave::banks()->resolveGbpIndividualAccount(
bankCode: '044',
accountNumber: '0690000031',
firstName: 'King',
lastName: 'LeBron',
middleName: 'Leo', // optional
);
use Gowelle\Flutterwave\Data\Banks\BankAccountResolveRequest;
$ngnRequest = BankAccountResolveRequest::forNgn('044', '0123456789');
$usdNgRequest = BankAccountResolveRequest::forUsdNg('044', '0690000031');
$gbpCorporateRequest = BankAccountResolveRequest::forGbpCorporate('044', '0690000031', 'Ajadi & Sons Ltd.');
$gbpIndividualRequest = BankAccountResolveRequest::forGbpIndividual(
'044',
'0690000031',
'King',
'LeBron',
'Leo',
);
$account = Flutterwave::banks()->resolveFromDto($gbpCorporateRequest);
$networks = Flutterwave::mobileNetworks()->list('TZ'); // Country code
foreach ($networks as $network) {
echo $network->name;
echo $network->code;
}
use Gowelle\Flutterwave\Facades\Flutterwave;
$account = Flutterwave::wallets()->resolveAccount(
provider: 'flutterwave',
identifier: 'wallet_123'
);
// Access resolved account details
echo $account->provider; // 'flutterwave'
echo $account->identifier; // 'wallet_123'
echo $account->name; // Account holder name
use Gowelle\Flutterwave\Facades\Flutterwave;
$statement = Flutterwave::wallets()->getStatement([
'currency' => 'NGN', // Required: 3-letter currency code
'size' => 20, // Optional: Page size (10-50, default 10)
'from' => '2024-01-01T00:00:00Z', // Optional: Start date (ISO 8601)
'to' => '2024-12-31T23:59:59Z', // Optional: End date (ISO 8601)
'next' => 'next_cursor', // Optional: Next page cursor
'previous' => 'prev_cursor', // Optional: Previous page cursor
]);
// Access statement data
echo $statement->cursor->total; // Total transactions
echo $statement->cursor->limit; // Page limit
echo $statement->cursor->hasMoreItems; // Whether more items exist
echo $statement->cursor->next; // Next page cursor
echo $statement->cursor->previous; // Previous page cursor
// Access transactions
foreach ($statement->transactions as $transaction) {
echo $transaction['transaction_direction']; // 'credit' or 'debit'
echo $transaction['amount']['value'];
echo $transaction['amount']['currency'];
echo $transaction['balance']['before'];
echo $transaction['balance']['after'];
}
use Gowelle\Flutterwave\Facades\Flutterwave;
$balance = Flutterwave::wallets()->getBalance('NGN');
echo $balance->currency; // 'NGN'
echo $balance->availableBalance; // 1200.09
use Gowelle\Flutterwave\Facades\Flutterwave;
$balances = Flutterwave::wallets()->getBalances();
foreach ($balances as $balance) {
echo $balance->currency; // 'NGN', 'USD', etc.
echo $balance->availableBalance; // Available balance
}
use Gowelle\Flutterwave\Facades\Flutterwave;
use Gowelle\Flutterwave\Data\VirtualAccount\CreateVirtualAccountRequestDTO;
use Gowelle\Flutterwave\Enums\VirtualAccountCurrency;
use Gowelle\Flutterwave\Enums\VirtualAccountType;
$request = new CreateVirtualAccountRequestDTO(
reference: 'unique-ref-' . time(), // 6-42 chars, unique
customerId: 'cus_123', // Existing customer ID
amount: 0, // 0 for static accounts
currency: VirtualAccountCurrency::NGN, // NGN, GHS, EGP, KES, MAD, or ZAR
accountType: VirtualAccountType::STATIC, // STATIC or DYNAMIC
narration: 'Payment for Order #123', // Optional
meta: ['order_id' => '123'], // Optional metadata
bankCode: '044', // Optional preferred bank code
);
$account = Flutterwave::banks()->createVirtualAccount($request);
// Access account details
echo $account->accountNumber; // Virtual account number
echo $account->accountBankName; // Bank name (e.g., "WEMA BANK")
echo $account->reference; // Your reference
echo $account->status->value; // 'active' or 'inactive'
$account = Flutterwave::banks()->retrieveVirtualAccount('va_123');
echo $account->accountNumber;
echo $account->accountBankName;
echo $account->status->value;
echo $account->currency->value;
$accounts = Flutterwave::banks()->listVirtualAccounts();
foreach ($accounts as $account) {
echo $account->accountNumber;
echo $account->status->value;
echo $account->currency->value;
}
use Gowelle\Flutterwave\Data\VirtualAccount\ListVirtualAccountsParamsDTO;
$params = new ListVirtualAccountsParamsDTO(
page: 1, // Page number (min: 1)
size: 20, // Page size (10-50)
from: '2024-01-01T00:00:00Z', // Start date (ISO 8601)
to: '2024-12-31T23:59:59Z', // End date (ISO 8601)
reference: 'unique-ref-123', // Filter by reference
);
$accounts = Flutterwave::banks()->listVirtualAccountsWithParams($params);
foreach ($accounts as $account) {
echo $account->accountNumber;
echo $account->reference;
}
use Gowelle\Flutterwave\Data\VirtualAccount\UpdateVirtualAccountRequestDTO;
use Gowelle\Flutterwave\Enums\VirtualAccountStatus;
// Deactivate an account
$request = UpdateVirtualAccountRequestDTO::forStatusUpdate(
VirtualAccountStatus::INACTIVE
);
$updated = Flutterwave::banks()->updateVirtualAccount('va_123', $request);
// Update BVN
$request = UpdateVirtualAccountRequestDTO::forBvnUpdate(
bvn: '12345678901',
meta: ['updated_by' => 'admin'] // Optional
);
$updated = Flutterwave::banks()->updateVirtualAccount('va_123', $request);
use Gowelle\Flutterwave\Facades\Flutterwave;
use Gowelle\Flutterwave\Data\VirtualAccount\CreateVirtualAccountRequestDTO;
use Gowelle\Flutterwave\Enums\VirtualAccountCurrency;
use Gowelle\Flutterwave\Enums\VirtualAccountType;
// Create a static account for a customer
$request = new CreateVirtualAccountRequestDTO(
reference: 'order-' . $order->id,
customerId: 'cus_' . $customer->id,
amount: 0,
currency: VirtualAccountCurrency::NGN,
accountType: VirtualAccountType::STATIC,
narration: "Payment for Order #{$order->id}",
meta: [
'order_id' => $order->id,
'customer_id' => $customer->id,
],
);
$account = Flutterwave::banks()->createVirtualAccount($request);
// Store the account number for the customer to pay into
$bankAccount = $account->accountNumber;
$bankName = $account->accountBankName;
// Later, retrieve to check status
$current = Flutterwave::banks()->retrieveVirtualAccount($account->id);
if ($current->isActive()) {
// Account is still active
}
// When no longer needed, deactivate
$api->update($account['data']['id'], [
'action_type' => 'update_status',
'status' => 'inactive',
]);
// Retrieve a list of all chargebacks/disputes
$chargebacks = Flutterwave::chargebacks()->list();
// Filter by page, size, and date range
$chargebacks = Flutterwave::chargebacks()->list([
'page' => 1,
'size' => 10,
'from' => '2025-04-21T10:55:16Z',
'to' => '2025-05-21T10:48:18Z',
]);
use Gowelle\Flutterwave\Data\Chargeback\CreateChargebackRequest;
$chargeback = Flutterwave::chargebacks()->create(
new CreateChargebackRequest(
chargeId: 'chg_eahdhfThdHsgaSra',
amount: 12.34,
type: 'local',
expiry: 72,
stage: 'new',
status: 'pending',
comment: 'Customer claims the charge was unauthorized.',
provider: 'Visa',
arn: '1243453453434234534443423',
initiator: 'customer',
uploadedProof: 'https://example.com/proofs/proof_123.pdf',
)
);
// Accept a chargeback (agree to refund the customer)
$chargeback = Flutterwave::chargebacks()->accept(
'chargeback-id',
'We accept this dispute and will process the reversal.'
);
use Gowelle\Flutterwave\Data\Chargeback\UpdateChargebackRequest;
// Decline a chargeback with evidence
$chargeback = Flutterwave::chargebacks()->decline(
'chargeback-id',
UpdateChargebackRequest::decline(
message: 'Service was securely delivered',
evidenceUrl: 'https://example.com/delivery/proof.jpg',
proofData: base64_encode('proof document bytes'),
provider: 'Visa',
arn: '1243453453434234534443423',
dueDatetime: '2025-05-30T23:59:59Z',
)
);
// Get details for a specific chargeback
$chargeback = Flutterwave::chargebacks()->retrieve('chargeback-id');
// Fetch transaction costs for a 5000 TZS charge
$fees = Flutterwave::fees()->calculate([
'amount' => 5000,
'currency' => 'TZS',
'payment_method' => 'mobile_money',
'network' => 'M-PESA', // Optional, for mobile money
]);
echo $fees->fee; // Direct gateway transaction cost
echo $fees->flutterwaveFee; // Direct markup
// app/Livewire/CheckoutPage.php
namespace App\Livewire;
use Livewire\Component;
use Gowelle\Flutterwave\Facades\Flutterwave;
use Gowelle\Flutterwave\Data\AuthorizationData;
class CheckoutPage extends Component
{
public int $amount = 10000;
public string $currency = 'TZS';
// Payment flow state
public string $step = 'form'; // 'form', 'pin', 'otp', 'status'
public ?string $chargeId = null;
public ?string $error = null;
protected $listeners = [
'payment-success' => 'handlePaymentSuccess',
'payment-error' => 'handlePaymentError',
'authorization- // Switch to appropriate input based on authorization type
match ($data['type']) {
'etMessage();
$this->step = 'form';
}
}
public function handleOtpSubmitted($otp)
{
try {
$authorization = AuthorizationData::createOtp(code: $otp);
$charge = Flutterwave::directCharge()->updateChargeAuthorization(
chargeId: $this->chargeId,
authorizationData: $authorization
);
$this->processChargeResult($charge);
} catch (\Exception $e) {
$this->error = $e->getMessage();
$this->step = 'form';
}
}
public function handleCancelled()
{
$this->step = 'form';
$this->chargeId = null;
}
protected function processChargeResult($charge)
{
if ($charge->status->isSuccessful()) {
return redirect()->route('payment.success');
}
if ($charge->status->
// routes/api.php
use App\Http\Controllers\FlutterwaveController;
Route::prefix('flutterwave')->group(function () {
Route::post('/charges', [FlutterwaveController::class, 'createCharge']);
Route::post('/charges/{chargeId}/authorize', [FlutterwaveController::class, 'authorize']);
Route::get('/charges/{chargeId}/status', [FlutterwaveController::class, 'status']);
});
// app/Http/Controllers/FlutterwaveController.php
namespace App\Http\Controllers;
use Gowelle\Flutterwave\Facades\Flutterwave;
use Gowelle\Flutterwave\Data\AuthorizationData;
use Illuminate\Http\Request;
class FlutterwaveController extends Controller
{
public function createCharge(Request $request)
{
$validated = $request->validate([
'amount' => 'ent_method' => ' 'pin' => AuthorizationData::createPin(
nonce: $request->input('nonce'),
encryptedPin: $request->input('encrypted_pin')
),
'otp' => AuthorizationData::createOtp(
code: $request->input('code')
),
default => throw new \InvalidArgumentException('Invalid authorization type'),
};
$charge = Flutterwave::directCharge()->updateChargeAuthorization(
chargeId: $chargeId,
authorizationData: $authorization
);
return response()->json(['charge' => $charge]);
}
public function status(string $chargeId)
{
$status = Flutterwave::directCharge()->status($chargeId);
return response()->json(['charge' => $status]);
}
}
'charge_sessions' => [
'enabled' => true,
'auto_create' => true, // Automatically create sessions on charge creation
],
use Gowelle\Flutterwave\Facades\Flutterwave;
use Gowelle\Flutterwave\Models\ChargeSession;
$charge = Flutterwave::directCharge()->create([
'amount' => 1000,
'currency' => 'TZS',
'reference' => 'ORDER-123',
'customer' => [...],
'payment_method' => [...],
'user_id' => auth()->id(), // Required for auto-create
'payment_id' => $payment->id, // Required for auto-create
]);
// Session is automatically created and linked
$session = ChargeSession::byRemoteChargeId($charge->id)->first();
use Gowelle\Flutterwave\Models\ChargeSession;
$session = ChargeSession::create([
'user_id' => auth()->id(),
'payment_id' => $payment->id,
'remote_charge_id' => $charge->id,
'status' => $charge->status->value,
'next_action_type' => $charge->nextAction->type->value ?? null,
'next_action_data' => $charge->nextAction->data ?? null,
'payment_method_type' => 'card',
'meta' => [
'order_id' => '12345',
],
]);
use Gowelle\Flutterwave\Models\ChargeSession;
use Gowelle\Flutterwave\Enums\DirectChargeStatus;
// Find by remote charge ID
$session = ChargeSession::byRemoteChargeId('charge-id')->first();
// Find pending sessions
$pendingSessions = ChargeSession::pending()->get();
// Find completed sessions
$completedSessions = ChargeSession::completed()->get();
// Find by status
$succeededSessions = ChargeSession::withStatus(DirectChargeStatus::SUCCEEDED)->get();
// Access relationships
$user = $session->user;
$payment = $session->payment;
$session->updateStatus(DirectChargeStatus::SUCCEEDED);
$session->updateNextAction($nextActionData);
$session->setMeta('custom_key', 'custom_value');
$session->save();
protected function schedule(Schedule $schedule)
{
$schedule->command('flutterwave:cleanup-sessions')->daily();
}
use Gowelle\Flutterwave\Events\FlutterwaveChargeCreated;
Event::listen(FlutterwaveChargeCreated::class, function (FlutterwaveChargeCreated $event) {
$chargeData = $event->chargeData;
$requestData = $event->requestData;
// Create charge session, send notification, etc.
});
use Gowelle\Flutterwave\Events\FlutterwaveChargeUpdated;
Event::listen(FlutterwaveChargeUpdated::class, function (FlutterwaveChargeUpdated $event) {
$chargeData = $event->chargeData;
$authorizationData = $event->authorizationData;
// Update charge session, process completion, etc.
});
use Gowelle\Flutterwave\Events\FlutterwaveTransferCreated;
Event::listen(FlutterwaveTransferCreated::class, function (FlutterwaveTransferCreated $event) {
$transferData = $event->transferData;
// Log transfer, update records, send notification, etc.
logger()->info('Transfer created', [
'id' => $transferData->id,
'status' => $transferData->status->value,
'amount' => $transferData->amount,
]);
});
use Gowelle\Flutterwave\Events\FlutterwaveWebhookReceived;
Event::listen(FlutterwaveWebhookReceived::class, function (FlutterwaveWebhookReceived $event) {
$eventType = $event->getEventType(); // String (backward compatible)
$eventTypeEnum = $event->getEventTypeEnum(); // WebhookEventType enum (recommended)
$transactionData = $event->getTransactionData();
// Using helper methods on the event
if ($event->isPaymentEvent()) {
// Handle payment-related webhook
} elseif ($event->isTransferEvent()) {
// Handle transfer-related webhook
}
// Or using the enum directly
if ($eventTypeEnum?->isPaymentEvent()) {
// Handle payment-related webhook
} elseif ($eventTypeEnum?->isTransferEvent()) {
// Handle transfer-related webhook
}
if ($event->isSuccessful()) {
// Transaction was successful
}
});
// app/Listeners/ProcessSuccessfulPayment.php
namespace App\Listeners;
use Gowelle\Flutterwave\Events\FlutterwaveWebhookReceived;
class ProcessSuccessfulPayment
{
public function handle(FlutterwaveWebhookReceived $event): void
{
if (!$event->isPaymentEvent() || !$event->isSuccessful()) {
return;
}
$transactionData = $event->getTransactionData();
$chargeId = $transactionData['id'] ?? null;
// Update your payment record, send confirmation email, etc.
}
}
use App\Listeners\ProcessSuccessfulPayment;
use Gowelle\Flutterwave\Events\FlutterwaveWebhookReceived;
protected $listen = [
FlutterwaveWebhookReceived::class => [
ProcessSuccessfulPayment::class,
],
];
use Gowelle\Flutterwave\Events\FlutterwaveWebhookReceived;
use Illuminate\Support\Facades\Event;
Event::listen(FlutterwaveWebhookReceived::class, function (FlutterwaveWebhookReceived $event) {
$payload = $event->payload;
$eventType = $event->getEventType(); // Returns string
$data = $event->getTransactionData();
// Process webhook event based on type
match ($eventType) {
'charge.completed' => $this->handleChargeCompleted($data),
'charge.failed' => $this->handleChargeFailed($data),
'transfer.completed' => $this->handleTransferCompleted($data),
default => logger()->info('Unhandled webhook event', ['type' => $eventType]),
};
});
use Gowelle\Flutterwave\Enums\WebhookEventType;
use Gowelle\Flutterwave\Events\FlutterwaveWebhookReceived;
use Illuminate\Support\Facades\Event;
Event::listen(FlutterwaveWebhookReceived::class, function (FlutterwaveWebhookReceived $event) {
$eventTypeEnum = $event->getEventTypeEnum(); // Returns WebhookEventType enum
$data = $event->getTransactionData();
if ($eventTypeEnum === null) {
logger()->warning('Unknown webhook event type', ['payload' => $event->payload]);
return;
}
// Use enum helper methods
if ($eventTypeEnum->isPaymentEvent()) {
// Handle payment-related webhook
if ($eventTypeEnum->isSuccessful()) {
$this->handleSuccessfulPayment($data);
} else {
$this->handleFailedPayment($data);
}
} elseif ($eventTypeEnum->isTransferEvent()) {
// Handle transfer-related webhook
$this->handleTransfer($data);
}
// Or use match with enum cases
match ($eventTypeEnum) {
WebhookEventType::CHARGE_COMPLETED => $this->handleChargeCompleted($data),
WebhookEventType::CHARGE_FAILED => $this->handleChargeFailed($data),
WebhookEventType::CHARGE_SUCCESSFUL => $this->handleChargeSuccessful($data),
WebhookEventType::PAYMENT_COMPLETED => $this->handlePaymentCompleted($data),
WebhookEventType::PAYMENT_FAILED => $this->handlePaymentFailed($data),
WebhookEventType::PAYMENT_SUCCESSFUL => $this->handlePaymentSuccessful($data),
WebhookEventType::TRANSFER_COMPLETED => $this->handleTransferCompleted($data),
};
});
bash
composer bash
php artisan vendor:publish --tag="flutterwave-config"
bash
php artisan vendor:publish --tag="flutterwave-config"
php artisan vendor:publish --tag="flutterwave-migrations"
bash
php artisan flutterwave:verify
bash
php artisan migrate
bash
# Publish Livewire Blade views (for customization)
php artisan vendor:publish --tag=flutterwave-views
# Publish Vue components (for Vue/Inertia apps)
php artisan vendor:publish --tag=flutterwave-vue
blade
{{-- resources/views/livewire/checkout-page.blade.php --}}
<div class="checkout-container">
@if ($error)
<div class="alert alert-danger">{{ $error }}</div>
@endif
@if ($step === 'form')
<livewire:flutterwave-payment-form
:amount="$amount"
:currency="$currency"
:customer="['email' => auth()->user()->email, 'firstName' => auth()->user()->first_name, 'lastName' => auth()->user()->last_name]"
/>
@elseif ($step === 'pin')
<livewire:flutterwave-pin-input :charge-id="$chargeId" />
@elseif ($step === 'otp')
<livewire:flutterwave-otp-input :charge-id="$chargeId" />
@elseif ($step === 'status')
<livewire:flutterwave-payment-status :charge-id="$chargeId" :auto-poll="true" />
@endif
</div>
bash
php artisan vendor:publish --tag=flutterwave-vue
bash
php artisan vendor:publish --tag="flutterwave-translations"
vue
<script setup>
const customLabels = {
pay: 'Lipa Sasa',
processing: 'Inachakata...'
};
</script>
<template>
<PaymentForm :labels="customLabels" />
</template>
bash
php artisan vendor:publish --tag="flutterwave-migrations"
php artisan migrate
bash
php artisan flutterwave:cleanup-sessions
php
use Gowelle\Flutterwave\Exceptions\FlutterwaveException;
use Gowelle\Flutterwave\Facades\Flutterwave;
try {
$payment = Flutterwave::payments()->process($data);
} catch (FlutterwaveException $e) {
// Get user-friendly message
$userMessage = $e->getUserFriendlyMessage();
// Check error type
if ($e->isValidationError()) {
// Handle validation error (400)
logger()->warning('Validation error', ['message' => $userMessage]);
} elseif ($e->isAuthenticationError()) {
// Handle authentication error (401)
logger()->error('Authentication failed', ['message' => $userMessage]);
} elseif ($e->isRateLimitError()) {
// Handle rate limit error (429)
logger()->warning('Rate limit exceeded', ['message' => $userMessage]);
} else {
// Handle other API errors
logger()->error('API error', ['message' => $userMessage]);
}
// Get technical details
$errorData = $e->getErrorData();
logger()->error('Error details', [
'message' => $errorData->getMessage(),
'code' => $errorData->getCode(),
'type' => $errorData->getType(),
]);
}
php
$dto = ChargeRequestBuilder::for('ORDER-123')
->amount(150, 'NGN')
->customer('[email protected] ', 'John', 'Doe', '+234812345678')
->card('5531886652142950', '09', '32', '564')
->redirectUrl('https://example.com/callback')
->meta(['order_id' => '12345'])
->customizations('My Store', 'Complete your purchase')
->idempotencyKey('unique-key-' . time())
->traceId('trace-' . uniqid())
->userId(auth()->id())
->paymentId($payment->id)
->build();
php
use Gowelle\Flutterwave\Support\EncryptionService;
$encryptionService = new EncryptionService(config('flutterwave.encryption_key'));
$encryptedCard = $encryptionService->encryptCardData([
'card_number' => '5531886652142950',
'expiry_month' => '09',
'expiry_year' => '32',
'cvv' => '564',
]);
// Returns: [
// 'nonce' => 'random_12_char_nonce',
// 'encrypted_card_number' => 'base64_encoded_ciphertext',
// 'encrypted_expiry_month' => 'base64_encoded_ciphertext',
// 'encrypted_expiry_year' => 'base64_encoded_ciphertext',
// 'encrypted_cvv' => 'base64_encoded_ciphertext',
// ]
php
/**
* Generate a cryptographically secure 12-character alphanumeric nonce
*/
function generateSecureNonce(int $length = 12): string
{
$characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$charactersLength = strlen($characters);
$nonce = '';
// Generate cryptographically secure random bytes
$randomBytes = random_bytes($length);
// Map bytes to alphanumeric characters
for ($i = 0; $i < $length; $i++) {
$nonce .= $characters[ord($randomBytes[$i]) % $charactersLength];
}
return $nonce;
}
function encryptCardData(string $plainText, string $encryptionKey, string $nonce): string
{
$key = base64_decode($encryptionKey);
$iv = $nonce; // 12-character nonce
// Encrypt using AES-256-GCM
$encrypted = openssl_encrypt(
$plainText,
'aes-256-gcm',
$key,
OPENSSL_RAW_DATA,
$iv,
$tag
);
// Combine encrypted data with authentication tag
$encryptedWithTag = $encrypted . $tag;
// Base64 encode
return base64_encode($encryptedWithTag);
}
// Usage
$encryptionKey = 'your_base64_encoded_encryption_key_from_dashboard';
$nonce = generateSecureNonce(12); // Generate cryptographically secure 12-character nonce
$encryptedCardNumber = encryptCardData('5531886652142950', $encryptionKey, $nonce);
$encryptedCvv = encryptCardData('564', $encryptionKey, $nonce);
$encryptedExpiryMonth = encryptCardData('09', $encryptionKey, $nonce);
$encryptedExpiryYear = encryptCardData('32', $encryptionKey, $nonce);
php
$charge = Flutterwave::directCharge()->create([
'amount' => 1000,
'currency' => 'TZS',
'reference' => 'ORDER-123',
'idempotency_key' => 'unique-key-' . time(),
// ... other data
]);
php
use Gowelle\Flutterwave\Services\FlutterwaveDirectChargeService;
class PaymentController
{
public function __construct(
private FlutterwaveDirectChargeService $chargeService
) {}
public function process()
{
$charge = $this->chargeService->create([...]);
}
}