B BGWA Docs
Mulai

Contoh kode

Salin-tempel contoh integrasi: cURL, PHP, Laravel, Node.js, dan Python.

Contoh siap pakai untuk skenario yang paling umum. Ganti YOUR_API_KEY dengan API key device Anda, dan simpan key di environment variable.

Fungsi kirim pesan

Bungkus pemanggilan API dalam satu fungsi yang menangani error dengan benar.

PHP
function bgwaKirim(string $to, string $text, array $extra = []): array
{
    $ch = curl_init('https://bgwa.web.id/api/v1/messages');
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 15,
        CURLOPT_HTTPHEADER => [
            'Authorization: Bearer ' . getenv('BGWA_API_KEY'),
            'Content-Type: application/json',
        ],
        CURLOPT_POSTFIELDS => json_encode(['to' => $to, 'text' => $text] + $extra),
    ]);
    $body   = json_decode(curl_exec($ch), true) ?: [];
    $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    return ['http' => $status] + $body;
}

$r = bgwaKirim('081234567890', 'Halo dari PHP!');
if ($r['http'] === 200) {
    echo 'Antre, id = ' . $r['id'];
} else {
    echo 'Gagal: ' . ($r['error'] ?? $r['http']);
}
Laravel
use Illuminate\Support\Facades\Http;

// config/services.php  =>  'bgwa' => ['key' => env('BGWA_API_KEY')]
$response = Http::withToken(config('services.bgwa.key'))
    ->acceptJson()
    ->timeout(15)
    ->post('https://bgwa.web.id/api/v1/messages', [
        'to'   => $order->customer_phone,
        'text' => "{Halo|Hai} {$order->customer_name}, pesanan #{$order->number} sudah kami proses.",
    ]);

if ($response->successful()) {
    $order->update(['wa_outbox_id' => $response->json('id')]);
} elseif (in_array($response->status(), [429, 503], true)) {
    // coba lagi nanti sesuai Retry-After
    dispatch(new KirimUlangWa($order))->delay((int) $response->header('Retry-After', 60));
} else {
    report(new RuntimeException($response->json('error', 'BGWA error ' . $response->status())));
}
Node.js
async function bgwaKirim(to, text, extra = {}) {
  const res = await fetch('https://bgwa.web.id/api/v1/messages', {
    method: 'POST',
    headers: {
      Authorization: 'Bearer ' + process.env.BGWA_API_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ to, text, ...extra }),
    signal: AbortSignal.timeout(15000),
  });
  return { http: res.status, ...(await res.json()) };
}

const r = await bgwaKirim('081234567890', 'Halo dari Node.js!');
console.log(r.http === 200 ? 'Antre, id = ' + r.id : 'Gagal: ' + r.error);
Python
import os
import requests

def bgwa_kirim(to, text, **extra):
    r = requests.post(
        "https://bgwa.web.id/api/v1/messages",
        headers={"Authorization": "Bearer " + os.environ["BGWA_API_KEY"]},
        json={"to": to, "text": text, **extra},
        timeout=15,
    )
    return r.status_code, r.json()

status, data = bgwa_kirim("081234567890", "Halo dari Python!")
print("Antre, id =", data["id"]) if status == 200 else print("Gagal:", data.get("error"))

Notifikasi tagihan dengan variasi pesan

Kirim tagihan ke banyak pelanggan tanpa isi yang identik. BGWA mengatur jeda, jadi cukup kirim satu per satu.

PHP
$template = '{Halo|Hai|Selamat pagi} {nama}, tagihan {bulan} sebesar Rp {jumlah} jatuh tempo {tanggal}. {Terima kasih|Terima kasih atas kepercayaan Anda}.';

foreach ($pelanggan as $p) {
    $r = bgwaKirim($p['hp'], $template, [
        'vars' => [
            'nama'    => $p['nama'],
            'bulan'   => 'November',
            'jumlah'  => number_format($p['tagihan'], 0, ',', '.'),
            'tanggal' => $p['jatuh_tempo'],
        ],
    ]);

    if ($r['http'] === 429 || $r['http'] === 503) {
        break;                       // batas tercapai: lanjutkan nanti
    }
    // simpan $r['id'] untuk mencocokkan webhook
}

Kirim OTP

PHP
$kode = random_int(100000, 999999);
// simpan hash $kode + masa berlaku di database Anda, lalu:
$r = bgwaKirim($hp, "Kode verifikasi Anda: {$kode}. Berlaku 5 menit. Jangan bagikan ke siapa pun.", [
    'type' => 'otp',
]);
Node.js
import crypto from 'node:crypto';

const kode = crypto.randomInt(100000, 1000000);
// simpan hash kode + masa berlaku, lalu:
await bgwaKirim(hp, `Kode verifikasi Anda: ${kode}. Berlaku 5 menit. Jangan bagikan ke siapa pun.`, {
  type: 'otp',
});

Kirim gambar (struk, poster)

cURL
curl -X POST https://bgwa.web.id/api/v1/messages \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "to=081234567890" \
  -F "text=Terima kasih, ini struk Anda." \
  -F "image=@/path/ke/struk.png"
Laravel
$response = Http::withToken(config('services.bgwa.key'))
    ->attach('image', file_get_contents($path), 'struk.png')
    ->post('https://bgwa.web.id/api/v1/messages', [
        'to'   => $hp,
        'text' => 'Terima kasih, ini struk Anda.',
    ]);

// pastikan gambar benar-benar ikut
if ($response->successful() && ! $response->json('image')) {
    // keterangan terlalu panjang: terkirim sebagai teks saja
}

Penerima webhook lengkap

Contoh endpoint yang memverifikasi tanda tangan, membuang duplikat, lalu memperbarui status pesan di database Anda.

Laravel
// routes/web.php  (kecualikan dari CSRF)
Route::post('/hooks/bgwa', function (Request $request) {
    $ts   = $request->header('X-BGWA-Timestamp', '');
    $body = $request->getContent();                       // body mentah
    $sig  = 'sha256=' . hash_hmac('sha256', $ts . '.' . $body, config('services.bgwa.webhook_secret'));

    abort_unless(hash_equals($sig, (string) $request->header('X-BGWA-Signature')), 401);
    abort_if(abs(time() - (int) $ts) > 300, 400);

    $delivery = $request->header('X-BGWA-Delivery');
    if (Cache::add('bgwa:' . $delivery, 1, now()->addDay()) === false) {
        return response()->noContent();                   // duplikat, sudah diproses
    }

    $event = $request->json()->all();
    Pesan::where('bgwa_id', $event['id'] ?? null)->update([
        'status' => $event['status'] ?? $event['event'],
        'alasan' => $event['reason'] ?? null,
    ]);

    return response()->noContent();
});
Node.js (Express)
const seen = new Set();   // produksi: pakai Redis/DB dengan masa kedaluwarsa

app.post('/hooks/bgwa', express.raw({ type: 'application/json' }), async (req, res) => {
  const ts = req.get('X-BGWA-Timestamp') || '';
  const raw = req.body.toString('utf8');
  const expected = 'sha256=' + crypto.createHmac('sha256', process.env.BGWA_WEBHOOK_SECRET)
    .update(ts + '.' + raw).digest('hex');
  const got = req.get('X-BGWA-Signature') || '';

  if (got.length !== expected.length || !crypto.timingSafeEqual(Buffer.from(got), Buffer.from(expected))) {
    return res.sendStatus(401);
  }

  const delivery = req.get('X-BGWA-Delivery');
  if (seen.has(delivery)) return res.sendStatus(200);
  seen.add(delivery);

  const event = JSON.parse(raw);
  await db.pesan.update({ bgwaId: event.id }, { status: event.status, alasan: event.reason });
  res.sendStatus(200);
});

Cek koneksi sebelum kirim massal

cURL
STATUS=$(curl -s https://bgwa.web.id/api/v1/device -H "Authorization: Bearer YOUR_API_KEY" | grep -o '"status":"[a-z]*"')
[ "$STATUS" = '"status":"open"' ] && echo "Device siap" || echo "Device belum terhubung"