hrc/nectapay 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

hrc/nectapay

Composer 安装命令:

composer require hrc/nectapay

包简介

Framework-agnostic PHP package for NectaPay virtual account provisioning, webhook handling, and payment processing.

README 文档

README

A framework-agnostic PHP package by Haiman Resources Consulting for NectaPay virtual account provisioning, webhook handling, and payment processing. Works with Laravel, Symfony, CodeIgniter, native PHP, and any PHP framework..

Installation

composer require hrc/nectapay

For standalone / native PHP (with Guzzle)

composer require hrc/nectapay guzzlehttp/guzzle

For Laravel

Laravel auto-discovers the service provider. Then publish config and migrations:

php artisan vendor:publish --tag=nectapay-config
php artisan vendor:publish --tag=nectapay-migrations
php artisan migrate

Configuration

Environment Variables

NECTAPAY_BASE_URL=https://demo.nectapay.com/api/
NECTAPAY_API_KEY=your-api-key
NECTAPAY_MERCHANT_ID=your-merchant-id
NECTAPAY_WEBHOOK_SECRET=your-webhook-secret
NECTAPAY_SYSTEM_FEE=200
NECTAPAY_ACCOUNT_PREFIX=MYAPP

Usage: Any PHP Framework / Native PHP

The core NectaPayClient is completely framework-agnostic. It depends only on simple interfaces you can implement with any HTTP client, cache, or logger.

Quick Start

use HRC\NectaPay\Config;
use HRC\NectaPay\NectaPayClient;
use HRC\NectaPay\Http\GuzzleHttpClient;
use HRC\NectaPay\Cache\InMemoryCache;

// 1. Create config
$config = new Config(
    baseUrl: 'https://demo.nectapay.com/api',
    apiKey: 'your-api-key',
    merchantId: 'your-merchant-id',
    webhookSecret: 'your-webhook-secret',
    systemFee: 200,
    accountPrefix: 'MYAPP',
);

// Or from an array:
// $config = Config::fromArray($configArray);

// 2. Create client
$client = new NectaPayClient(
    config: $config,
    httpClient: new GuzzleHttpClient(),
    cache: new InMemoryCache(),
    // logger: $anyPsr3Logger,  // optional PSR-3 logger
);

// 3. Use it

// Initiate a dynamic virtual account for a single transaction
$transfer = $client->initiateTransfer(1200.00, 'tx_unique_123', 'Order #123');
// Returns: account_number, bank_name, expires_in_minutes, etc.

$account = $client->createStaticAccount('John Doe - MYAPP', 'myapp_owner_123');
$result = $client->verifyTransaction('TXN_123456');
$isValid = $client->validateWebhookHash($webhookPayload);

Custom HTTP Client

Implement HttpClientInterface to use any HTTP library (cURL, Symfony HttpClient, etc.):

use HRC\NectaPay\Contracts\HttpClientInterface;

class MyHttpClient implements HttpClientInterface
{
    public function get(string $url, array $headers = []): array
    {
        // Your HTTP GET implementation
        return ['status' => 200, 'body' => $decodedJson];
    }

    public function post(string $url, array $data = [], array $headers = []): array
    {
        // Your HTTP POST implementation
        return ['status' => 200, 'body' => $decodedJson];
    }
}

Custom Cache

Implement CacheInterface to use Redis, Memcached, file cache, or any backend:

use HRC\NectaPay\Contracts\CacheInterface;

class RedisCacheAdapter implements CacheInterface
{
    public function get(string $key): ?string { /* ... */ }
    public function set(string $key, string $value, int $ttlSeconds): void { /* ... */ }
    public function forget(string $key): void { /* ... */ }
}

Webhook Validation (Any Framework)

// In your webhook endpoint handler:
$payload = json_decode(file_get_contents('php://input'), true);

if ($client->validateWebhookHash($payload)) {
    // Process the payment...
    $data = $payload['data'] ?? $payload;
    $accountNumber = $data['AccountNumber'];
    $amountPaid = (float) $data['AmountPaid'];
    $transactionId = $data['TransactionId'];
}

Payment Handler (Generic)

Implement PaymentHandlerInterface for framework-agnostic payment processing:

use HRC\NectaPay\Contracts\PaymentHandlerInterface;

class MyPaymentHandler implements PaymentHandlerInterface
{
    public function handlePayment(string $ownerId, float $amount, array $metadata): mixed
    {
        // Record payment in your database, generate receipt, etc.
        return $paymentRecord;
    }
}

Usage: Laravel

Laravel users get auto-wired services, Eloquent models, queued jobs, Facade, and artisan commands out of the box.

Laravel Configuration

Add to your .env:

NECTAPAY_BASE_URL=https://demo.nectapay.com/api/
NECTAPAY_API_KEY=your-api-key
NECTAPAY_MERCHANT_ID=your-merchant-id
NECTAPAY_WEBHOOK_SECRET=your-webhook-secret
NECTAPAY_SYSTEM_FEE=200
NECTAPAY_ACCOUNT_PREFIX=MYAPP
NECTAPAY_OWNER_MODEL=App\Models\Student
NECTAPAY_OWNER_ID_ATTRIBUTE=student_id

Owner Model Requirements

The owner model (student, customer, user, etc.) must have:

  • A UUID primary key (id)
  • A name accessor or attribute
  • Optionally, a unique identifier attribute (configured via NECTAPAY_OWNER_ID_ATTRIBUTE)
  • A virtualAccount relationship (add this to your model):
public function virtualAccount()
{
    return $this->hasOne(\HRC\NectaPay\Laravel\Models\VirtualAccount::class, 'owner_id');
}

Webhook CSRF Exemption

Exclude the webhook path from CSRF verification in your bootstrap/app.php:

->withMiddleware(function (Middleware $middleware) {
    $middleware->validateCsrfTokens(except: [
        'webhook/nectapay',
    ]);
})

Laravel Payment Handler

Implement the Laravel-specific PaymentHandler contract:

use HRC\NectaPay\Laravel\Contracts\PaymentHandler;
use Illuminate\Database\Eloquent\Model;

class MyPaymentHandler implements PaymentHandler
{
    public function handleWebhookPayment(Model $owner, float $amount, array $metadata): ?Model
    {
        // Record payment, allocate to invoices, generate receipt, etc.
        return $payment;
    }
}

Set it in your .env:

NECTAPAY_PAYMENT_HANDLER=App\Services\MyPaymentHandler

Provision a Single Account (Laravel)

use HRC\NectaPay\Laravel\Facades\NectaPay;

$account = NectaPay::createStaticAccount($owner);

Dispatch Async Job (Laravel)

use HRC\NectaPay\Laravel\Jobs\CreateVirtualAccountJob;

CreateVirtualAccountJob::dispatch($owner);

Artisan Command

# Provision for a specific owner
php artisan nectapay:provision-accounts --owner=000100500

# Batch provision all active owners without accounts
php artisan nectapay:provision-accounts

# Dry run
php artisan nectapay:provision-accounts --dry-run

Initiate a Dynamic Transfer (Laravel)

$transfer = NectaPay::initiateTransfer(1200.00, 'tx_unique_123', 'Order #123');
// $transfer['account_number']    — temporary account to pay into
// $transfer['bank_name']         — bank name
// $transfer['expires_in_minutes'] — time before the account expires

Verify a Transaction (Laravel)

$result = NectaPay::verifyTransaction($transactionId);

Architecture

The package is split into a framework-agnostic core and framework-specific adapters:

src/
├── Config.php                          ← Configuration value object
├── NectaPayClient.php                  ← Core API client (no framework deps)
├── Contracts/
│   ├── HttpClientInterface.php         ← HTTP abstraction
│   ├── CacheInterface.php              ← Cache abstraction
│   ├── PaymentHandlerInterface.php     ← Generic payment handler
│   └── OwnerInterface.php              ← Owner model contract
├── DTOs/
│   ├── VirtualAccountData.php          ← Virtual account data transfer object
│   └── WebhookResult.php               ← Webhook processing result
├── Http/
│   └── GuzzleHttpClient.php            ← Guzzle HTTP implementation
├── Cache/
│   └── InMemoryCache.php               ← Simple in-memory cache
├── Exceptions/
│   └── NectaPayException.php           ← Framework-agnostic exceptions
└── Laravel/                            ← Laravel-specific adapter
    ├── NectaPayServiceProvider.php
    ├── NectaPayService.php             ← Eloquent-aware service wrapper
    ├── Facades/NectaPay.php
    ├── Contracts/PaymentHandler.php
    ├── Models/
    │   ├── VirtualAccount.php
    │   └── WebhookLog.php
    ├── Console/ProvisionVirtualAccountsCommand.php
    ├── Http/
    │   ├── LaravelHttpClient.php
    │   └── Controllers/NectaPayWebhookController.php
    ├── Jobs/CreateVirtualAccountJob.php
    ├── Cache/LaravelCacheAdapter.php
    └── Exceptions/WebhookEarlyExitException.php

Core Dependencies

Interface Purpose Bundled Implementations
HttpClientInterface HTTP requests GuzzleHttpClient, LaravelHttpClient
CacheInterface Auth token caching InMemoryCache, LaravelCacheAdapter
PSR-3 LoggerInterface Logging (optional) Any PSR-3 logger

hrc/nectapay 适用场景与选型建议

hrc/nectapay 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 4 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 04 月 17 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 hrc/nectapay 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 hrc/nectapay 我们能提供哪些服务?
定制开发 / 二次开发

基于 hrc/nectapay 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 4
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 42
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-04-17