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.list({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 ? charge.dispute.id : "none" puts "#{charge.id},#{charge.amount},#{charge.currency},#{charge.refunded},#{dispute}" end

    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 end # Sum the net transaction volume net_volume += txn.amount end 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" account = "{{CONNECTED_STRIPE_ACCOUNT_ID}}" # 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.list({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 = Time.at(tr.date).strftime("%m/%d/%Y") # Output the payout id, amount, and date puts "#{tr.id}, #{tr.amount}, #{formatted_date}" end

    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" account = "{{CONNECTED_STRIPE_ACCOUNT_ID}}" now = Time.now.to_i # 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 = event.data.object if payout.date >= now # Format the date nicely formatted_date = Time.at(payout.date).getutc.strftime("%m/%d/%Y") # Output the payout id, amount, and expected deposit date puts "Payout Available #{formatted_date}" puts "#{payout.id},#{payout.amount}" end end # Retrieve transactions with an `available_on` date in the future transactions = Stripe::BalanceTransaction.list( {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] += txn.net else balances[txn.available_on] = txn.net end end # 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 = Time.at(date).getutc.strftime("%m/%d/%Y") # Only output non-zero balances unless net.eql?(0) puts "Balance Available on #{formatted_date}" puts net end end

    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" account = "{{CONNECTED_STRIPE_ACCOUNT_ID}}" 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 puts tr.id # Retrieve the balance transactions associated with this payout txns = Stripe::BalanceTransaction.list( {payout: tr.id, 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 = Time.at(txn.created).getutc.strftime("%m/%d/%Y") # Output the type (charge, refund, adjustment, etc.), ID, amount, and created date puts "#{txn.type},#{txn.source},#{txn.amount},#{formatted_date}" end end end

    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?

    Feedback about this page?

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

    On this page