import { userService } from './userService.js' let _stripe = null async function getStripe() { if (_stripe) return _stripe const config = useRuntimeConfig() const key = config.public.stripePublishableKey if (!key) throw new Error('Stripe publishable key not configured') const { loadStripe } = await import('@stripe/stripe-js') _stripe = await loadStripe(key) return _stripe } export const paymentService = { /** * Create a Stripe PaymentIntent via the backend and return the client_secret. * pack: 'starter' | 'studio' | 'agency' */ async createPaymentIntent(pack) { const config = useRuntimeConfig() const token = userService.getToken() const res = await fetch(`${config.public.apiBase}/api/payments/create-intent`, { method: 'POST', headers: { 'Content-Type': 'application/json', ...(token ? { Authorization: `Bearer ${token}` } : {}), }, body: JSON.stringify({ pack }), }) if (!res.ok) { const err = await res.json() throw new Error(err.message || 'Failed to create payment intent') } return res.json() }, /** * Mount Stripe Elements into the given DOM element and confirm payment. * Returns a promise that resolves when the payment is confirmed. */ async mountAndConfirm(mountElement, clientSecret) { const stripe = await getStripe() const elements = stripe.elements({ clientSecret }) const paymentElement = elements.create('payment') paymentElement.mount(mountElement) return { elements, confirm: async (returnUrl) => { const { error } = await stripe.confirmPayment({ elements, confirmParams: { return_url: returnUrl }, }) if (error) throw new Error(error.message) }, } }, }