Laravel with WhatsApp Integration — Up‑to‑Date Messages via WhatsApp

Laravel with WhatsApp Integration — Up‑to‑Date Messages via WhatsApp

Published: 21 November 2025 · Category: Laravel · Author: Zeus Technocrats

Learn how to send real‑time notifications and bi‑directional messages from your Laravel app using WhatsApp: Business API, Twilio, MessageBird, or third‑party providers. Includes code, webhook handling, queued jobs, and best practices for production.

Why integrate WhatsApp with Laravel?

WhatsApp has very high open and read rates. For transactional alerts (invoices, OTPs, delivery updates) and customer conversations, WhatsApp provides a reliable channel with broad adoption. Integrating it into Laravel gives you a controlled, auditable, and automated messaging platform.

Use cases: order status updates, delivery ETA, OTPs, alerts from monitoring systems, support chat handoff.

Choose a WhatsApp provider

WhatsApp Business API must run through an approved provider (Meta or a BSP — Business Solution Provider). Popular options:

  • Twilio WhatsApp — easy SDKs, good docs, pay-as-you-go.
  • MessageBird — global reach, webhooks, templates.
  • Vonage — focused on messaging, good for multi-channel.
  • Direct WhatsApp Business API via Meta — full control but operationally heavier.

This guide uses Twilio examples (widely used) but concepts transfer to other providers.

High-level integration steps

  1. Choose provider and verify your WhatsApp Business profile (phone number + display name).
  2. Get API credentials (API key or Account SID + Auth Token for Twilio).
  3. Create message templates (for templated notifications) and get them approved if required.
  4. Implement sending from Laravel (HTTP client or provider SDK).
  5. Implement webhooks to receive incoming messages and delivery receipts.
  6. Queue messages and retry failures using Laravel queues.

Send a WhatsApp message from Laravel — Twilio example

Install Twilio SDK via Composer:

composer require twilio/sdk

Add credentials to .env:

TWILIO_SID=your_account_sid
TWILIO_TOKEN=your_auth_token
TWILIO_WHATSAPP_FROM=whatsapp:+1415XXXXXXX

Create a simple service to send messages: app/Services/WhatsAppService.php

namespace App\Services;

use Twilio\Rest\Client;

class WhatsAppService
{
    protected Client $client;
    protected string $from;

    public function __construct()
    {
        $this->client = new Client(config('services.twilio.sid'), config('services.twilio.token'));
        $this->from = config('services.twilio.whatsapp_from'); // e.g. whatsapp:+1415...
    }

    public function sendText(string $to, string $body): array
    {
        // to should be like: whatsapp:+9198XXXXXXXX
        $message = $this->client->messages->create($to, [
            'from' => $this->from,
            'body' => $body,
        ]);

        return $message->toArray();
    }
}

Usage in controller or job:

// inside a controller or job
$service = app(\App\Services\WhatsAppService::class);
$service->sendText('whatsapp:+9198XXXXXXXX', 'Your order #1234 is out for delivery');

Receive messages and delivery receipts (Webhooks)

Configure your provider's webhook URL (e.g., https://your-domain.com/webhooks/whatsapp). Create a controller to handle incoming events.

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Http\Response;

class WhatsAppWebhookController extends Controller
{
    public function handle(Request $request)
    {
        // Twilio posts form-encoded webhook. Example fields vary by provider.
        // Always verify signature (see Security section).
        $data = $request->all();

        // Example: user message
        if (isset($data['Body'])) {
            $from = $data['From']; // whatsapp:+9198...
            $body = $data['Body'];

            // Persist message and/or dispatch a job to respond
            \App\Models\WhatsAppMessage::create([
                'from' => $from,
                'message' => $body,
                'payload' => json_encode($data),
            ]);

            // Optionally queue an automated reply
            // dispatch(new \App\Jobs\AutoReplyJob($from, 'Thanks! We received your message.'));
        }

        return response('OK', 200);
    }
}

Tip: Use php artisan serve --port=8080 for local testing and ngrok to expose a temporary public URL for provider webhooks.

Working with message templates (mandatory for some message types)

Transactional or pre-approved messages often require templates (WhatsApp Business). Create templates in your provider console and include placeholders for variables. Use them for OTPs, invoices, and transactional updates.

Queues, retries & reliability

Sending messages synchronously will slow user requests and cause timeouts. Always dispatch message sending to a queue.

// Example job
namespace App\Jobs;

use App\Services\WhatsAppService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

class SendWhatsAppMessage implements ShouldQueue
{
    use Dispatchable, Queueable;

    protected string $to;
    protected string $body;

    public function __construct(string $to, string $body)
    {
        $this->to = $to;
        $this->body = $body;
    }

    public function handle(WhatsAppService $service)
    {
        $service->sendText($this->to, $this->body);
    }
}

Configure queue driver (Redis or database) and run workers with Supervisor or systemd. Use --tries and backoff strategies for transient failures.

Security & verification

Protect webhooks by verifying signatures:

  • Twilio: validate X-Twilio-Signature header.
  • Other providers: follow provider docs (HMAC or token verification).

Never store raw credentials in code — use environment variables and Laravel's encrypted storage if needed.

Compliance & message consent

WhatsApp requires that users opt-in to receive messages. Keep an audit trail of consent and allow users to opt out. For GDPR/PDPA compliance, store minimal PII and provide deletion mechanisms.

Testing and local development

Use provider sandbox environments (Twilio sandbox for WhatsApp) and local tunnels (ngrok) to test webhooks. In tests, mock the WhatsAppService or use dependency injection to swap a fake implementation.

// Example PHPUnit test snippet
public function test_send_whatsapp_message_job()
{
    Queue::fake();
    $job = new \App\Jobs\SendWhatsAppMessage('whatsapp:+9198...', 'Hello');
    dispatch($job);
    Queue::assertPushed(\App\Jobs\SendWhatsAppMessage::class);
}

Best practices & production checklist

  • Use queued jobs for sending messages.
  • Track delivery receipts using webhooks.
  • Implement idempotency for retries (store message UUIDs).
  • Use rate-limiting and backoff to avoid provider throttling.
  • Monitor queue length and failure rates (Horizon, Prometheus).

Conclusion

WhatsApp integration brings a powerful channel for notifications and customer conversations. With Laravel's queues, service layer, and webhooks, you can build a robust, scalable WhatsApp pipeline. Whether you use Twilio, MessageBird, or the direct WhatsApp Business API, the key is to queue work, verify webhooks, and handle retries safely.

If you want, we can implement a production-ready WhatsApp integration (including templates, multi-region delivery, and monitoring) for your project. Contact Zeus Technocrats.