Operations on Stripe Payout objects.
A Payout represents money moving from your Stripe balance to a connected
bank account or debit card. Payouts are the outbound leg of money movement —
inbound money arrives via Charge / PaymentIntent, and you (or Stripe's
automatic schedule) trigger a Payout to settle the balance to a bank.
Key behaviors
- Full CRUDL:
create/3,retrieve/3,update/4,list/3,stream!/3. cancel/4andreverse/4both use the canonical(client, id, params \\ %{}, opts \\ [])shape per D-03. Both endpoints accept at leastexpand, andreverseadditionally acceptsmetadata.- The
trace_idfield decodes into a typed%LatticeStripe.Payout.TraceId{}— pattern-match onpayout.trace_id.statusto branch your reconciliation flow. - Unknown future fields from Stripe land in
:extra(F-001). require_param!validates the payout id pre-network onretrieve,update,cancel, andreverse.
Expandable references
The following fields are typed as binary() | map() | nil because Stripe
returns an ID string by default and only inlines the expanded object when you
pass expand: [...]:
destination— expand then cast viaLatticeStripe.BankAccount.cast/1orLatticeStripe.Card.cast/1as appropriate.balance_transactionandfailure_balance_transaction— expand then cast viaLatticeStripe.BalanceTransaction.from_map/1.
Per D-05, these references stay polymorphic — the guide documents the "expand then cast via expected module" idiom.
Usage
client = LatticeStripe.Client.new!(api_key: "sk_live_...", finch: MyApp.Finch)
# Trigger a manual payout to the default external account
{:ok, payout} = LatticeStripe.Payout.create(client, %{
"amount" => 5000,
"currency" => "usd"
})
# Retrieve and branch on trace_id availability
{:ok, payout} = LatticeStripe.Payout.retrieve(client, "po_...")
case payout.trace_id do
%LatticeStripe.Payout.TraceId{status: "supported", value: trace} ->
reconcile(trace)
%LatticeStripe.Payout.TraceId{status: "pending"} ->
# Stripe will populate trace_id asynchronously — listen for payout.updated
:wait_for_webhook
_ ->
:skip
end
# Cancel a pending payout (no params needed)
{:ok, _} = LatticeStripe.Payout.cancel(client, "po_...")
# Cancel with expand for reconciliation
{:ok, payout} =
LatticeStripe.Payout.cancel(client, "po_...", %{
"expand" => ["balance_transaction"]
})
# Reverse a completed payout with reconciliation metadata
{:ok, reversed} =
LatticeStripe.Payout.reverse(client, "po_...", %{
"metadata" => %{"reason" => "customer_dispute"},
"expand" => ["balance_transaction"]
})Idempotency
create, cancel, and reverse are money-moving operations. Client.request/2
auto-generates an idempotency key for mutating requests and reuses it across
retries. Pass idempotency_key: in opts to set your own stable key.
Stripe API Reference
Summary
Functions
Cancels a pending Payout.
Like cancel/4 but raises LatticeStripe.Error on failure.
Creates a new Payout.
Like create/3 but raises LatticeStripe.Error on failure.
Converts a decoded Stripe API map to a %Payout{} struct.
Lists Payouts with optional filters.
Like list/3 but raises LatticeStripe.Error on failure.
Retrieves a Payout by ID.
Like retrieve/3 but raises LatticeStripe.Error on failure.
Reverses a Payout.
Like reverse/4 but raises LatticeStripe.Error on failure.
Returns a lazy stream of all Payouts matching the given params.
Updates a Payout by ID.
Like update/4 but raises LatticeStripe.Error on failure.
Types
@type t() :: %LatticeStripe.Payout{ amount: integer() | nil, application_fee: String.t() | nil, application_fee_amount: integer() | nil, arrival_date: integer() | nil, automatic: boolean() | nil, balance_transaction: LatticeStripe.BalanceTransaction.t() | String.t() | nil, created: integer() | nil, currency: String.t() | nil, description: String.t() | nil, destination: LatticeStripe.BankAccount.t() | LatticeStripe.Card.t() | String.t() | nil, extra: map(), failure_balance_transaction: LatticeStripe.BalanceTransaction.t() | String.t() | nil, failure_code: String.t() | nil, failure_message: String.t() | nil, id: String.t() | nil, livemode: boolean() | nil, metadata: map() | nil, method: atom() | String.t() | nil, object: String.t(), original_payout: String.t() | nil, reconciliation_status: String.t() | nil, reversed_by: String.t() | nil, source_type: String.t() | nil, statement_descriptor: String.t() | nil, status: atom() | String.t() | nil, trace_id: LatticeStripe.Payout.TraceId.t() | nil, type: atom() | String.t() | nil }
A Stripe Payout object.
See the Stripe Payout object for field definitions.
Functions
@spec cancel(LatticeStripe.Client.t(), String.t(), map(), keyword()) :: {:ok, t()} | {:error, LatticeStripe.Error.t()}
Cancels a pending Payout.
Sends POST /v1/payouts/:id/cancel. Only payouts with status: "pending"
can be canceled.
Signature (D-03)
cancel(client, id, params \\ %{}, opts \\ []) — the params default is
mandatory. Stripe's /cancel endpoint accepts expand, so dropping params
would force a breaking change the first time a caller needs
expand: ["balance_transaction"].
Example
{:ok, payout} = LatticeStripe.Payout.cancel(client, "po_...")
{:ok, payout} =
LatticeStripe.Payout.cancel(client, "po_...", %{
"expand" => ["balance_transaction"]
})
@spec cancel!(LatticeStripe.Client.t(), String.t(), map(), keyword()) :: t()
Like cancel/4 but raises LatticeStripe.Error on failure.
@spec create(LatticeStripe.Client.t(), map(), keyword()) :: {:ok, t()} | {:error, LatticeStripe.Error.t()}
Creates a new Payout.
Sends POST /v1/payouts with the given params.
Parameters
client— A%LatticeStripe.Client{}structparams— Payout attributes. Stripe requires"amount"and"currency"; LatticeStripe does not pre-validate —Stripereturns a400if missing.opts— Per-request overrides (e.g.,[idempotency_key: "..."],[stripe_account: "acct_..."])
Example
{:ok, payout} =
LatticeStripe.Payout.create(client, %{
"amount" => 5000,
"currency" => "usd",
"method" => "instant",
"source_type" => "card"
})
@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 %Payout{} struct.
Maps every known Stripe Payout field explicitly. The nested trace_id map
is cast to a typed %LatticeStripe.Payout.TraceId{} struct. Unknown fields
land in :extra (F-001).
@spec list(LatticeStripe.Client.t(), map(), keyword()) :: {:ok, LatticeStripe.Response.t()} | {:error, LatticeStripe.Error.t()}
Lists Payouts with optional filters.
Sends GET /v1/payouts and returns a paginated %Response{data: %List{}}
with typed %Payout{} items. All params are optional.
@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 Payout by ID.
Sends GET /v1/payouts/:id. Raises ArgumentError (pre-network) if id is
nil or an empty string.
@spec retrieve!(LatticeStripe.Client.t(), String.t(), keyword()) :: t()
Like retrieve/3 but raises LatticeStripe.Error on failure.
@spec reverse(LatticeStripe.Client.t(), String.t(), map(), keyword()) :: {:ok, t()} | {:error, LatticeStripe.Error.t()}
Reverses a Payout.
Sends POST /v1/payouts/:id/reverse. Only payouts with status: "paid" and
type: "bank_account" can be reversed.
Signature (D-03)
reverse(client, id, params \\ %{}, opts \\ []) — the params default is
mandatory. Stripe's /reverse endpoint accepts metadata and expand.
Example
{:ok, reversed} =
LatticeStripe.Payout.reverse(client, "po_...", %{
"metadata" => %{"reason" => "customer_dispute"},
"expand" => ["balance_transaction"]
})
@spec reverse!(LatticeStripe.Client.t(), String.t(), map(), keyword()) :: t()
Like reverse/4 but raises LatticeStripe.Error on failure.
@spec stream!(LatticeStripe.Client.t(), map(), keyword()) :: Enumerable.t()
Returns a lazy stream of all Payouts matching the given params.
Emits individual %Payout{} structs, fetching additional pages as needed.
Raises LatticeStripe.Error if any page fetch fails.
@spec update(LatticeStripe.Client.t(), String.t(), map(), keyword()) :: {:ok, t()} | {:error, LatticeStripe.Error.t()}
Updates a Payout by ID.
Sends POST /v1/payouts/:id. Note: Stripe only supports updating metadata
on a Payout.
@spec update!(LatticeStripe.Client.t(), String.t(), map(), keyword()) :: t()
Like update/4 but raises LatticeStripe.Error on failure.