← Back to all posts
2026-07-22 · MailAnvil Team

Cara Kirim Email Notifikasi Pembayaran dengan MailAnvil + Node.js

Setiap transaksi digital di Indonesia butuh email notifikasi. Entah itu invoice GoFood, konfirmasi pesanan Tokopedia, atau OTP BCA Mobile — email adalah jalur komunikasi paling resmi antara aplikasi dan pengguna.

Masalahnya: kebanyakan developer Indonesia pakai SendGrid atau Resend. Harganya dalam USD. Setiap bulan kena konversi kurs + biaya kartu kredit internasional. Untuk startup baru yang baru dapat 1000 transaksi per bulan, ini membengkak diam-diam.

MailAnvil hadir dengan harga Rupiah, pembayaran QRIS/GoPay, dan API standar REST. Artikel ini akan nunjukin cara kirim email notifikasi pembayaran kurang dari 10 menit.

Kenapa Email Notifikasi Pembayaran Penting

Tiga use case paling umum di aplikasi Indonesia:

  1. Food delivery — GoFood, GrabFood kirim invoice + rincian pesanan via email
  2. E-commerce — Tokopedia, Shopee kirim konfirmasi pesanan + link lacak pengiriman
  3. Fintech — OVO, Dana kirim bukti transfer + mutasi digital

Semua skenario ini pakai transactional email — email yang trigger otomatis dari aksi user, bukan marketing blast.

Prasyarat

Langkah 1: Setup Proyek Express.js

mkdir payment-notifier && cd payment-notifier
npm init -y
npm install express dotenv

Buat file .env:

MAILANVIL_API_KEY=ma_your_api_key_here
MAILANVIL_API_URL=https://api.mailanvil.com/v1

Langkah 2: Buat Fungsi Pengirim Email

Buat mailer.js:

// mailer.js — MailAnvil email sender
const MAILANVIL_URL = process.env.MAILANVIL_API_URL;

async function sendPaymentNotification({ to, customerName, orderId, amount, items }) {
  const response = await fetch(`${MAILANVIL_URL}/send`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${process.env.MAILANVIL_API_KEY}`,
      'Idempotency-Key': orderId  // ⬅️ anti-duplikasi
    },
    body: JSON.stringify({
      from: 'noreply@aplikasimu.com',
      to: [to],
      subject: `Pembayaran Berhasil — Pesanan #${orderId}`,
      html: buildInvoiceHTML({ customerName, orderId, amount, items }),
      text: `Halo ${customerName}, pembayaran Rp${amount.toLocaleString('id-ID')} untuk pesanan #${orderId} telah berhasil.`
    })
  });

  if (!response.ok) {
    const err = await response.json();
    throw new Error(`MailAnvil error: ${err.error?.message || response.status}`);
  }

  return response.json();
}

Poin penting: - Header Idempotency-Key dengan orderId — mencegah kirim email dua kali kalau request retry - Selalu sediakan versi text selain html — deliverability lebih baik - Format Rupiah pakai toLocaleString('id-ID')

Langkah 3: Template Invoice HTML

Buat invoice-template.js:

function buildInvoiceHTML({ customerName, orderId, amount, items }) {
  const itemRows = items.map(item => `
    <tr>
      <td style="padding:8px;border-bottom:1px solid #eee">${item.name}</td>
      <td style="padding:8px;border-bottom:1px solid #eee;text-align:center">${item.qty}x</td>
      <td style="padding:8px;border-bottom:1px solid #eee;text-align:right">Rp${item.price.toLocaleString('id-ID')}</td>
    </tr>
  `).join('');

  return `
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"></head>
<body style="font-family:Arial,sans-serif;max-width:600px;margin:0 auto;padding:20px">
  <div style="background:#ff801f;padding:20px;border-radius:8px 8px 0 0">
    <h1 style="color:#fff;margin:0;font-size:20px">✅ Pembayaran Berhasil</h1>
  </div>
  <div style="background:#1a1a2e;color:#e0e0e0;padding:20px;border-radius:0 0 8px 8px">
    <p style="font-size:16px">Halo <strong>${customerName}</strong>,</p>
    <p>Pembayaran kamu untuk pesanan <strong>#${orderId}</strong> telah kami terima.</p>

    <table style="width:100%;border-collapse:collapse;margin:20px 0">
      <thead>
        <tr style="background:#2a2a3e">
          <th style="padding:8px;text-align:left;color:#ff801f">Item</th>
          <th style="padding:8px;text-align:center;color:#ff801f">Qty</th>
          <th style="padding:8px;text-align:right;color:#ff801f">Harga</th>
        </tr>
      </thead>
      <tbody>${itemRows}</tbody>
    </table>

    <div style="text-align:right;font-size:18px;margin:20px 0;padding:15px;background:#2a2a3e;border-radius:6px">
      Total: <strong style="color:#ff801f">Rp${amount.toLocaleString('id-ID')}</strong>
    </div>

    <p style="color:#888;font-size:12px;margin-top:30px">
      Email ini dikirim otomatis oleh sistem kami. Tidak perlu dibalas.<br>
      Dikirim melalui <a href="https://mailanvil.com" style="color:#ff801f">MailAnvil</a> — Email API untuk developer Indonesia.
    </p>
  </div>
</body>
</html>`;
}

Dark theme + aksen oranye MailAnvil (#ff801f). Invoice terlihat profesional meski plain HTML — tanpa framework CSS tambahan.

Langkah 4: Integrasi ke Express Route

Buat server.js:

require('dotenv').config();
const express = require('express');
const { sendPaymentNotification } = require('./mailer');

const app = express();
app.use(express.json());

app.post('/api/payment-webhook', async (req, res) => {
  try {
    const { email, name, orderId, amount, items } = req.body;

    // Validasi minimal
    if (!email || !orderId || !amount) {
      return res.status(400).json({ error: 'email, orderId, amount wajib diisi' });
    }

    const result = await sendPaymentNotification({
      to: email,
      customerName: name,
      orderId,
      amount,
      items
    });

    console.log(`✅ Email terkirim: ${result.email_id}`);
    res.json({ success: true, email_id: result.email_id });

  } catch (err) {
    console.error('❌ Gagal kirim:', err.message);

    // Jangan return 500 mentah — beri pesan Bahasa Indonesia
    res.status(502).json({
      error: 'Gagal mengirim email notifikasi',
      detail: err.message
    });
  }
});

app.listen(3000, () => {
  console.log('🚀 Payment notifier siap di http://localhost:3000');
});

Langkah 5: Test Kirim

Jalankan server:

node server.js

Test dengan curl:

curl -X POST http://localhost:3000/api/payment-webhook \
  -H "Content-Type: application/json" \
  -d '{
    "email": "pelanggan@example.com",
    "name": "Budi Santoso",
    "orderId": "INV-20260722-0042",
    "amount": 127500,
    "items": [
      {"name": "Nasi Goreng Spesial", "qty": 2, "price": 35000},
      {"name": "Es Teh Manis", "qty": 2, "price": 8000},
      {"name": "Ayam Goreng Kremes", "qty": 1, "price": 41500}
    ]
  }'

Response sukses:

{"success": true, "email_id": "em_01ARZ3NDEKTSV4RRFFQ69G5FCV"}

Studi Kasus Nyata di Indonesia

1. Food Delivery (GoFood/GrabFood)

Setiap pesanan selesai → trigger webhook → kirim invoice ke email pembeli + email ke merchant. MailAnvil bisa handle 1000+ transaksi per menit tanpa antrian.

2. E-commerce (Tokopedia/Shopee)

Konfirmasi pesanan + update status pengiriman + link tracking — semua via transactional email. Dengan Idempotency-Key, tidak akan ada email terkirim dua kali meski webhook retry.

3. OTP & Verifikasi (Jago, Bank Jago)

Kirim OTP via email sebagai kanal kedua selain SMS. Biaya per email lewat MailAnvil jauh lebih murah dibanding per-SMS — cocok untuk fintech yang kirim ribuan OTP per hari.

Kenapa MailAnvil Bukan SendGrid/Resend

Fitur MailAnvil SendGrid Resend
Harga Rp 149rb/bulan (10k email) $19.95/bulan (~Rp 320rb) $20/bulan (~Rp 320rb)
Pembayaran QRIS, GoPay, Transfer Kartu kredit internasional Kartu kredit internasional
Support Bahasa Indonesia, fast Bahasa Inggris Bahasa Inggris
MCP-native ✅ AI agent auto-discovery
Dokumentasi Bahasa Indonesia + English English only English only
DKIM auto-setup ✅ CF DNS users Manual Manual

Untuk startup Indonesia: harga 50% lebih murah, bayar pakai GoPay, support Bahasa Indonesia. Tidak ada alasan pakai yang lain.

Coba Sekarang

  1. Daftar gratis di mailanvil.com — dapat 500 email/bulan tanpa biaya
  2. Verifikasi domain (panduan lengkap tersedia di docs.mailanvil.com)
  3. Copy-paste kode di atas, ganti from dengan domain kamu
  4. Kirim email pertama dalam 5 menit

Developer Indonesia bangun untuk Indonesia. MailAnvil — email API pertama yang ngerti kebutuhan developer lokal. 🇮🇩


Tags: #emailAPI #NodeJS #ExpressJS #Indonesia #GoFood #Tokopedia #fintech #transactionalEmail