Implementing Stripe 3D Secure to de-risk online payments
Right now, Stripe is arguably one of the best available options for companies wanting to take online payments from their customers. At Red River we’ve completed a number of Stripe implementations for our own customers and following the most recent one, I started thinking about security. In particular I wondered whether we needed to add a 3D Secure implementation.
Why should you add 3D Secure to your system? Well, 3D Secure provides a layer of protection against fraudulent payments that is supported by most card issuers. From the merchant’s point of view it not only reduces the risk of fraud but also shifts the liability for any chargebacks from the merchant to the card issuer.
On first floating the idea, the initial response I got was “Stripe doesn’t support 3D Secure” – and last time we used Stripe in a project it didn’t. However that’s now changed and 3D Secure is now supported by Stripe.
Step 1 – Setup
I’m assuming that you’ve already got an implementation of Stripe within your system but if not, go here. Generate a public/secret API key using your Stripe account (you can do this by logging into your account and going to the Stripe API keys page). From this setup we will get:
A Stripe object named stripe
A reference to our card element – card
Because we will be dealing with webhooks we need a way to test our API webhooks locally and we’ll do this with the help of ngrok to create a tunnel to our local server. This is a simple process.
- Install ngrok – you can get it from here
- Add a type and port to your API site bindings in IIS (e.g. http, 43865)
- Open a command window and run the following command:
ngrok http 43865
ngrok will generate a url (e.g. http://b6f54a55.ngrok.io) for tunneling to our API and route any requests to it.
We are now ready to add 3D Secure support.
Step 2 – Determine the Card Type
There are four types of 3D Secure card type: Required, Recommended, Optional and Not Supported. We are going to focus on Required cards only in this instance, all other card types will follow the regular transaction process. We begin by creating a stripe source as normal, and then we test the three_d_secure type on the returned source.
Step 3 – Perform 3D Secure Authentication
In our 3D Secure handler we’re going to call stripe.createSource again, but this time with an object of type “three_d_secure”, the transaction amount and the id of the original card source. We’re also going to have a url to redirect to once the user has entered their 3D Secure information.
Step 4 – Implement the Webhook API
Because 3D Secure authentication takes place asynchronously, the user is immediately redirected to the return url above and we have to wait for the authentication process to complete. When the process completes, Stripe will send a webhook event via an HTTP POST request to inform us of this.
In Stripe we need to add the url for webhook API and the types of event that it can process. To do this we:
- Go to https://dashboard.stripe.com/account/webhooks and click the
- Add the url to our API method (remember that we’re using the generated ngrok url for testing) http://b6f54a55.ngrok.io/api/stripe/stripe3dsecurewebhook
Select the types of event which we want to see by selecting
Select types to send and choosing the following events:
The Stripe3DSecureChargeableWebhookEvent is included here. To get the file I took the JSON from the Stripe test authentication page and ran it through a JSON to C# converter.
Step 5 – Charge the Card
When we receive the webhook POST request we know whether the card is chargeable and at this point we can charge the card and inform the user. We’re calling this method from our webhook above.
The payment service checks the chargeable status and then calls the Stripe service to charge the card.
The Stripe service is only used to talk to Stripe.
So there you have it. There are one or two quirks, but otherwise implementing Stripe 3D Secure is quite a straightforward process – and well worth considering if you’re concerned about de-risking online payments.