定制 atanunu/laravel-xpresswallet 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

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

atanunu/laravel-xpresswallet

最新稳定版本:v0.3.0

Composer 安装命令:

composer require atanunu/laravel-xpresswallet

包简介

Laravel integration for Providus Xpress Wallet API with token storage, caching, logging and audit.

README 文档

README

CI Coverage Security Audit License Endpoints Dashboard API Guide Mutation Score Packagist Version Packagist Downloads

This is a Laravel SDK for the Providus Bank XpressWallet API. It handles:

  • Login and token refresh (X-Access-Token / X-Refresh-Token)
  • Secure token storage (DB) + caching
  • Request/response logging & auditing (masking, truncation, correlation IDs)
  • Automatic retries with exponential (full-jitter) backoff & 429 handling
  • Automatic 401 refresh
  • Circuit breaker (configurable failure threshold & cool-down)
  • Rate limiting detection & events
  • Optional GET response caching
  • Idempotency-Key automatic header for unsafe methods
  • Pagination helper (paginate())
  • Webhook verification (multi-secret rotation & optional async queue)
  • OpenTelemetry tracing (optional)
  • Example controllers & routes
  • Pruning command for old logs & limiting token history
  • Publishable config & migrations
  • Testbench-powered tests, GitHub Actions CI, PHPStan level 8, Psalm (complementary), mutation testing config
  • Public endpoint coverage dashboard: https://atanunu.github.io/laravel-xpresswallet/
  • HTML API Guide (optional proxy routes): https://atanunu.github.io/laravel-xpresswallet/api-guide.html
  • Automatic Packagist sync on pushes & tags (set secrets PACKAGIST_USERNAME & PACKAGIST_TOKEN).

Installation

composer require atanunu/laravel-xpresswallet
php artisan vendor:publish --provider="Atanunu\XpressWallet\XpressWalletServiceProvider" --tag=xpresswallet-config
php artisan vendor:publish --provider="Atanunu\XpressWallet\XpressWalletServiceProvider" --tag=xpresswallet-migrations
php artisan migrate

Configuration Overview

Once published, open config/xpresswallet.php. Key sections & env flags:

Core Credentials:

  • XPRESSWALLET_BASE_URL – API base (e.g. sandbox URL)
  • XPRESSWALLET_EMAIL, XPRESSWALLET_PASSWORD – raw credentials (auto base64 on login)

Retry & Backoff:

  • XPRESSWALLET_RETRY_ATTEMPTS (default 2 total attempts)
  • XPRESSWALLET_RETRY_DELAY / XPRESSWALLET_RETRY_MAX_DELAY
  • XPRESSWALLET_RETRY_FULL_JITTER (bool) – full jitter algorithm
  • XPRESSWALLET_RATE_LIMIT_ATTEMPTS – separate cap for 429 retries

Authentication & Tokens:

  • XPRESSWALLET_AUTO_REFRESH – auto refresh on first 401
  • Cache TTL & keys under cache array

Logging:

  • XPRESSWALLET_LOG_BODIES – log raw bodies (careful in prod)
  • XPRESSWALLET_MAX_BODY – truncate length
  • XPRESSWALLET_MASK_TOKENS – mask auth headers

Retention & Pruning:

  • XPRESSWALLET_RETENTION_DAYS – older logs/webhooks removed by prune command
  • XPRESSWALLET_MAX_TOKENS – keep only latest N token rows

Webhooks:

  • XPRESSWALLET_WEBHOOK_SECRET – primary secret (legacy)
  • XPRESSWALLET_WEBHOOK_SECRETS – comma-separated list for rotation
  • XPRESSWALLET_WEBHOOK_SIGNATURE_HEADER
  • XPRESSWALLET_WEBHOOK_TOLERANCE
  • XPRESSWALLET_WEBHOOK_ASYNC – queue processing (provide queue config)

Response Caching:

  • XPRESSWALLET_CACHE_GET_TTL – seconds to cache successful GETs (0 disables)

Correlation IDs:

  • XPRESSWALLET_CORRELATION_HEADER – header injected; logged & can propagate downstream

Circuit Breaker:

  • XPRESSWALLET_CB_ENABLED
  • XPRESSWALLET_CB_FAILURES – consecutive failures to open
  • XPRESSWALLET_CB_COOLDOWN – cool-down in seconds

Idempotency:

  • XPRESSWALLET_IDEMPOTENCY_AUTO (bool)
  • XPRESSWALLET_IDEMPOTENCY_HEADER (default Idempotency-Key)

OpenTelemetry:

  • XPRESSWALLET_OTEL_ENABLED
  • XPRESSWALLET_OTEL_SERVICE

All settings may be overridden per environment. Keep secrets in .env and do not commit them.

Quick start

use Atanunu\XpressWallet\Facades\XpressWallet;

$response = XpressWallet::customers()->all();

Example routes

After installing in a Laravel app, you can load example routes:

Route::prefix('xpress-demo')->middleware('web')->group(function() {
    \Atanunu\XpressWallet\Routes\routes();
});

Built-in API Routes (Optional)

The package can automatically expose a comprehensive set of REST-style proxy endpoints (customers, wallets, transfers, cards, merchant, team, transactions). They are DISABLED by default to avoid accidentally exposing sensitive actions.

Enable in .env (after publishing config):

XPRESSWALLET_ROUTES_ENABLED=true
XPRESSWALLET_ROUTES_PREFIX=xpresswallet
XPRESSWALLET_ROUTES_MIDDLEWARE=api,auth:sanctum

Notes:

  • Use strong auth / rate limiting. These proxy real money-moving operations.
  • Adjust prefix & middleware in config/xpresswallet.php under the routes key.
  • Routes register only when enabled and routes cache is not already built (standard Laravel behavior).
  • Best suited for internal tools or rapid prototyping; for production domains build thin wrappers enforcing business rules.

Examples (with default prefix):

  • GET /xpresswallet/customers – list customers
  • POST /xpresswallet/wallets – create wallet
  • POST /xpresswallet/transfers/bank – bank transfer
  • POST /xpresswallet/cards/setup – initiate card setup

See src/Routes/routes.php for the full route map and names (all names start with xpresswallet.).

Testing & Coverage

Basic test run:

composer test

To generate coverage locally (requires Xdebug or PCOV):

# Enable Xdebug in php.ini (add: zend_extension=xdebug)
# Then run
composer coverage

If you prefer PCOV (often faster):

pecl install pcov
echo "extension=pcov" >> $(php --ini | grep ".ini" | head -1 | awk '{print $NF}')
php -d pcov.enabled=1 -d pcov.directory=src vendor/bin/pest --coverage

CI runs a separate coverage job (PHP 8.3) – you can later enforce a minimum threshold by raising the --min value in the workflow once baseline is established.

CI

GitHub Actions workflows:

  • ci.yml: matrix quality (PHP 8.2/8.3) + dedicated coverage job (8.3 with Xdebug).
  • release-draft.yml: auto-drafts release notes from merged PR labels on tag push (v*.*.*).

Planned enhancements you can enable:

  • Upload coverage to Codecov (add a step with codecov/codecov-action).
  • Add a minimum coverage gate by increasing --min=0 to your baseline (e.g. 70).

Maintenance / Pruning

Run periodically (e.g. daily):

php artisan xpress:prune

Use --dry-run to preview and --days=30 to override retention for that run.

Webhooks

Add the middleware to your webhook route:

Route::post('/xpress/webhook', XpressWebhookController::class)
    ->middleware(\Atanunu\XpressWallet\Http\Middleware\VerifyXpressWebhook::class);

Set XPRESSWALLET_WEBHOOK_SECRET and (optionally) XPRESSWALLET_WEBHOOK_SIGNATURE_HEADER.

Events

Dispatched:

  • Atanunu\XpressWallet\Events\LoginSucceeded
  • Atanunu\XpressWallet\Events\TokensRefreshed
  • Atanunu\XpressWallet\Events\RateLimited (each 429 attempt with method/url/attempt/retryAfter)
  • Atanunu\XpressWallet\Events\CircuitBreakerOpened (breaker transition)

Use listeners to instrument metrics, alerts or custom logging.

Example listener registration:

Event::listen(\Atanunu\XpressWallet\Events\RateLimited::class, function($e) {
    logger()->warning('Xpress rate limited', ['url' => $e->url, 'attempt' => $e->attempt, 'retry_after' => $e->retryAfterSeconds]);
});

Pagination Helper

Use paginate() when endpoint accepts page & per_page:

$page1 = XpressWallet::client()->paginate('customers', [], 1, 50);
while ($next = $page1['meta']['next_page']) {
    $page1 = XpressWallet::client()->paginate('customers', [], $next, 50);
}

Rate Limiting & Circuit Breaker

On 429, the client retries with full-jitter until rate_limit_max_attempts reached then throws RateLimitException (contains retryAfterSeconds). Consecutive failures trigger a breaker; once open, calls throw CircuitBreakerOpenException until cool-down passes.

GET Response Caching

Enable by setting XPRESSWALLET_CACHE_GET_TTL>0. Subsequent identical GET calls within TTL return cached payload (per URI+query). Use prudent TTLs for data freshness.

Idempotency

Unsafe methods automatically include an Idempotency-Key header (UUID) unless you override or disable via config. Set your own key by passing it in headers: XpressWallet::client()->post('endpoint', [...]); (add custom header via method overload / PR for header injection if needed).

Tracing (OpenTelemetry)

If OpenTelemetry SDK is installed, spans are created per request (attributes: http.method, http.url, http.status_code, errors flagged). Configure exporter in your host app; this package only emits spans when the global tracer provider is available.

Static Analysis

Run PHPStan (Larastan) locally: Run Psalm (complementary):

composer psalm
composer analyse

Raised to level 8 (strict). Keep code green by adding types / phpdoc when extending.

Dependency Updates

Consider enabling Dependabot (.github/dependabot.yml):

version: 2
updates:
    - package-ecosystem: "composer"
        directory: "/"
        schedule:
            interval: "weekly"
    - package-ecosystem: "github-actions"
        directory: "/"
        schedule:
            interval: "weekly"

Security

Recommendations:

  • Add roave/security-advisories (conflict package) in require-dev for vulnerable dependency prevention.
  • Run composer audit in CI (Composer 2.4+).
  • CodeQL workflow is currently disabled pending general availability for PHP; rely on PHPStan + Infection.

Release Process

  1. Update CHANGELOG.md (optional – or rely on auto draft).
  2. Bump version in your tag: git tag v0.1.0 && git push origin v0.1.0.
  3. GitHub Action drafts release notes (edit if needed, then publish).

Support / Issues

Open issues or PRs with clear reproduction steps. Use labels (bug, feature, docs, test) to improve autogenerated changelog quality.

Roadmap / Future

Planned and potential enhancements (open to contribution):

Short Term

  • Mutation score badge automation (parse latest Infection report and update Shields endpoint / static JSON).
  • Psalm baseline generation & gradual tightening of errorLevel.
  • Additional feature tests for edge-case error mappings (422 variants, timeout simulation).
  • Webhook middleware queueable job example & configurable model table names.

Medium Term

  • Pluggable cache store strategy (allow per-endpoint TTL overrides).
  • Configurable idempotency key provider interface.
  • Extended OpenTelemetry attributes (retry count, cache hit, circuit state).
  • Optional Redis-backed circuit breaker (distributed state) fallback.
  • Pagination auto-iterator helper (Generator yielding pages transparently).

Long Term / Ideas

  • Laravel Horizon metrics integration example (events -> metrics).
  • Publish a companion CLI to inspect stored tokens, breaker state, recent API logs.
  • Automatic generation of typed response DTOs via schema inference (if API specs become available).
  • Multi-tenant token segregation strategy helpers.
  • Add a lightweight HTTP fakes/replay tool for offline testing of recorded interactions.

Have another idea? Open a discussion or PR—align proposals with principles: stability, observability, least surprise.

License

MIT

统计信息

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

GitHub 信息

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

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-08-11