Search by

nayanthakor / laravel-whatsapp

nayan333

Easy WhatsApp Cloud API messaging & notifications for Laravel (official Meta approach).

Package info

github.com/nayanthakor/laravel-whatsapp

pkg:composer/nayanthakor/laravel-whatsapp

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-09-02 12:37 UTC

This package is not auto-updated.

Last update: 2026-09-03 10:56:55 UTC


README

Easy WhatsApp messaging for Laravel using the official Meta WhatsApp Cloud API — no Node.js, no QR codes, no unofficial browser automation. Pure PHP over Guzzle. Built for sending notifications and alerts (order updates, OTPs, reminders), with a first-class Laravel Notification channel, a facade, multi-number support, and an optional webhook endpoint for delivery receipts.

Why the Cloud API

This package uses Meta's official Cloud API, which means reliable delivery, message templates, and no risk of your number being banned for automation. It does require a Meta Business account with an approved WhatsApp Business phone number. Because it is the official channel, notifications sent to a user who has not messaged you in the last 24 hours must use a pre-approved message template — free-form text only works inside that 24-hour window. This package makes both paths easy.

Requirements

  • PHP 8.1+
  • Laravel 10, 11, or 12
  • A Meta App with WhatsApp product added, a phone number ID, and a permanent access token

Installation

composer require nayanthakor/laravel-whatsapp
php artisan vendor:publish --tag=whatsapp-config

Add your credentials to .env:

WHATSAPP_PHONE_NUMBER_ID=123456789012345
WHATSAPP_ACCESS_TOKEN=EAAG...your-permanent-token...
WHATSAPP_BUSINESS_ACCOUNT_ID=098765432109876

# Optional — only needed if you use the webhook
WHATSAPP_WEBHOOK_VERIFY_TOKEN=some-random-string-you-choose
WHATSAPP_APP_SECRET=your-meta-app-secret

Where to find these: Meta App dashboard → WhatsApp → API Setup for the phone number ID and a temporary token, and WhatsApp → Configuration plus App settings → Basic for the business account ID and app secret. Generate a permanent token via a System User in Business Settings.

Quick start

The facade

use Nayan\WhatsApp\Facades\WhatsApp;

// Free-form text (only reaches users active in the last 24h)
WhatsApp::sendText('+919876543210', 'Your order has shipped!');

// A pre-approved template (the reliable path for notifications)
WhatsApp::sendTemplate(
    to: '+919876543210',
    name: 'order_update',
    language: 'en_US',
    bodyParameters: ['Nayan', '#1024', 'out for delivery']
);

Numbers can be passed in any human format — +91 98765 43210, (555) 010-1234 — the package strips everything to digits before sending. Always include the country code.

As a Laravel Notification (recommended)

This is the cleanest way for your clients to send alerts. Create a notification:

use Illuminate\Notifications\Notification;
use Nayan\WhatsApp\Notifications\WhatsAppMessage;

class OrderShipped extends Notification
{
    public function __construct(public string $orderNumber) {}

    public function via($notifiable): array
    {
        return ['whatsapp'];
    }

    public function toWhatsApp($notifiable): WhatsAppMessage
    {
        return WhatsAppMessage::create()
            ->template('order_update', 'en_US', [
                $notifiable->name,
                $this->orderNumber,
            ]);
    }
}

Tell Laravel where to deliver it by adding a route method to your notifiable model:

class User extends Authenticatable
{
    use Notifiable;

    public function routeNotificationForWhatsApp($notification): string
    {
        return $this->phone; // e.g. "+919876543210"
    }
}

Then send it anywhere:

$user->notify(new OrderShipped('#1024'));

// or on demand, without a stored model
Notification::route('whatsapp', '+919876543210')
    ->notify(new OrderShipped('#1024'));

Templates

Templates are created and approved in the Meta dashboard (WhatsApp → Manage templates), then referenced by name. The builder fills placeholders in order:

use Nayan\WhatsApp\Messages\TemplateMessage;
use Nayan\WhatsApp\Facades\WhatsApp;

$message = TemplateMessage::make('appointment_reminder', 'en_US')
    ->headerImage('https://example.com/logo.png')      // media header
    ->body(['Nayan', 'Sept 5, 3:00 PM'])               // fills {{1}}, {{2}}
    ->urlButton('confirm/abc123');                      // dynamic button suffix

WhatsApp::send('+919876543210', $message);

Multiple numbers

Register more connections in config/whatsapp.php and switch at runtime:

WhatsApp::connection('sales')->sendText('+919876543210', 'Hi from sales');

In a notification: WhatsAppMessage::create()->connection('sales')->template(...).

Webhook (delivery receipts & inbound messages)

The package auto-registers a webhook route at whatsapp/webhook (configurable). Point Meta's webhook there and set your verify token. Incoming events are dispatched as Laravel events so you can listen without touching package internals:

Event::listen('whatsapp.status', function (array $status) {
    // $status['status'] is one of: sent, delivered, read, failed
});

Event::listen('whatsapp.message', function (array $message, array $contacts) {
    // an inbound message from a user
});

Set WHATSAPP_APP_SECRET to have every incoming payload verified via its X-Hub-Signature-256 header. Set WHATSAPP_WEBHOOK_ENABLED=false to disable the route entirely if you only send notifications.

Error handling

Any API failure throws Nayan\WhatsApp\Exceptions\WhatsAppException with Meta's message, error code, and fbtrace_id available via $e->context().

use Nayan\WhatsApp\Exceptions\WhatsAppException;

try {
    WhatsApp::sendTemplate('+919876543210', 'order_update', 'en_US', ['Nayan']);
} catch (WhatsAppException $e) {
    report($e);
    logger()->warning('WhatsApp failed', $e->context());
}

Debugging

Set WHATSAPP_LOGGING=true to log every request and response to your configured log channel while integrating.

Testing

composer install
vendor/bin/phpunit

License

MIT