Working with balances and transactions
Learn about financial account balances and the effect transactions have on them.
Financial accounts have their own balance separate from the balance of the account they’re attached to (platform account or connected account). Balance objects record the amount of funds in a financial account and their state of availability. Transaction and TransactionEntry objects debit or credit the funds in that balance.
Balances
A financial account has a balance of funds. The sum total of the balance isn’t always available for spending, however, as it might include pending transactions into or out of the financial account. The financial account balance contains three properties that define the availability of its funds:
cash—funds the user can spend right now.inbound_—funds not spendable yet, but that will become available at a later time. Thepending inbound_property is reserved for future functionality and always has a value of 0.pending outbound_—funds in the account, but not spendable because they’re being held for pending outbound flows.pending
Use GET /v1/treasury/financial_ to retrieve the balance details of a financial account with the associated ID. Provide the Stripe-Account header if the financial account is attached to one of your connected accounts. If the financial account is attached to your platform account, don’t include the Stripe-Account header.
If successful, the response is a FinancialAccount object with a balance hash that details the funds and their availability.
{ "object": "treasury.financial_account", "id": "{{FINANCIAL_ACCOUNT_ID}}", ... "balance": { // $90 is currently available for use, // with an additional $10 held in the outbound_pending sub-balance "cash": {"usd": 9000}, "inbound_pending": {"usd": 0}, "outbound_pending": {"usd": 1000} } }
Negative balances and overdrafts
If your connected account has a negative balance (for example, if your financial account receives an ACH credit that gets reversed), you’re responsible for restoring it to 0 USD. After 180 days of staying negative, Stripe debits your platform. We also contact you if individual or aggregate balances exceed our risk limits.
We recommend that you monitor your connected accounts to retrieve funds for their negative balances. You can top up funds into your financial account using Inbound Transfers or Stripe Payouts. Make sure that you regularly monitor your connected account balances and reach out promptly.
After a financial account has been negative for 180 days, Stripe debits funds from your platform’s financial account and emails you ahead of time. If the transfer fails due to insufficient funds, Stripe contacts you with next steps.
Transactions
All changes to a balance have a corresponding Transaction object that details money movements. Transactions affect only one balance and are in only one currency (currently, Financial Accounts for platforms supports only USD).
Each transaction points to the balance-affecting money movement object, such as an OutboundTransfer, ReceivedCredit, or ReceivedDebit.
Transaction state machine
| Status | State applied | Description | Transitions to |
|---|---|---|---|
open | initial | This is the initial state for all transactions. The transaction results in updates to the sub-balance amounts, but the current balance isn’t affected until the transaction posts. | posted or void |
posted | terminal | Funds have successfully entered or left the account. The current balance was affected. | N/A |
void | terminal | The transaction never impacted the balance. For example, a transaction enters this state if an outbound payment was initiated but then canceled before the funds left the account. | N/A |
The available Transaction endpoints enable you to retrieve specific transactions and list or filter transactions affecting a financial account. There are no webhooks available for transactions, but webhooks are available for the associated money movement objects (for example, OutboundPayments).
Retrieve a transaction
Use GET/v1/treasury/transactions/{{TRANSACTION_ to retrieve the transaction with the associated ID.
If successful, the response returns the Transaction object.
List Transactions
Use GET /v1/treasury/transactions to list transactions for a financial account. Set the required financial_ parameter in the body to the value of the financial account ID to retrieve transactions for. Include additional parameters to filter the results returned.
In addition to the standard set of list parameters, you can filter transactions by the following.
statusflow- Either
createdorposted_, but not bothat
{ // Standard list parameters limit, starting_after, ending_before, // Filter by FinancialAccount, required financial_account: "{{FINANCIAL_ACCOUNT_ID}}" // Filter by status status: "open" | "posted" | "void", // Filter by flow flow: "{{FLOW_OBJECT_ID}}", // Order the results by the created or posted_at timestamps, default is `created`. // For order_by=posted_at, setting status='posted' is required order_by: "created" | "posted_at", // created can only be specified with order_by = 'created' created: {gt, gte, lt, lte}, status_transitions: { // status_transitions.posted_at can only be specified with order_by = 'posted_at' and status = 'posted' posted_at: {gt, gte, lt, lte} } }
The following request retrieves the three most recent transactions created on the financial account that have a status of posted.
Webhooks
There are no webhooks for transactions because the various money movements that initiate a transaction have their own webhooks.
Transaction entries
TransactionEntry objects are the most granular view of money movements that affect a financial account balance. A single flow of money comprises multiple individual money movements, each represented by a transaction. Transactions, in turn, are an aggregation of transaction entries. For example, when initiating an outbound payment of 10 USD at time T, funds are moved from the cash sub-balance to the outbound_ sub-balance. The following Transaction object response demonstrates this initial event.
{ "id": "{{TRANSACTION_ID}}", "object": "treasury.transaction", "created": "{{T}}", ... "flow": "{{OUTBOUND_PAYMENT_ID}}", "flow_type": "outbound_payment", "status": "open", "amount": -1000, "currency": "usd",
After the outbound payment posts at time T+1, the funds are deducted from outbound_ and a new transaction entry is added to the transaction. The following Transaction response demonstrates this progression.
{ "id": "{{TRANSACTION_ID}}", "object": "treasury.transaction", "created": "{{T}}", ... "flow": "{{OUTBOUND_PAYMENT_ID}}", "flow_type": "outbound_payment", "status": "posted", "amount": -1000, "currency": "usd",
As the preceding responses show, a transaction can contain multiple transaction entries. The available TransactionEntry endpoints enable you to retrieve specific transaction entries and list or filter them for a particular transaction.
A Transaction in the void status won’t have any new transaction entries added to it. A Transaction in the posted status where all balance_ is to the cash sub-balance won’t have any new transaction entries added to it, either.
Retrieve transaction entries
Use GET /v1/treasury/transaction_ to retrieve details for the transaction entry with the associated ID.
If successful, the response returns a TransactionEntry object with the following form.
{ "id": "{{TRANSACTION_ENTRY_ID}}", "object": "treasury.transaction_entry", "created": "{{Timestamp}}", "livemode": false, // The FinancialAccount this transaction entry impacts. "financial_account": "{{FINANCIAL_ACCOUNT_ID}}", // The transaction that this transaction entry belongs to. "transaction": "{{TRANSACTION_ID}}", // The flow responsible for this transaction entry.
List TransactionEntries
Use GET /v1/treasury/transaction_ to list the transaction entries for a financial account. Set the required financial_ parameter in the body to the value of the financial account ID to retrieve transaction entries for. Include additional parameters if you want to filter the list.
In addition to the standard set of list parameters, you can filter transaction entries by:
transaction- Either
createdoreffective_, but not bothat
{ // Standard list parameters limit, starting_after, ending_before, // Filter by FinancialAccount, required financial_account: "fa_123" // Filter by transaction transaction: 'trxn_123', // Order the results by the created or effective_at timestamps, default is `created`. order_by: "created" | "effective_at", // created can only be specified with order_by = 'created' created: {gt, gte, lt, lte}, // effective_at can only be specified with order_by = 'effective_at' effective_at: {gt, gte, lt, lte}, }
The following request retrieves the transaction entries created before {{Timestamp}} and orders them by created date.
Webhooks
There are no webhooks for transaction entries because the various money movements that initiate a transaction entry have their own webhooks.