PHPackages                             padosoft/laravel-rebel-channel-vonage - 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. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. padosoft/laravel-rebel-channel-vonage

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

padosoft/laravel-rebel-channel-vonage
=====================================

Vonage provider for Laravel Rebel Channels: phone verification via Vonage Verify (SMS/voice), plain SMS delivery, and signed delivery-receipt webhooks. Part of padosoft/laravel-rebel-\*.

v0.1.0(1mo ago)01MITPHPPHP ^8.3CI passing

Since Jun 4Pushed 1mo agoCompare

[ Source](https://github.com/padosoft/laravel-rebel-channel-vonage)[ Packagist](https://packagist.org/packages/padosoft/laravel-rebel-channel-vonage)[ Docs](https://github.com/padosoft/laravel-rebel-channel-vonage)[ RSS](/packages/padosoft-laravel-rebel-channel-vonage/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (1)Dependencies (10)Versions (3)Used By (0)

Laravel Rebel — Vonage Channel
==============================

[](#laravel-rebel--vonage-channel)

> Official documentation:

> **Send phone verifications and SMS through Vonage, the Rebel way.** This package plugs [Vonage Verify](https://developer.vonage.com/en/verify/overview) (SMS / voice) and the [Vonage SMS API](https://developer.vonage.com/en/messaging/sms/overview) into [`laravel-rebel-channels`](https://github.com/padosoft/laravel-rebel-channels) as a `VerificationProvider` *and* a `MessageDeliveryChannel` — so you get Vonage's global delivery *plus* Rebel's fraud guard, rate limiting, fallback and audit on top. Part of the `padosoft/laravel-rebel-*` suite.

 [![Laravel Rebel](resources/screenshoots/Laravel-Rebel-banner.png)](resources/screenshoots/Laravel-Rebel-banner.png)

 [![Laravel 12|13](https://camo.githubusercontent.com/9e9b743bcbf97a29fe735334a4a8e906d05d60310969905af6607cef8da30138/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d313225323025374325323031332d4646324432303f7374796c653d666c61742d737175617265266c6f676f3d6c61726176656c266c6f676f436f6c6f723d7768697465)](https://camo.githubusercontent.com/9e9b743bcbf97a29fe735334a4a8e906d05d60310969905af6607cef8da30138/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d313225323025374325323031332d4646324432303f7374796c653d666c61742d737175617265266c6f676f3d6c61726176656c266c6f676f436f6c6f723d7768697465) [![PHP 8.3+](https://camo.githubusercontent.com/6aa777dd33ef43fbef727d8187b578003a61e5dc41bbc958b0938c996cdc92f2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e33253230253743253230382e34253230253743253230382e352d3737374242343f7374796c653d666c61742d737175617265266c6f676f3d706870266c6f676f436f6c6f723d7768697465)](https://camo.githubusercontent.com/6aa777dd33ef43fbef727d8187b578003a61e5dc41bbc958b0938c996cdc92f2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e33253230253743253230382e34253230253743253230382e352d3737374242343f7374796c653d666c61742d737175617265266c6f676f3d706870266c6f676f436f6c6f723d7768697465) [![PHPStan max](https://camo.githubusercontent.com/4b9a3c97d76534abb905e64bd9e5bb9f13fe68e962071e0ccbbe7b629112f11c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6d61782d3241364644423f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/4b9a3c97d76534abb905e64bd9e5bb9f13fe68e962071e0ccbbe7b629112f11c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6d61782d3241364644423f7374796c653d666c61742d737175617265) [![Pest 4](https://camo.githubusercontent.com/9b9da1d7d243a7465ab338e9374e47300a7fe2e26b5c291e7e3c95b53153789a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f74657374732d50657374253230342d3232433535453f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/9b9da1d7d243a7465ab338e9374e47300a7fe2e26b5c291e7e3c95b53153789a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f74657374732d50657374253230342d3232433535453f7374796c653d666c61742d737175617265) [![Vonage](https://camo.githubusercontent.com/e5aa0450e854c667d7e69fd3e9989e917b88e2aab546bbf82b55ee899899df07/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f566f6e6167652d566572696679253230253242253230534d532d3030303030303f7374796c653d666c61742d737175617265266c6f676f3d766f6e616765266c6f676f436f6c6f723d7768697465)](https://camo.githubusercontent.com/e5aa0450e854c667d7e69fd3e9989e917b88e2aab546bbf82b55ee899899df07/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f566f6e6167652d566572696679253230253242253230534d532d3030303030303f7374796c653d666c61742d737175617265266c6f676f3d766f6e616765266c6f676f436f6c6f723d7768697465) [![MIT](https://camo.githubusercontent.com/ac049ef4e7a0b7196b09add6ac2d4f180e544c0ac779c2b2ac2fd2723a209579/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75653f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/ac049ef4e7a0b7196b09add6ac2d4f180e544c0ac779c2b2ac2fd2723a209579/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75653f7374796c653d666c61742d737175617265)

---

Table of contents
-----------------

[](#table-of-contents)

- [What it is](#what-it-is)
- [Quick glossary](#quick-glossary)
- [Why this package](#why-this-package)
- [Rebel + Vonage vs the alternatives](#rebel--vonage-vs-the-alternatives)
- [Vonage dashboard setup (step by step)](#vonage-dashboard-setup-step-by-step)
- [Installation](#installation)
- [Configuration](#configuration)
- [Usage](#usage)
- [Delivery receipts (status webhook)](#delivery-receipts-status-webhook)
- [Live tests against the real API](#live-tests-against-the-real-api)
- [`.env.example`](#envexample)
- [Security notes](#security-notes)
- [Testing &amp; License](#testing--license)

---

What it is
----------

[](#what-it-is)

A thin, well-tested **Vonage** provider for Rebel Channels. You don't call it directly — you call the Channels `VerificationRouter`, and it routes through this provider (with Rebel's bot gate, IRSF defences, per-number rate limit, fallback and audit around it).

It speaks two Vonage APIs:

- **Vonage Verify** — start + check one-time codes over SMS / voice. Vonage generates, sends and validates the OTP; **you never store or generate the code yourself**.
- **Vonage SMS API** — send a plain SMS (e.g. a transactional notification) as a `MessageDeliveryChannel`.

A small **gateway seam** (`VonageGateway`) wraps the HTTP calls, so the whole thing is unit-testable offline and has a real **live** test-suite for the actual API.

Depends on [`padosoft/laravel-rebel-core`](https://github.com/padosoft/laravel-rebel-core)and [`padosoft/laravel-rebel-channels`](https://github.com/padosoft/laravel-rebel-channels).

```
            ┌─────────────────────────────────────────────┐
 your app   │  Channels VerificationRouter                │
   │        │   ├─ bot gate · IRSF guard · rate limit      │
   └───────▶│   ├─ fallback order  ─────────┐              │
            │   └─ HMAC'd audit trail        ▼             │
            │                       VonageVerifyProvider   │
            └───────────────────────────────┬─────────────┘
                                             │  VonageGateway (seam)
                                             ▼
                              Verify /verify/json · /verify/check/json
                              SMS    /sms/json
                                             │
                       delivery receipt ◀────┘  POST /rebel/vonage/status
                       (delivered / failed / cost) → audit event

```

---

Quick glossary
--------------

[](#quick-glossary)

TermIn plain words**Vonage Verify**A Vonage product that sends and checks one-time codes for you — you never store or generate the OTP.**API key / API secret**Your Vonage account credentials, shown on the dashboard home page.**`request_id`**The handle Vonage returns when you start a verification; you pass it back to check the code.**Brand**The sender name (≤18 alphanumeric chars) shown in the Verify message body.**DLR***Delivery receipt* — Vonage's server-to-server callback telling you whether an SMS was delivered, and what it cost.**Channel**`sms` or `voice`.---

Why this package
----------------

[](#why-this-package)

★WhatIn short★★★**Vonage Verify, fully wrapped**Start + check codes over SMS/voice; you never handle the OTP yourself.★★★**Rebel guarantees for free**Inherits the Channels fraud guard (IRSF), rate limit, fallback and HMAC'd audit.★★**SMS delivery too**Doubles as a `MessageDeliveryChannel` for plain transactional SMS via the Vonage SMS API.★★**Never throws out**Any transport error becomes a clean `provider_error`, so the router can fall back to another provider.★★**Offline-testable**A gateway seam + fake means your tests don't hit Vonage; a separate live suite does.★★**Real delivery receipts**A signed DLR webhook records delivered/failed + cost so the panel shows real numbers.★**Safe by default**No credentials → nothing registers, and no client is ever built with empty keys.---

Rebel + Vonage vs the alternatives
----------------------------------

[](#rebel--vonage-vs-the-alternatives)

Sending an OTP with Vonage, four ways:

Capability**Rebel + this package**ShopifyVonage Verify SDK (direct)Raw Vonage SMS + your own OTPSend/check a code via Vonage✅❌✅➖ (you build OTP logic)You never store/generate the OTP✅✅✅❌Anti toll-fraud / IRSF guard✅❌❌❌Per-number rate limit + bot gate✅➖❌❌**Provider fallback** to another vendor✅❌❌❌Signed, phone-bound reference (anti replay)✅❌❌❌Unified audit trail (number HMAC'd)✅❌❌❌Delivery receipts → delivered-rate + cost in panel✅❌➖➖Graceful failure → router fallback✅❌❌❌> Legend: ✅ built-in · ➖ partial / hosted-only · ❌ not available. Vonage is excellent at delivery; this package keeps all of that and adds the Rebel fraud/routing/audit layer around it. Shopify is a closed, hosted commerce platform: it sends its own customer OTPs but lets you neither pick Vonage as the sender, self-host it, fall back across vendors, nor configure its fraud controls — a black box, not a developer-facing verification library.

---

Vonage dashboard setup (step by step)
-------------------------------------

[](#vonage-dashboard-setup-step-by-step)

1. **Create a Vonage account** at [dashboard.nexmo.com/sign-up](https://dashboard.nexmo.com/sign-up). The **free trial** gives you a small credit — note that trial accounts can only send to **whitelisted** test numbers (add your test phone under *Account → Test numbers*).
2. **Grab your credentials**: on the [dashboard home page](https://dashboard.nexmo.com) copy your **API key** and **API secret** (top of the page).
3. **(SMS sends only)** decide your **sender ID** — an alphanumeric name (e.g. `RebelApp`, where alphanumeric senders are allowed) or a Vonage **virtual number** you rent under *Numbers → Buy numbers*. Put it in `VONAGE_SMS_FROM`.
4. **(Delivery receipts)** set the **Delivery Receipts** webhook URL (under *Account → API settings → SMS settings*, or per-application) to `https:///rebel/vonage/status` (see below).
5. Put the values in your `.env` (see below). Done — the provider auto-registers.

> **Pricing:** Vonage Verify is billed per successful verification + the channel cost; SMS is billed per segment. The free trial credit is enough to test end-to-end. Always keep the Rebel **geo allowlist** (in `laravel-rebel-channels`) tight to avoid IRSF charges.

---

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

[](#installation)

```
composer require padosoft/laravel-rebel-channel-vonage
php artisan vendor:publish --tag="rebel-channel-vonage-config"
```

Add your credentials to `.env`:

```
VONAGE_API_KEY=xxxxxxxx
VONAGE_API_SECRET=xxxxxxxxxxxxxxxx
VONAGE_BRAND=Verify
VONAGE_SMS_FROM=RebelApp
```

That's it — the provider registers itself into the Channels router under the key `vonage`.

---

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

[](#configuration)

File `config/rebel-channel-vonage.php`:

KeyDefaultWhat it does`api_key``env(VONAGE_API_KEY)`Vonage API key.`api_secret``env(VONAGE_API_SECRET)`Vonage API secret.`brand``env(VONAGE_BRAND, 'Verify')`Verify sender name (≤18 alphanumeric chars).`sms_from``env(VONAGE_SMS_FROM)`Sender ID for plain SMS sends.`channels``['sms','voice']`Which Rebel channels this provider may handle.`register_provider``true`Auto-register into the Channels registry (when credentials exist).`webhook.enabled``true`Register the delivery-receipt callback endpoint.`webhook.validate_signature``false`Validate the Vonage `sig` on the webhook (enable once you turn on request signing).`webhook.signature_secret``env(VONAGE_SIGNATURE_SECRET)`The signature secret from the dashboard.`webhook.signature_method``md5hash`Signature method: `md5hash` (default) or HMAC `md5`/`sha1`/`sha256`/`sha512`.`webhook.path``rebel/vonage/status`The webhook route path.---

Usage
-----

[](#usage)

### Verification (the common case)

[](#verification-the-common-case)

You typically don't touch this package directly — you use the Channels router:

```
use Padosoft\Rebel\Channels\Enums\Channel;
use Padosoft\Rebel\Channels\Routing\VerificationRouter;
use Padosoft\Rebel\Core\Context\SecurityContext;
use Padosoft\Rebel\Core\Contracts\KeyedHasher;
use Padosoft\Rebel\Core\Identifiers\PhoneIdentifier;

$router = app(VerificationRouter::class);
$ctx = SecurityContext::fromRequest($request, app(KeyedHasher::class));

// Send a code (Vonage Verify delivers it)
$start = $router->start(PhoneIdentifier::from('+39 333 1234567'), Channel::Sms, $ctx);

// Keep $start->reference (the Vonage request_id) — you pass it back on check.
$reference = $start->reference;

// Check what the user typed
$result = $router->check(PhoneIdentifier::from('+39 333 1234567'), $request->string('code'), $reference, $ctx);
if ($result->approved()) {
    // verified!
}
```

> **Note:** Vonage checks the code against the `request_id` returned by `start()` — **not** the phone number. Always store and pass back `$start->reference`. (Without it, `check()` fails closed with `missing_reference`.)

To force Vonage specifically, set it first in the Channels fallback order:

```
// config/rebel-channels.php
'providers' => ['vonage'],
```

### Plain SMS delivery

[](#plain-sms-delivery)

The provider also implements `MessageDeliveryChannel`, so you can send a transactional SMS:

```
use Padosoft\Rebel\Channels\Contracts\MessageDeliveryChannel;
use Padosoft\Rebel\Channels\Enums\Channel;
use Padosoft\Rebel\Channels\Routing\ProviderRegistry;

$vonage = app(ProviderRegistry::class)->get('vonage');

if ($vonage instanceof MessageDeliveryChannel) {
    $result = $vonage->send(
        PhoneIdentifier::from('+39 333 1234567'),
        'Your order has shipped!',
        Channel::Sms,
        $ctx,
    );

    $result->accepted(); // true when Vonage accepted it for delivery
}
```

---

Delivery receipts (status webhook)
----------------------------------

[](#delivery-receipts-status-webhook)

Vonage knows whether an SMS was actually **delivered**, **failed**, and exactly how much it **cost** — but only it knows, unless you let it call you back. This package ships a delivery-receipt (DLR) webhook that turns those callbacks into Rebel audit events, so the admin panel's **Channel Performance** can show real delivered / failed rates and spend per channel.

**What it records.** On each callback the endpoint writes one audit event (recipient number stored only as a keyed HMAC, never in clear):

Vonage statusAudit `event_type``delivered``channel.verification.delivered``failed`, `rejected`, `expired`, `undeliverable``channel.verification.undelivered``accepted`, `buffered`, `unknown`, …`channel.verification.dispatched`Each event carries `channel: 'sms'`, `provider: 'vonage'`, the HMAC'd recipient, and a `metadata`object:

```
{
  "message_status": "delivered",
  "price": 0.0333,
  "price_unit": null,
  "message_sid": "0A00000123ABCD01",
  "error_code": "0"
}
```

It accepts **both** DLR shapes Vonage uses:

- the classic **SMS-API** DLR (`msisdn`, `messageId`, `err-code`, `price`), and
- the newer **Messages-API** status callback (`to`, `message_uuid`, `usage.price`, `usage.currency`).

(Vonage quotes `price` as a positive string; we store the **absolute** value so spend sums cleanly, and to stay consistent with the other Rebel channel providers. `price`/`error_code` are `null` when absent.)

**Set the webhook URL.** In the Vonage dashboard, point the **Delivery Receipts** callback at your app:

```
https:///rebel/vonage/status

```

The endpoint is enabled by default (`REBEL_VONAGE_WEBHOOK=true`); set it to `false` to drop the route. The path is configurable via `webhook.path`.

**Signature validation.** The route has **no auth middleware** — Vonage posts server-to-server. Vonage only signs callbacks when you enable **request signing** on the account; once you do, set `webhook.validate_signature=true` and provide the `signature_secret` (and the matching `signature_method`). Every request must then carry a valid `sig` (recomputed from the sorted params

- your secret); a missing or forged signature is rejected with **403** and nothing is recorded. A malformed or empty payload is acknowledged with **204** and recorded as nothing, so a junk callback never 500s.

```
REBEL_VONAGE_WEBHOOK=true             # register the /rebel/vonage/status route
REBEL_VONAGE_WEBHOOK_VALIDATE=false   # set true once request signing is on
VONAGE_SIGNATURE_SECRET=              # the signature secret from the dashboard
VONAGE_SIGNATURE_METHOD=md5hash       # md5hash | md5 | sha1 | sha256 | sha512
REBEL_VONAGE_WEBHOOK_PATH=rebel/vonage/status
```

> Build now, wire live later: the endpoint and its audit events exist today, so you can simulate Vonage callbacks (the test suite does exactly that) and the admin aggregates real delivered/cost data as soon as you set the DLR URL in Vonage.

---

Live tests against the real API
-------------------------------

[](#live-tests-against-the-real-api)

The offline suite uses a fake gateway. To exercise the **real** Vonage Verify API (`tests/Live`), opt in explicitly — it **sends a real message**:

```
# .env (or shell env)
REBEL_VONAGE_LIVE=1
VONAGE_TEST_PHONE=+39XXXXXXXXXX   # a whitelisted test number on trial accounts

vendor/bin/pest --group=live
```

Without `REBEL_VONAGE_LIVE=1` or with any credential missing, the live tests **self-skip**, so `composer test` and external PRs never trigger a send. In CI, supply the values as **secrets** and set `REBEL_VONAGE_LIVE=1` on a dedicated job.

---

`.env.example`
--------------

[](#envexample)

```
VONAGE_API_KEY=xxxxxxxx
VONAGE_API_SECRET=xxxxxxxxxxxxxxxx
VONAGE_BRAND=Verify
VONAGE_SMS_FROM=RebelApp
REBEL_VONAGE_REGISTER=true

REBEL_VONAGE_WEBHOOK=true
REBEL_VONAGE_WEBHOOK_VALIDATE=false
VONAGE_SIGNATURE_SECRET=
VONAGE_SIGNATURE_METHOD=md5hash
REBEL_VONAGE_WEBHOOK_PATH=rebel/vonage/status

# Live tests (opt-in: SENDS A REAL MESSAGE)
REBEL_VONAGE_LIVE=0
VONAGE_TEST_PHONE=+391234567890
```

---

Security notes
--------------

[](#security-notes)

- **No client with empty keys**: the Vonage gateway is only constructed when both the API key and secret are present.
- **No exception leakage**: transport errors are caught and returned as a generic `provider_error`— Vonage internals never bubble up to your app or logs.
- **Explicit status mapping**: only Vonage's `0` is treated as success; any unexpected status fails closed (no bogus "pending" with an empty reference).
- **No PII in clear**: the recipient number in delivery receipts is stored only as a keyed HMAC; OTPs and secrets are never logged.
- **Keep IRSF defences on**: pair this with the Channels geo allowlist / per-prefix cap to avoid premium-rate fraud charges.

---

🔋 Vibe coding with batteries included
-------------------------------------

[](#-vibe-coding-with-batteries-included)

This package ships **AI batteries** — so you (and your AI agent) can extend it correctly on the first try:

- **`CLAUDE.md`** — a concise AI working guide (purpose, conventions, architecture, how to extend, Definition of Done). Plain Markdown, so Claude Code, Cursor, Copilot and Codex all read it.
- **`AGENTS.md`** — the agent/workflow contract (branch → PR → CI → tag/release, the gates).
- **`.claude/skills/`** — invocable skills (at least `rebel-package-dev`) encoding the suite's TDD loop, the **PHPStan-level-max** recipes, the security/telemetry rules, and the release discipline.

Open the repo in your AI editor and just start — the rules, guardrails and extension recipes come with it. PRs that follow the shipped `CLAUDE.md` pass CI (PHPStan max + Pest + Pint) and review the first time around.

Testing &amp; License
---------------------

[](#testing--license)

```
composer test      # Pest (provider + gateway + webhook + Channels integration; live suite self-skips)
composer phpstan   # static analysis, level max
composer pint      # code style
```

**License:** MIT — see [LICENSE](LICENSE). Part of the [`padosoft/laravel-rebel`](https://github.com/padosoft) suite.

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance91

Actively maintained with recent releases

Popularity1

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity40

Maturing project, gaining track record

 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

Unknown

Total

1

Last Release

51d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/10467699?v=4)[Lorenzo](/maintainers/lopadova)[@lopadova](https://github.com/lopadova)

---

Top Contributors

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

---

Tags

laravelAuthenticationverifysmsvonagenexmopadosoftRebel

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/padosoft-laravel-rebel-channel-vonage/health.svg)

```
[![Health](https://phpackages.com/badges/padosoft-laravel-rebel-channel-vonage/health.svg)](https://phpackages.com/packages/padosoft-laravel-rebel-channel-vonage)
```

###  Alternatives

[defstudio/telegraph

A laravel facade to interact with Telegram Bots

813336.8k3](/packages/defstudio-telegraph)[harris21/laravel-fuse

Circuit breaker for Laravel queue jobs. Protect your workers from cascading failures.

45955.7k](/packages/harris21-laravel-fuse)[rawilk/profile-filament-plugin

Profile &amp; MFA starter kit for filament.

3914.8k](/packages/rawilk-profile-filament-plugin)[masterix21/laravel-licensing

Laravel licensing package with polymorphic assignment to any model, activation keys, expirations/renewals, and seat control via LicenseUsage. Supports offline verification with public-key–signed tokens, a CLI to generate/rotate/revoke keys, and an extensible architecture via config and contracts.

1613.3k4](/packages/masterix21-laravel-licensing)[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)
