defmodule TarakanWeb.BillingLive do @moduledoc """ Account billing page: managed-disclosure retainer status, period end, and the Stripe customer portal exit. No feature gates hang off it. """ use TarakanWeb, :live_view alias Tarakan.Billing @impl true def mount(_params, _session, socket) do account = socket.assigns.current_scope.account {:ok, socket |> assign(:page_title, "Billing") |> assign(:subscription, Billing.subscription(account))} end @impl true def handle_params(params, _uri, socket) do socket = case params["checkout"] do "success" -> put_flash(socket, :info, "Subscription started - welcome aboard.") "cancelled" -> put_flash(socket, :info, "Checkout cancelled; nothing was charged.") _other -> socket end {:noreply, socket} end @impl true def handle_event("subscribe", %{"plan" => plan}, socket) do case Billing.ensure_checkout(socket.assigns.current_scope, plan) do {:ok, checkout_url} -> {:noreply, redirect(socket, external: checkout_url)} {:error, _reason} -> {:noreply, put_flash(socket, :error, "Checkout could not be started. Try again shortly.")} end end def handle_event("manage", _params, socket) do case Billing.portal_session(socket.assigns.current_scope.account) do {:ok, portal_url} -> {:noreply, redirect(socket, external: portal_url)} {:error, _reason} -> {:noreply, put_flash(socket, :error, "The billing portal is unavailable for this account.")} end end defp status_label(nil), do: "No subscription" defp status_label(%{status: "active"}), do: "Active" defp status_label(%{status: "past_due"}), do: "Past due - update your payment method" defp status_label(%{status: "canceled"}), do: "Canceled" defp status_label(%{status: "incomplete"}), do: "Incomplete" defp plan_label(%{plan: "enterprise"}), do: "Managed disclosure" # Retired tier; kept so historical rows still render. defp plan_label(%{plan: "team"}), do: "Team (retired)" defp plan_label(_other), do: "None" @impl true def render(assigns) do ~H"""

Billing

Managed disclosure retainer. Everything else on Tarakan is free.

Plan
{plan_label(@subscription)}
Status
{status_label(@subscription)}
Current period ends
<%= if @subscription && @subscription.current_period_end do %> {Calendar.strftime(@subscription.current_period_end, "%Y-%m-%d %H:%M UTC")} <% else %> - <% end %>
Your last payment failed. Update your payment method from the billing portal to keep the retainer active.
This retainer is canceled. Your account keeps full access to the record, alerts, and the API.
<.button :if={@subscription && @subscription.stripe_customer_id} id="billing-manage-button" type="button" phx-click="manage" size="sm" > Manage subscription <.button :if={is_nil(@subscription) || @subscription.status in ["canceled", "incomplete"]} id="billing-subscribe-enterprise" type="button" variant="primary" size="sm" phx-click="subscribe" phx-value-plan="enterprise" > Start managed disclosure

See <.link navigate={~p"/pricing"} class="text-ink-muted underline hover:text-ink"> pricing . Payments are processed by Stripe.

""" end end