Operations on Stripe Product objects.
A Product in Stripe represents a good or service that you sell. Products are paired with Prices to define what customers pay. Products power subscriptions, checkout sessions, invoices, and one-off charges.
Usage
client = LatticeStripe.Client.new!(api_key: "sk_live_...", finch: MyApp.Finch)
# Create a product
{:ok, product} = LatticeStripe.Product.create(client, %{
"name" => "Premium Subscription",
"type" => "service"
})
# Retrieve a product
{:ok, product} = LatticeStripe.Product.retrieve(client, product.id)
# List products
{:ok, resp} = LatticeStripe.Product.list(client, %{"limit" => "10"})
# Search products
{:ok, resp} = LatticeStripe.Product.search(client, "active:'true' AND name~'shirt'")
# Stream all products lazily (auto-pagination)
client
|> LatticeStripe.Product.stream!()
|> Stream.take(100)
|> Enum.each(&process_product/1)Operations not supported by the Stripe API
delete — Stripe's Products API does not expose a delete endpoint. To stop a Product from being used, archive it with
update/4:LatticeStripe.Product.update(client, product_id, %{"active" => "false"})
Stripe API Reference
See the Stripe Product API for the full object reference and available parameters.
Summary
Functions
Creates a new Product.
Like create/3 but raises LatticeStripe.Error on failure.
Converts a decoded Stripe API map to a %Product{} struct.
Lists Products with optional filters.
Like list/3 but raises LatticeStripe.Error on failure.
Retrieves a Product by ID.
Like retrieve/3 but raises LatticeStripe.Error on failure.
Searches Products using Stripe's search query language.
Like search/3 but raises LatticeStripe.Error on failure.
Returns a lazy stream of all Products matching the search query (auto-pagination).
Returns a lazy stream of all Products matching the given params (auto-pagination).
Updates a Product by ID.
Like update/4 but raises LatticeStripe.Error on failure.
Types
@type t() :: %LatticeStripe.Product{ active: boolean() | nil, attributes: [String.t()] | nil, caption: String.t() | nil, created: integer() | nil, default_price: String.t() | nil, deleted: boolean(), description: String.t() | nil, extra: map(), features: [map()] | nil, id: String.t() | nil, images: [String.t()] | nil, livemode: boolean() | nil, marketing_features: [map()] | nil, metadata: map() | nil, name: String.t() | nil, object: String.t(), package_dimensions: map() | nil, shippable: boolean() | nil, statement_descriptor: String.t() | nil, tax_code: String.t() | nil, type: :good | :service | String.t() | nil, unit_label: String.t() | nil, updated: integer() | nil, url: String.t() | nil }
A Stripe Product object.
See the Stripe Product API for field definitions.
Functions
@spec create(LatticeStripe.Client.t(), map(), keyword()) :: {:ok, t()} | {:error, LatticeStripe.Error.t()}
Creates a new Product.
Sends POST /v1/products with the given params and returns {:ok, %Product{}}.
Parameters
client- A%LatticeStripe.Client{}structparams- Map of product attributes (e.g.,%{"name" => "...", "type" => "service"})opts- Per-request overrides (e.g.,[idempotency_key: "..."])
Returns
{:ok, %Product{}}on success{:error, %LatticeStripe.Error{}}on failure
Example
{:ok, product} = LatticeStripe.Product.create(client, %{
"name" => "Premium Plan",
"type" => "service"
})
@spec create!(LatticeStripe.Client.t(), map(), keyword()) :: t()
Like create/3 but raises LatticeStripe.Error on failure.
Converts a decoded Stripe API map to a %Product{} struct.
Maps all known Stripe Product fields. Any unrecognized fields are collected
into the extra map so no data is silently lost.
Per D-03, the type field is atomized via a whitelist: "good" → :good,
"service" → :service. Unknown values pass through as raw strings for
forward compatibility with future Stripe enum additions.
@spec list(LatticeStripe.Client.t(), map(), keyword()) :: {:ok, LatticeStripe.Response.t()} | {:error, LatticeStripe.Error.t()}
Lists Products with optional filters.
Sends GET /v1/products and returns {:ok, %Response{data: %List{}}} with
typed %Product{} items.
Parameters
client- A%LatticeStripe.Client{}structparams- Filter params (e.g.,%{"limit" => "10", "active" => "true"})opts- Per-request overrides
Returns
{:ok, %Response{data: %List{data: [%Product{}, ...]}}}on success{:error, %LatticeStripe.Error{}}on failure
Example
{:ok, resp} = LatticeStripe.Product.list(client, %{"limit" => "20"})
Enum.each(resp.data.data, &IO.inspect/1)
@spec list!(LatticeStripe.Client.t(), map(), keyword()) :: LatticeStripe.Response.t()
Like list/3 but raises LatticeStripe.Error on failure.
@spec retrieve(LatticeStripe.Client.t(), String.t(), keyword()) :: {:ok, t()} | {:error, LatticeStripe.Error.t()}
Retrieves a Product by ID.
Sends GET /v1/products/:id and returns {:ok, %Product{}}.
Parameters
client- A%LatticeStripe.Client{}structid- The product ID string (e.g.,"prod_123")opts- Per-request overrides
Returns
{:ok, %Product{}}on success{:error, %LatticeStripe.Error{}}on failure
@spec retrieve!(LatticeStripe.Client.t(), String.t(), keyword()) :: t()
Like retrieve/3 but raises LatticeStripe.Error on failure.
@spec search(LatticeStripe.Client.t(), String.t(), keyword()) :: {:ok, LatticeStripe.Response.t()} | {:error, LatticeStripe.Error.t()}
Searches Products using Stripe's search query language.
Sends GET /v1/products/search with the query string and returns typed results.
Searchable fields
active, description, metadata, name, shippable, url.
Parameters
client— A%LatticeStripe.Client{}structquery— Stripe search query string (e.g.,"active:'true' AND name~'shirt'")opts— Per-request overrides
Returns
{:ok, %Response{data: %List{data: [%Product{}, ...]}}}on success{:error, %LatticeStripe.Error{}}on failure
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.
Example
{:ok, resp} = LatticeStripe.Product.search(client, "active:'true'")
@spec search!(LatticeStripe.Client.t(), String.t(), keyword()) :: LatticeStripe.Response.t()
Like search/3 but raises LatticeStripe.Error on failure.
@spec search_stream!(LatticeStripe.Client.t(), String.t(), keyword()) :: Enumerable.t()
Returns a lazy stream of all Products matching the search query (auto-pagination).
Emits individual %Product{} structs, fetching additional search pages as needed.
Raises LatticeStripe.Error if any page fetch fails.
Parameters
client- A%LatticeStripe.Client{}structquery- Stripe search query stringopts- Per-request overrides
Returns
An Enumerable.t() of %Product{} structs.
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_stream!/3
in read-after-write flows where strict consistency is necessary. See
https://docs.stripe.com/search#data-freshness.
@spec stream!(LatticeStripe.Client.t(), map(), keyword()) :: Enumerable.t()
Returns a lazy stream of all Products matching the given params (auto-pagination).
Emits individual %Product{} structs, fetching additional pages as needed.
Raises LatticeStripe.Error if any page fetch fails.
Parameters
client- A%LatticeStripe.Client{}structparams- Filter params (e.g.,%{"limit" => "100"})opts- Per-request overrides
Returns
An Enumerable.t() of %Product{} structs.
Example
client
|> LatticeStripe.Product.stream!()
|> Stream.take(500)
|> Enum.to_list()
@spec update(LatticeStripe.Client.t(), String.t(), map(), keyword()) :: {:ok, t()} | {:error, LatticeStripe.Error.t()}
Updates a Product by ID.
Sends POST /v1/products/:id with the given params and returns {:ok, %Product{}}.
To archive a product (Stripe has no delete endpoint), pass %{"active" => "false"}.
Parameters
client- A%LatticeStripe.Client{}structid- The product ID stringparams- Map of fields to updateopts- Per-request overrides
Returns
{:ok, %Product{}}on success{:error, %LatticeStripe.Error{}}on failure
@spec update!(LatticeStripe.Client.t(), String.t(), map(), keyword()) :: t()
Like update/4 but raises LatticeStripe.Error on failure.