@@ -79,23 +79,7 @@ def handle_subscription_paid(event)
7979
8080 plan = resolve_plan ( product_id )
8181
82- if user_id . present?
83- user = User . find_by ( id : user_id )
84- if user
85- duration = plan &.pass? ? plan . pass_days . days : 1 . month
86- user . activate_subscription! (
87- provider : "creem" ,
88- customer_id : data [ "customer_id" ] ,
89- duration : duration
90- )
91- user . update (
92- last_payment_at : Time . current ,
93- subscription_plan_name : plan &.display_name || "Starter" ,
94- subscription_amount : plan ? plan . price_dollars : 6.99
95- )
96- Rails . logger . info ( "[Creem Webhook] Activated #{ plan &.id || 'unknown' } for user #{ user_id } " )
97- end
98- end
82+ activate_user_subscription ( user_id : user_id , plan : plan , customer_id : data [ "customer_id" ] )
9983
10084 if project_id . present?
10185 project = Project . find_by ( id : project_id )
@@ -107,11 +91,7 @@ def handle_subscription_paid(event)
10791 server_plan : plan &.id || project . server_plan ,
10892 pass_expires_at : plan &.pass? ? plan . pass_days . days . from_now : nil
10993 )
110- if project . pending_payment?
111- project . mark_paid!
112- ContainerProvisionJob . perform_later ( project . id , user_id : project . created_by_id )
113- Rails . logger . info ( "[Creem Webhook] Project #{ project . id } marked paid, provisioning started" )
114- end
94+ mark_project_paid_and_provision ( project )
11595 end
11696 end
11797 end
@@ -166,7 +146,64 @@ def handle_subscription_upgraded(event)
166146 def handle_checkout_completed ( event )
167147 data = event [ "object" ] || event [ "data" ] || { }
168148 metadata = data [ "metadata" ] || { }
149+ product_id = data [ "product_id" ] || data . dig ( "product" , "id" )
150+ plan = resolve_plan ( product_id )
151+ project = find_project ( event )
152+
169153 Rails . logger . info ( "[Creem Webhook] Checkout completed for user #{ metadata [ 'user_id' ] } " )
154+
155+ activate_user_subscription (
156+ user_id : metadata [ "user_id" ] ,
157+ plan : plan ,
158+ customer_id : data [ "customer_id" ]
159+ )
160+
161+ unless project
162+ Rails . logger . warn ( "[Creem Webhook] Checkout completed but no project found for checkout #{ data [ 'id' ] } " )
163+ return
164+ end
165+
166+ updates = {
167+ payment_status : "paid" ,
168+ server_plan : plan &.id || project . server_plan ,
169+ pass_expires_at : plan &.pass? ? plan . pass_days . days . from_now : nil
170+ }
171+ updates [ :checkout_session_id ] = data [ "id" ] if data [ "id" ] . present?
172+ updates [ :subscription_id ] = data [ "subscription_id" ] if data [ "subscription_id" ] . present?
173+ updates [ :subscription_status ] = "active" if data [ "subscription_id" ] . present?
174+ project . update ( updates )
175+
176+ mark_project_paid_and_provision ( project )
177+ end
178+
179+ def activate_user_subscription ( user_id :, plan :, customer_id : nil )
180+ return unless user_id . present?
181+
182+ user = User . find_by ( id : user_id )
183+ return unless user
184+
185+ duration = plan &.pass? ? plan . pass_days . days : 1 . month
186+ user . activate_subscription! (
187+ provider : "creem" ,
188+ customer_id : customer_id ,
189+ duration : duration
190+ )
191+ user . update (
192+ last_payment_at : Time . current ,
193+ subscription_plan_name : plan &.display_name || "Starter" ,
194+ subscription_amount : plan ? plan . price_dollars : 6.99
195+ )
196+ Rails . logger . info ( "[Creem Webhook] Activated #{ plan &.id || 'unknown' } for user #{ user_id } " )
197+ end
198+
199+ def mark_project_paid_and_provision ( project )
200+ if project . pending_payment?
201+ project . mark_paid!
202+ ContainerProvisionJob . perform_later ( project . id , user_id : project . created_by_id )
203+ Rails . logger . info ( "[Creem Webhook] Project #{ project . id } marked paid, provisioning started" )
204+ else
205+ Rails . logger . info ( "[Creem Webhook] Project #{ project . id } already processed (status=#{ project . status } , payment_status=#{ project . payment_status } )" )
206+ end
170207 end
171208
172209 def resolve_plan ( product_id )
0 commit comments