WhatsApp API untuk Kirim OTP & Verifikasi
Cara kirim OTP via WhatsApp API. Verifikasi nomor HP, 2FA authentication, lebih murah dari SMS. Tutorial lengkap dengan kode!
OTP via WhatsApp = Lebih murah dari SMS!
| Channel | Biaya | Delivery Rate |
|---|---|---|
| SMS | Rp 350-500/msg | 95% |
| Rp 300/conv | 98% |
WhatsApp Cloud API punya tipe conversation "Authentication" khusus untuk OTP dengan harga termurah.
Flow OTP WhatsApp
1. User request OTP (login/register)
↓
2. Server generate OTP (random 4-6 digit)
↓
3. Simpan OTP + expiry ke database
↓
4. Kirim OTP via WhatsApp API
↓
5. User input OTP
↓
6. Server verify: cocok + belum expired?
↓
7. Success / FailedImplementasi
1. Generate OTP
javascript
function generateOTP(length = 6) {
let otp = '';
for (let i = 0; i < length; i++) {
otp += Math.floor(Math.random() * 10);
}
return otp;
}
// Result: "384729"2. Store OTP
javascript
// Using Redis (recommended)
async function storeOTP(phone, otp) {
const key = `otp:${phone}`;
const expiry = 300; // 5 minutes
await redis.set(key, otp, 'EX', expiry);
}
// Using Database
async function storeOTPDB(phone, otp) {
const expiry = new Date(Date.now() + 5 * 60 * 1000);
await db.query(`
INSERT INTO otp (phone, code, expires_at)
VALUES (?, ?, ?)
ON DUPLICATE KEY UPDATE code = ?, expires_at = ?
`, [phone, otp, expiry, otp, expiry]);
}3. Send via WhatsApp
javascript
async function sendOTP(phone, otp) {
// Menggunakan template authentication
const response = await fetch(
`https://graph.facebook.com/v17.0/${PHONE_ID}/messages`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${TOKEN}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
messaging_product: 'whatsapp',
to: phone,
type: 'template',
template: {
name: 'otp_verification', // Harus dibuat dulu di Meta
language: { code: 'id' },
components: [{
type: 'body',
parameters: [{
type: 'text',
text: otp
}]
}]
}
})
}
);
return response.json();
}
// Atau kirim text biasa (untuk user-initiated conversation)
async function sendOTPText(phone, otp) {
const message = `🔐 Kode OTP kamu: ${otp}
Berlaku 5 menit.
Jangan bagikan ke siapapun!`;
await sendWhatsApp(phone, message);
}4. Verify OTP
javascript
async function verifyOTP(phone, inputOTP) {
// From Redis
const storedOTP = await redis.get(`otp:${phone}`);
if (!storedOTP) {
return { success: false, message: 'OTP expired or not found' };
}
if (storedOTP !== inputOTP) {
return { success: false, message: 'Invalid OTP' };
}
// Delete after successful verification
await redis.del(`otp:${phone}`);
return { success: true, message: 'OTP verified' };
}5. Complete Flow
javascript
// API Endpoint: Request OTP
app.post('/api/otp/request', async (req, res) => {
const { phone } = req.body;
// Rate limit check
const attempts = await redis.incr(`otp_attempts:${phone}`);
await redis.expire(`otp_attempts:${phone}`, 3600);
if (attempts > 5) {
return res.status(429).json({ error: 'Too many attempts' });
}
const otp = generateOTP();
await storeOTP(phone, otp);
await sendOTP(phone, otp);
res.json({ success: true, message: 'OTP sent' });
});
// API Endpoint: Verify OTP
app.post('/api/otp/verify', async (req, res) => {
const { phone, otp } = req.body;
const result = await verifyOTP(phone, otp);
if (result.success) {
// Generate token/session
const token = generateAuthToken(phone);
res.json({ success: true, token });
} else {
res.status(400).json(result);
}
});Template OTP (Cloud API)
Buat template di Meta Business Suite:
Template Name: otp_verificationCategory: Authentication Language: Indonesian
Content:
🔐 Kode verifikasi kamu: {{1}}
Kode berlaku 5 menit.
Jangan bagikan kode ini ke siapapun.Best Practices
1. Security
- OTP expire dalam 5 menit
- Max 5 attempts per hour
- Delete after successful verify
- Jangan log OTP plaintext
2. UX
- Jelaskan bahwa OTP dikirim via WA
- Auto-focus ke input OTP setelah request
- Timer countdown untuk resend
- Clear error messages
3. Rate Limiting
- 5 OTP requests per phone per hour
- 3 verification attempts per OTP
- Block suspicious patterns
Cost Comparison
| Volume/bulan | SMS Cost | WhatsApp Cost | Savings |
|---|---|---|---|
| 1.000 | Rp 500k | Rp 300k | 40% |
| 5.000 | Rp 2.5jt | Rp 1.5jt | 40% |
| 10.000 | Rp 5jt | Rp 3jt | 40% |
WhatsApp consistently 40% lebih murah!