PHPackages                             puntjes/laravel - 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. puntjes/laravel

ActiveLibrary[API Development](/categories/api)

puntjes/laravel
===============

Laravel integration for the Puntjes loyalty API — service provider, facade, config and a cache-backed token store.

v0.1.1(today)00MITPHPPHP ^8.2

Since Jul 30Pushed todayCompare

[ Source](https://github.com/TheGangOfFour/puntjes-laravel)[ Packagist](https://packagist.org/packages/puntjes/laravel)[ Docs](https://github.com/TheGangOfFour/puntjes-laravel)[ RSS](/packages/puntjes-laravel/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (8)Versions (3)Used By (0)

puntjes/laravel
===============

[](#puntjeslaravel)

Laravel integration for the [Puntjes](https://puntjes.app) loyalty API.

A thin layer over [`puntjes/php-sdk`](https://github.com/TheGangOfFour/puntjes-php-sdk): config, a service provider, a facade, and — the part that actually matters in production — a **cache-backed token store** so your app grants one access token per hour instead of one per web request.

All the API surface, retry rules and error types live in the core SDK. Read its [README](https://github.com/TheGangOfFour/puntjes-php-sdk#readme) for those; this one covers only the Laravel wiring.

Install
-------

[](#install)

```
composer require puntjes/laravel
```

Add your credentials from **Puntjes → Settings → API clients**:

```
PUNTJES_CLIENT_ID=…
PUNTJES_CLIENT_SECRET=…
PUNTJES_BASE_URL=https://puntjes.app/api/v1
```

That is the whole setup — the provider and facade are auto-discovered.

Publish the config only if you need to change something in it:

```
php artisan vendor:publish --tag=puntjes-config
```

Use
---

[](#use)

```
use Puntjes\Laravel\Facades\Puntjes;
use Puntjes\Request\SubmitTransaction;

$customer = Puntjes::customers()->lookup(identifier: $card);

Puntjes::transactions()->submit(new SubmitTransaction(
    identifier:     $card,
    totalAmount:    $order->total_cents,
    idempotencyKey: 'order-'.$order->id,
));
```

Or inject the client — preferable in domain code, and trivially fakeable in tests:

```
use Puntjes\Puntjes;

final class AwardLoyaltyPointsAction
{
    public function __construct(private readonly Puntjes $puntjes) {}

    public function handle(Order $order): void
    {
        $this->puntjes->transactions->submit(new SubmitTransaction(
            identifier:     $order->loyalty_card,
            totalAmount:    $order->total_cents,
            idempotencyKey: 'order-'.$order->id,
        ));
    }
}
```

The facade exposes each endpoint group as a method — `Puntjes::customers()`, `transactions()`, `wallets()`, `rewards()`, `redemptions()`, `products()`, `campaigns()`, `statistics()` — plus `Puntjes::me()`, `Puntjes::ping()` and `Puntjes::client()` for the underlying SDK instance.

> The SDK exposes those groups as readonly *properties*, which a facade cannot proxy (`__callStatic` only forwards method calls). Hence the accessor methods.

Configuration
-------------

[](#configuration)

KeyEnvDefaultNotes`client_id``PUNTJES_CLIENT_ID`—Required`client_secret``PUNTJES_CLIENT_SECRET`—Required. Never commit it`base_url``PUNTJES_BASE_URL``https://puntjes.app/api/v1`As documented; the bare host also works`cache.store``PUNTJES_CACHE_STORE`app defaultUse a shared store in production`cache.prefix``PUNTJES_CACHE_PREFIX``puntjes``http.retries``PUNTJES_RETRIES``2`Retry-safe requests only`http.timeout``PUNTJES_TIMEOUT``10`Seconds`http.connect_timeout``PUNTJES_CONNECT_TIMEOUT``5`Seconds`PUNTJES_BASE_URL` takes the base URL exactly as the API docs state it, `https://puntjes.app/api/v1`. The bare host is accepted as well — the SDK keeps only the host either way, because the API lives under `/api/v1` while the OAuth token endpoint sits at `/oauth/token`, off the root.

Missing credentials raise a `ConfigurationException` when the client is first resolved, not at boot, so an app that has the package installed but not yet configured still runs `artisan`, migrations and unrelated routes.

Token caching
-------------

[](#token-caching)

Set `PUNTJES_CACHE_STORE` to a **shared** store — `redis`, `database`, `memcached`. The `array` and `file` drivers are per-process and per-server, so every worker grants its own token. Correct, just wasteful.

Tokens are stored under a key derived from a hash of the credentials, so the secret is never written to the cache, and two vendors configured in one app — or one vendor mid secret-rotation — never read each other's token.

Custom HTTP client
------------------

[](#custom-http-client)

By default the package builds a Guzzle client honouring the configured timeouts. Bind your own PSR-18 client to take over completely — for instrumentation, a proxy, or custom TLS:

```
$this->app->bind(\Psr\Http\Client\ClientInterface::class, fn () => new MyTracedClient);
```

The `http.timeout` and `http.connect_timeout` settings then no longer apply; configure them on your client.

Testing
-------

[](#testing)

Bind a fake client in your tests and assert against it, rather than hitting the API:

```
use Puntjes\Puntjes;

$this->app->instance(Puntjes::class, $fakePuntjes);
```

For request-level control, bind a stub `Psr\Http\Client\ClientInterface` and let the real SDK run against it — that keeps the auth flow, retries and error mapping in the test rather than mocking them away.

Requirements
------------

[](#requirements)

- PHP 8.2+
- Laravel 11, 12 or 13

The core SDK targets PHP 8.1 so it can reach older WooCommerce hosts; this package tracks Laravel's own floor instead.

Roadmap
-------

[](#roadmap)

Webhook routing and signature-verification middleware land here once outbound webhooks ship on the API.

Development
-----------

[](#development)

```
composer install
composer test        # Testbench
composer analyse     # PHPStan level 6
composer format      # Pint
```

The core SDK resolves from Packagist. To develop both packages side by side with SDK edits visible here immediately, add a path repository **locally, without committing it**:

```
composer config repositories.sdk '{"type": "path", "url": "../puntjes-php-sdk", "options": {"symlink": true}}'
composer update puntjes/php-sdk
```

Revert `composer.json` before committing.

License
-------

[](#license)

MIT.

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance100

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity37

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% 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

2

Last Release

0d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/15e6cbb2bcf0d3a7b424f0442acf726db53a822af83b63eb4626f2cfbc707517?d=identicon)[JuniorE.](/maintainers/JuniorE.)

---

Top Contributors

[![JuniorE](https://avatars.githubusercontent.com/u/4274000?v=4)](https://github.com/JuniorE "JuniorE (4 commits)")

---

Tags

apilaravelsdkloyaltypuntjes

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

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

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

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M348](/packages/psalm-plugin-laravel)[laravel/ai

The official AI SDK for Laravel.

1.0k3.2M256](/packages/laravel-ai)[defstudio/telegraph

A laravel facade to interact with Telegram Bots

813336.8k3](/packages/defstudio-telegraph)[moonshine/moonshine

Laravel administration panel

1.3k253.1k86](/packages/moonshine-moonshine)[api-platform/laravel

API Platform support for Laravel

58174.6k17](/packages/api-platform-laravel)[simplestats-io/laravel-client

Server-side analytics for Laravel that follows the full funnel from visit to registration to payment, attributed to the channel that drove it. Revenue, MRR, churn and ad-spend profit (ROAS/CAC) per channel. GDPR compliant, ad-blocker proof.

5022.6k](/packages/simplestats-io-laravel-client)

PHPackages © 2026

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