# `LatticeStripe.SetupIntent`
[🔗](https://github.com/szTheory/lattice_stripe/blob/v1.1.0/lib/lattice_stripe/setup_intent.ex#L1)

Operations on Stripe SetupIntent objects.

A SetupIntent guides you through the process of setting up and saving a customer's
payment method for future payments. Use SetupIntents when you want to save a payment
method without immediately collecting payment.

Common use cases include:
- Saving a card for subscription billing (usage: `"off_session"`)
- Saving a card to charge at a later date
- Migrating existing payment method data

## Usage

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

    # Create a SetupIntent to save a payment method for future use
    {:ok, si} = LatticeStripe.SetupIntent.create(client, %{
      "customer" => "cus_123",
      "usage" => "off_session",
      "payment_method_types" => ["card"]
    })

    # Confirm the SetupIntent with a payment method
    {:ok, si} = LatticeStripe.SetupIntent.confirm(client, si.id, %{
      "payment_method" => "pm_card_visa"
    })

    # Cancel a SetupIntent that is no longer needed
    {:ok, si} = LatticeStripe.SetupIntent.cancel(client, si.id, %{
      "cancellation_reason" => "abandoned"
    })

    # Verify microdeposits for bank account payment methods (e.g., ACH/BECS)
    {:ok, si} = LatticeStripe.SetupIntent.verify_microdeposits(client, si.id, %{
      "amounts" => [32, 45]
    })

    # List SetupIntents with filters
    {:ok, resp} = LatticeStripe.SetupIntent.list(client, %{"customer" => "cus_123"})
    setup_intents = resp.data.data  # [%SetupIntent{}, ...]

    # Stream all SetupIntents lazily (auto-pagination)
    client
    |> LatticeStripe.SetupIntent.stream!()
    |> Stream.take(100)
    |> Enum.each(&process_setup_intent/1)

## Security and Inspect

The `Inspect` implementation hides `client_secret` — this value must never
appear in logs. Only `id`, `object`, `status`, and `usage` are shown in
inspect output.

Note: SetupIntents cannot be deleted. There is no `delete/3` function.

## Stripe API Reference

See the [Stripe SetupIntent API](https://docs.stripe.com/api/setup_intents) for the full
object reference and available parameters.

# `t`

```elixir
@type t() :: %LatticeStripe.SetupIntent{
  application: String.t() | nil,
  attach_to_self: boolean() | nil,
  automatic_payment_methods: map() | nil,
  cancellation_reason: String.t() | nil,
  client_secret: String.t() | nil,
  created: integer() | nil,
  customer: String.t() | nil,
  customer_account: map() | nil,
  description: String.t() | nil,
  excluded_payment_method_types: [String.t()] | nil,
  extra: map(),
  flow_directions: [String.t()] | nil,
  id: String.t() | nil,
  last_setup_error: map() | nil,
  latest_attempt: String.t() | map() | nil,
  livemode: boolean() | nil,
  mandate: String.t() | nil,
  metadata: map() | nil,
  next_action: map() | nil,
  object: String.t(),
  on_behalf_of: String.t() | nil,
  payment_method: String.t() | nil,
  payment_method_configuration_details: map() | nil,
  payment_method_options: map() | nil,
  payment_method_types: [String.t()] | nil,
  single_use_mandate: String.t() | nil,
  status: String.t() | nil,
  usage: String.t() | nil
}
```

A Stripe SetupIntent object.

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

# `cancel`

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

Cancels a SetupIntent.

Sends `POST /v1/setup_intents/:id/cancel` with optional params and returns
`{:ok, %SetupIntent{status: "canceled"}}`. A SetupIntent can be canceled when
it is in `requires_payment_method`, `requires_confirmation`, or
`requires_action` status.

## Parameters

- `client` - A `%LatticeStripe.Client{}` struct
- `id` - The SetupIntent ID string
- `params` - Optional cancel params (e.g., `%{"cancellation_reason" => "abandoned"}`)
- `opts` - Per-request overrides

## Returns

- `{:ok, %SetupIntent{status: "canceled"}}` on success
- `{:error, %LatticeStripe.Error{}}` on failure

## Example

    {:ok, si} = LatticeStripe.SetupIntent.cancel(client, si.id, %{
      "cancellation_reason" => "abandoned"
    })

# `cancel!`

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

Like `cancel/4` but raises `LatticeStripe.Error` on failure.

# `confirm`

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

Confirms a SetupIntent, attempting to save the payment method.

Sends `POST /v1/setup_intents/:id/confirm` with optional params and returns
`{:ok, %SetupIntent{}}`. After confirmation, the SetupIntent will have a
`status` indicating whether the setup succeeded or requires additional steps.

## Parameters

- `client` - A `%LatticeStripe.Client{}` struct
- `id` - The SetupIntent ID string
- `params` - Optional confirmation params (e.g., `%{"payment_method" => "pm_..."}`)
- `opts` - Per-request overrides

## Returns

- `{:ok, %SetupIntent{}}` on success
- `{:error, %LatticeStripe.Error{}}` on failure

## Example

    {:ok, si} = LatticeStripe.SetupIntent.confirm(client, si.id, %{
      "payment_method" => "pm_card_visa"
    })

# `confirm!`

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

Like `confirm/4` but raises `LatticeStripe.Error` on failure.

# `create`

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

Creates a new SetupIntent.

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

## Parameters

- `client` - A `%LatticeStripe.Client{}` struct
- `params` - Map of SetupIntent attributes (e.g., `%{"customer" => "cus_123", "usage" => "off_session"}`)
- `opts` - Per-request overrides (e.g., `[idempotency_key: "..."]`)

## Returns

- `{:ok, %SetupIntent{}}` on success
- `{:error, %LatticeStripe.Error{}}` on failure

## Example

    {:ok, si} = LatticeStripe.SetupIntent.create(client, %{
      "customer" => "cus_123",
      "payment_method_types" => ["card"]
    })

# `create!`

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

Like `create/3` but raises `LatticeStripe.Error` on failure.

# `from_map`

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

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

Maps all known Stripe SetupIntent fields. Any unrecognized fields are
collected into the `extra` map so no data is silently lost.

## Example

    si = LatticeStripe.SetupIntent.from_map(%{
      "id" => "seti_123",
      "status" => "requires_payment_method",
      "usage" => "off_session"
    })

# `list`

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

Lists SetupIntents with optional filters.

Sends `GET /v1/setup_intents` and returns `{:ok, %Response{data: %List{}}}` with
typed `%SetupIntent{}` items.

## Parameters

- `client` - A `%LatticeStripe.Client{}` struct
- `params` - Filter params (e.g., `%{"customer" => "cus_123", "limit" => "10"}`)
- `opts` - Per-request overrides

## Returns

- `{:ok, %Response{data: %List{data: [%SetupIntent{}, ...]}}}` on success
- `{:error, %LatticeStripe.Error{}}` on failure

## Example

    {:ok, resp} = LatticeStripe.SetupIntent.list(client, %{"customer" => "cus_123"})
    Enum.each(resp.data.data, &IO.inspect/1)

# `list!`

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

Like `list/3` but raises `LatticeStripe.Error` on failure.

# `retrieve`

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

Retrieves a SetupIntent by ID.

Sends `GET /v1/setup_intents/:id` and returns `{:ok, %SetupIntent{}}`.

## Parameters

- `client` - A `%LatticeStripe.Client{}` struct
- `id` - The SetupIntent ID string (e.g., `"seti_123"`)
- `opts` - Per-request overrides

## Returns

- `{:ok, %SetupIntent{}}` on success
- `{:error, %LatticeStripe.Error{}}` on failure

# `retrieve!`

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

Like `retrieve/3` but raises `LatticeStripe.Error` on failure.

# `stream!`

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

Returns a lazy stream of all SetupIntents matching the given params (auto-pagination).

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

## Parameters

- `client` - A `%LatticeStripe.Client{}` struct
- `params` - Filter params (e.g., `%{"limit" => "100"}`)
- `opts` - Per-request overrides

## Returns

An `Enumerable.t()` of `%SetupIntent{}` structs.

## Example

    client
    |> LatticeStripe.SetupIntent.stream!()
    |> Stream.take(500)
    |> Enum.to_list()

# `update`

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

Updates a SetupIntent by ID.

Sends `POST /v1/setup_intents/:id` with the given params and returns
`{:ok, %SetupIntent{}}`.

## Parameters

- `client` - A `%LatticeStripe.Client{}` struct
- `id` - The SetupIntent ID string
- `params` - Map of fields to update
- `opts` - Per-request overrides

## Returns

- `{:ok, %SetupIntent{}}` on success
- `{:error, %LatticeStripe.Error{}}` on failure

# `update!`

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

Like `update/4` but raises `LatticeStripe.Error` on failure.

# `verify_microdeposits`

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

Verifies microdeposits on a SetupIntent for bank account payment methods.

Sends `POST /v1/setup_intents/:id/verify_microdeposits` with the deposit amounts
or descriptor code and returns `{:ok, %SetupIntent{}}`. Used for ACH, BECS, and
similar bank transfer payment methods that require microdeposit verification.

## Parameters

- `client` - A `%LatticeStripe.Client{}` struct
- `id` - The SetupIntent ID string
- `params` - Verification params:
  - `%{"amounts" => [32, 45]}` for amount-based verification
  - `%{"descriptor_code" => "SM11AA"}` for descriptor-based verification
- `opts` - Per-request overrides

## Returns

- `{:ok, %SetupIntent{}}` on success
- `{:error, %LatticeStripe.Error{}}` on failure

## Example

    {:ok, si} = LatticeStripe.SetupIntent.verify_microdeposits(client, si.id, %{
      "amounts" => [32, 45]
    })

# `verify_microdeposits!`

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

Like `verify_microdeposits/4` but raises `LatticeStripe.Error` on failure.

---

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