const STRIPE_POLL_INTERVAL = 100 const STRIPE_POLL_TIMEOUT = 15000 function waitForStripe() { return new Promise((resolve, reject) => { if (typeof globalThis.Stripe !== 'undefined') { resolve() return } let elapsed = 0 const interval = setInterval(() => { if (typeof globalThis.Stripe !== 'undefined') { clearInterval(interval) resolve() } else { elapsed += STRIPE_POLL_INTERVAL if (elapsed >= STRIPE_POLL_TIMEOUT) { clearInterval(interval) reject(new Error('Stripe failed to load after ' + STRIPE_POLL_TIMEOUT + 'ms')) } } }, STRIPE_POLL_INTERVAL) }) } export function initStripePayment() { const container = document.getElementById('payment-card') if (!container) return const publicKey = container.dataset.stripeKey const stripeAccount = container.dataset.stripeAccount const intentUrl = container.dataset.intentUrl const returnUrl = container.dataset.returnUrl const fallbackUrl = container.dataset.fallbackUrl const amount = container.dataset.amount if (!publicKey || !intentUrl) return const submitBtn = document.getElementById('payment-submit') const messageEl = document.getElementById('payment-message') const messageText = document.getElementById('payment-message-text') let stripe let elements waitForStripe().then(() => { /* global Stripe */ stripe = Stripe(publicKey, { stripeAccount: stripeAccount || undefined, }) return globalThis.fetch(intentUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, }) }) .then(r => r.json()) .then(data => { elements = stripe.elements({ clientSecret: data.clientSecret, appearance: { theme: 'flat', variables: { colorPrimary: '#4f46e5', fontFamily: 'system-ui, sans-serif', fontWeightNormal: '700', borderRadius: '0px', colorBackground: '#ffffff', }, rules: { '.Input': { border: '2px solid #111827', boxShadow: 'none', }, '.Input:focus': { border: '2px solid #4f46e5', boxShadow: 'none', }, }, }, }) const paymentElement = elements.create('payment', { layout: 'tabs' }) paymentElement.mount('#payment-element') }) .catch(() => { if (fallbackUrl) { globalThis.location.href = fallbackUrl } else { messageText.textContent = 'Impossible de charger le module de paiement. Veuillez rafraichir la page.' messageEl.classList.remove('hidden') submitBtn.disabled = true } }) submitBtn.addEventListener('click', async () => { if (!stripe || !elements) return submitBtn.disabled = true submitBtn.textContent = 'Traitement...' messageEl.classList.add('hidden') const { error } = await stripe.confirmPayment({ elements, confirmParams: { return_url: returnUrl, }, }) if (error) { messageText.textContent = error.message messageEl.classList.remove('hidden') submitBtn.disabled = false submitBtn.textContent = 'Payer ' + amount + ' \u20AC' } }) }