hansajith18/laravel-paycorp
Composer 安装命令:
composer require hansajith18/laravel-paycorp
包简介
Laravel integration for the Paycorp (Bancstac) payment gateway. Supports Hosted Page flow, Real-Time tokenised payments, and Refund/Void.
README 文档
README
Laravel integration for the Paycorp (Bancstac) payment gateway.
Supports the Sampath/Paycorp Paycenter Web 4.0 API — Hosted Page flow, Real-Time tokenised card payments, and Refund/Void operations — with full database audit logging and PCI DSS safe-handling baked in.
Features
- Hosted Page flow — redirect payer to Paycorp-hosted card entry, receive callback
- Real-Time flow — charge previously tokenised (saved) cards without redirecting
- Refund & Void — session-authenticated back-office API with AES-256 encryption
- HMAC-SHA256 request signing — every outgoing request is signed
- Auto-registered log channel —
paycorp-YYYY-MM-DD.logwith zero config required - Sandbox mode — automatic amount normalisation for the Paycorp test environment
- Full gateway audit log — all requests/responses written to
payment_gateway_logstable - PCI DSS safe — never stores raw card numbers or CVVs; only masked card data persisted
- Laravel 11 & 12 support
Requirements
- PHP
^8.2 - Laravel
^11.0or^12.0 ext-openssl
Installation
composer require hansajith18/laravel-paycorp
The service provider is auto-discovered. No manual registration required.
Publish config and migrations
php artisan paycorp:publish
Or publish individually:
# Config only php artisan vendor:publish --tag=paycorp-config # Migrations only php artisan vendor:publish --tag=paycorp-migrations
Then run migrations:
php artisan migrate
Configuration
Add the following to your .env file:
# ── Required ────────────────────────────────────────────────────────────────── PAYCORP_ENDPOINT=https://paycorp-smp.prod.aws.paycorp.lk/rest/service/proxy PAYCORP_AUTH_TOKEN=your_auth_token PAYCORP_HMAC_SECRET=your_hmac_secret # ── Client IDs (provided by Paycorp per currency) ────────────────────────────── PAYCORP_CLIENT_ID_LKR=your_lkr_client_id PAYCORP_CLIENT_ID_USD=your_usd_client_id # ── Tokenised payment client IDs (required for saved-card flow) ──────────────── PAYCORP_TOKEN_CLIENT_ID_LKR=your_tokenize_lkr_client_id PAYCORP_TOKEN_CLIENT_ID_USD=your_tokenize_usd_client_id # ── Return URL (Paycorp redirects here after card entry) ─────────────────────── PAYCORP_RETURN_URL="${APP_URL}/api/payments/paycorp/return" # ── Optional ─────────────────────────────────────────────────────────────────── PAYCORP_DEFAULT_CURRENCY=LKR PAYCORP_SANDBOX=false PAYCORP_API_VERSION=1.04 PAYCORP_TIMEOUT=30 PAYCORP_CONNECT_TIMEOUT=10 PAYCORP_RETRY_TIMES=2 PAYCORP_RETRY_SLEEP_MS=500 # ── Refund / Void credentials (required only if using refund features) ───────── PAYCORP_REFUND_ENDPOINT=https://paycorp-console.prod.aws.paycorp.lk PAYCORP_REFUND_USERNAME=your_console_username PAYCORP_REFUND_PASSWORD=your_console_password PAYCORP_REFUND_IV_PHRASE=your_iv_phrase PAYCORP_REFUND_AES_SECRET=your_aes_secret PAYCORP_REFUND_DEVICE_ID=your_device_id # ── Logging ──────────────────────────────────────────────────────────────────── PAYCORP_LOG_CHANNEL=paycorp PAYCORP_LOG_LEVEL=debug PAYCORP_LOG_DAYS=14
The package auto-registers a paycorp daily log channel — no changes to config/logging.php are needed. To redirect logs to an existing channel (e.g. stack), set PAYCORP_LOG_CHANNEL=stack.
Usage
Hosted Page Flow
1 — Initialize a payment
use Hansajith18\LaravelPaycorp\PaycorpClient; $client = app(PaycorpClient::class); // or: $client = app('paycorp'); $response = $client->initPayment( amountCents: 50000, // 500.00 LKR clientRef: 'ORDER-' . $orderId, returnUrl: route('payments.callback'), currency: 'LKR', ); // Redirect the user to the Paycorp-hosted payment page return redirect($response->paymentPageUrl);
2 — Complete the payment (callback route)
use Hansajith18\LaravelPaycorp\PaycorpClient; $client = app(PaycorpClient::class); $reqId = $request->query('reqid'); $response = $client->completePayment($reqId, 'LKR'); if ($response->isApproved()) { $txnRef = $response->txnReference; $last4 = $response->cardLast4(); // e.g. "4564" // fulfil the order… } else { // $response->responseCode, $response->responseText }
Tokenization (Save a Card)
To save a card during payment, pass tokenize: true to the service-level initializePayment:
use Hansajith18\LaravelPaycorp\Services\PaycenterPaymentService; use Hansajith18\LaravelPaycorp\Enums\PaymentPurposeEnum; $service = app(PaycenterPaymentService::class); $payment = $service->initializePayment( userId: auth()->id(), amountCents: 100, // small verification charge — auto-voided after card saved purpose: PaymentPurposeEnum::CARD_REGISTRATION, currency: 'LKR', tokenize: true, ); return redirect($payment->payment_page_url);
After the callback, the token is stored in saved_payments. The verification charge is automatically voided by the VoidTokenizationCharge queued job.
Real-Time Charge (Saved Card)
use Hansajith18\LaravelPaycorp\Models\SavedPayment; use Hansajith18\LaravelPaycorp\Services\PaycenterPaymentService; use Hansajith18\LaravelPaycorp\Enums\PaymentPurposeEnum; $savedPayment = SavedPayment::where('user_id', auth()->id())->firstOrFail(); $service = app(PaycenterPaymentService::class); $payment = $service->chargeWithSavedPayment( userId: auth()->id(), amountCents: 50000, purpose: PaymentPurposeEnum::RIDE_PAYMENT, savedPayment: $savedPayment, currency: 'LKR', ); // $payment->status === GatewayPaymentStatusEnum::COMPLETED on success
Refund
$response = $client->refund( originalTxnReference: $txnReference, amountCents: 50000, clientRef: 'REFUND-' . $refundId, currency: 'LKR', comment: 'Customer request', ); if ($response->isApproved()) { // refund successful }
Events
Listen to payment outcomes in your EventServiceProvider:
use Hansajith18\LaravelPaycorp\Events\PaymentSucceeded; use Hansajith18\LaravelPaycorp\Events\PaymentFailed; Event::listen(PaymentSucceeded::class, function ($event) { $payment = $event->payment; // fulfil order, send receipt, etc. }); Event::listen(PaymentFailed::class, function ($event) { // notify user, release reservation, etc. });
Payable Status Auto-Update (Optional)
If you want the package to automatically update a payment_status column on a related payable model when a payment completes or fails, list the model class base-names in config/paycorp.php:
// config/paycorp.php 'payable_status_classes' => ['Order', 'Booking'],
Leave the array empty (default) and handle status updates in your own event listeners instead.
Database Tables
| Table | Purpose |
|---|---|
payments |
One row per payment attempt; tracks status, masked card info, gateway references |
payment_gateway_logs |
Full request/response audit trail per gateway operation |
saved_payments |
Tokenised cards per user (for Real-Time flow) |
Sandbox Mode
Set PAYCORP_SANDBOX=true when using the Paycorp test environment. The package automatically:
- Strips sub-unit cents (e.g.
5389.20 LKR → 5389.00 LKR) - Enforces a minimum amount of
200cents (2.00 LKR)
No code changes needed between sandbox and production.
Testing
composer test
Or directly:
./vendor/bin/phpunit
Quality Tooling
# Code style (Laravel Pint) composer format # Static analysis (PHPStan level 5) composer analyse
Security
- All API requests are signed with HMAC-SHA256
- TLS verification enforced (
verify: true) — HTTP connections always use TLS - Card numbers and CVVs are never stored — only masked card data persisted
toSafeArray()explicitly excludes cardholder name, raw expiry, and internal comments- Refund credentials are AES-256-CBC encrypted before transmission
- Gateway audit logs sanitise all sensitive fields before writing to the database
Please see SECURITY.md for how to report a security vulnerability.
Changelog
See CHANGELOG.md for release history.
For maintainers: see docs/releases.md for the full release workflow guide.
License
The MIT License (MIT). See LICENSE for details.
Credits
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 2
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-06-26