1+ /**
2+ * Initialize the Stripe payment page
3+ */
4+ export function initStripePaymentPage ( ) {
5+ const urlParams = new URLSearchParams ( window . location . search ) ;
6+ const paymentStatus = urlParams . get ( 'payment' ) ;
7+
8+ if ( paymentStatus === 'success' ) {
9+ window . showFloatingAlert ( 'Payment successful! Your subscription is now active.' , 'success' ) ;
10+ // Remove the query parameter from the URL
11+ window . history . replaceState ( { } , document . title , window . location . pathname ) ;
12+ } else if ( paymentStatus === 'cancel' ) {
13+ window . showFloatingAlert ( 'Payment cancelled. You can try again when you\'re ready.' , 'info' ) ;
14+ // Remove the query parameter from the URL
15+ window . history . replaceState ( { } , document . title , window . location . pathname ) ;
16+ }
17+
18+ // Pre-fill the form with data from localStorage if available
19+ const emailInput = document . getElementById ( 'email' ) ;
20+ if ( emailInput ) {
21+ // Get email from localStorage
22+ const email = localStorage . getItem ( 'stripe_payment_email' ) ;
23+ if ( email ) {
24+ emailInput . value = email ;
25+ // Clear the localStorage item
26+ localStorage . removeItem ( 'stripe_payment_email' ) ;
27+ }
28+ }
29+
30+ // Get plan from localStorage
31+ const plan = localStorage . getItem ( 'stripe_payment_plan' ) ;
32+ if ( plan && ( plan === 'monthly' || plan === 'yearly' ) ) {
33+ // Select the appropriate radio button
34+ const planRadios = document . querySelectorAll ( 'input[name="plan"]' ) ;
35+ planRadios . forEach ( radio => {
36+ if ( radio . value === plan ) {
37+ radio . checked = true ;
38+ // Update the selected class
39+ document . querySelectorAll ( '.plan-option' ) . forEach ( option => {
40+ if ( option . contains ( radio ) ) {
41+ option . classList . add ( 'selected' ) ;
42+ } else {
43+ option . classList . remove ( 'selected' ) ;
44+ }
45+ } ) ;
46+ // Update price display
47+ updatePriceDisplay ( plan ) ;
48+ }
49+ } ) ;
50+
51+ // Clear the localStorage item
52+ localStorage . removeItem ( 'stripe_payment_plan' ) ;
53+ }
54+
55+ // Get elements
56+ const monthlyPlan = document . getElementById ( 'monthly-plan' ) ;
57+ const yearlyPlan = document . getElementById ( 'yearly-plan' ) ;
58+ const monthlyRadio = document . querySelector ( 'input[value="monthly"]' ) ;
59+ const yearlyRadio = document . querySelector ( 'input[value="yearly"]' ) ;
60+
61+ // Add event listeners for plan selection
62+ if ( monthlyPlan && yearlyPlan && monthlyRadio && yearlyRadio ) {
63+ monthlyRadio . addEventListener ( 'change' , function ( ) {
64+ updatePriceDisplay ( 'monthly' ) ;
65+ } ) ;
66+
67+ yearlyRadio . addEventListener ( 'change' , function ( ) {
68+ updatePriceDisplay ( 'yearly' ) ;
69+ } ) ;
70+
71+ monthlyPlan . addEventListener ( 'click' , function ( ) {
72+ monthlyRadio . checked = true ;
73+ updatePriceDisplay ( 'monthly' ) ;
74+ } ) ;
75+
76+ yearlyPlan . addEventListener ( 'click' , function ( ) {
77+ yearlyRadio . checked = true ;
78+ updatePriceDisplay ( 'yearly' ) ;
79+ } ) ;
80+ }
81+
82+ // Function to update price display
83+ function updatePriceDisplay ( plan ) {
84+ const priceDisplay = document . getElementById ( 'price-display' ) ;
85+ const selectedPlanInput = document . getElementById ( 'selected-plan' ) ;
86+ const monthlyPlan = document . getElementById ( 'monthly-plan' ) ;
87+ const yearlyPlan = document . getElementById ( 'yearly-plan' ) ;
88+
89+ if ( priceDisplay && selectedPlanInput ) {
90+ const monthlyPrice = 5 ;
91+ const yearlyPrice = 30 ;
92+
93+ // Update price display
94+ if ( plan === 'yearly' ) {
95+ priceDisplay . textContent = `$${ yearlyPrice . toFixed ( 2 ) } /year` ;
96+ } else {
97+ priceDisplay . textContent = `$${ monthlyPrice . toFixed ( 2 ) } /month` ;
98+ }
99+
100+ // Update selected plan input
101+ selectedPlanInput . value = plan ;
102+
103+ // Update selected class
104+ if ( monthlyPlan && yearlyPlan ) {
105+ if ( plan === 'yearly' ) {
106+ yearlyPlan . classList . add ( 'selected' ) ;
107+ monthlyPlan . classList . remove ( 'selected' ) ;
108+ } else {
109+ monthlyPlan . classList . add ( 'selected' ) ;
110+ yearlyPlan . classList . remove ( 'selected' ) ;
111+ }
112+ }
113+
114+ console . log ( `Price display updated to: ${ priceDisplay . textContent } for plan: ${ plan } ` ) ;
115+ }
116+ }
117+
118+ // Initialize price display based on default selection
119+ const defaultPlan = document . querySelector ( 'input[name="plan"]:checked' ) ?. value || 'monthly' ;
120+ updatePriceDisplay ( defaultPlan ) ;
121+
122+ // Handle form submission
123+ const form = document . getElementById ( 'stripe-form' ) ;
124+ if ( form ) {
125+ form . addEventListener ( 'submit' , async function ( e ) {
126+ e . preventDefault ( ) ;
127+
128+ const email = document . getElementById ( 'email' ) . value . trim ( ) ;
129+ const plan = document . getElementById ( 'selected-plan' ) . value ;
130+
131+ if ( ! email ) {
132+ window . showFloatingAlert ( 'Please enter your email address' , 'error' ) ;
133+ return ;
134+ }
135+
136+ // Show loading state
137+ const submitButton = document . getElementById ( 'payment-button' ) ;
138+ submitButton . disabled = true ;
139+ submitButton . textContent = 'Processing...' ;
140+
141+ // Get the current URL for success and cancel URLs
142+ const currentUrl = window . location . href ;
143+ const successUrl = `${ currentUrl } ?payment=success` ;
144+ const cancelUrl = `${ currentUrl } ?payment=cancel` ;
145+
146+ try {
147+ console . log ( 'Creating checkout session with:' , { email, plan, successUrl, cancelUrl } ) ;
148+
149+ // Show processing state
150+ submitButton . disabled = true ;
151+ submitButton . textContent = 'Processing...' ;
152+
153+ // Create checkout session
154+ const response = await fetch ( '/api/1/payments/stripe/create-checkout-session' , {
155+ method : 'POST' ,
156+ headers : {
157+ 'Content-Type' : 'application/json'
158+ } ,
159+ body : JSON . stringify ( {
160+ email,
161+ plan,
162+ success_url : successUrl ,
163+ cancel_url : cancelUrl
164+ } )
165+ } ) ;
166+
167+ if ( ! response . ok ) {
168+ const errorText = await response . text ( ) ;
169+ console . error ( 'Server error response:' , errorText ) ;
170+ throw new Error ( `Server responded with ${ response . status } : ${ response . statusText } ` ) ;
171+ }
172+
173+ const data = await response . json ( ) ;
174+ console . log ( 'Checkout session created:' , data ) ;
175+
176+ if ( data && data . checkout_url ) {
177+ console . log ( 'Redirecting to:' , data . checkout_url ) ;
178+ // Redirect to Stripe checkout
179+ window . location . href = data . checkout_url ;
180+ } else {
181+ console . error ( 'No checkout URL in response:' , data ) ;
182+ window . showFloatingAlert ( 'Failed to create checkout session' , 'error' ) ;
183+ submitButton . disabled = false ;
184+ submitButton . textContent = 'Subscribe with Stripe' ;
185+ }
186+ } catch ( error ) {
187+ console . error ( 'Payment error:' , error ) ;
188+ window . showFloatingAlert ( 'An error occurred while processing your payment' , 'error' ) ;
189+ submitButton . disabled = false ;
190+ submitButton . textContent = 'Subscribe with Stripe' ;
191+ }
192+ } ) ;
193+ }
194+ }
195+
196+ // Initialize the page when the module is imported
197+ initStripePaymentPage ( ) ;
0 commit comments