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

Kirim Email Notifikasi Pesanan untuk E-commerce dengan MailAnvil + Node.js

Platform e-commerce di Indonesia tumbuh 30% per tahun. Setiap pesanan baru, pembayaran masuk, dan status pengiriman butuh notifikasi email real-time. Masalahnya? Email API internasional mahal — apalagi kalau volume sudah ribuan per hari.

MailAnvil solusinya. API email lokal dengan harga Rp0 mulai, Rp149rb/bln untuk 10.000 email. Bayar pakai QRIS atau GoPay. Docs dalam Bahasa Indonesia. MCP-native — AI agent bisa setup sendiri.

Di tutorial ini, kamu akan integrasi MailAnvil ke backend Node.js e-commerce dalam 10 menit.

Yang Kamu Butuhin

1. Setup Proyek

Buat folder baru dan init:

mkdir mailanvil-ecommerce
cd mailanvil-ecommerce
npm init -y
npm install node-fetch

Buat file .env:

MAILANVIL_API_KEY=key_01j83...
[email protected]
FROM_NAME=Toko Online

2. Fungsi Kirim Email

Bikin mail.js — helper untuk kirim email via MailAnvil API:

import fetch from 'node-fetch';

const API_BASE = 'https://api.mailanvil.com/v1';

export async function sendEmail({ to, subject, html, text }) {
  const res = await fetch(`${API_BASE}/send`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${process.env.MAILANVIL_API_KEY}`,
    },
    body: JSON.stringify({
      from: {
        email: process.env.FROM_EMAIL,
        name: process.env.FROM_NAME,
      },
      to: [{ email: to }],
      subject,
      html,
      text,
    }),
  });

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

  return res.json(); // { emailId: "em_01j83..." }
}

Itu aja. Dua fungsi — kirim email. IDempotency-Key opsional kalau mau cegah duplikat kiriman ulang.

3. Template Email Konfirmasi Pesanan

Buat templates.js:

export function orderConfirmation(order) {
  const items = order.items.map(i =>
    `<tr><td>${i.name}</td><td>${i.qty}x</td><td>Rp ${i.price.toLocaleString('id-ID')}</td></tr>`
  ).join('');

  return {
    subject: `Pesanan #${order.id} Dikonfirmasi — ${order.store}`,
    html: `
      <div style="background:#0a0a0a;color:#e0e0e0;padding:40px 20px;font-family:-apple-system,sans-serif;max-width:600px;margin:0 auto;">
        <div style="text-align:center;margin-bottom:30px;">
          <span style="color:#ff801f;font-size:28px;font-weight:bold;">✓</span>
          <h1 style="color:#ffffff;font-size:22px;margin:10px 0;">Pesanan Dikonfirmasi</h1>
        </div>
        <div style="background:#1a1a1a;border:1px solid rgba(214,235,253,0.12);border-radius:12px;padding:24px;">
          <p style="color:#a0a0a0;">Halo <strong style="color:#ffffff;">${order.customer}</strong>,</p>
          <p>Pesanan kamu #${order.id} sudah dikonfirmasi dan sedang diproses.</p>

          <table style="width:100%;border-collapse:collapse;margin:20px 0;">
            <thead>
              <tr style="border-bottom:1px solid #333;">
                <th style="text-align:left;padding:8px;color:#a0a0a0;">Produk</th>
                <th style="text-align:center;padding:8px;color:#a0a0a0;">Qty</th>
                <th style="text-align:right;padding:8px;color:#a0a0a0;">Harga</th>
              </tr>
            </thead>
            <tbody>${items}</tbody>
          </table>

          <div style="border-top:1px solid #333;padding-top:12px;text-align:right;font-size:18px;">
            <span style="color:#a0a0a0;">Total: </span>
            <strong style="color:#ff801f;">Rp ${order.total.toLocaleString('id-ID')}</strong>
          </div>

          <div style="margin-top:20px;padding:16px;background:rgba(255,128,31,0.1);border-radius:8px;border-left:3px solid #ff801f;">
            <p style="margin:0;color:#a0a0a0;font-size:13px;">
              📦 Estimasi pengiriman: ${order.estimatedDelivery}
            </p>
          </div>
        </div>
        <p style="text-align:center;margin-top:24px;color:#555;font-size:12px;">
          Dikirim via <a href="https://mailanvil.com" style="color:#ff801f;">MailAnvil</a>
        </p>
      </div>`,
    text: `Pesanan #${order.id} Dikonfirmasi\n\nHalo ${order.customer},\n\nPesanan kamu #${order.id} sudah dikonfirmasi.\nTotal: Rp ${order.total.toLocaleString('id-ID')}\nEstimasi: ${order.estimatedDelivery}\n\n--\nDikirim via MailAnvil`,
  };
}

Dark theme, orange accent — sama kayak branding MailAnvil. HTML + plain text biar deliverability terjaga.

4. Contoh Kirim Notifikasi

Buat send-order.js:

import { sendEmail } from './mail.js';
import { orderConfirmation } from './templates.js';

const order = {
  id: 'INV-20260731-1234',
  customer: 'Budi Santoso',
  store: 'Toko Elektronik ID',
  items: [
    { name: 'Logitech MX Master 3S', qty: 1, price: 1450000 },
    { name: 'USB-C Hub 7-in-1', qty: 2, price: 289000 },
  ],
  total: 2028000,
  estimatedDelivery: '3-5 hari kerja',
};

const email = orderConfirmation(order);

try {
  const result = await sendEmail({
    to: '[email protected]',
    subject: email.subject,
    html: email.html,
    text: email.text,
  });
  console.log('Email terkirim:', result.emailId);
} catch (err) {
  console.error('Gagal:', err.message);
}

Jalankan:

node send-order.js

5. Webhook Tracking Status

Integrasi webhook biar backend tau kalau email udah terkirim atau bounce:

// Endpoint Express.js
app.post('/webhooks/mailanvil', (req, res) => {
  const signature = req.headers['x-signature'];
  const payload = JSON.stringify(req.body);

  // Verifikasi HMAC
  const hmac = crypto.createHmac('sha256', process.env.MAILANVIL_WEBHOOK_SECRET);
  hmac.update(payload);
  if (signature !== hmac.digest('hex')) {
    return res.status(403).json({ error: 'Invalid signature' });
  }

  const { emailId, status, recipients } = req.body;

  if (status === 'delivered') {
    await db.updateOrderStatus(emailId, 'email_terkirim');
  } else if (status === 'bounced') {
    // Email invalid — minta customer update email
    await db.flagBouncedEmail(recipients[0].email);
  }

  res.json({ received: true });
});

Kenapa Pilih MailAnvil buat E-commerce?

Fitur MailAnvil Resend SendGrid
Harga Starter Rp 149rb ~Rp 320rb ~Rp 580rb
Mata Uang IDR USD USD
Pembayaran QRIS / GoPay Kartu kredit Kartu kredit
Docs Bahasa Indonesia English English
MCP-Native
Bayar per bulan
Free tier 500/bln 100/bln 100/hari (lalu bayar)

E-commerce lokal kirim 10.000-100.000 email per bulan? Hemat 60% dibanding SendGrid. Plus bayar pakai QRIS — transfer langsung dari GoPay, tanpa kartu kredit.

Kesimpulan

Integrasi email notifikasi e-commerce dengan MailAnvil cuma butuh 3 langkah: 1. Daftar gratis di mailanvil.com 2. Ambil API key 3. Panggil endpoint /v1/send

Support Bahasa Indonesia, bayar pakai QRIS/GoPay, dan kalau domain kamu di Cloudflare — DKIM setup otomatis.

Mulai gratis sekarang → mailanvil.com