# `LatticeStripe.Price`
[🔗](https://github.com/szTheory/lattice_stripe/blob/v2.2.2/lib/lattice_stripe/price.ex#L1)

Operations on Stripe Price objects.

A Price represents how much a Product costs and how it's billed — one-time or
recurring, per-unit or tiered, flat or percent-based. Prices are immutable
identifiers — to change a price, archive the old one (`update(active: false)`)
and create a new one.

## Usage

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

    # One-time price
    {:ok, price} = LatticeStripe.Price.create(client, %{
      "currency" => "usd",
      "unit_amount" => 2000,
      "product" => "prod_abc"
    })

    # Recurring price
    {:ok, price} = LatticeStripe.Price.create(client, %{
      "currency" => "usd",
      "unit_amount" => 2000,
      "product" => "prod_abc",
      "recurring" => %{"interval" => "month"}
    })

    # Search
    {:ok, resp} = LatticeStripe.Price.search(client, "active:'true' AND product:'prod_abc'")

## Operations not supported by the Stripe API

- **delete** — Prices are immutable once created. To stop a Price from being used,
  archive it with `update/4`:

      LatticeStripe.Price.update(client, price_id, %{"active" => "false"})

## Stripe API Reference

See the [Stripe Price API](https://docs.stripe.com/api/prices).

# `t`

```elixir
@type t() :: %LatticeStripe.Price{
  active: boolean() | nil,
  billing_scheme: :per_unit | :tiered | String.t() | nil,
  created: integer() | nil,
  currency: String.t() | nil,
  currency_options: map() | nil,
  custom_unit_amount: map() | nil,
  deleted: boolean(),
  extra: map(),
  id: String.t() | nil,
  livemode: boolean() | nil,
  lookup_key: String.t() | nil,
  metadata: map() | nil,
  nickname: String.t() | nil,
  object: String.t(),
  product: String.t() | nil,
  recurring: LatticeStripe.Price.Recurring.t() | nil,
  tax_behavior: :inclusive | :exclusive | :unspecified | String.t() | nil,
  tiers: [LatticeStripe.Price.Tier.t()] | nil,
  tiers_mode: String.t() | nil,
  transform_quantity: map() | nil,
  type: :one_time | :recurring | String.t() | nil,
  unit_amount: integer() | nil,
  unit_amount_decimal: String.t() | nil
}
```

A Stripe Price object.

See the [Stripe Price API](https://docs.stripe.com/api/prices/object) for field definitions.

# `create`

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

Creates a new Price.

Sends `POST /v1/prices` with the given params and returns `{:ok, %Price{}}`.

# `create!`

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

Like `create/3` but raises on failure.

# `from_map`

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

Converts a decoded Stripe API map to a `%Price{}` struct.

Atomizes `type`, `billing_scheme`, `tax_behavior` via whitelists (D-03).
Decodes nested `recurring` to `%Price.Recurring{}` and each element of
`tiers` to `%Price.Tier{}` (D-01).

# `list`

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

Lists Prices with optional filters.

Sends `GET /v1/prices`.

# `list!`

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

Like `list/3` but raises on failure.

# `retrieve`

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

Retrieves a Price by ID.

Sends `GET /v1/prices/:id` and returns `{:ok, %Price{}}`.

# `retrieve!`

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

Like `retrieve/3` but raises on failure.

# `search`

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

Searches Prices using Stripe's search query language.

Sends `GET /v1/prices/search` with the query string.

## Searchable fields

`active`, `currency`, `lookup_key`, `metadata`, `product`, `type`.

## Eventual consistency

Search results have eventual consistency. Under normal operating conditions,
newly created or updated objects appear in search results within ~1 minute.
During Stripe outages, propagation may be slower. Do not use `search/3` in
read-after-write flows where strict consistency is necessary. See
https://docs.stripe.com/search#data-freshness.

# `search!`

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

Like `search/3` but raises on failure.

# `search_stream!`

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

Returns a lazy stream of all Prices matching a search query (auto-pagination).

# `stream!`

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

Returns a lazy stream of all Prices (auto-pagination).

# `update`

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

Updates a Price by ID.

Sends `POST /v1/prices/:id`. Use `update(client, id, %{"active" => "false"})`
to archive a Price — the Stripe API does not support deletion.

# `update!`

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

Like `update/4` but raises on failure.

---

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