10

In the stripe documentation they have this:

customer = Stripe::Customer.create(email: params[:stripeEmail], card: params[:stripeToken])
charge = Stripe::Charge.create(customer: customer.id, amount: price, description: '123', currency: 'usd')

But I think it's wrong as for each payment we have to check if a customer exists first, I just tried it with a test account and it turned out there were created a number of different customers with the same email but different ids.

How do I check if a customer already exists?

Incerteza
  • 32,326
  • 47
  • 154
  • 261

4 Answers4

15

There is no check on Stripe's end to ensure uniqueness of customers (email, card, name, etc,) and this is something you have to do on your end.

Usually, when you create a customer with a specific email address you need to associate the customer id you got back from the API with the email address. Then next time, you check whether this email address is already in your system and either create a new customer or re-use the customer id from the previous time.

koopajah
  • 23,792
  • 9
  • 78
  • 104
  • `Usually, when you create a customer with a specific email address` - do you mean "at Stripe"? – Incerteza Dec 22 '14 at 01:03
  • 1
    Yes when you call the Create Customer API – koopajah Dec 22 '14 at 06:42
  • 2
    In addition to storing the Customer ID and Email in your own database, you should always check for the existence of the Customer ID in the Stripe Database to make sure it hasn't been deleted (maybe by accounting dept.). You can test and catch for an error when requesting the Customer ID here: https://stripe.com/docs/api/errors?lang=ruby – Jonny O Mar 12 '19 at 19:07
  • 1
    What's to prevent somebody putting in an email of another customer and creating charges on that customer? Or is this flow is only valid if its already behind a auth guard? – Genu Dec 11 '19 at 12:59
  • 1
    Correct, it's the latter, only works if you have some logic to let customers log into your website – koopajah Dec 12 '19 at 19:25
9

You may check if the customer exists or not by calling GET /customers with the email as a form-urlencoded parameter. You will get 200 OK response but the returned data[] will be empty if this customer email is not there.

https://stripe.com/docs/api/customers/list
MSaudi
  • 4,442
  • 2
  • 40
  • 65
2

I think a simple "exists" test is essential to avoid unwanted exceptions being generated.

If your customer is new then they won't have a stripe ID, which is fine. However you might get a situation where you are using an existing customer with an existing stripe ID, but have performed some sort of dormant clean-up Stripe side. In which case its good practice to test the supplied stripeID to see if its still valid.

For example I store the stripeID with the customer profile. When I make a payment I check to see if the stripeID field in the profile exists. If it does I fire off a API request to my backend to check its existence.

Something like this (.net backend example).

    [HttpGet]
    public ActionResult<bool> CheckCustomer(string id)
    {

        var service = new CustomerService();
        Customer cust;

        try
        {
            service.Get(id);
        }
        catch
        {
            return Ok(false);
        }

        if (cust.Deleted ?? false)
        {
            return Ok(false);
        }

        return Ok(true);
    }

I don't need the result, just it not throwing an exception is good enough. However, when you delete customers in Stripe live it keeps a copy of the ID stub and sets the delete property to true, so you need to check for that too.

The front end then can either use the stripeId for the payment or create a new stripe customer first then take the payment.

Darren Street
  • 1,652
  • 17
  • 21
1

You can search for the customer by email address...

public async Task<Customer> GetCustomerByEmail(string oneEmail)
{
    var service = new CustomerService();
    try
    {
            StripeList<Customer> customerList = await service.ListAsync(new CustomerListOptions() { Email=oneEmail },null);
            Debug.WriteLine(customerList.ToList().Count);
            return customerList.ToList().FirstOrDefault();
    }
    catch
    {
        return null;
    }

}
CYoung
  • 307
  • 1
  • 10