// 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 = `
Payment Form Error: ${error.message || 'Failed to load payment form'}
Please refresh the page and try again. If the problem persists, contact support.
`;
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 = `
🛡️ Ad Blocker Detected
Error: ${errorMessage}
Your ad blocker or privacy extension is preventing the secure payment form from loading. This is normal security behavior, but we need to process your payment securely through Stripe.
🔧 Quick Fix:
${browserSpecificInstructions}
🔒 Why This Happens:
• Ad blockers block payment tracking
• Privacy extensions block third-party scripts
• This protects your privacy normally
• Stripe needs access for secure payments
✅ Alternative Solutions:
1. Incognito/Private Mode
Usually has fewer extensions
2. Different Browser
Try Chrome, Firefox, or Safari
3. Mobile Device
Often has fewer blockers
We use Stripe for secure payment processing. Your payment information is encrypted and safe.
`;
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');