diff --git a/src/components/admin/settings/NotifikasiTab.tsx b/src/components/admin/settings/NotifikasiTab.tsx index a0ceb80..f8cfdfa 100644 --- a/src/components/admin/settings/NotifikasiTab.tsx +++ b/src/components/admin/settings/NotifikasiTab.tsx @@ -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 +
+

Scan QR untuk Pembayaran

+ QRIS Payment QR Code +

Scan dengan aplikasi e-wallet atau mobile banking Anda

+

Berlaku hingga: {qr_expiry_time}

+
+ Bayar Sekarang +
+
+

Langkah Selanjutnya:

  1. Selesaikan pembayaran sebelum batas waktu
  2. diff --git a/src/pages/Checkout.tsx b/src/pages/Checkout.tsx index 771b097..9af8dd9 100644 --- a/src/pages/Checkout.tsx +++ b/src/pages/Checkout.tsx @@ -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}`); diff --git a/supabase/functions/send-notification/index.ts b/supabase/functions/send-notification/index.ts index a07f355..b36f1ce 100644 --- a/supabase/functions/send-notification/index.ts +++ b/supabase/functions/send-notification/index.ts @@ -1,6 +1,7 @@ import { serve } from "https://deno.land/std@0.190.0/http/server.ts"; import { createClient } from "https://esm.sh/@supabase/supabase-js@2"; import { EmailTemplateRenderer } from "../shared/email-template-renderer.ts"; +import QRCode from 'https://esm.sh/qrcode@1.5.3'; const corsHeaders = { "Access-Control-Allow-Origin": "*", @@ -246,6 +247,24 @@ serve(async (req: Request): Promise => { ...variables, }; + // Special handling for order_created: generate QR code image + if (template_key === 'order_created' && allVariables.qr_string) { + console.log('[SEND-NOTIFICATION] Generating QR code for order_created email'); + try { + const qrDataUrl = await QRCode.toDataURL(allVariables.qr_string, { + width: 300, + margin: 2, + color: { dark: '#000000', light: '#FFFFFF' } + }); + allVariables.qr_code_image = qrDataUrl; + console.log('[SEND-NOTIFICATION] QR code generated successfully'); + } catch (qrError) { + console.error('[SEND-NOTIFICATION] Failed to generate QR code:', qrError); + // Continue without QR code - don't fail the email + allVariables.qr_code_image = ''; + } + } + const subject = replaceVariables(template.subject, allVariables); const htmlContent = replaceVariables(template.body_html || template.body_text || "", allVariables);