← Blog  •  12 Jun 2026  •  Tim LoginWA

Cara Kirim Notifikasi WhatsApp dari Website PHP & Laravel

Ada order baru masuk ke toko online kamu jam 11 malam. Email notifikasi terkirim, tapi baru dibaca pembeli besok sore, itu pun kalau tidak nyangkut di folder promosi. Padahal kalau notifikasinya masuk WhatsApp, hampir pasti dibaca dalam hitungan menit.

Di artikel ini kita akan bikin notifikasi WhatsApp otomatis dari website: mulai dari nol (daftar akun, scan QR) sampai kode PHP murni dan Laravel yang siap copy-paste, lengkap dengan contoh notifikasi order baru dan cara menangani error 429 dan 503. Total waktu praktiknya sekitar 15 menit.

Kenapa Notifikasi WhatsApp, Bukan Email?

Beberapa alasan praktis kenapa banyak website di Indonesia pindah ke WA untuk notifikasi transaksional:

  • Hampir semua pelanggan Indonesia aktif di WhatsApp, dan pesan WA biasanya dibaca jauh lebih cepat daripada email.
  • Tidak ada masalah spam folder seperti di email.
  • Bisa dua arah, pelanggan tinggal balas pesan kalau ada pertanyaan, dan kamu bisa pasang auto-reply.
  • Untuk kasus notifikasi internal (alert ke admin, laporan harian), WA jauh lebih "kerasa" daripada email yang menumpuk.

Untuk mengirim WA dari kode, ada dua jalan: WhatsApp Business API resmi (proses approval panjang, cocok untuk korporasi) atau WhatsApp gateway unofficial seperti LoginWA, Fonnte, atau Wablas yang bisa langsung jalan hari ini dengan nomor WA biasa. Tutorial ini memakai LoginWA karena paket gratisnya sudah cukup untuk eksperimen (500 pesan/bulan tanpa kartu kredit), tapi konsepnya sama untuk gateway lain.

Catatan jujur: karena unofficial, selalu ada risiko nomor dibatasi WhatsApp kalau dipakai spam. Gateway yang baik (termasuk LoginWA) memakai typing indicator dan delay acak menyerupai manusia untuk meminimalkan risiko, bukan menghilangkannya. Gunakan untuk notifikasi yang memang diharapkan pelanggan.

Yang Kamu Butuhkan

  • Nomor WhatsApp khusus pengirim (sebaiknya bukan nomor pribadi).
  • Akun LoginWA gratis, 500 pesan/bulan, dengan watermark kecil "Dikirim via loginwa.com".
  • PHP 7.4+ dengan ekstensi cURL, atau project Laravel.

Langkah 1: Daftar, Buat App, Scan QR

Daftar dengan OTP WhatsApp

Buka loginwa.com/auth/otp, masukkan nomor WA kamu, lalu masukkan kode OTP yang dikirim ke WhatsApp. Tidak perlu email atau kartu kredit.

Buat App dan ambil API key

Dari dashboard, buat App baru (misalnya "Toko Online"). Setiap app punya API key sendiri, salin dan simpan baik-baik, key ini yang dipakai di header Authorization semua request.

Scan QR untuk menghubungkan device

Masih di dashboard, tambahkan device lalu scan QR code-nya dengan aplikasi WhatsApp di HP nomor pengirim (menu Perangkat Tertaut), persis seperti login WhatsApp Web. Begitu status device berubah jadi connected, kamu siap kirim pesan.

Langkah 2: Tes Kirim dari Terminal

Sebelum menulis PHP, pastikan semuanya jalan dengan satu perintah cURL:

curl -X POST https://api.loginwa.com/api/v1/messages/send \
  -H "Authorization: Bearer API_KEY_KAMU" \
  -H "Content-Type: application/json" \
  -d '{"phone":"6281234567890","message":"Halo! Tes notifikasi dari terminal."}'

Nomor tujuan memakai format internasional tanpa tanda plus (62812..., bukan 0812...). Kalau pesan masuk ke WA kamu, lanjut ke kode PHP.

Langkah 3: Kirim WhatsApp dari PHP Murni (cURL)

Ini fungsi reusable yang bisa kamu taruh di file helper. API key diambil dari environment variable, jangan pernah hardcode di repository.

<?php

function kirimWhatsApp(string $phone, string $message): array
{
    $apiKey = getenv('LOGINWA_API_KEY');

    $ch = curl_init('https://api.loginwa.com/api/v1/messages/send');
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST           => true,
        CURLOPT_HTTPHEADER     => [
            'Authorization: Bearer ' . $apiKey,
            'Content-Type: application/json',
        ],
        CURLOPT_POSTFIELDS     => json_encode([
            'phone'   => $phone,
            'message' => $message,
        ]),
        CURLOPT_TIMEOUT        => 15,
    ]);

    $response  = curl_exec($ch);
    $httpCode  = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curlError = curl_error($ch);
    curl_close($ch);

    if ($response === false) {
        return ['ok' => false, 'status' => 0, 'error' => $curlError];
    }

    return [
        'ok'     => $httpCode >= 200 && $httpCode < 300,
        'status' => $httpCode,
        'body'   => json_decode($response, true) ?? [],
    ];
}

Fungsi ini mengembalikan array berisi status HTTP dan body response, jadi pemanggilnya bisa memutuskan mau retry, log, atau diam saja.

Contoh nyata: notifikasi order baru

Panggil fungsi tadi setelah order tersimpan ke database, misalnya di akhir proses checkout:

$order = [
    'name'    => 'Budi',
    'phone'   => '6281234567890',
    'invoice' => 'INV-2026-0612-001',
    'total'   => 'Rp250.000',
];

$pesan = "Halo {$order['name']}!\n\n"
       . "Pesanan kamu sudah kami terima dan sedang diproses.\n"
       . "No. Invoice: {$order['invoice']}\n"
       . "Total: {$order['total']}\n\n"
       . "Kami kabari lagi begitu paket dikirim. Terima kasih sudah belanja!";

$hasil = kirimWhatsApp($order['phone'], $pesan);

if (!$hasil['ok']) {
    error_log('Gagal kirim notifikasi WA: ' . json_encode($hasil));
}

Pola yang sama berlaku untuk notifikasi lain: pembayaran terkonfirmasi, resi pengiriman, reminder booking, sampai alert ke nomor admin kalau ada error di server.

Mau melampirkan gambar (misalnya bukti pembayaran atau foto produk)? Tambahkan tiga field di payload: "type":"image", "media_url":"https://contoh.com/invoice.jpg", dan "caption":"Invoice kamu". LoginWA mendukung gambar, video, dokumen, dan audio, detailnya ada di dokumentasi.

Langkah 4: Versi Laravel

Di Laravel kita pakai HTTP Client bawaan. Pertama, daftarkan kredensial di .env dan config/services.php:

// .env
// LOGINWA_API_KEY=api_key_kamu

// config/services.php
'loginwa' => [
    'key'      => env('LOGINWA_API_KEY'),
    'base_url' => 'https://api.loginwa.com',
],

Lalu buat job antrian. Ini penting: notifikasi WA jangan dikirim langsung di request checkout, karena kalau API lambat, pelanggan ikut menunggu. Lempar ke queue:

<?php
// app/Jobs/KirimNotifikasiWa.php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class KirimNotifikasiWa implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable;

    public int $tries = 3;

    public function __construct(
        private string $phone,
        private string $message,
    ) {}

    public function handle(): void
    {
        $response = Http::withToken(config('services.loginwa.key'))
            ->timeout(15)
            ->post(config('services.loginwa.base_url') . '/api/v1/messages/send', [
                'phone'   => $this->phone,
                'message' => $this->message,
            ]);

        // 429 (rate limit/kuota) & 503 (device disconnect): coba lagi nanti
        if (in_array($response->status(), [429, 503])) {
            Log::warning('LoginWA balas ' . $response->status() . ', job di-release.');
            $this->release(60); // antri ulang 60 detik kemudian
            return;
        }

        $response->throw(); // error lain (400/401) biar tercatat sebagai failed job
    }
}

Pemakaiannya satu baris di controller atau event listener:

KirimNotifikasiWa::dispatch($order->phone, $pesan);

Menangani Error 429 dan 503

Dua kode error ini yang paling sering ditemui di produksi, dan penanganannya berbeda:

429 Too Many Requests. Artinya kamu mengirim terlalu cepat atau kuota bulanan habis (di paket Free, 500 pesan). Solusinya: retry dengan jeda yang membesar (exponential backoff), dan kalau sering kejadian karena kuota, naikkan paket di halaman pricing. Versi PHP murni dengan backoff:

function kirimWhatsAppDenganRetry(string $phone, string $message, int $maxRetry = 3): array
{
    for ($i = 0; $i < $maxRetry; $i++) {
        $hasil = kirimWhatsApp($phone, $message);

        if ($hasil['ok']) {
            return $hasil;
        }

        if ($hasil['status'] === 429) {
            sleep(2 ** $i);           // tunggu 1, 2, 4 detik
        } elseif ($hasil['status'] === 503) {
            sleep(5);                 // device mungkin baru reconnect
        } else {
            break;                    // 400/401: salah payload/API key, retry percuma
        }
    }

    return $hasil;
}

503 Service Unavailable. Biasanya berarti device WhatsApp kamu sedang disconnect, HP mati, internet putus, atau sesi tertaut kadaluarsa. Retry sekali-dua kali wajar, tapi kalau terus 503, satu-satunya solusi adalah buka dashboard dan scan ulang QR. Supaya tidak kecolongan, pasang webhook LoginWA: ada 10 jenis event (termasuk status device) yang dikirim ke endpoint kamu dengan signature HMAC-SHA256, jadi kamu bisa auto-alert admin begitu device putus.

Tips Produksi

  • Validasi nomor dulu. Tidak semua nomor di database terdaftar di WhatsApp. Panggil POST /api/v1/numbers/check sebelum kirim supaya kuota tidak terbuang ke nomor mati.
  • Selalu lewat queue (Laravel) atau cron worker (PHP murni) untuk volume besar, plus atur delay antar pesan kalau mengirim massal.
  • Satu pesan = satu kuota, berlaku sama untuk teks, media, maupun OTP, jadi mudah menghitung kebutuhan paket.
  • Amankan API key. Simpan di environment variable, dan kalau sudah di paket Business, aktifkan IP whitelist supaya key hanya bisa dipakai dari server kamu.

Berapa Biayanya?

Perbandingan singkat harga gateway WA populer di Indonesia (per Juni 2026):

Layanan Paket murah Yang didapat
LoginWA Rp0 / Rp25.000 500 pesan gratis (watermark, media boleh) / Lite 3.000 pesan tanpa watermark
Fonnte Rp0 / Rp25.000 1.000 pesan gratis (watermark, tanpa attachment) / Lite 1.000 pesan
Wablas mulai Rp22.000/bln trial 15 hari, ekosistem plugin lengkap
Watzap.id Rp449.000/tahun pesan unlimited, bayar tahunan

Fair saja: Fonnte adalah pemain terbesar dengan fitur paling lengkap dan dokumentasi matang, kalau kamu butuh fitur yang sangat spesifik, cek mereka juga. LoginWA unggul di kuota per rupiah (Lite Rp25.000 dapat 3.000 pesan vs 1.000 di Fonnte), paket gratis yang boleh kirim media, dan pembayaran QRIS yang aktif instan. Detail semua paket ada di loginwa.com/pricing.

Penutup

Mengirim notifikasi WhatsApp otomatis dari PHP ternyata cuma satu request POST: daftar, scan QR, panggil /api/v1/messages/send, dan tangani 429/503 dengan retry. Sisanya tinggal kreativitas, notifikasi order, reminder, alert server, semuanya pola yang sama.

Kalau mau langsung praktik, daftar gratis di loginwa.com/auth/otp, 500 pesan per bulan tanpa kartu kredit, cukup untuk membuktikan konsepnya ke diri sendiri (atau ke bos kamu). Referensi endpoint lengkap, SDK JavaScript dan PHP, plus contoh webhook ada di dokumentasi.

Ready to try? Free 500 messages/month, no credit card.
Start free See pricing