Integrasi WhatsApp OTP di Flutter dalam 5 Menit

Verifikasi nomor HP adalah salah satu flow paling umum di aplikasi Flutter — dan WhatsApp OTP jadi pilihan favorit di Indonesia karena familiar dan delivery rate-nya tinggi. Tutorial ini bahas integrasi lengkap dari nol: kirim OTP, tampilkan input, dan verifikasi kode.

Prasyarat

Catatan keamanan: API key (sk_live_*) itu rahasia. Untuk produksi, jangan hardcode di aplikasi — proxy panggilan lewat backend kamu sendiri supaya key gak ikut ke-bundle di APK/IPA. Contoh di bawah memanggil API langsung biar tutorialnya ringkas; untuk rilis, pindahkan pemanggilan ke server kamu.

1. Setup API Client

Bikin satu class yang membungkus dua endpoint: /v1/send dan /v1/verify. Endpoint verify menerima nomor HP dan kode (bukan id OTP), dan semua response dibungkus dalam success + data.

import 'dart:convert';
import 'package:http/http.dart' as http;

class OtpSpaceService {
  static const _base = 'https://api.otpspace.com/v1';
  final String apiKey;
  OtpSpaceService(this.apiKey);

  Map<String, String> get _headers => {
        'Authorization': 'Bearer $apiKey',
        'Content-Type': 'application/json',
      };

  // Kirim OTP ke nomor WhatsApp. Return otp_id kalau sukses.
  Future<String> sendOtp(String phone) async {
    final res = await http.post(
      Uri.parse('$_base/send'),
      headers: _headers,
      body: jsonEncode({'phone': phone, 'template': 'login'}),
    );
    final body = jsonDecode(res.body);
    if (res.statusCode != 202 || body['success'] != true) {
      throw Exception(body['error'] ?? 'Gagal mengirim OTP');
    }
    return body['data']['otp_id'] as String;
  }

  // Verifikasi kode yang diinput user. Return true kalau cocok.
  Future<bool> verifyOtp(String phone, String code) async {
    final res = await http.post(
      Uri.parse('$_base/verify'),
      headers: _headers,
      body: jsonEncode({'phone': phone, 'code': code}),
    );
    final body = jsonDecode(res.body);
    return res.statusCode == 200 && body['success'] == true;
  }
}

2. Layar Input Nomor HP

Pakai TextFormField dengan validator format Indonesia (+62 atau 08...). Saat submit, panggil sendOtp() lalu pindah ke layar verifikasi.

final _phoneCtrl = TextEditingController();
bool _loading = false;

Future<void> _submit() async {
  setState(() => _loading = true);
  try {
    await otp.sendOtp(_phoneCtrl.text.trim());
    if (mounted) {
      Navigator.push(context, MaterialPageRoute(
        builder: (_) => VerifyScreen(phone: _phoneCtrl.text.trim()),
      ));
    }
  } catch (e) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text('$e')),
    );
  } finally {
    if (mounted) setState(() => _loading = false);
  }
}

3. Layar Verifikasi Kode

Tampilkan input 6 digit (package pin_code_fields atau custom). Saat lengkap, panggil verifyOtp(); kalau sukses, lanjut ke home.

Future<void> _verify(String code) async {
  final ok = await otp.verifyOtp(widget.phone, code);
  if (!mounted) return;
  if (ok) {
    Navigator.pushReplacementNamed(context, '/home');
  } else {
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(content: Text('Kode salah, coba lagi.')),
    );
  }
}

4. Handling Edge Case

API mengembalikan status code yang jelas — tangani biar UX-nya rapi:

5. Testing

Pakai 10 OTP gratis dari signup buat nyoba. Test dengan nomor WhatsApp kamu sendiri dulu sebelum production, dan pantau status tiap kiriman di dashboard OTP Space (menu Logs). Detail request/response lengkap ada di dokumentasi API.

Penutup

Dengan satu service class dan dua layar, kamu udah punya flow verifikasi WhatsApp yang jalan dari nol. Untuk rilis, ingat pindahkan pemanggilan API ke backend kamu supaya sk_live_* tetap aman di server.

Belum punya API key? Daftar OTP Space dan dapat 10 OTP gratis buat langsung nyoba integrasi ini.

Ready to ship in 5 minutes?

Sign up free, get 10 OTPs for testing, no credit card or tax ID needed.

Sign up free