mosesadewale/kora-laravel
Composer 安装命令:
composer require mosesadewale/kora-laravel
包简介
Laravel integration for the Kora payment API (formerly KoraPay)
README 文档
README
Laravel integration for the Kora PHP SDK. Provides a service provider, facade, and an optional verified webhook receiver.
Requirements
- PHP 8.2+
- Laravel 10, 11, 12, or 13
- mosesadewale/kora-php ^2.0
Installation
composer require mosesadewale/kora-laravel
The service provider and Kora facade are auto-discovered via Laravel's package discovery.
Configuration
Publish the config file:
php artisan vendor:publish --tag=kora-config
Then add to your .env:
KORA_SECRET_KEY=sk_live_... KORA_ENCRYPTION_KEY=... # required for card payments (32 bytes)
KORA_ENVIRONMENT is optional. When omitted, the package infers the environment from KORA_SECRET_KEY.
Full config reference (config/kora.php):
return [ 'secret_key' => env('KORA_SECRET_KEY', ''), 'encryption_key' => env('KORA_ENCRYPTION_KEY', ''), 'environment' => env('KORA_ENVIRONMENT'), 'webhook_path' => env('KORA_WEBHOOK_PATH', 'webhooks/kora'), 'register_webhook_route' => env('KORA_REGISTER_ROUTE', false), 'timeout' => (float) env('KORA_TIMEOUT', 30), 'retry_attempts' => (int) env('KORA_RETRY_ATTEMPTS', 3), ];
If you want to be explicit, set KORA_ENVIRONMENT=live or KORA_ENVIRONMENT=sandbox. A mismatch with the key prefix throws InvalidArgumentException at boot time.
Usage
Use the Kora facade anywhere in your application:
use Kora\Laravel\Facades\Kora; // Initialize a charge $charge = Kora::charges()->charge([ 'reference' => 'ref_' . uniqid(), 'amount' => 5000, 'currency' => 'NGN', 'customer' => ['email' => 'user@example.com', 'name' => 'Ada Okonkwo'], 'redirect_url' => 'https://yourapp.com/callback', ]); return redirect($charge->checkoutUrl);
All resources are available on the facade:
Kora::charges() // ChargesResource Kora::mobileMoney() // MobileMoneyResource Kora::payouts() // PayoutsResource Kora::bulkPayouts() // BulkPayoutsResource Kora::balances() // BalancesResource Kora::conversions() // ConversionsResource Kora::refunds() // RefundsResource Kora::poolAccounts() // PoolAccountsResource Kora::chargebacks() // ChargebacksResource Kora::webhooks() // WebhookResource
See the kora-php README for full method signatures and usage examples for each resource.
Webhooks
Kora signs webhooks with your API secret_key.
Optional route
The package can register POST webhooks/kora with signature verification middleware applied, but the route is disabled by default so installing the package does not expose a public endpoint unexpectedly.
Enable it when you want the package-managed receiver:
KORA_REGISTER_ROUTE=true KORA_WEBHOOK_PATH=webhooks/kora
The route is registered outside Laravel's web middleware group, so no CSRF exemption is needed.
Laravel event
When a valid webhook arrives, the controller dispatches one generic event:
use Illuminate\Support\Facades\Event; use Kora\Laravel\Events\KoraWebhookReceived; use Kora\Sdk\Enums\WebhookEventType; Event::listen(KoraWebhookReceived::class, function (KoraWebhookReceived $e) { match (WebhookEventType::tryFrom($e->event->type)) { WebhookEventType::ChargeSuccess => ProcessSuccessfulCharge::dispatch($e->event->data), WebhookEventType::PayoutSuccess => ProcessSuccessfulPayout::dispatch($e->event->data), WebhookEventType::RefundSuccess => ProcessSuccessfulRefund::dispatch($e->event->data), default => null, }; });
Your application owns business processing, idempotency, queueing, and event-specific jobs/listeners.
Each KoraWebhookReceived event carries a WebhookEvent $event property:
$e->event->type; // raw event string e.g. "charge.success" $e->event->data; // array — the full data payload from Kora $e->event->data['reference'] // the transaction reference
Unknown future Kora event strings are still dispatched through KoraWebhookReceived; use $e->event->type when you need the raw provider value.
Custom webhook route
If you need full control, disable the built-in route and define your own:
// KORA_REGISTER_ROUTE=false in .env // routes/api.php Route::post('webhooks/kora', function (Request $request) { $raw = $request->getContent(); $signature = $request->headers->get('x-korapay-signature') ?? ''; if (!Kora::webhooks()->verify($raw, $signature)) { abort(401); } $event = Kora::webhooks()->parse($raw); // dispatch your own event/job or handle $event manually return response()->json(['received' => true]); });
Error handling
use Kora\Sdk\Exceptions\ApiException; use Kora\Sdk\Exceptions\AuthenticationException; use Kora\Sdk\Exceptions\DuplicateReferenceException; use Kora\Sdk\Exceptions\InsufficientFundsException; use Kora\Sdk\Exceptions\KoraException; use Kora\Sdk\Exceptions\NetworkException; use Kora\Sdk\Exceptions\ValidationException; try { Kora::payouts()->disburse($payload); } catch (DuplicateReferenceException $e) { // reference already used } catch (InsufficientFundsException $e) { // wallet balance too low } catch (ValidationException $e) { Log::warning('Kora validation', $e->errors()); } catch (ApiException $e) { Log::error('Kora server error', ['context' => $e->context()]); } catch (KoraException $e) { Log::error($e->getMessage()); }
Testing
Bind a mock against KoraClientInterface in your test — no network calls, no real credentials:
use Kora\Sdk\Contracts\KoraClientInterface; use Kora\Sdk\DTOs\ChargeResponse; use Kora\Sdk\Resources\ChargesResource; $charges = $this->createMock(ChargesResource::class); $charges->method('charge')->willReturn(ChargeResponse::fromArray([ 'reference' => 'ref_001', 'status' => 'pending', 'amount' => 5000, 'currency' => 'NGN', 'checkout_url' => 'https://pay.korahq.com/checkout/ref_001', ])); $kora = $this->createMock(KoraClientInterface::class); $kora->method('charges')->willReturn($charges); $this->app->instance(KoraClientInterface::class, $kora); // Kora facade and injected KoraClientInterface now use the mock
For webhook controller tests, use Event::fake() and post a signed payload:
use Illuminate\Support\Facades\Event; use Kora\Laravel\Events\KoraWebhookReceived; Event::fake(); $secret = config('kora.secret_key'); $data = ['reference' => 'ref_001', 'status' => 'success']; $payload = json_encode(['event' => 'charge.success', 'data' => $data]); $sig = hash_hmac('sha256', json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), $secret); $this->call('POST', config('kora.webhook_path'), [], [], [], [ 'HTTP_X_KORAPAY_SIGNATURE' => $sig, 'CONTENT_TYPE' => 'application/json', ], $payload)->assertStatus(200); Event::assertDispatched(KoraWebhookReceived::class, function (KoraWebhookReceived $e) { return $e->event->type === 'charge.success' && $e->event->data['reference'] === 'ref_001'; });
Laravel
This package is the Laravel integration. For framework-agnostic usage see mosesadewale/kora-php.
License
MIT
mosesadewale/kora-laravel 适用场景与选型建议
mosesadewale/kora-laravel 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 3 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 06 月 10 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「payments」 「sdk」 「laravel」 「africa」 「korapay」 「kora」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 mosesadewale/kora-laravel 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 mosesadewale/kora-laravel 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 mosesadewale/kora-laravel 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Dealing with payments through the Egyptian payment gateway PayMob
Librería para la gestión sencilla de pagos mediante TPV Redsys y Paypal
Alfabank REST API integration
Scanpay module for Magento 2
Laravel package for Accurate Online API integration.
Official Safaricom Daraja M-Pesa integration for Laravel built on ysg/payment-core.
统计信息
- 总下载量: 3
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 40
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-06-10