# `LatticeStripe.BillingPortal.Configuration`
[🔗](https://github.com/szTheory/lattice_stripe/blob/v2.3.0/lib/lattice_stripe/billing_portal/configuration.ex#L1)

Manages Stripe customer portal configurations controlling branding, features,
and business info.

A portal configuration defines the appearance and available actions for your
customers' self-service billing portal (the page returned by
`LatticeStripe.BillingPortal.Session.create/3`).

## Lifecycle

Configurations cannot be deleted — only deactivated via
`update(client, id, %{"active" => false})`. Once deactivated, the
configuration can be re-activated by setting `active` back to `true`.

A configuration marked `is_default: true` is Stripe's account default and
**cannot be deactivated**. Attempting to deactivate the default configuration
returns a Stripe error; no client-side guard is applied — let Stripe enforce
this invariant.

## Usage

    client = LatticeStripe.Client.new!(api_key: "sk_live_...", finch: MyApp.Finch)

    # Create a custom portal configuration
    {:ok, config} = LatticeStripe.BillingPortal.Configuration.create(client, %{
      "business_profile" => %{
        "headline" => "Manage your subscription",
        "privacy_policy_url" => "https://example.com/privacy",
        "terms_of_service_url" => "https://example.com/terms"
      },
      "features" => %{
        "invoice_history" => %{"enabled" => true}
      }
    })

    # Retrieve a configuration
    {:ok, config} = LatticeStripe.BillingPortal.Configuration.retrieve(client, "bpc_123")

    # Deactivate a configuration (cannot delete)
    {:ok, _config} = LatticeStripe.BillingPortal.Configuration.update(
      client, config.id, %{"active" => false}
    )

    # List all configurations
    {:ok, resp} = LatticeStripe.BillingPortal.Configuration.list(client)
    configs = resp.data.data  # [%Configuration{}, ...]

    # Stream all configurations lazily (auto-pagination)
    client
    |> LatticeStripe.BillingPortal.Configuration.stream!()
    |> Enum.each(&process_config/1)

## Stripe API Reference

See the [Stripe Portal Configuration API](https://docs.stripe.com/api/customer_portal/configuration)
for the full object reference and available parameters.

# `t`

```elixir
@type t() :: %LatticeStripe.BillingPortal.Configuration{
  active: boolean() | nil,
  application: String.t() | nil,
  business_profile: map() | nil,
  created: integer() | nil,
  default_return_url: String.t() | nil,
  extra: map(),
  features: LatticeStripe.BillingPortal.Configuration.Features.t() | nil,
  id: String.t() | nil,
  is_default: boolean() | nil,
  livemode: boolean() | nil,
  login_page: map() | nil,
  metadata: map() | nil,
  name: String.t() | nil,
  object: String.t() | nil,
  updated: integer() | nil
}
```

# `create`

```elixir
@spec create(LatticeStripe.Client.t(), map(), keyword()) ::
  {:ok, t()} | {:error, LatticeStripe.Error.t()}
```

Create a customer portal configuration.

Pass `params` as a string-keyed map matching Stripe's wire format. Returns
`{:ok, %Configuration{}}` on success or `{:error, %LatticeStripe.Error{}}` on
failure.

# `create!`

```elixir
@spec create!(LatticeStripe.Client.t(), map(), keyword()) :: t()
```

Bang variant of `create/3`. Raises `LatticeStripe.Error` on failure.

# `from_map`

```elixir
@spec from_map(map() | nil) :: t() | nil
```

Decode a Stripe-shaped string-keyed map into a `%Configuration{}`.

The `features` field is dispatched to `Features.from_map/1` for typed
sub-struct decoding. The `business_profile` and `login_page` fields are kept
as raw maps (Level 1 nesting per D-01 — single-boolean or shallow objects
with no sub-type value). Unknown top-level keys land in `:extra`.

# `list`

```elixir
@spec list(LatticeStripe.Client.t(), map(), keyword()) ::
  {:ok, LatticeStripe.Response.t()} | {:error, LatticeStripe.Error.t()}
```

List customer portal configurations. Supports cursor-based pagination via
`starting_after` and `ending_before`, and filtering via `active` and
`is_default`.

# `list!`

```elixir
@spec list!(LatticeStripe.Client.t(), map(), keyword()) :: LatticeStripe.Response.t()
```

Bang variant of `list/3`. Raises `LatticeStripe.Error` on failure.

# `retrieve`

```elixir
@spec retrieve(LatticeStripe.Client.t(), String.t(), keyword()) ::
  {:ok, t()} | {:error, LatticeStripe.Error.t()}
```

Retrieve a customer portal configuration by ID.

# `retrieve!`

```elixir
@spec retrieve!(LatticeStripe.Client.t(), String.t(), keyword()) :: t()
```

Bang variant of `retrieve/3`. Raises `LatticeStripe.Error` on failure.

# `stream!`

```elixir
@spec stream!(LatticeStripe.Client.t(), map(), keyword()) :: Enumerable.t()
```

Returns a lazy stream of all customer portal configurations (auto-pagination).

Emits individual `%Configuration{}` structs, fetching additional pages as
needed. Raises `LatticeStripe.Error` if any page fetch fails.

# `update`

```elixir
@spec update(LatticeStripe.Client.t(), String.t(), map(), keyword()) ::
  {:ok, t()} | {:error, LatticeStripe.Error.t()}
```

Update a customer portal configuration.

To deactivate a configuration: `update(client, id, %{"active" => false})`.
Note: configurations with `is_default: true` cannot be deactivated — Stripe
returns an error in that case.

# `update!`

```elixir
@spec update!(LatticeStripe.Client.t(), String.t(), map(), keyword()) :: t()
```

Bang variant of `update/4`. Raises `LatticeStripe.Error` on failure.

---

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