// HelcimPay.js integration composable export const useHelcimPay = () => { let checkoutToken = null let secretToken = null // Initialize HelcimPay.js session const initializeHelcimPay = async (customerId, customerCode, amount = 0) => { try { const response = await $fetch('/api/helcim/initialize-payment', { method: 'POST', body: { customerId, customerCode, amount } }) if (response.success) { checkoutToken = response.checkoutToken secretToken = response.secretToken return true } throw new Error('Failed to initialize payment session') } catch (error) { console.error('Payment initialization error:', error) throw error } } // Show payment modal const showPaymentModal = () => { return new Promise((resolve, reject) => { if (!checkoutToken) { reject(new Error('Payment not initialized. Call initializeHelcimPay first.')) return } // Load HelcimPay.js modal script if (!window.appendHelcimPayIframe) { console.log('HelcimPay script not loaded, loading now...') const script = document.createElement('script') script.src = 'https://secure.helcim.app/helcim-pay/services/start.js' script.async = true script.onload = () => { console.log('HelcimPay script loaded successfully!') console.log('Available functions:', Object.keys(window).filter(key => key.includes('Helcim') || key.includes('helcim'))) console.log('appendHelcimPayIframe available:', typeof window.appendHelcimPayIframe) openModal(resolve, reject) } script.onerror = () => { reject(new Error('Failed to load HelcimPay.js')) } document.head.appendChild(script) } else { console.log('HelcimPay script already loaded, calling openModal') openModal(resolve, reject) } }) } // Open the payment modal const openModal = (resolve, reject) => { try { console.log('Trying to open modal with checkoutToken:', checkoutToken) if (typeof window.appendHelcimPayIframe === 'function') { // Set up event listener for HelcimPay.js responses const helcimPayJsIdentifierKey = 'helcim-pay-js-' + checkoutToken const handleHelcimPayEvent = (event) => { console.log('Received window message:', event.data) if (event.data.eventName === helcimPayJsIdentifierKey) { console.log('HelcimPay event received:', event.data) // Remove event listener to prevent multiple responses window.removeEventListener('message', handleHelcimPayEvent) if (event.data.eventStatus === 'SUCCESS') { console.log('Payment success:', event.data.eventMessage) // Parse the JSON string eventMessage let paymentData try { paymentData = JSON.parse(event.data.eventMessage) console.log('Parsed payment data:', paymentData) } catch (parseError) { console.error('Failed to parse eventMessage:', parseError) reject(new Error('Invalid payment response format')) return } // Extract transaction details from nested data structure const transactionData = paymentData.data?.data || {} console.log('Transaction data:', transactionData) resolve({ success: true, transactionId: transactionData.transactionId, cardToken: transactionData.cardToken, cardLast4: transactionData.cardNumber ? transactionData.cardNumber.slice(-4) : undefined, cardType: transactionData.cardType || 'unknown' }) } else if (event.data.eventStatus === 'ABORTED') { console.log('Payment aborted:', event.data.eventMessage) reject(new Error(event.data.eventMessage || 'Payment failed')) } else if (event.data.eventStatus === 'HIDE') { console.log('Modal closed without completion') reject(new Error('Payment cancelled by user')) } } } // Add event listener window.addEventListener('message', handleHelcimPayEvent) // Open the HelcimPay iframe modal console.log('Calling appendHelcimPayIframe with token:', checkoutToken) window.appendHelcimPayIframe(checkoutToken, true) console.log('appendHelcimPayIframe called, waiting for window messages...') // Add timeout to clean up if no response setTimeout(() => { console.log('60 seconds passed, cleaning up event listener...') window.removeEventListener('message', handleHelcimPayEvent) reject(new Error('Payment timeout - no response received')) }, 60000) } else { reject(new Error('appendHelcimPayIframe function not available')) } } catch (error) { console.error('Error opening modal:', error) reject(error) } } // Process payment verification const verifyPayment = async () => { try { return await showPaymentModal() } catch (error) { throw error } } // Cleanup tokens const cleanup = () => { checkoutToken = null secretToken = null } return { initializeHelcimPay, verifyPayment, cleanup } }