承接 cpr/laravel-cecabank 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

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

cpr/laravel-cecabank

最新稳定版本:v0.2.0

Composer 安装命令:

composer require cpr/laravel-cecabank

包简介

Cecabank TPV integration for Laravel — models, signature engine, polymorphic payment transactions, events and webhook routes. Frontend-agnostic: ship your own Blade/Vue/React UI.

README 文档

README

Tests

Cecabank TPV (Virtual POS) integration for Laravel — frontend-agnostic.

The package ships the data model, signature engine, polymorphic transaction log, lifecycle events and public callback routes. Everything user-facing (admin CRUD, redirect page, sandbox UI) is the host's job: render it with Blade, Inertia + Vue, Livewire, React… the package only hands you DTOs.

Security at a glance

  • Server-to-server callback authenticated by Cecabank's SHA-256 signature, verified with hash_equals.
  • Browser return URLs authenticated by a TTL'd HMAC token bound to the operation number (config('cecabank.return_token.ttl'), default 30 min).
  • All state transitions run inside DB::transaction { lockForUpdate; … } — concurrent callbacks cannot double-fulfil.
  • payable_type / payable_id are intentionally NOT mass-assignable; use PaymentTransaction::attachPayable($payable).
  • The provider refuses to boot if cecabank.urls.{test,production} aren't https:// to a .ceca.es host.
  • The callback route lives OUTSIDE the web middleware group so CSRF can never reject a legitimate Cecabank confirmation.

See SECURITY-AUDIT.md for the full third-party review and the patches that addressed it.

Install

composer require cpr/laravel-cecabank
php artisan vendor:publish --tag=cecabank-config
php artisan migrate

Optionally:

php artisan vendor:publish --tag=cecabank-views   # Blade auto-submit fallback
php artisan vendor:publish --tag=cecabank-lang    # Flash-message translations

Make your host model payable

use Cpr\Cecabank\Contracts\Payable;
use Cpr\Cecabank\Models\PaymentTransaction;

class Order extends Model implements Payable
{
    public function paymentAmount(): float        { return (float) $this->total; }
    public function paymentReference(): string    { return $this->order_number; }
    public function paymentDescription(): ?string { return "Order {$this->order_number}"; }
    public function isPayable(): bool             { return $this->status === 'pending_payment'; }
    public function paymentSuccessRoute(): string { return 'orders.index'; }
    public function paymentFailureRoute(): string { return 'orders.index'; }

    public function paymentTransactions()
    {
        return $this->morphMany(PaymentTransaction::class, 'payable');
    }
}

Start a checkout

Cecabank::checkout() persists a pending PaymentTransaction and returns a CheckoutPayload DTO with the fields and gateway URL. You decide how to render the redirect.

With Inertia + Vue

use Cpr\Cecabank\Facades\Cecabank;

public function pay(Order $order)
{
    abort_unless($order->isPayable() && $this->ownsOrder($order), 403);

    $payload = Cecabank::checkout($order);

    return Inertia::render('Payment/Redirect', [
        'fields'     => $payload->fields,
        'gatewayUrl' => $payload->gatewayUrl,
        'reference'  => $order->paymentReference(),
    ]);
}

With Blade (using the bundled view)

return view('cecabank::redirect', [
    'fields' => $payload->fields,
    'action' => $payload->gatewayUrl,
    'title'  => 'Redirigiendo a la pasarela…',
]);

As JSON (SPA / API)

return response()->json($payload->toArray());

React to payment lifecycle events

use Cpr\Cecabank\Events\{PaymentCompleted, PaymentFailed, PaymentCanceled};

Event::listen(PaymentCompleted::class, function ($e) {
    $e->payable?->update(['status' => 'confirmed']);
});

Routes the package owns

Name Verb URI Purpose
cecabank.success GET/POST /payment/success URL_OK browser return — redirects to Payable::paymentSuccessRoute()
cecabank.failure GET/POST /payment/failure URL_NOK browser return — redirects to Payable::paymentFailureRoute()
cecabank.callback POST /payment/callback Server-to-server confirmation — returns $*$OKY$*$ / $*$NOK$*$

URI prefix and middleware are configurable in config/cecabank.php.

Admin CRUD & sandbox

Out of scope for this package. You own the gateway CRUD UI; use Cpr\Cecabank\Models\PaymentGateway directly. For sandbox flows the package exposes:

$payload = Cecabank::sandboxCheckout($gateway, 1.00, 'demo', 'test');
$preview = Cecabank::previewSandboxSignature($gateway, 1.00, 'test');
$tx      = Cecabank::reconcileSandboxReturn($operationNumber, $request->all(), success: true);

Wire your own admin sandbox return routes and point the package at them:

// config/cecabank.php
'sandbox_return_routes' => [
    'ok'  => 'admin.cecabank.sandbox.return-ok',
    'nok' => 'admin.cecabank.sandbox.return-nok',
],

Service API quick reference

All methods are exposed through the Cecabank facade (Cpr\Cecabank\CecabankService):

Cecabank::checkout($payable, ?$gateway = null): CheckoutPayload
Cecabank::sandboxCheckout($gateway, $amount, ?$description = null, ?$environment = null): SandboxPayload
Cecabank::previewSandboxSignature($gateway, $amount, ?$environment = null): array
Cecabank::reconcileSandboxReturn($operationNumber, $params, $success): ?PaymentTransaction
Cecabank::verifyCallbackSignature($params, $gateway, ?$environment = null): bool
Cecabank::sanitizeResponse($params): array
Cecabank::calculateSignature($data): string
Cecabank::returnToken($operationNumber): string
Cecabank::verifyReturnToken($operationNumber, $token): bool
Cecabank::amountToCents($amount): string

Testing

composer install
vendor/bin/phpunit

统计信息

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

GitHub 信息

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

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-05-14

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固