Stripe 3DS2 Implementation with jBilling
A practical guide to implementing the 3D Secure 2.0 payment workflow using Stripe's payment gateway with jBilling, covering the three most common use cases for online transactions.
A practical guide to implementing the 3D Secure 2.0 payment workflow using Stripe's payment gateway with jBilling, covering the three most common use cases for online transactions.
In September 2018, the European Union commission made a significant move to enhance online payment security by mandating the 3D Secure Version 2 (abbreviated as 3DS2) for all online payments. This requirement wasn't just another regulatory checkbox. It represented a fundamental shift in how online transactions are authenticated.
To comply with the 3DS2 workflow changes, Stripe introduced new Payment Intents APIs that enable merchants to authenticate card transactions with the 3DS2 workflow. Starting from September 14, 2019, all online card transactions in Europe must be implemented as secured payments using the 3DS2 workflow.
This guide walks you through the technical implementation of Stripe's 3DS2 protocol within jBilling, focusing on three critical use cases that cover the most common scenarios in online transaction processing.
Before diving into implementation, it's helpful to understand what the 3DS2 workflow actually involves. The 3D Secure workflow requires that the payment you trigger online must be validated with an additional PIN or password. Which is not part of the card details itself, but will be received as a One Time Password (OTP) on your mobile or email linked to your card.
When you initiate an online payment with your credit card, the transaction flows through the merchant's portal or website to a backend software system, which is responsible for carrying out the payment transaction using a payment gateway with which the merchant is tied up.
When the gateway receives the transaction, if it determines that authentication is required, it will respond back with a code for authentication. This triggers a user interface page on the merchant's website asking the user to enter an OTP. The user receives the OTP on their mobile and enters it to submit the transaction again.
The gateway then honors the payment request and provides a successful response back to the calling system. If there's any card error or insufficient funds, the gateway would respond back with a failure message.
This is the overall payment workflow in a nutshell. Now, let's look at how this workflow could be implemented with the Stripe gateway. Stripe has evolved as one of the most trusted payment gateways over the last couple of years.
The workflow has been established as an off-the-shelf plugin. This is because jBilling is an off-the-shelf billing engine, but essentially a similar implementation can be replicated for any other billing system or merchant portal that integrates with the Stripe Payment Gateway.
The implementation focuses on three crucial use cases that can be considered the most important when dealing with the online transaction:
The diagram in our implementation focuses on these three use cases, showing the technical layers and systems involved for an online transaction through the merchant's site. Let's explore each use case in detail.
This is a common use case where the user is required to supply their credit card details on the merchant's portal and get it validated and authorized for a payment. There needs to be an optional checkbox to store the card on the profile for future payments; otherwise the card would be used for a one-time payment.
When the card details are supplied on the merchant's portal, the portal would receive card details and create a Payment Intent with the Stripe gateway and pass the Stripe Payment Intent to the user to load using updateStripePaymentMethod. This API method would be available on a base Payment Method.
The jBilling API would delegate the call to the Stripe 3DS2 plugin in jBilling, and the plugin would invoke the Stripe API to store the new payment method on Stripe gateway. When the Stripe gateway receives this request, it would test if the card has not been authenticated before, and would raise an exception authentication required and give this response back to the merchant portal application via the jBilling API method.
The jBilling API would delegate this call to the Stripe 3DS2 plugin and the plugin would invoke Stripe API to store the new payment method on the Stripe gateway. In response to this, the Stripe gateway would send back the Payment Method Id along with the Stripe Customer Id.
The portal would now invoke a user interface that would prompt the user for an OTP. Once the OTP is supplied by the user, the same API in jBilling updateStripePaymentMethod would be invoked by the portal. This time with the Stripe Payment Intent which is created using the same Payment Method.
The Payment Intent is received by jBilling, and through its Stripe 3DS2 plugin, it attempts to validate the charge and gives back a successful response to the jBilling API. In case of any card error or insufficient funds error, this response is given back through the API by providing proper error codes supplied by the gateway.
Once the user has registered their card on the merchant's portal and has completed the 3DS2 authentication, the card is now ready to be utilized and charged for any desired payment. The user may choose to do a payment online while on the session on the portal.
In this case, the merchant portal has two options, it can invoke a jBilling API createPaymentWithStripe in two different ways:
jBilling then combines the payment object and processes the payment via the Stripe 3DS2 plugin. The Stripe 3DS2 plugin first confirms the payment intent with Stripe gateway. This step also gets the gateway know that the payment intent has been confirmed. This would still not complete the payment.
The last step instructed by the plugin would be to capture the payment by sending a capture call on the payment intent. If the capture call is successful, then the payment is taken by the gateway and response is received by the plugin. The recurring billing system can store the response of the successful payment attempt or the response of a failed payment attempt with details like reason for payment failure.
In case of a recurring payment, the payment intent parameters change slightly. The Stripe 3DS2 plugin in this case sends to the Stripe gateway the capture method as automatic and the off-session payment parameter is flagged as true.
This configuration tells the gateway that this is an automatic recurring payment, which is being done off-session (which means there is no live session with a customer). This lets the gateway know that this is an automatic recurring payment, which is being done off-session.
If the payment intent creation call is successful, then the payment is taken by the gateway and response is received by the plugin. The recurring billing system can store the response of the successful payment attempt or the response of a failed payment attempt with details like reason for payment failure.
This automated approach is particularly valuable for subscription-based businesses where manual intervention for each payment would be impractical. The system handles authentication transparently while maintaining security compliance.
When implementing Stripe 3DS2 with jBilling, several technical factors deserve attention:
Proper error handling is crucial. The system needs to gracefully manage scenarios like insufficient funds, card validation errors, network issues, and authentication failures. Each error type should be logged and communicated appropriately to the user.
The authentication flow requires careful session management. Payment intents have a limited lifetime, and the system must handle timeout scenarios while ensuring security isn't compromised.
While security is critical, user experience shouldn't be sacrificed. The OTP entry interface should be intuitive, provide clear instructions, and offer helpful error messages when authentication fails.
Stripe provides test cards for various 3DS2 scenarios. Comprehensive testing across all three use cases is essential before going live to ensure smooth operation in production.
EarnBill provides a cohesive implementation of Stripe's 3DS2 specification using jBilling as the billing engine. The implementation is available as an off-the-shelf plugin. The plugin can be incorporated along with jBilling's core billing engine to provide the recurring payment support, along with the API based capabilities that are essential for integrating with your portal or other in-house billing systems.
Implementing 3DS2 compliance doesn't have to be a daunting task. With the right approach and tools, you can enhance your payment security while maintaining a smooth customer experience. The three use cases covered here address the vast majority of online payment scenarios, providing a solid foundation for PSD2 compliance.
Whether you're adding payment functionality to a new portal or updating an existing system to meet regulatory requirements, understanding these implementation patterns will help you build a powerful, secure, and user-friendly payment infrastructure.
The key is to approach implementation systematically, test thoroughly, and always keep the end-user experience in mind while maintaining the highest security standards.
Our team has extensive experience implementing secure payment workflows across various billing systems. We can help you implement Stripe 3DS2 or integrate other payment gateways with your platform.
Get in Touch →