PHPackages                             elgibor-solution/laravel-whatsapp-meta - 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. elgibor-solution/laravel-whatsapp-meta

ActiveLibrary[API Development](/categories/api)

elgibor-solution/laravel-whatsapp-meta
======================================

Laravel package for Meta WhatsApp Business Cloud API: templates CRUD, sending messages, multi-account, broadcasts, webhooks.

1.0.2(3mo ago)2961↓50%Apache-2.0PHPPHP &gt;=8.2

Since Aug 24Pushed 3mo agoCompare

[ Source](https://github.com/elgiborsolution/laravel-whatsapp)[ Packagist](https://packagist.org/packages/elgibor-solution/laravel-whatsapp-meta)[ RSS](/packages/elgibor-solution-laravel-whatsapp-meta/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (3)Dependencies (6)Versions (8)Used By (0)

Laravel WhatsApp Cloud API Package
==================================

[](#laravel-whatsapp-cloud-api-package)

Laravel package for integrating **Meta WhatsApp Business Cloud API**, providing:

- **CRUD Templates** for WhatsApp Business
- **Send messages** (text, media, template, interactive, location, document)
- **Multi-account support** (auto-pick default if only one)
- **Broadcast** to millions of recipients (chunking, scheduling, job queue)
- **Webhook** to update message status (sent, delivered, read, failed)
- **Inbound Tokens** for OTP, Vouchers, and mixed-message parsing
- **Queue + Retry** for reliability

---

🚀 Installation
--------------

[](#-installation)

1. Install:

```
composer require elgibor-solution/laravel-whatsapp-meta:*
```

3. Publish config &amp; migrations:

```
php artisan vendor:publish --tag=whatsapp-config
php artisan vendor:publish --tag=whatsapp-migrations
php artisan migrate
```

4. Add to **scheduler**:

```
// routes/console.php
$schedule->command('whatsapp:broadcast-run')->everyMinute();
```

---

⚙️ Configuration
----------------

[](#️-configuration)

### Single Account (via `.env`)

[](#single-account-via-env)

```
WHATSAPP_SINGLE_ACCOUNT=true
WHATSAPP_NAME=default
WHATSAPP_PHONE_NUMBER_ID=YOUR_PHONE_ID
WHATSAPP_ACCESS_TOKEN=YOUR_LONG_LIVED_TOKEN
WHATSAPP_WABA_ID=YOUR_WABA_ID
WHATSAPP_WEBHOOK_VERIFY_TOKEN=change-me
```

### Multi Account

[](#multi-account)

If multiple accounts are needed:

- Insert rows into `whatsapp_accounts` table (migration provided).
- Mark one with `is_default = 1` as the default account.

---

📡 Routes
--------

[](#-routes)

All endpoints are available with prefix `/whatsapp/*`:

- `GET /whatsapp/webhook` – webhook verification
- `POST /whatsapp/webhook` – handle message status updates
- `POST /whatsapp/messages/send` – send a message
- `GET/POST/PUT/DELETE /whatsapp/templates` – manage templates
- `POST /whatsapp/broadcasts` – create broadcast
- `POST /whatsapp/broadcasts/{id}/schedule` – schedule broadcast
- `POST /whatsapp/broadcasts/{id}/pause|resume` – control broadcast

---

🧩 Usage via Facade
------------------

[](#-usage-via-facade)

```
use WhatsApp;
use ESolution\WhatsApp\Models\WhatsappAccount;

$acc = WhatsappAccount::resolve();

// 1. Send text
WhatsApp::sendText($acc, '08123456789', 'Hello from Cloud API!');

// 2. Send template
WhatsApp::sendTemplate($acc, '08123456789', 'order_update', 'en', [
    ['type'=>'body','parameters'=>[['type'=>'text','text'=>'John']]]
]);

// 3. Send media
WhatsApp::sendMedia($acc, '08123456789', 'image', [
    'link'=>'https://example.com/img.jpg',
    'caption'=>'Promo'
]);

// 4. Send location
WhatsApp::sendLocation($acc, '08123456789', -6.2, 106.8, 'Office', 'Jakarta');

// 5. Send interactive
WhatsApp::sendInteractive($acc, '08123456789', [
    'type'=>'list',
    'header'=>['type'=>'text','text'=>'Menu'],
    'body'=>['text'=>'Choose option'],
    'footer'=>['text'=>'E-Solution'],
    'action'=>[
        'button'=>'View',
        'sections'=>[
            ['title'=>'Products','rows'=>[
                ['id'=>'prod1','title'=>'Product 1','description'=>'Description 1'],
                ['id'=>'prod2','title'=>'Product 2','description'=>'Description 2'],
            ]]
        ]
    ]
]);
```

---

🔑 Inbound Tokens (OTP / Vouchers)
---------------------------------

[](#-inbound-tokens-otp--vouchers)

Allow users to verify or claim items by sending a unique code back to your WhatsApp Business Number. The system automatically searches for these tokens even if they are buried within a longer message.

### 1. Create a Token

[](#1-create-a-token)

```
use ESolution\WhatsApp\Facades\WhatsApp;

// Generate an 8-character alphanumeric code (default)
$token = WhatsApp::createToken('08123456789', 'otp');

// Generate a 10% discount voucher valid for 1 hour
$voucher = WhatsApp::createToken('08123456789', 'voucher', [
    'discount' => '10%',
    'campaign' => 'black_friday'
], [
    'expires_in' => 60,
    'length' => 12
]);

// Generate a secure UUID token
$uuid = WhatsApp::createToken('08123456789', 'secure_claim', [], [
    'format' => 'uuid'
]);
```

### 2. Handle Verification

[](#2-handle-verification)

When the user sends a message containing the token (e.g., "Hi, here is my code: ABC-123"), the package fires an event.

**Register Listeners:**

```
// app/Providers/EventServiceProvider.php
protected $listen = [
    'whatsapp.token.verified' => [
        \App\Listeners\LogVerification::class,
    ],
    /** OR type-specific listener **/
    'whatsapp.token.verified.voucher' => [
        \App\Listeners\ApplyDiscount::class,
    ],
];
```

**Listener Example:**

```
public function handle($token)
{
    // $token is an instance of ESolution\WhatsApp\Models\WhatsappToken
    $phone = $token->phone;
    $metadata = $token->metadata; // ['discount' => '10%', ...]

    // Perform your logic here
}
```

---

📜 Template CRUD
---------------

[](#-template-crud)

```
$acc = WhatsappAccount::resolve();

// List
$list = WhatsApp::listTemplates($acc);

// Create
$tpl = WhatsApp::createTemplate($acc, [
  'name'=>'promo_aug',
  'category'=>'MARKETING',
  'language'=>'en',
  'components'=>[['type'=>'BODY','text'=>'Hello {{1}}, August promo!']]
]);

// Delete
WhatsApp::deleteTemplate($acc, 'promo_aug', 'en');
```

---

📢 Broadcast
-----------

[](#-broadcast)

### Create Broadcast

[](#create-broadcast)

```
POST /whatsapp/broadcasts
{
  "name": "Promo August",
  "type": "template",
  "payload": {
    "name": "promo_aug",
    "language": "en",
    "components": [
      { "type": "body", "parameters": [ { "type": "text", "text": "Customer" } ] }
    ]
  },
  "recipients": ["0811111111","0812222222","0813333333"],
  "chunk_size": 2000,
  "rate_per_min": 6000
}
```

### Schedule Broadcast

[](#schedule-broadcast)

```
POST /whatsapp/broadcasts/1/schedule
{ "scheduled_at": "2025-08-24 22:00:00" }
```

### Run Scheduler

[](#run-scheduler)

```
php artisan schedule:run
```

Broadcasts will be dispatched in chunks using `SendBroadcastChunkJob` with respect to `chunk_size` and `rate_per_min`.

---

🚀 Tech Provider (Partner) Services
----------------------------------

[](#-tech-provider-partner-services)

For Meta Tech Providers, this package provides specialized services and **API endpoints** for managing client accounts at scale.

### 🌐 API Endpoints

[](#-api-endpoints)

All routes are prefixed with `/whatsapp/` (customizable in config).

#### 📱 Asset Management (Phone Numbers)

[](#-asset-management-phone-numbers)

- `GET /accounts/{acc_id}/phone-numbers` – List phone numbers for WABA.
- `GET /accounts/{acc_id}/phone-numbers/{phone_id}` – Get details.
- `POST /accounts/{acc_id}/phone-numbers/{phone_id}/register` – Register for Cloud API.
- `POST /accounts/{acc_id}/phone-numbers/{phone_id}/verify` – Verify with SMS code.

#### 🌊 WhatsApp Flows

[](#-whatsapp-flows)

- `GET /accounts/{acc_id}/flows` – List all flows.
- `POST /accounts/{acc_id}/flows` – Create new flow.
- `POST /accounts/{acc_id}/flows/{flow_id}/assets` – Upload JSON asset.
- `POST /accounts/{acc_id}/flows/{flow_id}/publish` – Publish flow.

#### 📁 Media Management

[](#-media-management)

- `POST /accounts/{acc_id}/media` – Upload media (multipart/form-data).
- `GET /accounts/{acc_id}/media/{media_id}` – Get metadata.
- `DELETE /accounts/{acc_id}/media/{media_id}` – Delete media.

#### 🤝 Onboarding

[](#-onboarding)

- `POST /onboarding/exchange-token` – Exchange short-lived FB token.
- `POST /onboarding/debug-token` – Get WABA/token info.

#### 👤 Business Profile

[](#-business-profile)

- `GET /accounts/{acc_id}/profile/{phone_id}` – Get profile.
- `POST /accounts/{acc_id}/profile/{phone_id}` – Update profile fields.

#### 📊 Analytics &amp; Health

[](#-analytics--health)

- `GET /accounts/{acc_id}/analytics` – WABA messaging metrics.
- `GET /accounts/{acc_id}/phone-numbers/{phone_id}/health` – Quality rating &amp; status.

---

🔑 Inbound Tokens (OTP / Vouchers)
---------------------------------

[](#-inbound-tokens-otp--vouchers-1)

### 🌐 API Endpoints

[](#-api-endpoints-1)

- `POST /whatsapp/tokens` – Create a token.
- `POST /whatsapp/tokens/consume` – Manually verify token from string.

---

🔔 Webhook
---------

[](#-webhook)

- **URL**: `/whatsapp/webhook`
- **Verify**: Meta calls `GET /webhook?hub_mode=subscribe&hub_verify_token=xxx&hub_challenge=1234`
- **Status**: Meta sends `POST` updates with message status (`sent`, `delivered`, `read`, `failed`).
- **Call Permission**: Meta sends `POST` updates with call\_permission\_reply status (`accept`, `reject`).
- **Forwarding**: If `webhook_forward_url` is set for an account, the raw payload is forwarded to that URL via a queued POST request.

Statuses are saved to:

- `whatsapp_messages`
- `whatsapp_broadcast_recipients`

Call permission are broadcast through event: `whatsapp.call_permission.updated`

You need to create your own event listener and register it at EventServiceProvider

```
// app/Providers/EventServiceProvider.php
protected $listen = [
  'whatsapp.call_permission.updated' => [
    \App\Listeners\HandleCallPermissionUpdated::class,
  ],
];
```

---

⏱️ Queue &amp; Retry
--------------------

[](#️-queue--retry)

- Messages are sent via `SendMessageJob`.
- Broadcasts are handled via `SendBroadcastChunkJob`.
- Use Redis / SQS / Horizon queues for scaling.
- Automatic retry: `tries = 3`, `backoff = 30s`.

---

✅ Best Practices
----------------

[](#-best-practices)

- Always use **APPROVED templates** for outbound messages beyond 24h window.
- Respect **WABA tier rate limits**. `rate_per_min` only throttles locally.
- Media must be **public URLs**.
- Phone numbers are normalized: leading `0` → `62`. Adjust if needed.
- Store and log Graph API responses for error analysis.

---

🧪 Testing
---------

[](#-testing)

The package uses **Orchestra Testbench** for comprehensive testing.

1. Install dev dependencies:

```
composer install
```

2. Run tests:

```
./vendor/bin/phpunit
```

Test coverage includes:

- **Unit**: Component logic and traits.
- **Integration**: Database models and migrations.
- **Feature**: Webhook routes and payload processing.

---

Support &amp; Hiring
--------------------

[](#support--hiring)

Need professional help or want to move faster? **Hire the E-Solution / Elgibor team** for integration, audits, or custom features.
📧 ****

---

Donations
---------

[](#donations)

If this package saves you time, consider supporting development ❤️

- **Ko‑fi**: [![ko-fi](https://camo.githubusercontent.com/201ef269611db7eb6b5d08e9f756ab8980df3014b64492770bdf13a6ed924641/68747470733a2f2f6b6f2d66692e636f6d2f696d672f676974687562627574746f6e5f736d2e737667)](https://ko-fi.com/U7U21L7D5J)

###  Health Score

43

—

FairBetter than 91% of packages

Maintenance81

Actively maintained with recent releases

Popularity21

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity53

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

Every ~84 days

Total

3

Last Release

98d ago

PHP version history (2 changes)1.0.0PHP &gt;=8.1

1.0.1PHP &gt;=8.2

### Community

Maintainers

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

---

Top Contributors

[![elgibor-solution](https://avatars.githubusercontent.com/u/783039?v=4)](https://github.com/elgibor-solution "elgibor-solution (37 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/elgibor-solution-laravel-whatsapp-meta/health.svg)

```
[![Health](https://phpackages.com/badges/elgibor-solution-laravel-whatsapp-meta/health.svg)](https://phpackages.com/packages/elgibor-solution-laravel-whatsapp-meta)
```

###  Alternatives

[spatie/laravel-query-builder

Easily build Eloquent queries from API requests

4.4k26.9M220](/packages/spatie-laravel-query-builder)[essa/api-tool-kit

set of tools to build an api with laravel

52680.5k](/packages/essa-api-tool-kit)[joggapp/laravel-aws-sns

Laravel package for the SNS events by AWS

3171.8k](/packages/joggapp-laravel-aws-sns)[esign/laravel-conversions-api

A laravel wrapper package around the Facebook Conversions API

69145.4k](/packages/esign-laravel-conversions-api)[surface/laravel-webfinger

A Laravel package to create an ActivityPub webfinger.

113.8k](/packages/surface-laravel-webfinger)

PHPackages © 2026

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