import React from 'react' import { Button } from '../../../components/ui/button' import { getPaymentMode } from '../lib/paymentMode' import { Alert } from '../../../components/alert/Alert' import { LoadingOverlay } from '../../../components/LoadingOverlay' import { mapErrorToUserMessage } from '../../../lib/errorMessages' import { Logger } from '../../../lib/logger' import { SnapTokenService } from './SnapTokenService' interface SnapPaymentTriggerProps { orderId: string amount: number customer?: { name?: string; phone?: string; email?: string } paymentMethod?: string onSuccess?: (result: any) => void onError?: (error: any) => void onChargeInitiated?: () => void } export function SnapPaymentTrigger({ orderId, amount, customer, paymentMethod, onSuccess, onError, onChargeInitiated }: SnapPaymentTriggerProps) { const mode = getPaymentMode() // If Core mode, render the appropriate Core component if (mode === 'CORE') { return ( ) } // Snap mode - use hosted payment interface return ( ) } function CorePaymentComponent({ paymentMethod, orderId, amount, onChargeInitiated }: { paymentMethod: string orderId: string amount: number onChargeInitiated?: () => void }) { const [Component, setComponent] = React.useState | null>(null) const [loading, setLoading] = React.useState(true) React.useEffect(() => { const loadComponent = async () => { try { let componentModule: any switch (paymentMethod) { case 'bank_transfer': componentModule = await import('../core/BankTransferPanel') setComponent(() => componentModule.BankTransferPanel) break case 'credit_card': componentModule = await import('../core/CardPanel') setComponent(() => componentModule.CardPanel) break case 'gopay': componentModule = await import('../core/GoPayPanel') setComponent(() => componentModule.GoPayPanel) break case 'cstore': componentModule = await import('../core/CStorePanel') setComponent(() => componentModule.CStorePanel) break default: componentModule = await import('../core/BankTransferPanel') setComponent(() => componentModule.BankTransferPanel) } } catch (error) { console.error('Failed to load payment component:', error) } finally { setLoading(false) } } loadComponent() }, [paymentMethod]) if (loading) { return Loading payment component... } if (!Component) { return Payment method not available } return } function SnapHostedPayment({ orderId, amount, customer, onSuccess, onError }: Omit) { const [loading, setLoading] = React.useState(false) const [error, setError] = React.useState('') const handleSnapPayment = async () => { try { setLoading(true) setError('') Logger.paymentInfo('snap.payment.init', { orderId, amount, customer }) // Create Snap transaction token using service const token = await SnapTokenService.createToken({ transaction_details: { order_id: orderId, gross_amount: amount }, customer_details: customer ? { first_name: customer.name, email: customer.email, phone: customer.phone } : undefined, item_details: [{ id: orderId, name: 'Payment', price: amount, quantity: 1 }] }) Logger.paymentInfo('snap.token.received', { orderId, token: token.substring(0, 10) + '...' }) // Trigger Snap payment popup if (window.snap && typeof window.snap.pay === 'function') { window.snap.pay(token, { onSuccess: (result: any) => { Logger.paymentInfo('snap.payment.success', { orderId, transactionId: result.transaction_id }) onSuccess?.(result) }, onPending: (result: any) => { Logger.paymentInfo('snap.payment.pending', { orderId, transactionId: result.transaction_id }) // Handle pending state }, onError: (result: any) => { Logger.paymentError('snap.payment.error', { orderId, error: result }) const message = mapErrorToUserMessage(result) setError(message) onError?.(result) }, onClose: () => { Logger.paymentInfo('snap.popup.closed', { orderId }) // User closed the popup without completing payment } }) } else { throw new Error('Snap.js not loaded') } } catch (e: any) { Logger.paymentError('snap.payment.error', { orderId, error: e.message }) const message = mapErrorToUserMessage(e) setError(message) onError?.(e) } finally { setLoading(false) } } return ( {error && ( {error} )} Klik tombol di bawah untuk melanjutkan pembayaran dengan Midtrans Snap {loading ? 'Memproses...' : 'Bayar Sekarang'} {loading && } ) }
Klik tombol di bawah untuk melanjutkan pembayaran dengan Midtrans Snap