Building a Seller Dashboard

    If your platform uses Custom accounts, your users don’t have access to the Stripe Dashboard. This means you need to build a dashboard for them so they can view payouts, initiate refunds, and access other functionality. This recipe provides backend solutions you can integrate with your own web or mobile frontend to display this information.

    Accessing data

    The dashboard in this recipe uses the list_charges, balance_history, list_payouts, and list_events API calls to retrieve data. This data includes charge amounts, pending and available balances, dispute status, and more. To access this data, you need to use the Stripe-Account header in your API calls. If your connected accounts process significant volume, or if you’re repeatedly retrieving large data sets, you should store some of this data on your end.

    Payment information

    The list_charges API call returns charge amounts and other useful information. This Ruby example retrieves the 100 most recent charges, iterates through them, and outputs the charge ID, amount, currency, refund status, and dispute status:

    require 'stripe'
    Stripe.api_key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"
    # Authenticate as the connected account and retrieve the first 100 charges
    charges = Stripe::Charge.all({limit: 100},{stripe_account: "{{CONNECTED_STRIPE_ACCOUNT_ID}}"})
    # Iterate through charges using auto-pagination
    charges.auto_paging_each do |charge|
      # Output the charge ID, amount, currency, refund, and dispute status
      dispute = charge.dispute ? : "none"
      puts "#{},#{charge.amount},#{charge.currency},#{charge.refunded},#{dispute}"

    In the dashboard, you can use your own branding and styling to display this information:

    Payment information

    Balance information

    The balance_history API call can be used to calculate gross and net volume totals. Using Ruby again, the 100 most recent transactions are retrieved and iterated over. The total_volume and net_volume are calculated and then outputted:

    require 'stripe'
    Stripe.api_key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"
    # Authenticate as the connected account and retrieve the first 100 transactions
    transactions = Stripe::BalanceTransaction.list(
      {limit: 100},
      {stripe_account: '{{CONNECTED_STRIPE_ACCOUNT_ID}}'}
    total_volume = 0
    net_volume = 0
    # Iterate through transactions using auto-pagination
    transactions.auto_paging_each do |txn|
      # Sum the total payments volume
      if txn.type.eql?('charge')
        total_volume += txn.amount
      # Sum the net transaction volume
      net_volume += txn.amount
    puts "Total volume: #{total_volume}"
    puts "Net volume: #{net_volume}"

    In the dashboard, you might want to display these amounts prominently to the user:

    Total and net volumes

    Retrieving and calculating balance data can take time. If your dashboard’s performance drops, try storing this information on your end.

    It’s often useful to display the current and pending balance amounts for connected accounts as well. The retrieve_balance call can be used with the list_payouts call to display this information:

    require 'stripe'
    Stripe.api_key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"
    # Retrieve available balance for the connected account
    balance = Stripe::Balance.retrieve(stripe_account: account)
    puts "Available balance: #{balance.available[0].amount}"
    puts "Pending balance: #{balance.pending[0].amount}"
    # Authenticate as the connected account and retrieve the first 100 payouts
    payouts = Stripe::Payout.all({limit: 100}, {stripe_account: account})
    # Iterate through created payouts using auto-pagination
    puts "Past Payouts"
    payouts.auto_paging_each do |tr|
      # Format the date
      formatted_date ="%m/%d/%Y")
      # Output the payout id, amount, and date
      puts "#{}, #{tr.amount}, #{formatted_date}"

    In the dashboard, this information can be displayed side-by-side, with the payouts listed underneath:

    Balance and payout amounts

    You can also list payouts that aren’t paid out yet and calculate projected balance amounts. Listen for new payouts with payout dates in the future, and then use the balance_history API call to find the available_on date. The available_on date is the date funds are available in the connected account’s Stripe balance. You may want to explain to users that the deposit day may differ from the available_on date due to weekends, bank holidays, and the account’s payout schedule.

    require 'stripe'
    Stripe.api_key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"
    now =
    # List `payout.created` events on the connected account
    events = Stripe::Event.list(
      {type: "payout.created", limit: 100},
      {stripe_account: connected_account})
    # Iterate through each event
    events.each do | event |
      # Inspect each payout, looking for created payouts with expected payout dates in the future
      payout =
      if >= now
        # Format the date nicely
        formatted_date ="%m/%d/%Y")
        # Output the payout id, amount, and expected deposit date
        puts "Payout Available #{formatted_date}"
        puts "#{},#{payout.amount}"
    # Retrieve transactions with an `available_on` date in the future
    transactions = Stripe::BalanceTransaction.all(
      {limit: 100, available_on: {gte: now}},
      {stripe_account: connected_account})
    balances = {}
    # Iterate through transactions and sum values for each `available_on` date
    transactions.auto_paging_each do |txn|
      if balances.key?(txn.available_on)
        balances[txn.available_on] +=
        balances[txn.available_on] =
    # Sort the results
    balances = balances.sort_by {|date,net| date}
    # Output the available dates and net amounts
    balances.each do |date,net|
      # Format the date nicely
      formatted_date ="%m/%d/%Y")
      # Only output non-zero balances
      unless net.eql?(0)
        puts "Balance Available on #{formatted_date}"
        puts net

    In the dashboard, you can display upcoming payout and balance amounts by date:

    Future balances and payouts

    Listing transactions for automatic payouts

    When automatic payouts are enabled, you can show users each charge, refund, and adjustment that contributed to their payouts. This breakdown provides a detailed look at the funds flow for each payout. To display this information, fetch the payouts, iterate through them to find the payout IDs, and then use the IDs to find the transactions associated with each payout. In Ruby, your code might look something like this:

    require 'stripe'
    Stripe.api_key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"
    require 'stripe'
    # Retrieve the last 10 payouts for the connected account
    payouts = Stripe::Payout.list({limit:10},{stripe_account: account})
    # Iterate through payouts for the connected account
    payouts.each do | tr |
      # Output the payout ID
      # Retrieve the balance transactions associated with this payout
      txns = Stripe::BalanceTransaction.list(
        {payout:, limit: 100},
        {stripe_account: account})
      # Iterate through and list each balance transaction
      txns.auto_paging_each do | txn |
        # Don't include the payout balance transaction
        unless txn.type.eql?("payout")
          # Format the date nicely
          formatted_date ="%m/%d/%Y")
          # Output the type (charge, refund, adjustment, etc.), ID, amount, and created date
          puts "#{txn.type},#{txn.source},#{txn.amount},#{formatted_date}"

    In your dashboard, when users select a specific payout, you can display this information:

    Transactions within a payout

    Other information and recipes

    This recipe covers some of the most common dashboard content, but you can display much more information to your users. Showing them why charges are declined, tracking dispute status, and providing functionality to submit dispute evidence are a few. You can also build custom reports.

    Was this page helpful? Yes No


    Thank you for helping improve Stripe's documentation. If you need help or have any questions, please consider contacting support.


    We're always happy to help with code or other questions you might have. Search our documentation, contact support, or connect with our sales team. You can also chat live with other developers in #stripe on freenode.

    On this page