Question

When calling Stripe::Customer.all(:limit => 100) there is a limit of 100 per call. We have a lot more customers than that, and I would like to get them all at once. Am I missing something, or is this only possible by writing a naive loop that checks on the has_more attribute and then makes a new call until has_more = false?

Was it helpful?

Solution

You are right, you must write a naive loop with a cursor per the stripe docs:

starting_after

optional

A cursor for use in pagination. starting_after is an object ID that defines your place in the list. For instance, if you make a list request and receive 100 objects, ending with obj_foo, your subsequent call can include starting_after=obj_foo in order to fetch the next page of the list.

Here's one in case anyone needs a quick copy-paste.

  def self.all_stripe_customers
    starting_after = nil
    customers = []
    loop do
      results = Stripe::Customer.list(limit: 100, starting_after: starting_after)
      break if results.data.length == 0
      customers = customers + results.data
      starting_after = results.data.last.id  
    end
    return customers
  end

OTHER TIPS

Probably a little late to the game here, but here's a yielding version of Doug's answer which loops through every customer, yielding them to a block:

def each_stripe_customer
  starting_after = nil
  loop do
    customers = Stripe::Customer.list(limit: 100, starting_after: starting_after)
    break if customers.data.length == 0
    customers.each do |customer|
      yield customer
    end
    starting_after = customers.data.last.id  
  end
end

You can use this as follows:

each_stripe_customer do |customer|
  puts customer.id
end

This abstracts away the fetching of customers from however you actually want to use them.

Adding to docs "auto pagination", https://stripe.com/docs/api/pagination/auto

customers = Stripe::Customer.list({limit: 10})
customers.auto_paging_each do |customer|
  # Do something with customer
end

Another option is to go to Stripe Dashboard and export all customers to a CSV file. Maybe not the best approach since you will not get the updates, but it's an option.

Since Google points here and the question only mentions ruby in the tags, if someone needs the python code, here is @Doug's answer "translated" to the python stripe api, then generalized to get any stripe object:

import stripe #https://stripe.com/docs/api?lang=python
# must loop e.g.: https://stackoverflow.com/questions/23393300/what-is-the-best-practice-to-retrieve-all-customers-from-stripe-api-into-one-lis
def get_all_stripe_objects(stripe_listable):
    objects = []
    get_more = True
    starting_after = None
    while get_more:
        #stripe.Customer implements ListableAPIResource(APIResource):
        resp = stripe_listable.list(limit=100,starting_after=starting_after)
        objects.extend(resp['data'])
        get_more = resp['has_more']
        if len(resp['data'])>0:
            starting_after = resp['data'][-1]['id']
    return objects
all_stripe_customers = get_all_stripe_objects(stripe.Customer)
all_stripe_products  = get_all_stripe_objects(stripe.Product)

I would suggest to keep a local copy of customer data. so you get the data from Stripe API only once & use that local copy instead of asking that same data again-again.

For syncing changes, There are two main approaches you might use to make sure your database has the latest state:

The primary benefit to storing this data locally apart from getting around API limitations, is speed.

You will want to make sure you're storing the customer ID in your database so that you can match up the Stripe customer with your local user.

Hope it helps

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top