Building an Analytics Service

This guide is an in-depth walkthrough to providing an analytics service to Stripe users using Connect. If you need help after reading this, check out our answers to common questions or chat live with other developers in #stripe on freenode.

With thousands of businesses built on top of Stripe, there’s a sizable demand for providing advanced analytics as a service. Although users can always see their information in the Dashboard, custom reporting requires external parsing of data. Just a few of the services you could provide are:

  • Trend identification, such as sales by weekday.
  • Percentage reporting, like how many charges are authorized but not captured or captured and later refunded.
  • Aggregation, such as the total fees paid within a period.
  • Custom accounting, for example, showing the difference between the cash on hand and the transfers pending.
  • Tax reporting, watching sales by geographic location.

To implement an analytics service for Stripe users, you can build it using Connect. With Connect, your platform can be hooked into an existing Stripe account and read its data, no matter how the Stripe user processes charges: through their own integration, through a third-party; using subscriptions; using auth and capture; and anywhere in the world that Stripe operates.

Let’s look at how you’d do that in some detail, with certain assumptions:

  • Your service would neither create nor manage the other Stripe accounts.
  • The connected Stripe accounts may or may not have already processed charges before connecting to your service.
  • Your service would only read data from the connected account, never create transactions on their behalf (i.e., you can see the charges processed, but not initiate any).

Getting prepared

The first thing you need to do is register your platform with Stripe. When you do so, be certain that you have a webhook defined. As your platform won’t take any “create” actions on behalf of connected accounts, webhooks will be the only way to be notified of new transactions as they occur.

Next, create two pages on your website:

  • A start page that begins the connection process (i.e., where the user goes to connect to your platform).
  • A destination page to which the user will be redirected after connecting their Stripe account.

The start page would have your branding—it’s on your site, after all. You should also indicate to the user what you’ll do with their data (e.g., storage and retention policy), that you cannot process charges or transfer funds on the account, and that they will be able to disconnect the platform through the Stripe Dashboard. Basically, you’re offering all the benefits of third-party analytics without any risk of you being able to touch their money.

This latter page is the redirect_uri value, identified in your platform’s settings. You might use this page to create their account on your site, where they can view the reporting.

Connecting accounts

This scenario uses the OAuth flow to connect to a standalone Stripe account (that may or may not already exist). This option is quick to set up, as Stripe handles much of the user experience for you: your user will be redirected to Stripe, prompted to create or connect an existing Stripe account, and then returned to your site.

Connect supports connections under two different scopes: read_only and read_write. As the analytics service, you’ll want to request read_only scope. This permission type allows you to read data from the user’s account, but not create charges or transfers: you can see the money moving around, but not move it yourself.

At the end of the OAuth workflow, you’ll be provided with authorization credentials for the connected account:

  "stripe_user_id": "acct_BeLSA3LyTiliQD",

You’ll want to store the stripe_user_id on your side, as this is used to identify the account.

Fetching historical data

With the connection made, the only remaining issue is how the platform accesses the connected account’s data. There are two options: via the API and via webhook notifications.

Connect’s core functionality is the ability of one Stripe account to perform API requests on behalf of another Stripe account. Generally speaking, you can perform nearly any kind of request, but when granted only read-level scope, the platform is restricted to GET requests: fetching individual objects (e.g., a single charge) or lists of objects. This means that you can, through the API, make “list all” requests to fetch a connected user’s historical data.

curl \
   -u sk_test_BQokikJOvBiI2HlWgH4olfQ2: \
   -H "Stripe-Account: acct_BeLSA3LyTiliQD"

By default, that request will return the 10 most recent charges, which is just the start of grabbing their data.

Taking this further, you can use the created parameter to filter what transactions are returned, and paginate the request using the limit, ending_before, and starting_after parameters. As an example of that, this request will fetch the first 50 charges starting at the beginning of the year:

curl \
   -u sk_test_BQokikJOvBiI2HlWgH4olfQ2: \
   -H "Stripe-Account: acct_BeLSA3LyTiliQD" \
   -d limit=50 \
   -d created[lte]=1451606400

The response will look something like this:

  "object": "list",
  "url": "/v1/charges",
  "has_more": true,
  "data": [

All of the charges will be within the data attribute, which you can loop through. You could then use the final charge in that group as the after value in the request to retrieve the next 50 charges. (See the list all charges documentation.)

Although the API was designed for performance, repeatedly fetching large bodies of data will undoubtedly hurt the responsiveness of your application. We recommended storing fetched data on your side for subsequent analysis and reporting.

Watching for future data

The second way you can access a connected account’s data is via webhooks. Once you’ve defined a platform webhook URL in your account, Stripe will send event notifications to your webhook URL for every connected account. Look at the event object’s user_id property to see the account on which the event occurred.

  "id": "evt_CMC1wZh8SW8wv0",
  "livemode": true,
  "object": "event",
  "type": "customer.created",
  "user_id": "acct_BeLSA3LyTiliQD",
  "pending_webhooks": 2,
  "created": 1349654313,
  "data": {...}

The above event shows that a customer was created in the acct_BeLSA3LyTiliQD account. Again, we recommend storing these events locally for subsequent analysis and reporting. By watching for events as they occur, your service won’t require repeated and laborious API requests to fetch previous data.

Note: timely payment of invoices in Stripe requires proper acknowledgement by all webhooks associated with the account. Please make sure your platform’s webhooks always respond properly to avoid a delay in your users’ payments.


At any point in time, a connected user can disconnect their account from your platform. When that occurs, you’ll receive an account.application.deauthorized event notification at your webhook URL. You can use this notification to perform any necessary clean up on your end, such as disabling the user’s account (on your site) and removing their data.

You can disconnect an account from your platform by making a request to the OAuth deauthorization endpoint.

Charging for your service

Your analytics service is working great: you’re connecting users, reading in historical data, recording new events as they occur, and crunching the numbers. But…you’re apparently doing all this for free! When it’s time to monetize your service, Stripe can help there, too.

As your platform has, appropriately, a read-only connection, you cannot charge your users through Connect. That’s for the best, as such an arrangement may scare off business and make the accounting all wonky. But it’s still easy to accept payment for your service: your platform’s Stripe account can be used to process its own charges. After your customers connect their Stripe accounts, ask for their payment details and then create a subscription for them in your Stripe account. Store the created customer ID with the associated Stripe ID, and you’ll easily be able to see which of your users are paid and active, and which are not.

While you’re at it, run your Stripe account’s data through your analytics code to parse how your own business is growing!

Other recipes

Looking to build another type of platform? Check out these other recipes.