Skip to Content
SimulatorsStripeBalance and payouts

Simulators

Balance and payouts

The balance moves with every payment, refund and payout, and each move writes the balance transaction Stripe would, so an account’s transactions add up to its balance. Fund a payout with the test card whose funds are available at once:

curl -s "$RYSTIC_URL/v1/charges" -u sk_test_123: -d amount=10000 -d currency=usd -d source=tok_bypassPending | jq -c '{id, amount, balance_transaction}'
# -> {"id":"ch_000000000000000000000001","amount":10000,"balance_transaction":"txn_000000000000000000000001"}
curl -s "$RYSTIC_URL/v1/balance" -u sk_test_123: | jq -c '{available: .available[0].amount, pending: .pending[0].amount}'
# -> {"available":9680,"pending":0}
curl -s "$RYSTIC_URL/v1/payouts" -u sk_test_123: -d amount=5000 -d currency=usd | jq -c '{status}'
# -> {"status":"pending"}
curl -s "$RYSTIC_URL/v1/balance" -u sk_test_123: | jq -c '{available: .available[0].amount}'
# -> {"available":4680}

What moves the balance

Every account starts with a usd entry at zero in available and pending; a connected account’s also lists instant_available, and the platform’s lists connect_reserved at zero. A captured card payment adds its amount less Stripe’s 2.9% + 30¢ fee: to available for the tok_bypassPending or pm_card_bypassPending test card (4000000000000077, also when saved as a PaymentMethod and paid by PaymentIntent or invoice, the customer’s default card included), whose funds Stripe makes available at once, and to pending for every other card and for a SEPA payment the clock settles. A verified US bank payment the clock settles adds its amount less the ACH fee to available (SEPA and US bank debits). Pending funds never become available on the simulator’s clock, so fund payouts with the bypassPending card, as Stripe’s test-mode docs advise.

An invoice paid by card credits the balance as a card payment does, and a credit note’s refund_amount debits it as a refund does. A refund of a captured charge takes its amount out of the side the charge went to, and the fee is not returned. A refund on any route is limited to the captured amount less what is already refunded, so a partly captured charge never refunds its uncaptured part. A charge in another currency is credited in that currency, where Stripe converts it to usd at a market rate. Disputes do not move the balance. Destination charges move the platform’s and the connected account’s balances as Connect says.

Balance transactions

Every captured card charge, whether a PaymentIntent, POST /v1/charges or its capture, an invoice or a subscription paid it, writes a charge balance transaction for its amount less the fee, the one its balance_transaction names; expand[]=balance_transaction on the charge embeds it, and it reads the charge’s current description. A PaymentIntent’s confirmed charge names its transaction at the confirm, and its charge.updated follows about 3 seconds later on the simulator’s clock. A refund’s transaction is written at its create on each of the three refund routes and by a credit note’s refund_amount; a release of an uncaptured charge writes none. A payout writes a payout transaction for minus its amount, the one its balance_transaction names, and a cancel that succeeds writes a payout_cancel one. GET /v1/balance_transactions filters by source or type and lists each account’s own only; another account’s transaction answers 404 resource_missing.

Payouts

A payout draws on available; one above it, or in a currency the balance does not hold, answers 400 balance_insufficient. The create answers the payout pending, as Stripe’s does, and every later read finds it paid, as test mode pays a payout at once, so a cancel answers 400 “Payouts can only be canceled while they are pending.” and the funds stay paid out. The platform’s payouts name one stand-in bank account as destination, and a connected account’s name its own external account (Connect). arrival_date is midnight UTC of the payout’s day.

Last updated on