// Stripe Integration for Company Registration // This file handles the Stripe Elements integration for the Yew WASM application let stripe; let elements; let paymentElement; // Stripe publishable key - this should be set from the server or environment const STRIPE_PUBLISHABLE_KEY = 'pk_test_51234567890abcdef'; // Replace with actual key // Initialize Stripe when the script loads document.addEventListener('DOMContentLoaded', function() { console.log('🔧 Stripe integration script loaded'); // Initialize Stripe if (window.Stripe) { stripe = Stripe(STRIPE_PUBLISHABLE_KEY); console.log('✅ Stripe initialized'); } else { console.error('❌ Stripe.js not loaded'); } }); // Initialize Stripe Elements with client secret window.initializeStripeElements = async function(clientSecret) { console.log('🔧 Initializing Stripe Elements with client secret:', clientSecret); try { if (!stripe) { throw new Error('Stripe not initialized'); } // Create Elements instance with client secret elements = stripe.elements({ clientSecret: clientSecret, appearance: { theme: 'stripe', variables: { colorPrimary: '#198754', colorBackground: '#ffffff', colorText: '#30313d', colorDanger: '#df1b41', fontFamily: 'system-ui, sans-serif', spacingUnit: '4px', borderRadius: '6px', } } }); // Clear the payment element container first const paymentElementDiv = document.getElementById('payment-element'); if (!paymentElementDiv) { throw new Error('Payment element container not found'); } paymentElementDiv.innerHTML = ''; // Create and mount the Payment Element paymentElement = elements.create('payment'); paymentElement.mount('#payment-element'); // Handle real-time validation errors from the Payment Element paymentElement.on('change', (event) => { const displayError = document.getElementById('payment-errors'); if (event.error) { displayError.textContent = event.error.message; displayError.style.display = 'block'; displayError.classList.remove('alert-success'); displayError.classList.add('alert-danger'); } else { displayError.style.display = 'none'; } }); // Handle when the Payment Element is ready paymentElement.on('ready', () => { console.log('✅ Stripe Elements ready for payment'); // Add a subtle success indicator const paymentCard = paymentElementDiv.closest('.card'); if (paymentCard) { paymentCard.style.borderColor = '#198754'; paymentCard.style.borderWidth = '2px'; } // Update button text to show payment is ready const submitButton = document.getElementById('submit-payment'); const submitText = document.getElementById('submit-text'); if (submitButton && submitText) { submitButton.disabled = false; submitText.textContent = 'Complete Payment'; submitButton.classList.remove('btn-secondary'); submitButton.classList.add('btn-success'); } }); // Handle loading state paymentElement.on('loaderstart', () => { console.log('🔄 Stripe Elements loading...'); }); paymentElement.on('loaderror', (event) => { console.error('❌ Stripe Elements load error:', event.error); showAdBlockerGuidance(event.error.message || 'Failed to load payment form'); }); console.log('✅ Stripe Elements initialized successfully'); return true; } catch (error) { console.error('❌ Error initializing Stripe Elements:', error); // Check if this might be an ad blocker issue const isAdBlockerError = error.message && ( error.message.includes('blocked') || error.message.includes('Failed to fetch') || error.message.includes('ERR_BLOCKED_BY_CLIENT') || error.message.includes('network') || error.message.includes('CORS') ); if (isAdBlockerError) { showAdBlockerGuidance(error.message || 'Failed to load payment form'); } else { // Show generic error for non-ad-blocker issues const errorElement = document.getElementById('payment-errors'); if (errorElement) { errorElement.innerHTML = ` `; errorElement.style.display = 'block'; } } throw error; } }; // Create payment intent on server window.createPaymentIntent = async function(formDataJson) { console.log('💳 Creating payment intent...'); try { // Parse the JSON string from Rust let formData; if (typeof formDataJson === 'string') { formData = JSON.parse(formDataJson); } else { formData = formDataJson; } console.log('Form data:', formData); const response = await fetch('/company/create-payment-intent', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(formData) }); if (!response.ok) { const errorText = await response.text(); console.error('Payment intent creation failed:', errorText); let errorData; try { errorData = JSON.parse(errorText); } catch (e) { errorData = { error: errorText }; } throw new Error(errorData.error || 'Failed to create payment intent'); } const responseData = await response.json(); console.log('✅ Payment intent created:', responseData); const { client_secret } = responseData; if (!client_secret) { throw new Error('No client secret received from server'); } return client_secret; } catch (error) { console.error('❌ Payment intent creation error:', error); throw error; } }; // Confirm payment with Stripe window.confirmStripePayment = async function(clientSecret) { console.log('🔄 Confirming payment...'); try { // Ensure elements are ready before submitting if (!elements) { throw new Error('Payment form not ready. Please wait a moment and try again.'); } console.log('🔄 Step 1: Submitting payment elements...'); // Step 1: Submit the payment elements first (required by new Stripe API) const { error: submitError } = await elements.submit(); if (submitError) { console.error('Elements submit failed:', submitError); // Provide more specific error messages if (submitError.type === 'validation_error') { throw new Error('Please check your payment details and try again.'); } else if (submitError.type === 'card_error') { throw new Error(submitError.message || 'Card error. Please check your card details.'); } else { throw new Error(submitError.message || 'Payment form validation failed.'); } } console.log('✅ Step 1 complete: Elements submitted successfully'); console.log('🔄 Step 2: Confirming payment...'); // Step 2: Confirm payment with Stripe const { error, paymentIntent } = await stripe.confirmPayment({ elements, clientSecret: clientSecret, confirmParams: { return_url: `${window.location.origin}/company/payment-success`, }, redirect: 'if_required' // Handle success without redirect if possible }); if (error) { // Payment failed - redirect to failure page console.error('Payment confirmation failed:', error); window.location.href = `${window.location.origin}/company/payment-failure`; return false; } if (paymentIntent && paymentIntent.status === 'succeeded') { // Payment succeeded console.log('✅ Payment completed successfully:', paymentIntent.id); // Clear saved form data since registration is complete localStorage.removeItem('freezone_company_registration'); // Redirect to success page with payment details window.location.href = `${window.location.origin}/company/payment-success?payment_intent=${paymentIntent.id}&payment_intent_client_secret=${clientSecret}`; return true; } else if (paymentIntent && paymentIntent.status === 'requires_action') { // Payment requires additional authentication (3D Secure, etc.) console.log('🔐 Payment requires additional authentication'); // Stripe will handle the authentication flow automatically return false; // Don't redirect yet } else { // Unexpected status - redirect to failure page console.error('Unexpected payment status:', paymentIntent?.status); window.location.href = `${window.location.origin}/company/payment-failure`; return false; } } catch (error) { console.error('❌ Payment confirmation error:', error); throw error; } }; // Show comprehensive ad blocker guidance function showAdBlockerGuidance(errorMessage) { const errorElement = document.getElementById('payment-errors'); if (!errorElement) return; // Detect browser type for specific instructions const isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor); const isFirefox = /Firefox/.test(navigator.userAgent); const isSafari = /Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent); const isEdge = /Edg/.test(navigator.userAgent); let browserSpecificInstructions = ''; if (isChrome) { browserSpecificInstructions = ` Chrome Instructions:
1. Click the shield icon 🛡️ in the address bar
2. Select "Allow" for this site
3. Or go to Settings → Privacy → Ad blockers
`; } else if (isFirefox) { browserSpecificInstructions = ` Firefox Instructions:
1. Click the shield icon 🛡️ in the address bar
2. Turn off "Enhanced Tracking Protection" for this site
3. Or disable uBlock Origin/AdBlock Plus temporarily
`; } else if (isSafari) { browserSpecificInstructions = ` Safari Instructions:
1. Go to Safari → Preferences → Extensions
2. Temporarily disable ad blocking extensions
3. Or add this site to your allowlist
`; } else if (isEdge) { browserSpecificInstructions = ` Edge Instructions:
1. Click the shield icon 🛡️ in the address bar
2. Turn off tracking prevention for this site
3. Or disable ad blocking extensions
`; } errorElement.innerHTML = ` `; errorElement.style.display = 'block'; // Scroll to error errorElement.scrollIntoView({ behavior: 'smooth', block: 'center' }); // Add visual indication const paymentCard = document.querySelector('#payment-information-section'); if (paymentCard) { paymentCard.style.borderColor = '#ffc107'; paymentCard.style.borderWidth = '2px'; paymentCard.classList.add('border-warning'); } } // Show contact information function showContactInfo() { alert('Contact Support:\n\nEmail: support@hostbasket.com\nPhone: +1 (555) 123-4567\nLive Chat: Available 24/7\n\nPlease mention "Payment Form Loading Issue" when contacting us.'); } // Export functions for use by Rust/WASM window.stripeIntegration = { initializeElements: window.initializeStripeElements, createPaymentIntent: window.createPaymentIntent, confirmPayment: window.confirmStripePayment }; console.log('✅ Stripe integration script ready');