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!

WhatsApp API untuk Kirim OTP & Verifikasi
WhatsApp API untuk Kirim OTP & Verifikasi

OTP via WhatsApp = Lebih murah dari SMS!

ChannelBiayaDelivery Rate
SMSRp 350-500/msg95%
WhatsAppRp 300/conv98%

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 / Failed

Implementasi

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/bulanSMS CostWhatsApp CostSavings
1.000Rp 500kRp 300k40%
5.000Rp 2.5jtRp 1.5jt40%
10.000Rp 5jtRp 3jt40%

WhatsApp consistently 40% lebih murah!

Coba Platform OTP — Gratis! →


Artikel Terkait