cashkdiopen/payments

Laravel package for unified payment integration with Orange Money, MTN MoMo, and Bank Cards in Africa

Installs: 4

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/cashkdiopen/payments

dev-main 2025-09-03 07:05 UTC

This package is auto-updated.

Last update: 2026-01-03 07:47:01 UTC


README

Latest Version Total Downloads Tests License

A modern Laravel package for unified payment integration with African mobile money providers and bank cards. Supports Orange Money, MTN Mobile Money, and major card networks with a single, elegant API.

๐Ÿš€ Features

  • Unified API for multiple payment providers
  • Laravel Native with ServiceProvider, Artisan commands, and migrations
  • Secure Webhooks with HMAC signature validation
  • Comprehensive Testing with PHPUnit and Pest
  • Type Safety with full PHP 8.2+ support
  • Production Ready with monitoring and error handling

๐Ÿ“‹ Supported Providers

Provider Status Methods
Orange Money โœ… Mobile Money
MTN Mobile Money โœ… Mobile Money
Bank Cards โœ… Visa, Mastercard
Moov Money ๐Ÿ”„ Coming Soon

๐Ÿ“ฆ Installation

Install the package via Composer:

composer require cashkdiopen/payments

Publish the configuration and run migrations:

php artisan vendor:publish --provider="Cashkdiopen\\Payments\\CashkdiopenServiceProvider"
php artisan migrate

โš™๏ธ Configuration

Configure your environment variables in .env:

# API Configuration
CASHKDIOPEN_API_KEY=ck_live_your_api_key_here
CASHKDIOPEN_WEBHOOK_SECRET=whk_your_webhook_secret_here
CASHKDIOPEN_ENVIRONMENT=production

# Provider Settings
ORANGE_MONEY_CLIENT_ID=your_client_id
ORANGE_MONEY_CLIENT_SECRET=your_client_secret
ORANGE_MONEY_WEBHOOK_SECRET=your_webhook_secret

MTN_MOMO_API_USER=your_api_user
MTN_MOMO_API_KEY=your_api_key
MTN_MOMO_SUBSCRIPTION_KEY=your_subscription_key

๐ŸŽฏ Quick Start

Create a Payment

use Cashkdiopen\\Payments\\Facades\\Cashkdiopen;

$payment = Cashkdiopen::createPayment([
    'amount' => 10000, // Amount in cents (100.00 XOF)
    'currency' => 'XOF',
    'method' => 'orange_money',
    'customer_phone' => '+22607123456',
    'description' => 'Order #12345',
    'callback_url' => route('webhooks.cashkdiopen'),
    'return_url' => route('payment.success'),
    'metadata' => [
        'order_id' => '12345',
        'customer_id' => '67890',
    ]
]);

// Redirect user to payment page
return redirect($payment->redirect_url);

Handle Webhooks

// routes/web.php
Route::post('/webhooks/cashkdiopen', [WebhookController::class, 'handle'])
    ->name('webhooks.cashkdiopen')
    ->withoutMiddleware(['web', 'csrf']);

// app/Http/Controllers/WebhookController.php
use Cashkdiopen\\Payments\\Http\\Middleware\\ValidateWebhookSignature;

class WebhookController extends Controller
{
    public function __construct()
    {
        $this->middleware(ValidateWebhookSignature::class);
    }
    
    public function handle(Request $request)
    {
        $payload = $request->all();
        
        switch ($payload['event']) {
            case 'payment.succeeded':
                $this->handlePaymentSuccess($payload['data']);
                break;
                
            case 'payment.failed':
                $this->handlePaymentFailure($payload['data']);
                break;
        }
        
        return response('OK', 200);
    }
    
    private function handlePaymentSuccess($paymentData)
    {
        $orderId = $paymentData['metadata']['order_id'];
        
        // Update your order status
        Order::where('id', $orderId)->update([
            'status' => 'paid',
            'payment_reference' => $paymentData['provider_reference'],
            'paid_at' => now(),
        ]);
        
        // Send confirmation email, etc.
    }
}

Check Payment Status

$payment = Cashkdiopen::getPayment('txn_01J5XYZABC123');

if ($payment->status === 'success') {
    // Payment confirmed
    $this->fulfillOrder($payment->metadata['order_id']);
}

๐Ÿ› ๏ธ Advanced Usage

Custom Provider Configuration

// config/cashkdiopen.php
return [
    'default_provider' => 'orange_money',
    
    'providers' => [
        'orange_money' => [
            'base_url' => env('ORANGE_MONEY_BASE_URL'),
            'client_id' => env('ORANGE_MONEY_CLIENT_ID'),
            'client_secret' => env('ORANGE_MONEY_CLIENT_SECRET'),
            'timeout' => 30,
        ],
        
        'mtn_momo' => [
            'base_url' => env('MTN_MOMO_BASE_URL'),
            'api_user' => env('MTN_MOMO_API_USER'),
            'api_key' => env('MTN_MOMO_API_KEY'),
            'subscription_key' => env('MTN_MOMO_SUBSCRIPTION_KEY'),
            'timeout' => 30,
        ],
    ],
];

Event Listeners

// app/Providers/EventServiceProvider.php
use Cashkdiopen\\Payments\\Events\\PaymentSucceeded;
use App\\Listeners\\SendPaymentConfirmation;

protected $listen = [
    PaymentSucceeded::class => [
        SendPaymentConfirmation::class,
    ],
];

Artisan Commands

# Generate API key for a user
php artisan cashkdiopen:generate-key user@example.com --name="Production API" --environment=production

# Clean up expired transactions
php artisan cashkdiopen:cleanup --days=30

# Sync payment statuses
php artisan cashkdiopen:sync-status --provider=orange_money

๐Ÿงช Testing

The package includes comprehensive tests. Run them with:

# Run all tests
composer test

# Run with coverage
composer test-coverage

# Run specific test suite
vendor/bin/pest --filter=PaymentCreationTest

Mock Payments in Tests

use Cashkdiopen\\Payments\\Testing\\CashkdiopenFake;

public function test_payment_creation()
{
    CashkdiopenFake::fake();
    
    $payment = Cashkdiopen::createPayment([
        'amount' => 1000,
        'currency' => 'XOF',
        'method' => 'orange_money',
        // ... other parameters
    ]);
    
    CashkdiopenFake::assertPaymentCreated($payment->id);
}

๐Ÿš€ Production Deployment

Security Checklist

  • Store API keys in environment variables
  • Use HTTPS for all webhooks
  • Validate webhook signatures
  • Implement proper error logging
  • Set up monitoring and alerts

Performance Optimization

// Cache payment status for 5 minutes
$status = Cache::remember("payment_status_{$paymentId}", 300, function () use ($paymentId) {
    return Cashkdiopen::getPaymentStatus($paymentId);
});

// Queue webhook processing
dispatch(new ProcessPaymentWebhookJob($webhookPayload));

๐Ÿ“š Documentation

๐Ÿค Contributing

We welcome contributions! Please read our Contributing Guide for details.

Development Setup

git clone https://github.com/cashkdiopen/payments.git
cd payments
composer install
cp .env.example .env
vendor/bin/pest

๐Ÿ“„ License

The MIT License (MIT). Please see License File for more information.

๐Ÿ’ฌ Support

๐Ÿ™ Credits

Made with โค๏ธ by Cashkdi for African developers