paynexus/laravel-paynexus

Accept payments through PayNexus on your Laravel website. Supports M-Pesa STK Push, payment pages, webhooks, and optional Filament admin panel integration.

Maintainers

Package info

github.com/MCBANKSKE/paynexus-laravel-plugin

Homepage

Documentation

pkg:composer/paynexus/laravel-paynexus

Statistics

Installs: 24

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.1.0 2026-05-21 20:47 UTC

This package is auto-updated.

Last update: 2026-05-21 20:48:37 UTC


README

Accept payments through PayNexus on your Laravel website. Supports M-Pesa STK Push, embeddable payment pages, webhooks, and optional Filament admin panel integration.

Installation

composer require paynexus/laravel-paynexus

Core Installation (Without Filament)

  1. Install the package:

    composer require paynexus/laravel-paynexus
  2. Publish the configuration:

    php artisan vendor:publish --tag=paynexus-config
  3. Set your API credentials in .env:

    PAYNEXUS_SECRET_KEY=sk_your_secret_key_here
    PAYNEXUS_WEBHOOK_SECRET=whsec_your_webhook_secret
    PAYNEXUS_BASE_URL=https://paynexus.co.ke/api
    PAYNEXUS_CURRENCY=KES

    Where to get these credentials:

    • Secret Key: From PayNexus Dashboard → API Keys (sk_...)
    • Webhook Secret: From PayNexus Dashboard → Webhooks → Generate webhook secret
    • Dashboard URL: https://paynexus.co.ke/merchant/login
  4. Publish migrations (optional):

    php artisan vendor:publish --tag=paynexus-migrations
    php artisan migrate

Filament Integration (Optional)

If you use Filament and want admin panel integration:

  1. Install Filament (if not already installed):

    composer require filament/filament
  2. Enable Filament integration in your .env:

    PAYNEXUS_FILAMENT_ENABLED=true
  3. Register the plugin in your PanelProvider:

    // In your Filament PanelProvider
    ->plugins([
        \PayNexus\Filament\PayNexusPlugin::make(),
    ])

This adds:

  • Payments Resource — View and manage payments in your admin panel
  • Revenue Widget — Dashboard chart showing payment trends
  • Payment Stats Widget — Quick overview stats

Configuration Options

Basic Configuration

Option Environment Variable Default Description
Secret Key PAYNEXUS_SECRET_KEY - Your PayNexus secret key (sk_...)
Base URL PAYNEXUS_BASE_URL https://paynexus.co.ke/api PayNexus API base URL
Currency PAYNEXUS_CURRENCY KES Default currency
Webhook Secret PAYNEXUS_WEBHOOK_SECRET - Webhook signature secret
Log Channel PAYNEXUS_LOG_CHANNEL null Custom log channel

Filament Configuration

Option Environment Variable Default Description
Filament Enabled PAYNEXUS_FILAMENT_ENABLED false Enable Filament integration
Navigation Group PAYNEXUS_FILAMENT_GROUP PayNexus Admin panel navigation group
Auto Register PAYNEXUS_FILAMENT_AUTO_REGISTER true Auto-register resources/widgets

Quick Start

Initiate an M-Pesa Payment

use PayNexus\Facades\PayNexus;

// Step 1: Get payment accounts to determine account type
$accountsResponse = PayNexus::getPaymentAccounts();

if (!$accountsResponse['success']) {
    // Handle error
    throw new Exception('Failed to get payment accounts: ' . $accountsResponse['message']);
}

$mpesaAccount = null;
foreach ($accountsResponse['data'] as $account) {
    if ($account['provider'] === 'mpesa') {
        $mpesaAccount = $account;
        break;
    }
}

if (!$mpesaAccount) {
    throw new Exception('No M-Pesa payment account found');
}

// Step 2: Validate phone number
$phoneValidation = PayNexus::validatePhone('0746990866');

if (!$phoneValidation['success'] || !$phoneValidation['data']['valid']) {
    throw new Exception('Invalid phone number');
}

$normalizedPhone = $phoneValidation['data']['normalized'];

// Step 3: Determine account reference based on account type
if ($mpesaAccount['type'] === 'paybill') {
    $accountReference = $mpesaAccount['account_number'];
} elseif ($mpesaAccount['type'] === 'till') {
    $accountReference = 'ORDER_' . time();
}

// Step 4: Initiate payment
$result = PayNexus::pay([
    'payment_account_id' => $mpesaAccount['id'],
    'amount' => 1000,
    'phone' => $normalizedPhone,
    'account_reference' => $accountReference,
    'description' => 'Order #12345',
]);

if ($result['success']) {
    // STK push sent — $result['data']['checkout_request_id']
}

Check Payment Status

$status = PayNexus::status($checkoutRequestId);
// $status['status'] => 'completed', 'pending', 'failed'

Embedded Payment Page

Generate a hosted payment page URL:

$url = PayNexus::paymentPage([
    'amount' => 500,
    'title' => 'Premium Subscription',
    'description' => 'Monthly plan',
    'customer_name' => 'John Doe',
    'customer_email' => 'john@example.com',
    'success_url' => route('payment.success'),
    'cancel_url' => route('payment.cancel'),
]);

return redirect($url);

Webhooks

The package registers a webhook route at /paynexus/webhook automatically. Implement listeners for payment events:

// In EventServiceProvider
use PayNexus\Events\PaymentCompleted;
use PayNexus\Events\PaymentFailed;

protected $listen = [
    PaymentCompleted::class => [
        \App\Listeners\HandlePaymentSuccess::class,
    ],
    PaymentFailed::class => [
        \App\Listeners\HandlePaymentFailure::class,
    ],
];

Blade Components

<!-- Payment Button -->
<x-paynexus::pay-button
    :amount="1000"
    phone="254746990866"
    description="Order Payment"
    reference="ORD-123"
    class="bg-blue-500 text-white px-6 py-3 rounded-lg"
>
    Pay KES 1,000
</x-paynexus::pay-button>

Filament Integration (Optional)

If your project uses Filament, the package provides optional resources and widgets:

// In your Filament PanelProvider
->plugins([
    \PayNexus\Filament\PayNexusPlugin::make(),
])

This adds:

  • Payments Resource — View and manage payments in your admin panel
  • Revenue Widget — Dashboard chart showing payment trends
  • Payment Stats Widget — Quick overview stats

API Reference

PayNexus::getPaymentAccounts(): array

Get available payment accounts from your merchant dashboard.

PayNexus::validatePhone(string $phone): array

Validate and normalize a phone number.

Parameter Type Required Description
phone string Yes Phone number to validate

PayNexus::pay(array $data): array

Initiate an M-Pesa STK Push payment.

Parameter Type Required Description
payment_account_id string Yes Payment account ID from getPaymentAccounts()
amount float Yes Payment amount
phone string Yes Normalized phone number
account_reference string Yes Account reference (paybill number or order ID)
description string No Payment description
remark string No Payment remark

PayNexus::status(string $checkoutRequestId): array

Check payment status by checkout request ID.

PayNexus::paymentPage(array $data): string

Generate a hosted payment page URL.

PayNexus::transactions(array $filters): array

List transactions with optional filters.

Events

Event Description
PayNexus\Events\PaymentCompleted Fired when a payment succeeds
PayNexus\Events\PaymentFailed Fired when a payment fails

Troubleshooting

Common Issues

  1. "PayNexus configuration key 'secret_key' is required"

    • Ensure you've set PAYNEXUS_SECRET_KEY in your .env file
    • Make sure the secret key starts with sk_
    • Run php artisan config:clear after updating environment variables
  2. "Connection error: Unable to reach PayNexus API"

    • Check your internet connection
    • Verify PAYNEXUS_BASE_URL is correct
    • Ensure your API keys are valid
  3. Filament resources not showing

    • Set PAYNEXUS_FILAMENT_ENABLED=true in your .env
    • Ensure you've registered the plugin in your PanelProvider
    • Clear caches: php artisan config:clear && php artisan filament:cache
  4. Webhook signature verification failing

    • Ensure PAYNEXUS_WEBHOOK_SECRET matches your PayNexus dashboard settings
    • Check that your webhook URL is accessible from the internet

Debug Mode

To enable debug logging, set a log channel:

PAYNEXUS_LOG_CHANNEL=paynexus

Then configure the channel in config/logging.php.

Upgrade Guide

From v1.x to v2.x

  1. Refund functionality removed - If you were using refund methods, they are no longer available
  2. Filament integration is now opt-in - You must explicitly enable it in configuration
  3. Better error handling - Error messages are now more descriptive
  4. Configuration validation - Invalid configurations will throw exceptions during registration

License

MIT