← Back to all posts

Migrasi dari PHP mail() dan PHPMailer ke Email API — Panduan Lengkap untuk Developer Indonesia

2026-10-18 · MailAnvil Team

Email dari aplikasi PHP masih jadi tulang punggung notifikasi di Indonesia — WordPress plugin, sistem internal kantor, aplikasi booking, sampai fintech kecil yang ditulis dengan Laravel lama. Mayoritas masih pakai mail() bawaan PHP atau PHPMailer yang relay lewat SMTP hosting. Masalahnya bukan kode-nya salah. Masalahnya: email yang keluar dari jalur itu punya kemungkinan besar masuk spam, delay, atau hilang diam-diam.

Artikel ini bahas kenapa itu terjadi, dan cara migrasi ke email API secara bertahap tanpa mematikan sistem yang sudah jalan.

Kenapa mail() dan SMTP hosting sering gagal

Tiga penyebab utama:

  1. Reputasi IP buruk. Email keluar langsung dari IP VPS atau shared hosting kamu. IP itu dipakai (atau pernah dipakai) ratusan domain lain. Gmail dan Outlook menilai reputasi IP itu, bukan niat baik kamu. Hasilnya: inbox rate rendah bahkan untuk email yang benar-benar dibutuhkan user.

  2. Autentikasi setengah jadi. DKIM dan SPF butuh record DNS yang dikonfigurasi benar per domain, plus signing di level pesan. Di setup mail()/SMTP klasik, sering kali SPF ada tapi DKIM tidak pernah di-setup, atau Return-Path tidak cocok dengan domain pengirim. DMARC? Sering tidak ada sama sekali.

  3. Tidak ada feedback loop. Email bounce (alamat salah, mailbox penuh) tidak terpantau. Kamu terus kirim ke alamat mati, reputation makin jatuh, dan tidak ada yang kasih tahu.

Email API menyelesaikan ketiganya: kirim lewat infrastruktur yang reputasinya dijaga, DKIM ditandatangani otomatis setelah domain terverifikasi, dan bounce/complaint masuk laporan yang bisa diproses.

Migrasi bertahap, bukan big bang

Jangan tukar satu tombol untuk semua email sekaligus. Pola yang aman:

Tahap 1 — email non-kritis dulu. Mulai dari notifikasi internal, laporan harian, email digest. Ini kelas email yang kalau gagal tidak bikin panik user. Jalankan seminggu, pantau deliverability.

Tahap 2 — email transaksional inti. OTP, verifikasi akun, reset password, invoice. Di sini penting dua hal: idempotency key supaya retry tidak mengirim dobel, dan penanganan error yang jelas — 429 berarti tunggu dan retry dengan backoff, 4xx lain jangan di-retry karena biasanya alamat invalid atau domain belum verified.

Tahap 3 — matikan jalur lama. Setelah semua template pindah, hapus konfigurasi SMTP lama. Jangan dibiarkan setengah aktif — dua jalur kirim dengan reputasi berbeda bikin debugging deliverability jadi tebak-tebakan.

Contoh: mengganti PHPMailer dengan panggilan API

Perubahan di kode biasanya lebih kecil dari yang dibayangkan. Sebelum:

$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host = 'smtp.hostingkamu.com';
$mail->Username = '[email protected]';
$mail->Password = 'password-hosting';
$mail->send();

Sesudah:

$ch = curl_init('https://api.mailanvil.com/v1/send');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('MAILANVIL_API_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'from' => '[email protected]',
        'to' => $user['email'],
        'subject' => 'Konfirmasi pesanan #' . $orderId,
        'html' => $template,
    ]),
]);
$response = json_decode(curl_exec($ch), true);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($httpCode !== 200) {
    error_log("Email send failed: {$httpCode} " . print_r($response, true));
}

Catatan penting: API key disimpan di environment variable atau secret manager, bukan di file konfigurasi yang ter-commit ke git. Ini kesalahan yang masih sangat umum di repo PHP Indonesia.

Untuk aplikasi Laravel, bungkus panggilan API di dalam sebuah mailer class sendiri, lalu queue-kan pengirimannya supaya request user tidak menunggu round-trip ke API email. Aplikasi CodeIgniter pakai library cURL yang sama — polanya identik.

Checklist sebelum dipindah ke production

Kalau semua item hijau dan email transaksional sudah jalan stabil di jalur baru selama seminggu, migrasi selesai. Total effort untuk aplikasi PHP menengah biasanya satu sampai dua hari kerja — jauh lebih murah daripada biaya berkelanjutan dari email OTP yang tidak sampai ke user.