I have saved stripe customer id's in my db for later payments. A customer will have multiple cards and I would like to check/validate new customer cards with their existing cards.
Suppose the same card details can be stored multiple times as multiple cards.
I want to check using the Stripe token whether a newly entered card already exists or not. It will use it if it's already there, if not it will create a new card.
To view payment details, simply go to Payments in your Stripe dashboard. Here you will see a list of your most recent payments and can filter or navigate to narrow down to find specific records. Once a payment is selected you should see all its details excluding the full credit card number.
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.
To update the payment information of an existing customer, you'd need to first collect the new card's information (using Checkout or your own form with Stripe. js), then send a customer update request with the new card's token in the source parameter.
Unfortunately while working on Stripe today I noticed that it do allows storing of duplicate cards. To avoid this, I did following steps:
#fetch the customer
customer = Stripe::Customer.retrieve(stripe_customer_token)
#Retrieve the card fingerprint using the stripe_card_token
card_fingerprint = Stripe::Token.retrieve(stripe_card_token).try(:card).try(:fingerprint)
# check whether a card with that fingerprint already exists
default_card = customer.cards.all.data.select{|card| card.fingerprint == card_fingerprint}.last if card_fingerprint
#create new card if do not already exists
default_card = customer.cards.create({:card => stripe_card_token}) unless default_card
#set the default card of the customer to be this card, as this is the last card provided by User and probably he want this card to be used for further transactions
customer.default_card = default_card.id
# save the customer
customer.save
fingerprint of a card stored with stripe is always unique
If you want to make fewer calls to stripe, it is recommended that you store the fingerprints of all the cards locally and use them for checking uniqueness. Storing fingerprints of cards locally is secure and it uniquely identifies a card.
For people reading this in 2016: Sahil Dhankhar answer is still correct, although Stripe have apparently changed their API syntax:
customer.cards
is now:
customer.sources
So, correct syntax would now be:
#fetch the customer
customer = Stripe::Customer.retrieve(stripe_customer_token)
#Retrieve the card fingerprint using the stripe_card_token
card_fingerprint = Stripe::Token.retrieve(stripe_card_token).try(:card).try(:fingerprint)
# check whether a card with that fingerprint already exists
default_card = customer.sources.all.data.select{|card| card.fingerprint == card_fingerprint}.last if card_fingerprint
#create new card if do not already exists
default_card = customer.sources.create({:card => stripe_card_token}) unless default_card
#set the default card of the customer to be this card, as this is the last card provided by User and probably he want this card to be used for further transactions
customer.default_card = default_card.id
# save the customer
customer.save
Hope this helps someone!
The card fingerprint is only useful for matching the card number. You must also check to make sure the expiration date hasn't changed as well. If a customer has the same card number, but an updated expiration date
customer = Stripe::Customer.retrieve(customer_stripe_id)
# Retrieve the card fingerprint using the stripe_card_token
newcard = Stripe::Token.retrieve(source_token)
card_fingerprint = newcard.try(:card).try(:fingerprint)
card_exp_month = newcard.try(:card).try(:exp_month)
card_exp_year = newcard.try(:card).try(:exp_year)
# Check whether a card with that fingerprint already exists
default_card = customer.sources.all(:object => "card").data.select{|card| ((card.fingerprint==card_fingerprint)and(card.exp_month==card_exp_month)and(card.exp_year==card_exp_year))}.last
default_card = customer.sources.create(source: source_token) if !default_card
# Set the default card of the customer to be this card, as this is the last card provided by User and probably he wants this card to be used for further transactions
customer.default_card = default_card.id
# Save the customer
customer.save
It sounds like you're caching the card data locally to be able to display it to the customer.
If that is correct, Stripe provides a fingerprint for each card/token which you can begin storing in the card records (if you're not already). Each fingerprint is unique to a card, so before storing additional cards for a customer, you can simply search the user's cards by fingerprint.
As a simple example, assuming a User has_many :cards
:
token = Stripe::Token.retrieve("tok_a1b2c3d4")
unless current_user.cards.find_by(fingerprint: token.card.fingerprint)
current_user.cards.create( ... # data from token )
end
If you're not caching the card data locally, Stripe handles duplicates for you and you don't need to do anything.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With