Public API for plan and subscription management.
HawkEx.Billing owns the lifecycle of account subscriptions: creating a
subscription, finding the current subscription or plan, canceling access, and
changing plans. Functions accept either an account struct with an :id field
or a raw account id string.
Subscription changes emit events through HawkEx.Events when PubSub is
configured. Without PubSub, the billing operations still complete and event
emission is a no-op.
Examples
HawkEx.Billing.subscribe(account, :pro)
HawkEx.Billing.current_subscription(account)
HawkEx.Billing.cancel(account)
HawkEx.Billing.change_plan(account, :enterprise)Error tuples
The context returns tagged error tuples for expected business failures:
{:error, :plan_not_found}- no active plan matches the requested name.{:error, :active_subscription_exists}- the account already has a trialing or active subscription.{:error, :no_active_subscription}- cancel or change-plan was requested for an account with no active subscription.
Summary
Functions
Cancels the account's active subscription immediately.
Changes an account's current plan in place.
Returns the current plan for an account.
Returns the current trialing or active subscription for an account.
Returns a single subscription by id with its plan preloaded.
Returns a paginated list of trialing and active subscriptions.
Searches active subscriptions by account id or plan name.
Creates a subscription for an account on the given plan.
Functions
Cancels the account's active subscription immediately.
The subscription record is kept with status "canceled" and canceled_at
set to the current UTC time. Subscriptions are never deleted.
Returns {:ok, subscription} on success or
{:error, :no_active_subscription} when there is no active subscription.
Changes an account's current plan in place.
This updates plan_id on the existing active subscription. It does not
cancel and recreate the subscription, so billing period history remains on a
single record in the current release.
Returns {:ok, subscription} on success, {:error, :plan_not_found} when
the target plan is not active, or {:error, :no_active_subscription} when
there is no active subscription to change.
Returns the current plan for an account.
Returns nil when the account has no active subscription.
Returns the current trialing or active subscription for an account.
The returned subscription has its plan preloaded. Returns nil when the
account has no active subscription.
Returns a single subscription by id with its plan preloaded.
Returns nil if no subscription exists for the id.
Returns a paginated list of trialing and active subscriptions.
Entries are ordered newest first and preload :plan.
Options
:page- 1-indexed page number. Defaults to1.:per_page- rows per page. Defaults to50.:search- optional search term matchingaccount_id.Matches against the UUID cast to text, since exact-substring search on a raw UUID is rarely practical for a human typing into a search box.
Returns %{entries:, page:, per_page:, total_count:, total_pages:}.
Example
HawkEx.Billing.recent_subscriptions(page: 1, per_page: 50)
# => %{entries: [...], page: 1, per_page: 50, total_count: 25, total_pages: 2}
Searches active subscriptions by account id or plan name.
Accepts :limit in opts, defaulting to 5. Results are ordered newest
first and preload :plan.
Creates a subscription for an account on the given plan.
plan_name may be an atom or string and is matched against active
HawkEx.Billing.Plan.name values. If the plan has trial_days > 0, the
subscription starts in "trialing" status. Otherwise it starts as
"active".
Returns {:ok, subscription} on success.
Returns:
{:error, :plan_not_found}{:error, :active_subscription_exists}{:error, changeset}if the repo rejects the insert.