main
rb 63 lines 2.18 KB
Raw
1 # frozen_string_literal: true
2
3 module Api
4 module V1
5 # siGit Code billing for the authenticated user. The desktop app / CLI call
6 # these with the smbCloud bearer token; checkout/portal return a URL the
7 # client opens in a browser (purchases happen on the web, not in-app, to
8 # avoid the App Store cut).
9 class BillingController < Api::BaseController
10 before_action :authenticate_token!
11
12 # GET /api/v1/billing — current plan + cloud entitlement.
13 def show
14 subscription = current_user.subscription
15 render json: {
16 plan: subscription&.plan || "free",
17 status: subscription&.status || "active",
18 entitled_to_cloud: current_user.entitled_to_cloud?,
19 cloud_requests_used: current_user.cloud_requests_used,
20 cloud_allowance: current_user.cloud_allowance,
21 current_period_end: subscription&.current_period_end
22 }, status: :ok
23 end
24
25 # POST /api/v1/billing/checkout { plan: "pro" | "team" } → { url }
26 def checkout
27 return render_billing_unavailable unless StripeService.configured?
28
29 plan = params[:plan].presence || "pro"
30 unless StripeService::PRICE_LOOKUP_KEYS.key?(plan)
31 return render_error(ERR_INVALID, "Unknown plan.", status: :unprocessable_entity)
32 end
33
34 url = StripeService.checkout_url(
35 user: current_user,
36 plan: plan,
37 success_url: "#{request.base_url}/billing?billing=success",
38 cancel_url: "#{request.base_url}/billing?billing=cancel"
39 )
40 render json: { url: url }, status: :ok
41 end
42
43 # POST /api/v1/billing/portal → { url }
44 def portal
45 return render_billing_unavailable unless StripeService.configured?
46
47 url = StripeService.portal_url(
48 user: current_user,
49 return_url: "#{request.base_url}/billing"
50 )
51 return render_error(ERR_INVALID, "No subscription to manage.", status: :not_found) unless url
52
53 render json: { url: url }, status: :ok
54 end
55
56 private
57
58 def render_billing_unavailable
59 render_error(ERR_UNKNOWN, "Billing is not configured.", status: :service_unavailable)
60 end
61 end
62 end
63 end