What is the best practice to retrieve all customers from Stripe API into one list

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

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.