# `AshBilling`
[🔗](https://github.com/sfelixalejandro/ash_billing/blob/v0.1.3/lib/ash_billing.ex#L1)

Top-level API for `AshBilling`.

Provides functions for managing billing customers, checkout sessions,
customer portals, and subscriptions.

# `cancel_subscription`

```elixir
@spec cancel_subscription(struct() | String.t(), keyword()) ::
  {:ok, map()} | {:error, term()}
```

Cancels a subscription.

## Options

  * `:at_period_end` - If `true` (default), cancels at the end of the current billing cycle.
  * `:provider` - The billing provider module.

# `check_configuration`

```elixir
@spec check_configuration(keyword()) :: {:ok, map()} | {:error, [String.t()]}
```

Performs pre-flight configuration and resource health diagnostics.

Verifies that billing customer resources, subscription resources, and API credentials
are properly configured and compliant with AshBilling requirements.

Returns `{:ok, %{status: :valid}}` or `{:error, [reasons]}`.

## Options

  * `:customer_resource` - The Ash resource representing billing customers.
  * `:subscription_resource` - The Ash resource representing subscriptions.
  * `:api_key` - Stripe API key to validate format (defaults to application env).
  * `:webhook_secret` - Stripe webhook secret to validate format (defaults to application env).

# `create_checkout_session`

```elixir
@spec create_checkout_session(struct() | String.t(), keyword()) ::
  {:ok, %{url: String.t(), id: String.t()}} | {:error, term()}
```

Creates a checkout session for a customer.

## Options

  * `:price` - The price ID to subscribe to or purchase (shortcut for `:line_items`).
  * `:quantity` - The quantity of the price (defaults to 1).
  * `:line_items` - Explicit list of line items (e.g. `[%{price: "price_123", quantity: 1}]`).
  * `:success_url` - The URL to redirect to upon success (required).
  * `:cancel_url` - The URL to redirect to if the user cancels (required).
  * `:mode` - `"subscription"` (default) or `"payment"`.
  * `:provider` - The billing provider module.

# `create_customer`

```elixir
@spec create_customer(struct() | map(), keyword()) ::
  {:ok, String.t()} | {:error, term()}
```

Creates a billing customer in the configured provider.

If the record already has a customer ID, returns `{:ok, existing_customer_id}` without calling the provider.

# `create_portal_session`

```elixir
@spec create_portal_session(struct() | String.t(), keyword()) ::
  {:ok, %{url: String.t()}} | {:error, term()}
```

Creates a billing portal session for a customer to manage subscriptions and payment methods.

## Options

  * `:return_url` - The URL to return to after leaving the portal (required).
  * `:provider` - The billing provider module.

# `customer_id`

```elixir
@spec customer_id(struct()) :: String.t() | nil
```

Extracts the customer ID from a record configured with `AshBilling.Resource`.

# `get_subscription`

```elixir
@spec get_subscription(struct() | String.t(), keyword()) ::
  {:ok, map()} | {:error, term()}
```

Retrieves a subscription from the billing provider.

# `resume_subscription`

```elixir
@spec resume_subscription(struct() | String.t(), keyword()) ::
  {:ok, map()} | {:error, term()}
```

Resumes a subscription that was scheduled to cancel at period end.

Sets `cancel_at_period_end` to `false` in the billing provider.

# `subscribed?`

```elixir
@spec subscribed?(struct(), String.t() | nil) :: boolean()
```

Checks if a record has an active subscription.

Checks loaded subscriptions associated with the record for `:active` or valid `:trialing` status.
If a `price_id` is passed as the second argument, verifies that the subscription matches the price.

# `subscription`

```elixir
@spec subscription(struct(), String.t() | nil) :: struct() | nil
```

Returns the active subscription record for a customer, or `nil` if none is active.

If a `price_id` is passed as the second argument, returns the active subscription matching that price.
Expects the `:subscriptions` relationship to be loaded on the record.

# `swap_plan`

```elixir
@spec swap_plan(struct() | String.t(), String.t(), keyword()) ::
  {:ok, map()} | {:error, term()}
```

Swaps a subscription to a new price/plan in the billing provider.

## Options

  * `:proration_behavior` - `"create_prorations"` (default), `"none"`, or `"always_invoice"`.
  * `:subscription_item_id` - Explicit Stripe subscription item ID (avoids an extra GET call if known).
  * `:quantity` - Updated quantity for the new price.
  * `:proration_date` - Unix timestamp to use for calculating prorations.
  * `:provider` - The billing provider module.

# `update_quantity`

```elixir
@spec update_quantity(struct() | String.t(), pos_integer(), keyword()) ::
  {:ok, map()} | {:error, term()}
```

Updates the quantity of a subscription (e.g. per-seat billing).

## Options

  * `:proration_behavior` - `"create_prorations"` (default), `"none"`, or `"always_invoice"`.
  * `:subscription_item_id` - Explicit Stripe subscription item ID (avoids an extra GET call if known).
  * `:price_id` - The existing price ID (if known, skips the GET call).
  * `:provider` - The billing provider module.

# `verify_configuration!`

```elixir
@spec verify_configuration!(keyword()) :: :ok
```

Same as `check_configuration/1`, but raises `ArgumentError` if any misconfiguration is found.
Ideal for calling in `Application.start/2` or `config/runtime.exs`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
