PHPackages                             kodemeric/payment-gateways - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Payment Processing](/categories/payments)
4. /
5. kodemeric/payment-gateways

ActiveLibrary[Payment Processing](/categories/payments)

kodemeric/payment-gateways
==========================

A Laravel package for integrating multiple payment gateways (Paystack, Flutterwave, Monnify, and more)

v1.0.0(5mo ago)05MITPHPPHP ^8.1CI passing

Since Nov 21Pushed 5mo agoCompare

[ Source](https://github.com/kodemeric/payment-gateways)[ Packagist](https://packagist.org/packages/kodemeric/payment-gateways)[ Docs](https://github.com/olotudammy/payment-gateways)[ RSS](/packages/kodemeric-payment-gateways/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (6)Versions (2)Used By (0)

Payment Gateways
================

[](#payment-gateways)

A Laravel package for integrating multiple payment gateways with a clean, extensible interface. Supports Paystack, Flutterwave, Monnify, Stripe.

[![Tests](https://github.com/kodemeric/payment-gateways/workflows/Tests/badge.svg)](https://github.com/kodemeric/payment-gateways/actions)

Features
--------

[](#features)

- 🚀 Support for multiple payment gateways (Paystack, Flutterwave, Monnify, Stripe, PayPal)
- 🚀 Coming soon: Pesapal, Interswitch, PayFast
- 🌍 Country-agnostic - add any payment gateway from any country
- 🔌 Easy to extend with new gateways (programming to an interface)
- 📊 Transaction tracking and logging
- 🔔 Webhook support for all gateways
- ✅ Transaction verification
- 🧪 Comprehensive test coverage

Installation
------------

[](#installation)

```
composer require kodemeric/payment-gateways
```

### Quick Install

[](#quick-install)

Run the install command to set up everything at once:

```
php artisan payment-gateways:install
```

This command will:

- Publish the configuration file
- Publish the migrations
- Optionally run the migrations

### Manual Installation

[](#manual-installation)

If you prefer to install manually:

**1. Publish configuration and migrations:**

```
php artisan payment-gateways:publish
```

Or publish individually:

```
# Publish config only
php artisan vendor:publish --tag="payment-gateways-config"

# Publish migrations only
php artisan vendor:publish --tag="payment-gateways-migrations"
```

**2. Run migrations:**

```
php artisan payment-gateways:migrate
```

Or use the standard Laravel command:

```
php artisan migrate
```

Configuration
-------------

[](#configuration)

After publishing, configure your gateway credentials in `config/payment-gateways.php`:

```
return [
    'default_gateway' => 'paystack',

    'gateways' => [
        'paystack' => [
            'test_mode' => env('PAYSTACK_TEST_MODE', true),
            'public_key' => env('PAYSTACK_PUBLIC_KEY', ''),
            'secret_key' => env('PAYSTACK_SECRET_KEY', ''),
        ],
        // ... other gateways
    ],
];
```

Usage
-----

[](#usage)

### Basic Usage

[](#basic-usage)

```
use SoftPayment\PaymentGateways\Facades\PaymentGateway;

// Using default gateway
$gateway = PaymentGateway::default();

// Or specify a gateway
$gateway = PaymentGateway::gateway('paystack');
```

### Initiate Transaction

[](#initiate-transaction)

The package uses DTOs (Data Transfer Objects) for type safety and better structure:

```
use SoftPayment\PaymentGateways\Facades\PaymentGateway;
use SoftPayment\PaymentGateways\Dtos\InitiateTransactionRequest;

// Create request using DTO
$request = InitiateTransactionRequest::fromArray([
    'amount' => 1000, // Amount in base currency
    'email' => 'customer@example.com',
    'reference' => 'unique_ref_123', // Optional, auto-generated if not provided
    'callback_url' => 'https://yoursite.com/callback', // Optional
    'user_id' => auth()->id(), // Optional, track which user initiated the transaction
    'metadata' => ['order_id' => 123], // Optional
]);

// Or create directly
$request = new InitiateTransactionRequest(
    amount: 1000,
    email: 'customer@example.com',
    reference: 'unique_ref_123',
    callbackUrl: 'https://yoursite.com/callback',
    userId: auth()->id(), // Track the authenticated user
    metadata: ['order_id' => 123]
);

$result = PaymentGateway::gateway('paystack')->initiateTransaction($request);

if ($result->success) {
    return redirect($result->paymentUrl);
}
```

### Verify Transaction

[](#verify-transaction)

```
use SoftPayment\PaymentGateways\Dtos\VerifyTransactionResponse;

$result = PaymentGateway::gateway('paystack')->verifyTransaction('unique_ref_123');

if ($result->success && $result->status === 'success') {
    // Transaction successful
    $amount = $result->amount;
    $currency = $result->currency;
}
```

### Webhooks

[](#webhooks)

Webhook routes are automatically registered:

- `/webhooks/paystack`
- `/webhooks/flutterwave`
- `/webhooks/monnify`
- `/webhooks/stripe`
- `/webhooks/paypal`

Configure these URLs in your gateway dashboards.

### Using Dependency Injection

[](#using-dependency-injection)

```
use SoftPayment\PaymentGateways\PaymentGatewayManager;
use SoftPayment\PaymentGateways\Dtos\InitiateTransactionRequest;

class PaymentController extends Controller
{
    public function __construct(
        protected PaymentGatewayManager $paymentManager
    ) {}

    public function pay(Request $request)
    {
        $gateway = $this->paymentManager->gateway('paystack');

        $transactionRequest = InitiateTransactionRequest::fromArray([
            'amount' => $request->amount,
            'email' => $request->email,
            'user_id' => auth()->id(), // Track the authenticated user
            'metadata' => ['order_id' => $request->order_id],
        ]);

        $result = $gateway->initiateTransaction($transactionRequest);

        if ($result->success) {
            return redirect($result->paymentUrl);
        }
    }
}
```

Models
------

[](#models)

### Transaction

[](#transaction)

```
use SoftPayment\PaymentGateways\Models\Transaction;

$transaction = Transaction::where('reference', 'ref_123')->first();
$logs = $transaction->logs; // Get related transaction logs

// Get user's transactions
$userTransactions = Transaction::where('user_id', auth()->id())->get();

// Get the user who made the transaction
$user = $transaction->user;
```

### TransactionLog

[](#transactionlog)

```
use SoftPayment\PaymentGateways\Models\TransactionLog;

$logs = TransactionLog::where('gateway', 'paystack')->get();
```

DTOs (Data Transfer Objects)
----------------------------

[](#dtos-data-transfer-objects)

The package uses DTOs for type safety and better structure. All DTOs have `fromArray()` and `toArray()` methods for easy conversion.

### InitiateTransactionRequest

[](#initiatetransactionrequest)

The request DTO used to initiate a payment transaction with any gateway.

**Properties:**

- `amount` (float, required) - The payment amount in the base currency (e.g., 1000.00)
- `email` (string, required) - Customer's email address
- `reference` (string, optional) - Unique transaction reference. If not provided, the gateway will auto-generate one
- `callbackUrl` (string, optional) - URL to redirect after payment completion. Defaults to config value
- `redirectUrl` (string, optional) - Alternative redirect URL (used by some gateways)
- `currency` (string, optional) - Currency code (ISO 4217). Defaults to 'NGN'
- `customerName` (string, optional) - Customer's full name
- `description` (string, optional) - Transaction description
- `metadata` (array, optional) - Additional metadata to attach to the transaction (e.g., `['order_id' => 123]`)
- `userId` (int, optional) - ID of the user making the transaction (for tracking purposes)

**Example:**

```
use SoftPayment\PaymentGateways\Dtos\InitiateTransactionRequest;

// Using fromArray (recommended)
$request = InitiateTransactionRequest::fromArray([
    'amount' => 5000.00,
    'email' => 'customer@example.com',
    'currency' => 'NGN',
    'customer_name' => 'John Doe',
    'description' => 'Payment for Order #12345',
    'reference' => 'ORDER_12345',
    'callback_url' => route('payment.callback'),
    'user_id' => auth()->id(),
    'metadata' => [
        'order_id' => 12345,
        'product_id' => 789,
    ],
]);

// Using constructor
$request = new InitiateTransactionRequest(
    amount: 5000.00,
    email: 'customer@example.com',
    currency: 'NGN',
    customerName: 'John Doe',
    description: 'Payment for Order #12345',
    reference: 'ORDER_12345',
    callbackUrl: route('payment.callback'),
    userId: auth()->id(),
    metadata: ['order_id' => 12345]
);
```

### InitiateTransactionResponse

[](#initiatetransactionresponse)

The response DTO returned after initiating a payment transaction.

**Properties:**

- `success` (bool) - Whether the transaction initiation was successful
- `paymentUrl` (string|null) - The payment URL to redirect the customer to (null on failure)
- `reference` (string|null) - The transaction reference (gateway-generated or the one you provided)
- `accessCode` (string|null) - Gateway-specific access code (e.g., used by Paystack)
- `transactionReference` (string|null) - Gateway's internal transaction reference (may differ from reference)
- `message` (string|null) - Error message (only present when `success` is false)
- `gatewayResponse` (array) - Raw response data from the gateway API

**Success Response Example:**

```
$response = $gateway->initiateTransaction($request);

if ($response->success) {
    // Redirect customer to payment page
    return redirect($response->paymentUrl);

    // Or get transaction details
    $reference = $response->reference; // 'ref_abc123'
    $accessCode = $response->accessCode; // 'ACC_xyz789' (if applicable)
}
```

**Failure Response Example:**

```
if (!$response->success) {
    $errorMessage = $response->message; // 'Failed to initialize transaction'
    $gatewayError = $response->gatewayResponse; // Raw gateway error details
}
```

### VerifyTransactionResponse

[](#verifytransactionresponse)

The response DTO returned when verifying a transaction status.

**Properties:**

- `success` (bool) - Whether the verification request was successful
- `reference` (string|null) - The transaction reference that was verified
- `status` (string|null) - Transaction status: 'success', 'pending', or 'failed'
- `amount` (float|null) - The transaction amount that was paid
- `currency` (string|null) - The currency code (ISO 4217)
- `message` (string|null) - Error message (only present when `success` is false)
- `gatewayResponse` (array) - Raw response data from the gateway API

**Example:**

```
use SoftPayment\PaymentGateways\Dtos\VerifyTransactionResponse;

$response = $gateway->verifyTransaction('ref_abc123');

if ($response->success) {
    if ($response->status === 'success') {
        // Transaction was successful
        $amount = $response->amount; // 5000.00
        $currency = $response->currency; // 'NGN'

        // Process successful payment
        // ...
    } elseif ($response->status === 'pending') {
        // Payment is still pending
    } else {
        // Payment failed
    }
} else {
    // Verification failed (network error, invalid reference, etc.)
    $errorMessage = $response->message;
}
```

### WebhookPayload

[](#webhookpayload)

The DTO that represents incoming webhook data from payment gateways. Automatically parsed from the raw request.

**Properties:**

- `data` (array) - The main webhook payload data (varies by gateway)
- `event` (string|null) - Event type identifier (e.g., 'charge.success', 'charge.completed')
- `eventType` (string|null) - Alternative event type field (used by some gateways like Monnify)

**Methods:**

- `getReference()` - Extracts the transaction reference from the payload, handling different gateway formats automatically

**Example:**

```
use SoftPayment\PaymentGateways\Dtos\WebhookPayload;

// In your webhook handler
public function handleWebhook(Request $request)
{
    // WebhookPayload automatically parses different gateway formats
    $payload = WebhookPayload::fromArray($request->all());

    // Get the transaction reference (works across all gateways)
    $reference = $payload->getReference();

    // Get event type
    $event = $payload->event ?? $payload->eventType;

    // Get full payload data
    $data = $payload->data;
}
```

**Gateway-Specific Formats:**

The `WebhookPayload` automatically handles different webhook formats:

- **Paystack:** `{ event: 'charge.success', data: {...} }`
- **Flutterwave:** `{ event: 'charge.completed', data: {...} }`
- **Monnify:** `{ eventType: 'SUCCESSFUL_TRANSACTION', eventData: {...} }`
- **Stripe:** `{ type: 'checkout.session.completed', data: { object: {...} } }`
- **PayPal:** `{ event_type: 'PAYMENT.CAPTURE.COMPLETED', resource: {...} }`

### WebhookResponse

[](#webhookresponse)

The response DTO returned after processing a webhook.

**Properties:**

- `success` (bool) - Whether the webhook was processed successfully
- `event` (string|null) - The webhook event type that was processed
- `reference` (string|null) - The transaction reference from the webhook
- `status` (string|null) - The transaction status after processing ('success', 'pending', 'failed')
- `message` (string|null) - Error message (only present when `success` is false)
- `data` (array) - Additional data from the webhook processing

**Example:**

```
use SoftPayment\PaymentGateways\Dtos\WebhookPayload;
use SoftPayment\PaymentGateways\Dtos\WebhookResponse;

// In WebhookController (handled automatically by the package)
$payload = WebhookPayload::fromArray($request->all());
$response = $gateway->handleWebhook($payload);

// Response is automatically returned as JSON
// Success: 200 status with response data
// Failure: 400 status with error message
```

**Success Response:**

```
{
    "success": true,
    "event": "charge.success",
    "reference": "ref_abc123",
    "status": "success",
    "data": {...}
}
```

**Failure Response:**

```
{
    "success": false,
    "message": "Unhandled webhook event",
    "event": "unknown.event"
}
```

Artisan Commands
----------------

[](#artisan-commands)

The package includes several helpful Artisan commands:

### Install Command

[](#install-command)

Install the package (publishes config, migrations, and optionally runs migrations):

```
php artisan payment-gateways:install
```

### Publish Command

[](#publish-command)

Publish all package resources (config and migrations):

```
php artisan payment-gateways:publish
```

Use `--force` to overwrite existing files:

```
php artisan payment-gateways:publish --force
```

### Migrate Command

[](#migrate-command)

Run the package migrations:

```
php artisan payment-gateways:migrate
```

Use `--force` to run in production:

```
php artisan payment-gateways:migrate --force
```

Testing
-------

[](#testing)

First, install dependencies:

```
composer install
```

Then run the tests:

```
# Run all tests
composer test
# or
./vendor/bin/phpunit

# Run only unit tests
composer test:unit
# or
./vendor/bin/phpunit --testsuite=Unit

# Run only feature tests
composer test:feature
# or
./vendor/bin/phpunit --testsuite=Feature
```

Requirements
------------

[](#requirements)

- PHP 8.1+ (tested on 8.1, 8.2, 8.3)
- Laravel 10.x, 11.x, or 12.x

License
-------

[](#license)

MIT

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance70

Regular maintenance activity

Popularity4

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

176d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/0f9dd2cd54368500bb58fef19914335579638ccc0ddedd73c76e935ca2fb32a0?d=identicon)[kodemeric](/maintainers/kodemeric)

---

Tags

laravelpaymentgatewayNigeriapaystackflutterwavemonnifypayment-gatewaysmulti-gateway

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/kodemeric-payment-gateways/health.svg)

```
[![Health](https://phpackages.com/badges/kodemeric-payment-gateways/health.svg)](https://phpackages.com/packages/kodemeric-payment-gateways)
```

###  Alternatives

[musahmusah/laravel-multipayment-gateways

A Laravel Package that makes implementation of multiple payment Gateways endpoints and webhooks seamless

852.2k1](/packages/musahmusah-laravel-multipayment-gateways)[dena-a/iran-payment

a Laravel package to handle Internet Payment Gateways for Iran Banking System

312.4k1](/packages/dena-a-iran-payment)[parsisolution/gateway

A Laravel package for connecting to all Iraninan payment gateways

231.7k](/packages/parsisolution-gateway)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
