Add 14-day free trial + trial cap for siGit Code Cloud
GTM: let users try cloud before paying (card-required trial converts well), while bounding trial COGS. - StripeService: trial_period_days=14 on checkout subscriptions - Subscription: trialing users get TRIAL_ALLOWANCE (300) cloud requests, well below the paid caps (pro 2000 / team 6000) - Copy: 402 + web CTAs invite the free trial (Start 14-day free trial), billing page shows trial status + trial-end date Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Seto Elkahfi committed
Jun 24, 2026 at 12:06 UTC
650bb5d6f7a6347de8a6254c7623f879c5159170
4 files changed
+33
-11
app/controllers/api/v1/chat_completions_controller.rb
+2
-1
@@ -44,7 +44,8 @@ module Api
44
return if current_user&.entitled_to_cloud?
45
46
render json: error_body(
47
- "siGit Code Cloud requires a Pro subscription. Upgrade in your siGit account to use cloud models."
47
+ "Start your free siGit Code Cloud trial to use cloud models — 14 days free, then $20/mo. " \
48
+ "Begin it in your siGit account billing page."
49
), status: :payment_required
50
end
51
app/models/subscription.rb
+8
-2
@@ -13,13 +13,19 @@ class Subscription < ApplicationRecord
13
# these are the included cloud requests before the cap kicks in.
14
CLOUD_ALLOWANCE = { "pro" => 2_000, "team" => 6_000 }.freeze
15
16
- # Entitled to siGit Code Cloud: on a paid plan in good standing.
16
+ # During the free trial, cap cloud usage well below the paid allowance so a
17
+ # trial can't run up an unbounded upstream bill. Enough to feel the product.
18
+ TRIAL_ALLOWANCE = 300
19
+
20
+ # Entitled to siGit Code Cloud: on a paid plan in good standing (incl. trial).
21
def entitled_to_cloud?
22
(pro? || team?) && (active? || trialing?)
23
end
24
21
- # Included cloud requests for this plan's billing period.
25
+ # Included cloud requests for this period. The trial gets a tighter cap.
26
def cloud_allowance
27
+ return TRIAL_ALLOWANCE if trialing?
28
+
29
CLOUD_ALLOWANCE.fetch(plan, 0)
30
end
31
app/services/stripe_service.rb
+8
-1
@@ -10,6 +10,10 @@ class StripeService
10
"team" => "sigit_code_team_monthly"
11
}.freeze
12
13
+ # Free-trial length for new subscriptions. Card is collected at checkout and
14
+ # Stripe auto-converts to paid when the trial ends. Tunable GTM knob.
15
+ TRIAL_DAYS = 14
16
+
17
# A subscription's price lookup_key → our plan.
18
PLAN_BY_LOOKUP_KEY = {
19
"sigit_code_pro_monthly" => :pro,
@@ -50,7 +54,10 @@ class StripeService
54
success_url: success_url,
55
cancel_url: cancel_url,
56
metadata: { user_id: user.id.to_s },
53
- subscription_data: { metadata: { user_id: user.id.to_s } }
57
+ subscription_data: {
58
+ metadata: { user_id: user.id.to_s },
59
+ trial_period_days: TRIAL_DAYS
60
+ }
61
}.compact)
62
63
session.url
app/views/billing/show.html.erb
+15
-7
@@ -24,16 +24,24 @@
24
<div class="px-6 py-6">
25
<% if @entitled %>
26
<p class="text-sm text-gray-300">
27
- You're on <span class="text-gray-100 font-medium"><%= @plan.to_s.capitalize %></span> — siGit Code Cloud is unlocked.
28
- <% if @period_end %>
29
- <span class="text-gray-500">Renews <%= @period_end.strftime("%b %-d, %Y") %>.</span>
27
+ <% if @status.to_s == "trialing" %>
28
+ You're on a <span class="text-gray-100 font-medium">free trial</span> of
29
+ <%= @plan.to_s.capitalize %> — siGit Code Cloud is unlocked.
30
+ <% if @period_end %>
31
+ <span class="text-gray-500">Trial ends <%= @period_end.strftime("%b %-d, %Y") %>, then $20/mo.</span>
32
+ <% end %>
33
+ <% else %>
34
+ You're on <span class="text-gray-100 font-medium"><%= @plan.to_s.capitalize %></span> — siGit Code Cloud is unlocked.
35
+ <% if @period_end %>
36
+ <span class="text-gray-500">Renews <%= @period_end.strftime("%b %-d, %Y") %>.</span>
37
+ <% end %>
38
<% end %>
39
</p>
40
<% else %>
41
<p class="text-sm text-gray-300">
42
You're on the free <span class="text-gray-100 font-medium">Garage</span> plan. AI runs
35
- <span class="text-gray-100">on your device</span> — private and free. Upgrade to use
36
- siGit Code Cloud (the Fast / Balanced / Large tiers) when you need more.
43
+ <span class="text-gray-100">on your device</span> — private and free. Try siGit Code Cloud
44
+ (the Fast / Balanced / Large tiers) free for 14 days when you need more.
45
</p>
46
<% end %>
47
</div>
@@ -63,8 +71,8 @@
71
<% if @entitled %>
72
<%= button_to "Manage billing", billing_portal_path, method: :post, data: { turbo: false }, class: "btn-primary cursor-pointer" %>
73
<% else %>
66
- <%= button_to "Upgrade to Pro", billing_checkout_path(plan: "pro"), method: :post, data: { turbo: false }, class: "btn-primary cursor-pointer" %>
67
- <%= button_to "Upgrade to Team", billing_checkout_path(plan: "team"), method: :post, data: { turbo: false }, class: "text-sm text-gray-400 hover:text-gray-200 transition-colors bg-transparent border-0 cursor-pointer" %>
74
+ <%= button_to "Start 14-day free trial", billing_checkout_path(plan: "pro"), method: :post, data: { turbo: false }, class: "btn-primary cursor-pointer" %>
75
+ <%= button_to "Try Team free", billing_checkout_path(plan: "team"), method: :post, data: { turbo: false }, class: "text-sm text-gray-400 hover:text-gray-200 transition-colors bg-transparent border-0 cursor-pointer" %>
76
<% end %>
77
</div>
78
</div>