Mengamankan Integrasi WhatsApp Gateway: API Key, Webhook, dan 2FA
Nomor WhatsApp bisnis adalah aset. Ini checklist supaya sesi, API key, dan webhook Anda tidak jadi celah pengambilalihan.
BacaREST API sederhana dengan JSON. Contoh kode Laravel HTTP Client, PHP cURL murni, dan verifikasi webhook.
Integrasi cukup lewat HTTP biasa: kirim JSON, dapat JSON. Tidak perlu SDK khusus, dan bisa dipanggil dari framework apa pun.
.envBuat API key di dashboard (menu Nomor WhatsApp), lalu simpan di server:
WA_API_URL=https://domainanda.com/api/v1
WA_API_KEY=wag_xxxxxxxxxxxxxxxxxxxx
Jangan pernah menaruh API key di JavaScript frontend atau aplikasi HP.
use Illuminate\Support\Facades\Http;
$res = Http::withToken(env('WA_API_KEY'))
->acceptJson()
->timeout(10)
->post(env('WA_API_URL').'/messages', [
'to' => '08123456789',
'message' => 'Pesanan #1234 sudah kami terima.',
'idempotency_key' => 'order-1234-received',
]);
if ($res->failed()) {
report(new \RuntimeException('WA gagal: '.$res->json('error.message')));
}
$messageId = $res->json('data.id'); // simpan untuk cek status
API membalas 202 Accepted karena pesan masuk antrian dan dikirim dengan jeda acak, bukan langsung.
$ch = curl_init(getenv('WA_API_URL').'/messages');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('WA_API_KEY'),
'Content-Type: application/json',
'Accept: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['to' => '08123456789', 'message' => 'Halo dari PHP']),
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
Http::withToken(env('WA_API_KEY'))->post(env('WA_API_URL').'/messages/bulk', [
'message' => '{Halo|Hai} {{nama}}, promo akhir bulan sudah dimulai.',
'recipients' => $customers->map(fn ($c) => [
'to' => $c->phone,
'variables' => ['nama' => $c->first_name],
])->all(),
]);
Setiap webhook membawa header X-Webhook-Timestamp dan X-Webhook-Signature. Tanda tangan dihitung dari timestamp.body dengan secret webhook Anda:
Route::post('/wa/webhook', function (Request $request) {
$ts = $request->header('X-Webhook-Timestamp');
$expected = 'sha256='.hash_hmac('sha256', $ts.'.'.$request->getContent(), env('WA_WEBHOOK_SECRET'));
abort_unless(hash_equals($expected, (string) $request->header('X-Webhook-Signature')), 401);
abort_if(abs(time() - (int) $ts) > 300, 401); // tolak request lama (replay)
$event = $request->input('event'); // message.sent, message.status, message.failed, message.incoming, ...
// proses event...
return response()->noContent();
});
Kecualikan route webhook ini dari CSRF (bootstrap/app.php → validateCsrfTokens(except: ['wa/webhook'])).
GET /messages/{id}: status pesanGET /device: status nomor & isi antrianPOST /numbers/check: cek nomor terdaftar WhatsAppGET /usage: sisa kuotaDaftar lengkap dan kode error ada di dokumentasi API.
Nomor WhatsApp bisnis adalah aset. Ini checklist supaya sesi, API key, dan webhook Anda tidak jadi celah pengambilalihan.
BacaPola kirim, isi pesan, dan daftar kontak menentukan apakah nomor Anda bertahan lama. Ini kebiasaan yang paling berpengaruh.
BacaPerbandingan jujur antara gateway berbasis WhatsApp Web dan WhatsApp Business Platform resmi dari Meta: biaya, risiko, dan kapan memilih yang mana.
Baca