Zoonk.Billing (Zoonk v0.1.0-dev)
View SourceHandles billing operations for the application.
This context provides functions for managing subscriptions, processing payments, and integrating with payment providers such as Stripe.
Summary
Functions
Cancels a user subscription.
Creates a changeset for a billing account.
Creates a billing account.
Creates a Customer Portal Session in Stripe.
Creates a tax ID for a customer in Stripe.
Creates a customer in Stripe.
Creates a user subscription.
Checks if a customer has any tax IDs.
Gets a billing account for a user.
Gets customer tax IDs from Stripe.
Gets unique currencies from all countries.
Gets a user from a stripe_customer_id
.
Gets a user subscription for a user.
Gets a user subscription by stripe_subscription_id
.
Lists all available pricing options for plans filtered by billing account currency.
Creates a Stripe Checkout Session for subscriptions.
Updates a customer in Stripe.
Updates an existing user subscription.
Functions
Cancels a user subscription.
Updates the subscription status to :canceled
and sets cancel_at_period_end
to true
.
Also cancels the subscription in Stripe if a Stripe subscription ID exists.
Examples
iex> cancel_user_subscription(scope, subscription)
{:ok, %UserSubscription{}}
iex> cancel_user_subscription(scope, subscription)
{:error, %Ecto.Changeset{}}
Creates a changeset for a billing account.
Examples
iex> change_billing_account(%BillingAccount{}, %{})
%Ecto.Changeset{}
Creates a billing account.
First creates a Stripe customer for the current user, then creates the billing account with the Stripe customer ID.
Examples
iex> create_billing_account(scope, %{currency: "USD", country_iso2: "US"})
{:ok, %BillingAccount{}}
iex> create_billing_account(scope, %{})
{:error, %Ecto.Changeset{}}
Creates a Customer Portal Session in Stripe.
This is used to redirect users to Stripe's Customer Portal where they can manage their subscriptions and billing details.
Examples
iex> create_customer_portal_session(%Scope{})
{:ok, "https://billing.stripe.com/session/1234567890"}
iex> create_customer_portal_session(%Scope{})
{:error, "No billing account found"}
Creates a tax ID for a customer in Stripe.
Creates a new tax ID for the customer using their Stripe customer ID.
Examples
iex> create_customer_tax_id(%Scope{}, %{"type" => "br_cpf", "value" => "123.456.789-00"})
{:ok, %{"id" => "txi_123", "type" => "br_cpf", "value" => "123.456.789-00"}}
iex> create_customer_tax_id(%Scope{}, %{})
{:error, "Invalid tax ID data"}
Creates a customer in Stripe.
Creates a new customer record in Stripe using the user's billing preferences and optional attributes.
Examples
iex> create_stripe_customer(%Scope{})
{:ok, %{"id" => "cus_1234567890", "email" => "user@example.com"}}
iex> create_stripe_customer(%Scope{})
{:error, "Invalid request"}
Creates a user subscription.
Takes a scope containing the user and org information, along with subscription attributes, to create a new user subscription record.
Examples
iex> create_user_subscription(%Scope{}, %{plan: :plus, interval: :monthly})
{:ok, %UserSubscription{}}
iex> create_user_subscription(%Scope{}, %{})
{:error, %Ecto.Changeset{}}
Checks if a customer has any tax IDs.
Returns true if the customer has any tax IDs, false otherwise.
Examples
iex> customer_has_tax_ids?(%Scope{})
true
iex> customer_has_tax_ids?(%Scope{})
false
Gets a billing account for a user.
Returns the billing account if found, otherwise returns nil.
Examples
iex> user = %Scope{}
iex> get_billing_account(scope)
%BillingAccount{}
iex> user = %Scope{}
iex> get_billing_account(scope)
nil
Gets customer tax IDs from Stripe.
Retrieves all tax IDs for a customer from Stripe using their customer ID.
Examples
iex> get_customer_tax_ids(%Scope{})
{:ok, [%{"id" => "txi_123", "type" => "br_cpf", "value" => "123.456.789-00"}]}
iex> get_customer_tax_ids(%Scope{})
{:error, "No billing account found"}
Gets unique currencies from all countries.
Returns a list of unique currencies sorted by their code.
Examples
iex> get_unique_currencies()
[%Currency{code: "AED", name: "UAE Dirham"}, %Currency{code: "AFN", name: "Afghan Afghani"}, ...]
Gets a user from a stripe_customer_id
.
Returns the user if found, otherwise returns nil.
Examples
iex> get_user_from_stripe_customer_id("cus_1234567890")
%User{}
iex> get_user_from_stripe_customer_id("cus_invalid")
nil
Gets a user subscription for a user.
Returns the active subscription if found, otherwise returns the latest subscription (the one with the most recent updated_at). Returns nil if no subscription exists.
Examples
iex> get_user_subscription(%Scope{user: user, org: org})
%UserSubscription{}
iex> get_user_subscription(%Scope{user: user, org: org})
nil
Gets a user subscription by stripe_subscription_id
.
Returns the user subscription if found, otherwise returns nil.
Examples
iex> get_user_subscription_by_stripe_id("sub_test_subscription_id")
%UserSubscription{}
iex> get_user_subscription_by_stripe_id("sub_invalid")
nil
Lists all available pricing options for plans filtered by billing account currency.
Returns a list of prices for all plan options in the billing account's currency. If the billing account is nil or the currency is not available in Stripe, falls back to USD.
Examples
iex> list_prices(%BillingAccount{currency: "BRL"})
{:ok, [%Price{currency: "brl"}]}
iex> list_prices(%BillingAccount{currency: "CAD"})
{:ok, [%Price{currency: "usd"}]}
iex> list_prices(nil)
{:ok, [%Price{currency: "usd"}]}
Creates a Stripe Checkout Session for subscriptions.
This function starts a checkout session where users can subscribe to a plan.
It requires a scope with user and org information, the price ID for the plan, and optional attributes for the session.
Examples
iex> subscription_checkout_session(%Scope{}, "price_12345", %{success_url: "https://zoonk.com/subscription"})
{:ok, %{"id" => "cs_test_1234567890"}}
iex> subscription_checkout_session(%Scope{}, "price_12345", %{})
{:error, "No billing account found"}
Updates a customer in Stripe.
Updates an existing customer record in Stripe using the user's billing preferences and optional attributes. Gets the Stripe customer ID from the user's billing account.
Examples
iex> update_stripe_customer(%Scope{}, %{"name" => "John Doe"})
{:ok, %{"id" => "cus_1234567890", "name" => "John Doe"}}
iex> update_stripe_customer(%Scope{}, %{})
{:error, "No billing account found"}
Updates an existing user subscription.
Takes a scope containing the user and org information, the subscription to update, and the attributes to update.
The user_id and org_id cannot be changed and will be enforced from the scope.
Examples
iex> update_user_subscription(%Scope{}, subscription, %{plan: :plus})
{:ok, %UserSubscription{}}
iex> update_user_subscription(%Scope{}, subscription, %{})
{:ok, %UserSubscription{}}
iex> update_user_subscription(%Scope{}, subscription, %{status: :invalid})
{:error, %Ecto.Changeset{}}