Before you ask for some code, understand that this question is about the implementation technique than code mongering.
OK, so in order to save a customer in stripe connect to charge them later or monthly, here is the prescribed process:
step 1. Use Stripe.js to get card details of the user such as card numbr, exp date, cvv etc. which will be sent to stripe.
step 2. Stripe returns a token corresponding to the card like: tok_xyz, now this token can be used to generate a customer in Stripe and you will get customer id.
step 3. Once you have customer id, you can charge them anytime.
Now I have two questions:
If I provide same card details in the step 1 above, will strip return same token everytime? I am asking it so that I may know how to handle the condition when a user enters same card details twice and I don't accidentally create multiple entries in the database for same card again and again.
It's documented in Stripe that after they issue card token (step 1 above) the CVV remains valid only for few minutes and if you don't make a charge in that time, later on the card will become invalid so do I need to charge the customer right away with a small amount like 0.01$ or something? or when I create customer (step 2 above), stripe takes care of that?
Thank you for any help in advance.
No, you will get a different token and tok_xxx ID value every time. However, there is a fingerprint property you can read from the token and compare to cards saved to the customer, to check for duplicates. There are some good answers on StackOverflow showing examples of that.
True, the CVC value is only held for a short amount of time. If you make a charge during that time, it can be checked by the bank. Creating a charge outside that time doesn't make the card invalid, but it will likely lead to more chance of a decline. Luckily this isn't an issue — when you create a customer object Stripe performs a $0 authorisation charge(as described in the blue box here). So as long as you either charge the token directly, or use it to create a customer object, as soon as you get it, you don't need to think about this.
Related
I have a website similar to TaskRabbit (employers hire employees). I'm trying to figure out how to set up payments to work with 3D secure - even though I'm in the United States and I don't think that many cards require it.
The payment flow is
Employers go to the Stripe hosted Customer portal to enter their payment method, and if they need authentication when entering a 3D secure card, Stripe will handle that there
Employers will bid on shifts for Employees. Since multiple bids may be needed and not all bids would be accepted by the employee, I don't have any payment processing done at this stage
Employee accepts a bid. Now using the stored payment method, an off session Payment Intent is created. PaymentIntent looks like this
curl https://api.stripe.com/v1/payment_intents
-d amount=1000
-d currency=usd
-d customer = cus_ABCDEFGHIJKLMNOP
-d automatic_payment_methods[enabled] = true
-d payment_method = pm_1MYlwuGbdc
-d confirm = true
-d transfer_data[destination] = acct_1MVqZx2eFvmfdu
-d off_session = true
-d transfer_data[amount] = 100
And this works for a few test cards in Stripe but not for this one for example:
This card requires authentication on all transactions, regardless of how the card is set up.
Right now my website is not live. How likely am I to encounter problems in the US with 3D secure? Is my payment flow going to be possible (the main thing is I don't want the employer having to go through a Checkout process)
When you collect payment method details at first, you should use the Setup Intents API to properly set up the payment method for future use. For card payments for example you will be able to have your customer go through 3D Secure if it's required.
After the SetupIntent succeeds, you will get a PaymentMethod pm_123 attached to your customer which you can use on future payments either on or off session.
Now, even if the card is set up properly, it's still possible that the bank will decline the payment. It might be because they want the cardholder to go through 3D Secure again, but it might simply be that they have insufficient funds or any other reason.
When that happens, your code should handle the payment failure and get your customer back on session to enter new payment method details. It might be a new card, or the existing one but they go through 3D Secure again. And that payment can still fail, the same as any payment.
Finally, the test card you are using was explicitly built by Stripe to always require 3DS. It's not really something most banks would do, it's just an easy card to use for forcing any transaction to require 3DS in Test mode. But ultimately, it'd work the same as any decline: you get the customer back "on session" on your website/app and you confirm that PaymentIntent client-side instead.
In my marketplace I have a requirement to:
Have a customer enter their card details
Once card details are submitted, process multiple charges against that card on the server side
I'm using stripe.js and creating a PaymentMethod on the client side using stripe.createPaymentMethod()
The ID of the PaymentMethod is posted to the server, which then does the following via the Stripe API library for PHP:
Retrieves the PaymentMethod from Stripe using the posted ID
Creates a Customer on Stripe, specifying the 'payment_method'
Creates multiple PaymentIntents, specifying the 'payment_method', the 'customer', 'save_payment_method' as true and 'confirm' as true.
I'm now wanting to handle scenarios where Stripe requires the use of 3D Secure.
Is there any way that 3D Secure verification can take place on the client, prior to the request to the server, whilst using stripe.createPaymentMethod() ?
If not, what alternative do I have?
It seems that a user completing the 3D Secure steps returns only a PaymentIntent. I don't believe I'm able to use this to make multiple charges against the card. This is whole reason for using createPaymentMethod() on the client in the first place.
Any ideas on how to go about this?
Is there any way that 3D Secure verification can take place on the client, prior to the request to the server, whilst using stripe.createPaymentMethod() ?
The approach to handle 3D Secure authentication on the client is to either use the confirmCardPayment [0] or handleCardAction [1] methods on Stripe.js. Unless you have specific needs, you would most likely want to use confirmCardPayment and follow this guide here:
https://stripe.com/docs/payments/accept-a-payment
I should note, that both these methods only work to process one payment at a time. In your case, you have multiple payment intents, so you would need to call either of the methods once per transaction. That is, if you have three payment intents you would need to call confirmCardPayment three times, repeating the last step in the guide [2] that many times as well.
This means that it is technically possible (but unlikely) that your users may have to authenticate multiple times to process each of their payments.
Unfortunately, there are really no workarounds for this. Even if you were to setup a user's card with SetupIntents [3] and charge them off-session at a later date, there is still a risk that you would need to bring user's back on-session to authenticate each individual payment intent.
All this being said, the majority of your users probably won't run into a scenario where they would need to authenticate multiple times in a row.
The only other option would be to create a single payment intent that covers the full cost of your product/service, which would allow you to call confirmCardPayment just once.
[0] https://stripe.com/docs/js/payment_intents/confirm_card_payment
[1] https://stripe.com/docs/js/payment_intents/handle_card_action
[2] https://stripe.com/docs/payments/accept-a-payment#web-submit-payment
[3] https://stripe.com/docs/payments/save-and-reuse
Our site currently asks customers to provide their CC data every time they put an order. Few days later we charge the card, very often with a different amount than shown during the checkout because of merging orders, changing shipment method and so on.
We'd like to migrate to Stripe, but we'd like not to change the current behaviour. Few questions arose while we read the Stripe docs:
1) Stripe.js allows to create a Source without a customer. This seems ideal for us, but the following text from Stripe docs caught our attention:
A card source must be used within a few minutes of its creation as CVC
information is only available for a short amount of time. Card sources
do not expire, but using them after a delay can result in a charge
request that is performed without CVC information. The consequences of
this can be higher decline rates and increased risk of fraud.
So we shouldn't charge the Source few days later? If so, isn't it also a problem for Sources attached to customers, because their CVCs are forgotten as well?
2) To keep things simple, we'd prefer to avoid creating customers and managing their sources in Stripe. Stripe has the concept of single-use sources, that can be charged without attaching them to customers, but the docs say that the amount is required when they are created. We don't know the exact amount at the checkout process, so could we put a bigger number as an upper limit of what we'll charge in the future and provide the exact amount during charging the source?
So you're correct, the CVC is lost anyway but this is not the point that Stripe is trying to make. When you attach the Source to a customer, Stripe will run a $0 or $1 authorization on the card with the bank to make sure it's valid. This lets them catch expired or invalid cards immediately. This also lets them send the CVC to the bank, since they have it at that point, to catch invalid CVC which is important to combat fraud.
If you were to create a Source and not charge it for a few days, that would technically work. The risk is that when you do charge it, the bank won't see the CVC and won't be able to tell you if it was correct or not, increasing the risk of fraud.
To avoid this, Stripe recommends that you save the Source on a Customer. This is just one extra API request which lets you catch invalid cards immediately. Then, days later, when you create the charge on that customer/source, the bank might still decline it (insufficient funds for example) but you would decrease the risk of charging a bad card and catch issues immediately on tokenization. It's better for you as a business but also better for the customer in case they mistyped their CVC or expiration date, etc.
I've been playing with stripe recently and while i fully understand that the token hides the clients credit card details from the server. This tutorial suggests that the server should not rely on the data-amount since it can be changed by the client
Don’t Rely on the Form’s Price
A frequent mistake stems from using form data to contain the price of
the product being purchased, possibly via a hidden input. Because a
user can easily edit this input’s value, it’s unwise to depend on it.
Always fetch the price of the product from the server-side. Never rely
on the form to tell you. A simple database query is the preferred option.
Can someone explain to be why stripe does not include the data-amount value as a parameter in the token generation? Is there not a potential for a server side code to change the agreed price and overcharge the client.
The token is a placeholder of a pending charge, it does not know how much you are going to charge yet. Once you are ready to charge the card an api request will be sent to Stripe along with the token. The concern about the amount deals with relying on POST data from a form that can be manipulated by the customer.
Its up to you to set the charge amount. For example a hotel could authorize $100 to spend the night but then at check out discover that you used the minibar and then charge $150. Or the auto calculated shipping is off so when you actually purchase the shipping its $5 less and you decide to charge $5 less than your auth.
What you should be doing is calculating the amount to charge the customer, save it via a shopping cart like function in your DB (or serverside somehow) sending the checkout form to the customer then using the previously calculated amount run the auth then the charge.
Form data can easily be changed by the end user. Just open the page and right click (in chrome) and click inspect element. You can then arbitrarily change form data. So if you were using that, the user could set the price to $.01 for your $1,000.00 product.
The propose of tokenization in the PCI world is to keep sensitive data off your servers. Otherwise you would collect the PCI data yourself then send the amount off to the processor along with the PCI data. By not ever having the sensitive data touch your systems you save a ton of money and headache in PCI compliance. See this 115 page document: https://www.pcisecuritystandards.org/documents/PCI_DSS_v3-1.pdf
Hope that helps, Please comment and I'll try to help further if it doesn't.
Is there a way in Stripe to automatically send an email to a customer when their credit card is about to expire?
Great news! There shouldn't be a need to notify the customer about expiration dates (or even replacement cards). Stripe's system automatically handles these changes with Smarter saved cards:
Now, when you save a customer with Stripe, their card will continue to work even if the physical card gets replaced by the bank. Stripe works directly with card networks so that your customers can continue using your service without interruption.
This feature started in early 2015, according to the article's date of 2015-01-21.
In the sense you're looking for the answer is likely no. If you're willing to pay for it, something like Stunning can do this for you. Otherwise I think you'd need to setup something on your system to periodically cycle through your customer database and ping Stripe about the status of any credit cards they have on file to see if any are expiring soon.
As Tyler mentioned, Stripe's Card Updater has changed the game when it comes to expired cards.
However, it won't automatically catch 100% of expiring cards. At best, maybe around 70%, as some international territories and card issuers are not yet covered.
Even so, this has made pre-dunning emails (notifying customers before their card expires) obsolete in the best case, and actively harmful in the worst case...triggering "payment problem" notifications to customers who will never actually have a payment problem. These notifications can burden support teams and cause unnecessary customer involvement & confusion.
If you decide not to send pre-dunning emails (we don't), you definitely do need to send dunning emails (when payments actually do fail) which will catch actual, expired cards missed by Card Updater, as well as other kinds of failures that couldn't have been caught by Card Updater.
This Stripe dunning checklist is useful in building the optimal system on top of Stripe.
Actually, now in stripe settings, you could set up the simple reminder email before the card expiration. It's inside Settings -> Prevent failed payments
No there is no such way. Stunning as mentioned by Dhaulagiri sure is a solution but its not free.
A simple alternative is:
When taking the card info by the users for the first time, add the
field for expiry date (stripe provides validation for it too).
Keep checking the card's expiry date at regular intervals (say
monthly or at the time of charging).
If the card is about to expire (in say a month or by the time of
next charge) handle that case to notify your customer.