Kirim Slip Gaji (Payslip) PDF Otomatis dengan MailAnvil + Node.js
Kirim Slip Gaji (Payslip) PDF Otomatis dengan MailAnvil + Node.js
Setiap tanggal 25, tim HR dan software payroll di Indonesia menghadapi pekerjaan yang sama: generate ratusan slip gaji PDF, lalu kirim satu per satu ke email karyawan. Dikirim manual dari Gmail, selain makan waktu berjam-jam, juga rawan salah kirim — dan email bulk dari akun Gmail pribadi sering masuk spam.
Tutorial ini membuktikan bahwa seluruh proses bisa otomatis dengan MailAnvil: payroll engine Anda generate PDF payslip, kirim via email API, dan setiap pengiriman tercatat statusnya (delivered, bounced, failed) di dashboard. Tidak ada lagi "apakah Pak Budi sudah terima slip-nya?"
Kenapa email API, bukan SMTP langsung?
- Terlacak per penerima. SMTP tidak kasih tahu apakah email diterima. MailAnvil menyimpan status per penerima — krusial untuk kepatuhan payroll.
- Bounce otomatis terdeteksi. Kalau email karyawan salah (misal dia resign dan email dinonaktifkan), Anda tahu lewat status
bounced, bukan dari komplain berminggu-minggu kemudian. - Murah. Paket Free 3.000 email/bulan cukup untuk karyawan ≤ 200 (slip gaji + memo bulanan). Paket Pro 50.000 email/bulan mulai Rp 249rb — dibanding pull-SMS atau kirim hardcopy, ini transaksional email murah paling masuk akal untuk startup Indonesia.
Prasyarat
- Akun MailAnvil di app.mailanvil.com (signup gratis).
- Domain perusahaan terverifikasi — tambahkan di tab Domains, tunggu status
verified. Tanpa ini, API menolak pengiriman (proteksi deliverability). - Node.js 18+.
Langkah 1 — Generate PDF payslip
Anggap payroll engine Anda sudah punya fungsi ini. Contoh dengan pdfkit:
import PDFDocument from 'pdfkit';
function buatPayslip(karyawan) {
return new Promise((resolve) => {
const doc = new PDFDocument({ size: 'A4', margin: 40 });
const chunks = [];
doc.on('data', (c) => chunks.push(c));
doc.on('end', () => resolve(Buffer.concat(chunks)));
doc.fontSize(16).text(karyawan.perusahaan, { align: 'center' });
doc.fontSize(12).text('Slip Gaji — Oktober 2026', { align: 'center' });
doc.moveDown(2);
doc.fontSize(11)
.text(`Nama : ${karyawan.nama}`)
.text(`Posisi : ${karyawan.posisi}`)
.text(`Gaji Pokok : Rp ${karyawan.gaji.toLocaleString('id-ID')}`)
.text(`Tunjangan : Rp ${karyawan.tunjangan.toLocaleString('id-ID')}`)
.text(`Potongan : Rp ${karyawan.potongan.toLocaleString('id-ID')}`)
.text(`Take Home : Rp ${karyawan.takeHome.toLocaleString('id-ID')}`);
doc.end();
});
}
Langkah 2 — Kirim via MailAnvil (dengan attachment)
MailAnvil menerima attachment langsung di payload POST /v1/send — hingga 10 file, total 25 MB. PDF payslip biasanya 30–100 KB, jadi sangat aman. Attachment dikirim sebagai base64:
const res = await fetch('https://api.mailanvil.com/v1/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.MAILANVIL_API_KEY}`,
'Idempotency-Key': `payslip-${karyawan.nik}-2026-10`,
},
body: JSON.stringify({
from: `[email protected]`,
to: karyawan.email,
subject: 'Slip Gaji — Oktober 2026',
html: `
<p>Selamat pagi ${karyawan.nama},</p>
<p>Terlampir slip gaji Anda periode Oktober 2026.
Untuk pertanyaan kompensasi, hubungi <a href="mailto:[email protected]">[email protected]</a>.</p>
<p>Salam,<br>Tim HR</p>
`,
text: `Slip gaji Oktober 2026 terlampir. Hubungi [email protected] untuk pertanyaan.`,
attachments: [{
filename: `slip-gaji-${karyawan.nik}-2026-10.pdf`,
content: pdfBuffer.toString('base64'),
content_type: 'application/pdf',
}],
}),
});
const data = await res.json();
console.log(data.id); // simpan untuk tracking status
Dua detail penting di kode atas:
Idempotency-Key— kalau script payroll crash dan re-run, karyawan tidak menerima slip dua kali. API mengenali key yang sama dan melewati pengiriman kedua.fromharus domain terverifikasi. Ini bukan batasan formalitas: email dari domain terverifikasi (SPF + DKIM aktif) yang membuat slip gaji tidak dicurigai sebagai phishing — kasus klasik rekayasa sosial berkedok "slip gaji" sedang ramai.
Langkah 3 — Loop untuk seluruh karyawan + cek status
for (const karyawan of daftarKaryawan) {
const pdf = await buatPayslip(karyawan);
await kirimPayslip(karyawan, pdf);
await sleep(300); // sosokkan ritme pengiriman
}
Besoknya, cek tab Logs di dashboard: setiap email punya status delivered / bounced. Filter bounced, perbarui email karyawan di database payroll, kirim ulang. Atau otomatis via endpoint GET /v1/emails.
Siapa yang pakai pola ini di Indonesia?
- Software payroll & HR SaaS (segmen yang dikerjakan Mekari Talenta, Gadjian, dan puluhan HR-tool lokal): slip gaji bulanan + rekap PPh 21 akhir tahun ke semua karyawan.
- Klinik & jaringan apotek: kirim jadwal shift bulanan + slip honorarium tenaga medis.
- Sekolah & lembaga kursus: kirim slip gaji guru part-time tiap periode pembayaran.
Semua polanya sama: satu template HTML, satu PDF per penerima, satu API key, dan log yang bisa diaudit.
CTA
Coba MailAnvil gratis di mailanvil.com — 3.000 email/bulan, tanpa kartu kredit, pembayaran Pro via QRIS/GoPay.