Add order_created email with QR code generation
Enhanced email notification system to send order confirmation emails immediately after order creation with embedded QR code for payment.
Changes:
- Checkout.tsx: Added send-notification call after payment creation with comprehensive logging
- send-notification: Added QRCode library integration for generating base64 QR images for order_created emails
- NotifikasiTab.tsx: Added QR code section to default order_created template and updated shortcodes list
Technical details:
- QR code generated as base64 data URL for email client compatibility
- Fire-and-forget pattern ensures checkout flow isn't blocked
- Added detailed console logging for debugging email send issues
- New shortcodes: {qr_code_image}, {qr_expiry_time}
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -26,7 +26,7 @@ interface NotificationTemplate {
|
||||
const RELEVANT_SHORTCODES = {
|
||||
'payment_success': ['{nama}', '{email}', '{order_id}', '{tanggal_pesanan}', '{total}', '{metode_pembayaran}', '{produk}', '{link_akses}', '{thank_you_page}'],
|
||||
'access_granted': ['{nama}', '{email}', '{produk}', '{link_akses}', '{username_akses}', '{password_akses}', '{kadaluarsa_akses}'],
|
||||
'order_created': ['{nama}', '{email}', '{order_id}', '{tanggal_pesanan}', '{total}', '{metode_pembayaran}', '{produk}', '{payment_link}', '{thank_you_page}'],
|
||||
'order_created': ['{nama}', '{email}', '{order_id}', '{tanggal_pesanan}', '{total}', '{metode_pembayaran}', '{produk}', '{payment_link}', '{thank_you_page}', '{qr_code_image}', '{qr_expiry_time}'],
|
||||
'payment_reminder': ['{nama}', '{email}', '{order_id}', '{tanggal_pesanan}', '{total}', '{metode_pembayaran}', '{batas_pembayaran}', '{jumlah_pembayaran}', '{bank_tujuan}', '{nomor_rekening}', '{payment_link}', '{thank_you_page}'],
|
||||
'consulting_scheduled': ['{nama}', '{email}', '{tanggal_konsultasi}', '{jam_konsultasi}', '{durasi_konsultasi}', '{link_meet}', '{jenis_konsultasi}', '{topik_konsultasi}'],
|
||||
'event_reminder': ['{nama}', '{email}', '{judul_event}', '{tanggal_event}', '{jam_event}', '{link_event}', '{lokasi_event}', '{kapasitas_event}'],
|
||||
@@ -143,6 +143,16 @@ const DEFAULT_TEMPLATES: { key: string; name: string; defaultSubject: string; de
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div style="text-align: center; margin: 30px 0; padding: 20px; background-color: #f5f5f5; border-radius: 8px;">
|
||||
<h3 style="margin: 0 0 15px 0; font-size: 18px; color: #333;">Scan QR untuk Pembayaran</h3>
|
||||
<img src="{qr_code_image}" alt="QRIS Payment QR Code" style="width: 200px; height: 200px; border: 2px solid #000; padding: 10px; background-color: #fff; display: inline-block;">
|
||||
<p style="margin: 15px 0 5px 0; font-size: 14px; color: #666;">Scan dengan aplikasi e-wallet atau mobile banking Anda</p>
|
||||
<p style="margin: 5px 0 0 0; font-size: 12px; color: #999;">Berlaku hingga: {qr_expiry_time}</p>
|
||||
<div style="margin-top: 15px;">
|
||||
<a href="{payment_link}" style="display: inline-block; padding: 12px 24px; background-color: #000; color: #fff; text-decoration: none; border-radius: 4px; font-weight: bold;">Bayar Sekarang</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>Langkah Selanjutnya:</h3>
|
||||
<ol>
|
||||
<li>Selesaikan pembayaran sebelum batas waktu</li>
|
||||
|
||||
@@ -116,6 +116,44 @@ export default function Checkout() {
|
||||
throw new Error(paymentError.message || 'Gagal membuat pembayaran');
|
||||
}
|
||||
|
||||
// Send order_created email with QR code (non-blocking, fire-and-forget)
|
||||
console.log('[CHECKOUT] About to send order_created email for order:', order.id);
|
||||
console.log('[CHECKOUT] User email:', user.email);
|
||||
console.log('[CHECKOUT] Payment data QR string:', paymentData?.qr_string);
|
||||
|
||||
supabase.functions.invoke('send-notification', {
|
||||
body: {
|
||||
template_key: 'order_created',
|
||||
recipient_email: user.email,
|
||||
recipient_name: user.user_metadata.name || user.email?.split('@')[0] || 'Pelanggan',
|
||||
variables: {
|
||||
nama: user.user_metadata.name || user.email?.split('@')[0] || 'Pelanggan',
|
||||
email: user.email,
|
||||
order_id: order.id,
|
||||
tanggal_pesanan: new Date().toLocaleDateString('id-ID', {
|
||||
day: '2-digit',
|
||||
month: 'short',
|
||||
year: 'numeric'
|
||||
}),
|
||||
total: formatIDR(total),
|
||||
metode_pembayaran: 'QRIS',
|
||||
produk: items.map(item => item.title).join(', '),
|
||||
payment_link: `${window.location.origin}/orders/${order.id}`,
|
||||
thank_you_page: `${window.location.origin}/orders/${order.id}`,
|
||||
qr_string: paymentData?.qr_string || '',
|
||||
qr_expiry_time: paymentData?.expired_at ? new Date(paymentData.expired_at).toLocaleString('id-ID') : ''
|
||||
}
|
||||
}
|
||||
}).then(result => {
|
||||
console.log('[CHECKOUT] send-notification called successfully:', result);
|
||||
}).catch(err => {
|
||||
console.error('[CHECKOUT] Failed to send order_created email:', err);
|
||||
console.error('[CHECKOUT] Error details:', JSON.stringify(err));
|
||||
// Don't block checkout flow if email fails
|
||||
});
|
||||
|
||||
console.log('[CHECKOUT] Order creation email call initiated');
|
||||
|
||||
// Clear cart and redirect to order detail page to show QR code
|
||||
clearCart();
|
||||
navigate(`/orders/${order.id}`);
|
||||
|
||||
Reference in New Issue
Block a user