Cara Integrasi WhatsApp Cloud API dengan Laravel
Apa Itu WhatsApp Cloud API?
WhatsApp Cloud API adalah bagian dari WhatsApp Business Platform yang dihosting oleh Meta. API ini memungkinkan bisnis menghubungkan WhatsApp dengan CRM, aplikasi kasir, sistem pemesanan, chatbot, dan aplikasi bisnis lainnya.
Beberapa contoh penggunaannya:
Konfirmasi pesanan.
Notifikasi pembayaran.
Informasi pengiriman.
Pengingat jadwal.
Pengiriman invoice.
Customer service otomatis.
Chatbot WhatsApp.
Integrasi CRM.
WhatsApp Cloud API dapat mengirim pesan teks, gambar, dokumen, video, audio, serta message template melalui endpoint /messages.
Persiapan Integrasi
Sebelum mulai, siapkan:
Akun Meta Developer.
Meta Business Portfolio.
WhatsApp Business Account.
Nomor WhatsApp bisnis.
Phone Number ID.
Access Token.
Laravel yang sudah berjalan.
Domain HTTPS untuk webhook.
Phone Number ID dan token pengujian dapat ditemukan pada halaman WhatsApp di Meta Developer Dashboard. Untuk production, gunakan system user access token dan simpan token dengan aman, bukan langsung di source code.
1. Menambahkan Konfigurasi .env
Buka file .env, lalu tambahkan:
WHATSAPP_API_VERSION=vXX.X
WHATSAPP_PHONE_NUMBER_ID=
WHATSAPP_ACCESS_TOKEN=
WHATSAPP_VERIFY_TOKEN=token-verifikasi-rahasia
WHATSAPP_APP_SECRET=
Ganti vXX.X dengan versi Graph API yang sedang digunakan pada dashboard Meta.
Jangan membagikan:
WHATSAPP_ACCESS_TOKEN
WHATSAPP_APP_SECRET
Pastikan file .env tidak masuk ke repository publik.
2. Menambahkan Konfigurasi Services
Buka:
config/services.php
Tambahkan konfigurasi:
'whatsapp' => [
'version' => env('WHATSAPP_API_VERSION'),
'phone_number_id' => env('WHATSAPP_PHONE_NUMBER_ID'),
'access_token' => env('WHATSAPP_ACCESS_TOKEN'),
'verify_token' => env('WHATSAPP_VERIFY_TOKEN'),
'app_secret' => env('WHATSAPP_APP_SECRET'),
],
Setelah mengubah .env, jalankan:
php artisan optimize:clear
3. Membuat WhatsApp Service
Buat file:
app/Services/WhatsAppService.php
Isi dengan kode berikut:
<?php
namespace App\Services;
use Illuminate\Support\Facades\Http;
class WhatsAppService
{
public function sendText(
string $phoneNumber,
string $message
): array {
$version = config('services.whatsapp.version');
$phoneNumberId = config(
'services.whatsapp.phone_number_id'
);
$response = Http::withToken(
config('services.whatsapp.access_token')
)
->acceptJson()
->timeout(20)
->retry(2, 500)
->post(
"https://graph.facebook.com/{$version}/{$phoneNumberId}/messages",
[
'messaging_product' => 'whatsapp',
'recipient_type' => 'individual',
'to' => $phoneNumber,
'type' => 'text',
'text' => [
'preview_url' => false,
'body' => $message,
],
]
);
$response->throw();
return $response->json();
}
}
WhatsApp mengirim pesan melalui request POST menuju endpoint:
/{PHONE_NUMBER_ID}/messages
Request membutuhkan Bearer Token dan objek pesan sesuai tipe yang dikirim. Respons yang berhasil akan menghasilkan ID pesan dengan awalan wamid, yang dapat digunakan untuk melacak status pesan melalui webhook.
Laravel HTTP Client menyediakan withToken(), timeout(), retry(), dan throw() untuk mengelola autentikasi, waktu tunggu, percobaan ulang, serta error request API.
4. Membuat Controller Pengiriman Pesan
Jalankan:
php artisan make:controller WhatsAppController
Buka:
app/Http/Controllers/WhatsAppController.php
Isi:
<?php
namespace App\Http\Controllers;
use App\Services\WhatsAppService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class WhatsAppController extends Controller
{
public function send(
Request $request,
WhatsAppService $whatsApp
): JsonResponse {
$validated = $request->validate([
'phone_number' => [
'required',
'string',
'max:30',
],
'message' => [
'required',
'string',
'max:4096',
],
]);
$result = $whatsApp->sendText(
$validated['phone_number'],
$validated['message']
);
return response()->json([
'success' => true,
'message' => 'Pesan berhasil dikirim.',
'data' => $result,
]);
}
}
Gunakan nomor penerima dalam format internasional yang sesuai dengan ketentuan WhatsApp.
5. Membuat Route Pengiriman Pesan
Tambahkan ke:
routes/api.php
use App\Http\Controllers\WhatsAppController;
use Illuminate\Support\Facades\Route;
Route::post(
'/whatsapp/send',
[WhatsAppController::class, 'send']
)->middleware('auth:sanctum');
Endpoint yang dihasilkan:
POST /api/whatsapp/send
Contoh request JSON:
{
"phone_number": "6281234567890",
"message": "Pesanan Anda sudah kami terima."
}
Sebaiknya endpoint pengiriman pesan dilindungi menggunakan autentikasi, role, permission, atau API key internal.
6. Membuat Webhook Controller
Webhook digunakan untuk menerima:
Pesan masuk.
Status pesan terkirim.
Status pesan diterima.
Status pesan dibaca.
Informasi pesan gagal.
Buat controller:
php artisan make:controller WhatsAppWebhookController
Isi:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Log;
class WhatsAppWebhookController extends Controller
{
public function verify(Request $request): Response
{
$mode = $request->query('hub_mode')
?? $request->query('hub.mode');
$token = $request->query('hub_verify_token')
?? $request->query('hub.verify_token');
$challenge = $request->query('hub_challenge')
?? $request->query('hub.challenge');
if (
$mode === 'subscribe'
&& is_string($token)
&& hash_equals(
(string) config(
'services.whatsapp.verify_token'
),
$token
)
) {
return response(
(string) $challenge,
200
)->header(
'Content-Type',
'text/plain'
);
}
abort(403, 'Webhook verification gagal.');
}
public function receive(
Request $request
): JsonResponse {
$signature = (string) $request->header(
'X-Hub-Signature-256'
);
$expectedSignature = 'sha256='.hash_hmac(
'sha256',
$request->getContent(),
(string) config(
'services.whatsapp.app_secret'
)
);
abort_unless(
$signature !== ''
&& hash_equals(
$expectedSignature,
$signature
),
401,
'Webhook signature tidak valid.'
);
$payload = $request->json()->all();
Log::info('WhatsApp webhook diterima', [
'payload' => $payload,
]);
return response()->json([
'received' => true,
]);
}
}
Saat proses verifikasi, Meta mengirimkan verification token. Jika token sesuai, aplikasi harus mengembalikan nilai hub.challenge. Payload webhook production juga sebaiknya diperiksa menggunakan header X-Hub-Signature-256 dan App Secret.
7. Membuat Route Webhook
Tambahkan ke routes/api.php:
use App\Http\Controllers\WhatsAppWebhookController;
Route::get(
'/webhooks/whatsapp',
[WhatsAppWebhookController::class, 'verify']
);
Route::post(
'/webhooks/whatsapp',
[WhatsAppWebhookController::class, 'receive']
);
Webhook URL yang dimasukkan ke Meta adalah:
https://domainanda.com/api/webhooks/whatsapp
Webhook harus menggunakan URL HTTPS yang dapat diakses secara publik. Setelah menerima webhook, aplikasi perlu memberikan respons berhasil agar layanan webhook mengetahui bahwa payload telah diterima.
Untuk proses berat, masukkan payload ke Laravel Queue dan segera kembalikan respons HTTP 200.
8. Mengambil Pesan Masuk
Struktur pesan masuk biasanya berada pada:
$payload['entry'][0]
['changes'][0]
['value']
['messages'][0];
Contoh sederhana:
$message = data_get(
$payload,
'entry.0.changes.0.value.messages.0'
);
if ($message) {
$sender = $message['from'] ?? null;
$type = $message['type'] ?? null;
$text = data_get(
$message,
'text.body'
);
Log::info('Pesan WhatsApp masuk', [
'sender' => $sender,
'type' => $type,
'text' => $text,
]);
}
Data tersebut dapat disimpan ke database, diteruskan ke customer service, atau diproses oleh chatbot.
9. Mengirim Message Template
Message template harus dibuat terlebih dahulu melalui WhatsApp Manager atau Business Management API.
Contoh request template:
$response = Http::withToken(
config('services.whatsapp.access_token')
)->post($url, [
'messaging_product' => 'whatsapp',
'to' => $phoneNumber,
'type' => 'template',
'template' => [
'name' => 'order_confirmation',
'language' => [
'code' => 'id',
],
'components' => [
[
'type' => 'body',
'parameters' => [
[
'type' => 'text',
'text' => $customerName,
],
[
'type' => 'text',
'text' => $invoiceNumber,
],
],
],
],
],
]);
$response->throw();
Nama template, bahasa, dan jumlah parameter harus sesuai dengan template yang telah dibuat.
Error yang Sering Terjadi
Invalid OAuth Access Token
Penyebabnya:
Token kedaluwarsa.
Token salah.
Permission token tidak sesuai.
Token tidak memiliki akses ke akun WhatsApp.
Periksa kembali token pada Meta Developer Dashboard.
Phone Number ID Tidak Sesuai
Pastikan menggunakan Phone Number ID, bukan nomor WhatsApp biasa atau WhatsApp Business Account ID.
Webhook Tidak Terverifikasi
Periksa:
URL menggunakan HTTPS.
Route dapat diakses publik.
Verify Token sama dengan konfigurasi Meta.
Server mengembalikan
hub.challenge.Tidak terdapat redirect login.
Pesan Tidak Masuk ke Webhook
Pastikan aplikasi Meta sudah berlangganan pada field webhook yang diperlukan dan callback URL mengarah ke route yang benar.
Pesan Template Gagal
Periksa nama template, kode bahasa, parameter, serta status template pada WhatsApp Manager.
Keamanan Integrasi WhatsApp API
Beberapa langkah keamanan yang perlu diterapkan:
Simpan token di
.env.Jangan mencatat access token ke log.
Gunakan HTTPS.
Verifikasi signature webhook.
Lindungi endpoint pengiriman pesan.
Validasi nomor dan isi pesan.
Gunakan Queue untuk pengiriman massal.
Simpan Message ID untuk pencatatan status.
Jangan mengirim pesan tanpa persetujuan pelanggan.
Pantau error dan penggunaan API.
Pengembangan WhatsApp API Bersama Ovla Media
Integrasi WhatsApp Cloud API dapat diterapkan pada:
Sistem Point of Sales.
Aplikasi inventory.
Toko online.
Sistem klinik.
CRM.
ERP.
Notifikasi pembayaran.
Pengiriman invoice.
Customer service.
Chatbot berbasis AI.
Ovla Media menyediakan layanan integrasi WhatsApp API, chatbot, CRM, notifikasi otomatis, dan pengembangan aplikasi Laravel sesuai kebutuhan bisnis.
Kesimpulan
Integrasi WhatsApp Cloud API dengan Laravel dapat dilakukan menggunakan HTTP Client bawaan Laravel.
Konfigurasi utama yang diperlukan adalah:
WHATSAPP_API_VERSION=
WHATSAPP_PHONE_NUMBER_ID=
WHATSAPP_ACCESS_TOKEN=
WHATSAPP_VERIFY_TOKEN=
WHATSAPP_APP_SECRET=
Pesan dikirim melalui endpoint:
/{PHONE_NUMBER_ID}/messages
Gunakan webhook untuk menerima pesan masuk dan perubahan status pesan. Pada production, lindungi token, periksa signature webhook, gunakan HTTPS, dan jalankan proses berat melalui Queue.
Dengan integrasi yang tepat, WhatsApp dapat dihubungkan dengan sistem penjualan, pembayaran, CRM, inventory, dan aplikasi bisnis lainnya.
Artikel Terkait
Cara Membuat Sistem Multi-Cabang Menggunakan Laravel
Sistem multi-cabang memungkinkan beberapa lokasi usaha menggunakan satu aplikasi Laravel dengan data yang tetap terpisah. Setiap produk, transaksi, stok, pelanggan, dan pengguna dapat dihubungkan dengan cabang tertentu melalui kolom branch_id.
Cara Menjalankan Queue Worker Laravel di cPanel Tanpa Supervisor
Queue Worker Laravel digunakan untuk memproses pekerjaan di belakang layar, seperti pengiriman email, notifikasi, pembuatan laporan, sinkronisasi API, dan pemrosesan data. Pada VPS, worker biasanya dijaga menggunakan Supervisor. Namun, pada shared hosting cPanel yang tidak menyediakan Supervisor, queue tetap dapat dijalankan menggunakan Cron Job dan perintah queue:work --stop-when-empty.
Cara Membuat Role dan Permission Laravel Tanpa Package
Role dan permission digunakan untuk membatasi akses pengguna berdasarkan tugas dan kewenangannya. Tanpa memasang package tambahan, Laravel dapat membuat sistem hak akses menggunakan migration, relasi Eloquent, middleware, Gate, Policy, dan Blade Directive. Artikel ini membahas pembuatan role dan permission dari awal, mulai dari struktur database, model, seeder, middleware, hingga penerapannya pada route dan tampilan.