PHPackages                             atanunu/laravel-xpresswallet - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. atanunu/laravel-xpresswallet

ActiveLibrary[API Development](/categories/api)

atanunu/laravel-xpresswallet
============================

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

v0.3.0(9mo ago)00[3 PRs](https://github.com/atanunu/laravel-xpresswallet/pulls)MITPHPPHP ^8.2CI passing

Since Aug 10Pushed 4mo agoCompare

[ Source](https://github.com/atanunu/laravel-xpresswallet)[ Packagist](https://packagist.org/packages/atanunu/laravel-xpresswallet)[ RSS](/packages/atanunu-laravel-xpresswallet/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (11)Versions (7)Used By (0)

Laravel SDK for Providus Bank XpressWallet
==========================================

[](#laravel-sdk-for-providus-bank-xpresswallet)

[![CI](https://github.com/atanunu/laravel-xpresswallet/actions/workflows/ci.yml/badge.svg)](https://github.com/atanunu/laravel-xpresswallet/actions/workflows/ci.yml/badge.svg)[![Coverage](https://camo.githubusercontent.com/ee983b982cb24a95950512731f03fc0253b5a7e43417896faf01a7749aa81c5e/68747470733a2f2f636f6465636f762e696f2f67682f6174616e756e752f6c61726176656c2d78707265737377616c6c65742f6272616e63682f6d61696e2f67726170682f62616467652e737667)](https://camo.githubusercontent.com/ee983b982cb24a95950512731f03fc0253b5a7e43417896faf01a7749aa81c5e/68747470733a2f2f636f6465636f762e696f2f67682f6174616e756e752f6c61726176656c2d78707265737377616c6c65742f6272616e63682f6d61696e2f67726170682f62616467652e737667)[![Security Audit](https://github.com/atanunu/laravel-xpresswallet/actions/workflows/security-audit.yml/badge.svg)](https://github.com/atanunu/laravel-xpresswallet/actions/workflows/security-audit.yml/badge.svg)[![License](https://camo.githubusercontent.com/86f39a8ee88c3d6b7f0476e7db205183f9c0f290809ffe32f7a1ea4194a86b2f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6174616e756e752f6c61726176656c2d78707265737377616c6c6574)](https://camo.githubusercontent.com/86f39a8ee88c3d6b7f0476e7db205183f9c0f290809ffe32f7a1ea4194a86b2f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6174616e756e752f6c61726176656c2d78707265737377616c6c6574)[![Endpoints Dashboard](https://camo.githubusercontent.com/da092983d494fc77a656a5d0aefd240cbf4da431dc6d793dc3c47de04ea2efc9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646f63732d656e64706f696e747325323064617368626f6172642d626c7565)](https://atanunu.github.io/laravel-xpresswallet/)[![API Guide](https://camo.githubusercontent.com/ac18481af77bed9ccffd8769f6821f147e57c6478d143b9148ed773277a5f351/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646f63732d61706925323067756964652d677265656e)](https://atanunu.github.io/laravel-xpresswallet/api-guide.html)[![Mutation Score](https://camo.githubusercontent.com/1bea9222bb2b12c9868c89341a18b8ba832ba57a6ce80c67e5e818317de01ae8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6d75746174696f6e25323073636f72652d6578706572696d656e74616c2d6c6967687467726579)](#mutation-testing)[![Packagist Version](https://camo.githubusercontent.com/298a89f7a5c0b04bfd950935e6e2f8a23dff6a345efecd2b9f59d934d14a4058/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6174616e756e752f6c61726176656c2d78707265737377616c6c6574)](https://packagist.org/packages/atanunu/laravel-xpresswallet)[![Packagist Downloads](https://camo.githubusercontent.com/47e1e321c3e8a3dd5f64b24fb09f0c05e783bcd401e130d1457840d4b499fead/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6174616e756e752f6c61726176656c2d78707265737377616c6c6574)](https://packagist.org/packages/atanunu/laravel-xpresswallet)

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 &amp; auditing (masking, truncation, correlation IDs)
- Automatic retries with exponential (full-jitter) backoff &amp; 429 handling
- Automatic 401 refresh
- Circuit breaker (configurable failure threshold &amp; cool-down)
- Rate limiting detection &amp; events
- Optional GET response caching
- Idempotency-Key automatic header for unsafe methods
- Pagination helper (`paginate()`)
- Webhook verification (multi-secret rotation &amp; optional async queue)
- OpenTelemetry tracing (optional)
- Example controllers &amp; routes
- Pruning command for old logs &amp; limiting token history
- Publishable config &amp; migrations
- Testbench-powered tests, GitHub Actions CI, PHPStan level 8, Psalm (complementary), mutation testing config
- Public endpoint coverage dashboard:
- HTML API Guide (optional proxy routes):
- Automatic Packagist sync on pushes &amp; tags (set secrets `PACKAGIST_USERNAME` &amp; `PACKAGIST_TOKEN`).

Installation
------------

[](#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
----------------------

[](#configuration-overview)

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

Core Credentials:

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

Retry &amp; 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 &amp; Tokens:

- `XPRESSWALLET_AUTO_REFRESH` – auto refresh on first 401
- Cache TTL &amp; 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 &amp; 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 &amp; 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
-----------

[](#quick-start)

```
use Atanunu\XpressWallet\Facades\XpressWallet;

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

Example routes
--------------

[](#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)
------------------------------

[](#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 &amp; 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 &amp; Coverage
----------------------

[](#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
--

[](#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
---------------------

[](#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
--------

[](#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
------

[](#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
-----------------

[](#pagination-helper)

Use `paginate()` when endpoint accepts `page` &amp; `per_page`:

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

Rate Limiting &amp; Circuit Breaker
-----------------------------------

[](#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
--------------------

[](#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
-----------

[](#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)
-----------------------

[](#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
---------------

[](#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
------------------

[](#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
--------

[](#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
---------------

[](#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
----------------

[](#support--issues)

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

Roadmap / Future
----------------

[](#roadmap--future)

Planned and potential enhancements (open to contribution):

### Short Term

[](#short-term)

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

### Medium Term

[](#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

[](#long-term--ideas)

- Laravel Horizon metrics integration example (events -&gt; 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
-------

[](#license)

MIT

###  Health Score

31

—

LowBetter than 68% of packages

Maintenance67

Regular maintenance activity

Popularity0

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity42

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 89.5% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

3

Last Release

274d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/e49ea612f9e87e598a561ee18c5c9a8e2577e5d602968deba369542de9c6e514?d=identicon)[atanunu](/maintainers/atanunu)

---

Top Contributors

[![atanunu](https://avatars.githubusercontent.com/u/47770330?v=4)](https://github.com/atanunu "atanunu (17 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (2 commits)")

---

Tags

apilaravelsdkpaymentswalletprovidusxpresswallet

###  Code Quality

TestsPest

Static AnalysisPHPStan, Psalm

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/atanunu-laravel-xpresswallet/health.svg)

```
[![Health](https://phpackages.com/badges/atanunu-laravel-xpresswallet/health.svg)](https://phpackages.com/packages/atanunu-laravel-xpresswallet)
```

###  Alternatives

[mollie/laravel-mollie

Mollie API client wrapper for Laravel &amp; Mollie Connect provider for Laravel Socialite

3624.1M28](/packages/mollie-laravel-mollie)[smodav/mpesa

M-Pesa API implementation

16363.7k1](/packages/smodav-mpesa)[mozex/anthropic-laravel

Anthropic PHP for Laravel is a supercharged PHP API client that allows you to interact with the Anthropic API

71226.4k1](/packages/mozex-anthropic-laravel)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
