defmodule Towerops.BillingFixtures do @moduledoc """ Test fixtures for billing-related entities. """ alias Towerops.Organizations.Organization alias Towerops.Repo @doc """ Update organization with Stripe customer ID. """ def organization_with_stripe_customer(organization, stripe_customer_id \\ "cus_test_123") do organization |> Organization.changeset(%{stripe_customer_id: stripe_customer_id}) |> Repo.update!() end @doc """ Update organization with active subscription. """ def organization_with_active_subscription(organization) do organization |> Organization.changeset(%{ stripe_customer_id: "cus_test_#{System.unique_integer()}", stripe_subscription_id: "sub_test_#{System.unique_integer()}", subscription_status: "active", subscription_plan: "paid", subscription_current_period_start: DateTime.utc_now(), subscription_current_period_end: DateTime.add(DateTime.utc_now(), 30, :day), payment_method_status: "valid" }) |> Repo.update!() end @doc """ Update organization with past_due subscription. """ def organization_with_past_due_subscription(organization) do organization |> Organization.changeset(%{ stripe_customer_id: "cus_test_#{System.unique_integer()}", stripe_subscription_id: "sub_test_#{System.unique_integer()}", subscription_status: "past_due", subscription_plan: "paid", payment_method_status: "requires_action" }) |> Repo.update!() end @doc """ Stripe customer object (mock). """ def stripe_customer_object(attrs \\ %{}) do %{ "id" => Map.get(attrs, :id, "cus_test_123"), "object" => "customer", "email" => Map.get(attrs, :email, "test@example.com"), "name" => Map.get(attrs, :name, "Test Org"), "metadata" => %{ "towerops_org_id" => Map.get(attrs, :org_id, "org_123"), "towerops_org_slug" => Map.get(attrs, :org_slug, "testorg") }, "invoice_settings" => %{ "default_payment_method" => Map.get(attrs, :payment_method, "pm_test_123") } } end @doc """ Stripe subscription object (mock). """ def stripe_subscription_object(attrs \\ %{}) do now = System.system_time(:second) base = %{ "id" => Map.get(attrs, :id, "sub_test_123"), "object" => "subscription", "customer" => Map.get(attrs, :customer, "cus_test_123"), "status" => Map.get(attrs, :status, "active"), "current_period_start" => Map.get(attrs, :period_start, now), "current_period_end" => Map.get(attrs, :period_end, now + 30 * 86_400), "items" => %{ "data" => [ %{ "price" => %{ "id" => "price_test_123" } } ] } } # Merge any additional string-key attrs (like "cancel_at_period_end") attrs |> Enum.filter(fn {k, _v} -> is_binary(k) or is_atom(k) end) |> Map.new(fn {k, v} -> {to_string(k), v} end) |> Map.merge(base, fn _k, v1, _v2 -> v1 end) end @doc """ Stripe checkout session object (mock). """ def stripe_checkout_session_object(attrs \\ %{}) do %{ "id" => Map.get(attrs, :id, "cs_test_123"), "object" => "checkout.session", "url" => Map.get(attrs, :url, "https://checkout.stripe.com/c/pay/cs_test_123"), "customer" => Map.get(attrs, :customer, "cus_test_123") } end @doc """ Stripe portal session object (mock). """ def stripe_portal_session_object(attrs \\ %{}) do %{ "id" => Map.get(attrs, :id, "bps_test_123"), "object" => "billing_portal.session", "url" => Map.get(attrs, :url, "https://billing.stripe.com/p/session/bps_test_123"), "customer" => Map.get(attrs, :customer, "cus_test_123") } end @doc """ Stripe invoice object (mock). """ def stripe_invoice_object(attrs \\ %{}) do %{ "id" => Map.get(attrs, :id, "in_test_123"), "object" => "invoice", "customer" => Map.get(attrs, :customer, "cus_test_123"), "status" => Map.get(attrs, :status, "paid"), "subscription" => Map.get(attrs, :subscription, "sub_test_123") } end @doc """ Stripe webhook event object (mock). """ def stripe_webhook_event_object(type, data) do %{ "id" => "evt_test_#{System.unique_integer()}", "object" => "event", "type" => type, "data" => %{ "object" => data }, "created" => System.system_time(:second) } end end