Zoonk.Billing (Zoonk v0.1.0-dev)

View Source

Handles 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

cancel_user_subscription(scope)

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{}}

change_billing_account(billing_account, attrs \\ %{})

Creates a changeset for a billing account.

Examples

iex> change_billing_account(%BillingAccount{}, %{})
%Ecto.Changeset{}

create_billing_account(scope, attrs)

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{}}

create_customer_portal_session(scope, attrs)

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"}

create_customer_tax_id(scope, attrs)

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"}

create_stripe_customer(scope, attrs \\ %{})

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"}

create_user_subscription(scope, attrs)

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{}}

customer_has_tax_ids?(scope)

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

get_billing_account(scope)

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

get_customer_tax_ids(scope)

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"}

get_unique_currencies()

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"}, ...]

get_user_from_stripe_customer_id(stripe_customer_id)

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

get_user_subscription(scope)

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

get_user_subscription_by_stripe_id(stripe_subscription_id)

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

list_prices(arg1)

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"}]}

subscription_checkout_session(scope, price_id, attrs \\ %{})

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"}

update_stripe_customer(scope, attrs \\ %{})

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"}

update_user_subscription(scope, attrs)

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{}}