Kirim Email Transaksional di Laravel dengan Mailanvil API — Tutorial Lengkap
Laravel punya driver mail bawaan untuk SMTP, SendGrid, dan Mailgun. Tapi kalau startup kamu butuh email API yang murah, bayar pakai QRIS, dan dukungannya dalam Bahasa Indonesia — Mailanvil jawabannya.
Tutorial ini cover: setup Laravel + Mailanvil API kirim email OTP, invoice booking, dan welcome email.
Kenapa Mailanvil untuk Laravel?
| Fitur | Mailanvil | SendGrid | Mailgun |
|---|---|---|---|
| Harga | Gratis 500/bulan, Starter Rp 149rb | $20/mo (100K) | $35/mo (50K) |
| Pembayaran | QRIS, GoPay, Xendit | Kartu kredit USD | Kartu kredit USD |
| MCP Support | ✅ Native | ❌ | ❌ |
| Bahasa Docs | Indonesia | English | English |
| Latency (ID) | Edge via Cloudflare | Singapore | US East |
Use case nyata di Indonesia: - Travel booking — kirim itinerary + e-ticket setelah pembayaran - Food delivery — invoice + struk ke customer - Fintech — OTP verifikasi akun + notifikasi transaksi
Langkah 1: Daftar & Dapatkan API Key
# Signup via API
curl -X POST https://api.mailanvil.com/v1/signup \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","password":"securepass123"}'
Response:
{
"id": "cus_01HXYZ1234567890",
"api_key": "key_xxxxxxxxxxxxxxxxxxxxxxxx"
}
Simpan api_key di file .env Laravel:
MAILANVIL_API_KEY=key_xxxxxxxxxxxxxxxxxxxxxxxx
Langkah 2: Tambahkan Domain di Mailanvil
Sebelum kirim email, domain harus terverifikasi DKIM:
curl -X POST https://api.mailanvil.com/v1/domains \
-H "Authorization: Bearer $MAILANVIL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"startupmu.com"}'
Mailanvil akan return DNS records yang perlu kamu tambahkan di Cloudflare/Domain registrar.
Langkah 3: Buat Mail Service Provider Custom di Laravel
Laravel tidak punya driver bawaan untuk Mailanvil, tapi kita bisa pakai Illuminate\Mail\MailManager dengan custom transport. Cara paling bersih: buat HTTP client langsung.
Buat file app/Services/MailanvilService.php:
<?php
namespace App\Services;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class MailanvilService
{
private string $apiKey;
private string $baseUrl = 'https://api.mailanvil.com/v1';
public function __construct()
{
$this->apiKey = config('services.mailanvil.api_key');
}
/**
* Kirim email transaksional via Mailanvil API
*/
public function send(array $params): array
{
$payload = [
'from' => $params['from'] ?? config('mailanvil.from_address'),
'to' => (array) $params['to'],
'subject' => $params['subject'],
];
// Support HTML + plain text
if (isset($params['html'])) {
$payload['html'] = $params['html'];
}
if (isset($params['text'])) {
$payload['text'] = $params['text'];
}
// Optional: cc, bcc, replyTo
if (isset($params['cc'])) {
$payload['cc'] = (array) $params['cc'];
}
if (isset($params['bcc'])) {
$payload['bcc'] = (array) $params['bcc'];
}
if (isset($params['reply_to'])) {
$payload['replyTo'] = $params['reply_to'];
}
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . $this->apiKey,
'Content-Type' => 'application/json',
])->post("{$this->baseUrl}/send", $payload);
if ($response->successful()) {
return [
'success' => true,
'email_id' => $response->json('id'),
'status' => $response->json('status'),
];
}
Log::error('MailAnvil send failed', [
'status' => $response->status(),
'error' => $response->json('error'),
]);
return [
'success' => false,
'error' => $response->json('error.message', 'Unknown error'),
];
}
}
Langkah 4: Konfigurasi di config/services.php
Tambahkan di config/services.php:
'mailanvil' => [
'api_key' => env('MAILANVIL_API_KEY'),
'from_address' => env('MAILANVIL_FROM_ADDRESS', '[email protected]'),
],
Langkah 5: Kirim Email OTP — Fintech Use Case
Kirim OTP 6 digit ke nomor/email user:
<?php
namespace App\Jobs;
use App\Services\MailanvilService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Str;
class SendOtpEmail implements ShouldQueue
{
use Queueable;
public function __construct(
private string $email,
private string $otpCode
) {}
public function handle(MailanvilService $mailanvil): void
{
$html = view('emails.otp', [
'code' => $this->otpCode,
'email' => $this->email,
])->render();
$mailanvil->send([
'to' => $this->email,
'subject' => 'Kode Verifikasi Akun Anda',
'html' => $html,
'text' => "Kode verifikasi Anda: {$this->otpCode}. Berlaku 5 menit.",
]);
}
}
Template Blade resources/views/emails/otp.blade.php:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body { background: #000; color: #fff; font-family: system-ui, sans-serif; }
.container { max-width: 560px; margin: 0 auto; padding: 40px 24px; }
.code { font-size: 48px; font-weight: 700; color: #ff801f; text-align: center;
letter-spacing: 12px; padding: 32px 0; }
.footer { color: #666; font-size: 13px; margin-top: 32px; }
</style>
</head>
<body>
<div class="container">
<h1>Verifikasi Akun</h1>
<p>Halo,</p>
<p>Masukkan kode berikut untuk verifikasi akun <strong>{{ $email }}</strong>:</p>
<div class="code">{{ $code }}</div>
<p>Kode ini berlaku selama <strong>5 menit</strong>. Jangan bagikan kode ini ke siapapun.</p>
<div class="footer">
<p>Email ini dikirim oleh MailAnvil untuk startupmu.com</p>
</div>
</div>
</body>
</html>
Langkah 6: Invoice Email — Travel Booking
Kirim invoice + itinerary setelah pembayaran travel:
<?php
namespace App\Services;
class TravelInvoiceService
{
public function __construct(
private MailanvilService $mailanvil
) {}
public function sendBookingConfirmation(array $booking): array
{
$html = view('emails.booking-confirmation', [
'booking_id' => $booking['id'],
'customer' => $booking['customer_name'],
'destination'=> $booking['destination'],
'check_in' => $booking['check_in'],
'check_out' => $booking['check_out'],
'amount' => number_format($booking['amount'], 0, ',', '.'),
])->render();
return $this->mailanvil->send([
'to' => $booking['customer_email'],
'subject' => "Booking Confirmed — {$booking['destination']}",
'html' => $html,
]);
}
}
Gunakan di controller:
// app/Http/Controllers/BookingController.php
public function store(BookingRequest $request, TravelInvoiceService $invoice)
{
$booking = Booking::create($request->validated());
// Kirim email async via queue
SendBookingEmail::dispatch($booking);
return response()->json([
'message' => 'Booking berhasil, email dikirim',
'booking' => $booking->id,
], 201);
}
Langkah 7: Monitoring via Dashboard
Login ke app.mailanvil.com untuk monitor: - Status setiap email (queued, sent, delivered, bounced) - Statistik harian - Domain verification status - API key management
Ringkasan
| Langkah | Aksi |
|---|---|
| 1 | Daftar Mailanvil, dapat API key |
| 2 | Verifikasi domain (DNS records) |
| 3 | Buat MailanvilService.php |
| 4 | Tambah config di services.php |
| 5 | Kirim OTP/email transaksional |
| 6 | Monitor di dashboard |
Harga: Free 500 email/bulan, Starter Rp 149rb/bulan untuk 10K email.
Coba sekarang: mailanvil.com
Tags: email API Indonesia, kirim email Laravel, transactional email murah, API email lokal, Laravel mail API, email OTP, fintech email