<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ 3ds - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ 3ds - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 24 May 2026 22:25:26 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/3ds/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to implement 3DS2 with Stripe for SCA compliance under PSD2 in Europe ]]>
                </title>
                <description>
                    <![CDATA[ By Ben Sears What are PSD2, SCA, and 3DS? PSD2 The second Payment Services Directive (PSD2) is an EU directive announced in 2015. The goal of PSD2 is to protect people when they pay online, promote open banking, and make cross-border European payment... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/implement-3ds2-for-your-saas-using-stripe-billing-and-be-sca-compliant-for-pds2/</link>
                <guid isPermaLink="false">66d45de0d7a4e35e38434949</guid>
                
                    <category>
                        <![CDATA[ 3DS2 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ psd2 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ 3ds ]]>
                    </category>
                
                    <category>
                        <![CDATA[ node ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ SCA ]]>
                    </category>
                
                    <category>
                        <![CDATA[ stripe ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 18 Oct 2019 20:27:18 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/10/BLOG_002_Implement-3DS2-for-your-SaaS-using-Stripe-Billing-and-be-SCA-compliant-for-PDS2.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ben Sears</p>
<h1 id="heading-what-are-psd2-sca-and-3ds"><strong>What are PSD2, SCA, and 3DS?</strong></h1>
<h2 id="heading-psd2"><strong>PSD2</strong></h2>
<p>The second Payment Services Directive (PSD2) is an EU directive announced in 2015. The goal of PSD2 is to protect people when they pay online, promote <a target="_blank" href="https://en.wikipedia.org/wiki/Open_banking">open banking</a>, and make cross-border European payment services safer. It went into effect September of 2019.</p>
<h2 id="heading-sca"><strong>SCA</strong></h2>
<p>Strong Customer Authentication (SCA) is a <a target="_blank" href="https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=uriserv:OJ.L_.2018.069.01.0023.01.ENG&amp;toc=OJ:L:2018:069:TOC">requirement of the PSD2</a> that ensures online payments are performed with multi-factor authentication to increase the security of online payments. Even though PSD2 was enacted in September of 2019, SCA has been delayed by 18 months to allow merchants and banks more time to implement solutions.</p>
<h2 id="heading-3ds2"><strong>3DS2</strong></h2>
<p>3-D Secure 2.0 (3DS2) is the second iteration of the 3DS, used to power brand-name systems such as <a target="_blank" href="https://usa.visa.com/visa-everywhere/security.html">Visa Secure</a>, <a target="_blank" href="https://www.mastercard.us/en-us/merchants/safety-security/identity-check.html">Mastercard Identity Check</a>, and <a target="_blank" href="https://network.americanexpress.com/globalnetwork/safekey/us/en/">American Express SafeKey</a>. It was designed to reduce fraud and provide added security to online payments and supported by many major banks.</p>
<p>3DS2 is considered an SCA compliant solution. If your business implements 3DS2, you will no longer be in danger of having your charges declined by banks.</p>
<h1 id="heading-does-sca-affect-your-saas-business"><strong>Does SCA affect your SaaS business?</strong></h1>
<p><img src="https://blog.servicebot.io/content/images/2019/10/image-21.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>SCA is considered in-effect on all e-commerce payments when both:</p>
<ul>
<li>The business is in the EU</li>
<li>The customer's bank is in the EU</li>
</ul>
<p>If SCA applies to you and you do not authenticate your customer's transactions you risk <strong>having charges declined by banks</strong>. </p>
<p>There are exemptions for several types of transactions defined in <a target="_blank" href="https://eba.europa.eu/documents/10180/1761863/Final+draft+RTS+on+SCA+and+CSC+under+PSD2+%28EBA-RTS-2017-02%29.pdf">Articles 12-18 of the PSD2</a>. As a SaaS company, the most critical exception to note is <strong>Article 13.</strong> This article states that recurring transactions do not need to be subject to SCA. What this means is that you only need to have an SCA implementation to handle the initial creation of a subscription and not the subsequent recurring charges.</p>
<p>If you are interested in reading a breakdown of the other exemptions and how they may apply to you, <a target="_blank" href="https://stripe.com/guides/strong-customer-authentication#exemptions-to-strong-customer-authentication">Stripe goes into depth on each here</a>.</p>
<h1 id="heading-should-you-be-sca-ready-even-if-you-arent-in-europe"><strong>Should you be SCA-ready even if you aren't in Europe?</strong></h1>
<p>There are benefits to implementing a solution such as 3DS2, even if you aren't affected by PSD2 or SCA. By implementing 3DS2, you will handle customer information in a much more secure manner, as well as shifting liability from you to the card issuer, reducing the risk of chargebacks.</p>
<h1 id="heading-how-do-you-become-sca-compliant"><strong>How do you become SCA compliant?</strong></h1>
<p>Being SCA compliant as a SaaS means that all online payments are authorized using two of the three elements,</p>
<p><img src="https://blog.servicebot.io/content/images/2019/10/image-19.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>As I mentioned before, 3DS2 is an SCA-compliant solution. Drop-in solutions such as <a target="_blank" href="https://servicebot.io">Servicebot</a>, PayPal, and <a target="_blank" href="https://stripe.com/payments/checkout">Stripe Checkout</a> already use 3DS2 and are therefore SCA-compliant. If you are using a custom-built solution using something like Stripe Billing or Braintree to manage your subscriptions, you will need to develop a 3DS2 implementation.</p>
<h1 id="heading-how-do-you-implement-3ds2-using-stripe-billing"><strong>How do you implement 3DS2 using Stripe Billing?</strong></h1>
<p><img src="https://blog.servicebot.io/content/images/2019/10/image-22.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Stripe has created two new objects as part of offering an SCA-compliant solution, PaymentIntent and SetupIntent, to facilitate using 3DS2. A PaymentIntent represents the intent to charge someone and is used as part of a payment authentication flow. SetupIntents are similar to PaymentIntents, but they represent the intent to charge someone's card eventually. You will use SetupIntents if your SaaS has a free trial, or offers a free tier, essentially anywhere a credit card will be charged at a later date.</p>
<h2 id="heading-using-paymentintents"><strong>Using PaymentIntents</strong></h2>
<p>If you are using Stripe Billing to create subscriptions, you are already using PaymentIntents by default. They are created and attached to each invoice for every new subscription. If you want to know if a new subscription requires SCA, you can check the status of the <code>payment_intent</code> on the <code>latest_invoice</code> of the subscription. The object will contain a <code>status</code> of <code>requires_action</code> - Run the following NodeJS code to see it in action.</p>
<h2 id="heading-this-code-creates-a-subscription-that-requires-sca">This code creates a subscription that requires SCA</h2>
<pre>const STRIPE_TEST_SECRET_KEY = "rk_test_3U9s3aPLquPOczvc4FVRQKdo00AhMZlMIE";
let stripe = require("stripe")(STRIPE_TEST_SECRET_KEY);
const sub = await stripe.subscriptions.create({ //creates a SCA-required subscription
    items: [{plan : "plan_FvnU01xoIPrg9l"}], //$300 per month plan without free trial
    customer: "cus_G0juGVZSLskx57",
    default_payment_method: "pm_1FUiR8CISNxwKLmI8uIQDdnv", //This PaymentMethod always requires SCA
    expand: ["latest_invoice.payment_intent"] //we expand the payload to show up the payment intent
});
const paymentIntent = sub.latest_invoice.payment_intent;
console.log(`Subscription Status: ${sub.status}`);
console.log(`PaymentIntent Status: ${paymentIntent.status}`)
console.log(paymentIntent.status === "requires_action" ? "SCA Required" : "No SCA Required");
console.log(sub);
</pre>

<p>Once you know you have a subscription that requires authentication, you can use the PaymentIntent's client_secret on the browser to start a 3DS2 Authentication process using Stripe.js</p>
<h2 id="heading-using-stripejs-handlecardpayment-with-the-paymentintent"><strong>Using Stripe.js handleCardPayment with the PaymentIntent</strong></h2>
<p>Stripe.js has a handy function called <a target="_blank" href="https://stripe.com/docs/stripe-js/reference#stripe-handle-card-payment">handleCardPayment</a>, which takes in a client secret from a payment intent and starts the 3DS2 process to authenticate the payment.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">await</span> stripe.handleCardPayment(<span class="hljs-string">'PAYMENTINTENT_SECRET'</span>);
</code></pre>
<p>You can see this in action here</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/bsears/embed/PooGOLg?editors=1111" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p>Once the customer authenticates, the subscription will move from an <code>incomplete</code> state to an <code>active</code> one, and the customer will be billed successfully.</p>
<h2 id="heading-setupintents"><strong>SetupIntents</strong></h2>
<p>As a SaaS business, you will mostly be interacting with SetupIntents if you are either using a Free-tier or give a Free trial. When someone enters a credit card, for one of these subscriptions, you will see a <code>pending_setup_intent</code> on the <a target="_blank" href="https://stripe.com/docs/api/subscriptions/object#subscription_object-pending_setup_intent">subscription object</a>. The SetupIntent's <code>client_secret</code> should be passed to the front-end so that Stripe.js can start the 3DS2 authentication flow.</p>
<h2 id="heading-using-stripejs-handlecardsetup-with-the-setupintent"><strong>Using Stripe.js handleCardSetup with the SetupIntent</strong></h2>
<p>This is  basically identical to how we handled the PaymentIntent, except we call handleCardSetup instead</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">await</span> stripe.handleCardSetup(<span class="hljs-string">'{SETUP_INTENT_CLIENT_SECRET}'</span>)
</code></pre>
<p>You can see a SetupIntent SCA Flow in action below.</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/bsears/embed/RwwGyYw?editors=1111" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p>Once authentication completes, the customer can be moved to a paid plan later or have their card charged after a free trial is over.</p>
<h1 id="heading-no-code-alternative"><strong>No-code alternative</strong></h1>
<p>If you are looking for an SCA-compliant solution for Stripe Billing without having to deal with the 3DS2 integration development, check out <a target="_blank" href="https://servicebot.io">Servicebot</a>. We provide a drop-in UI for SaaS companies using Stripe, which is SCA-compliant out-of-the-box! Want to see it in action? Check out <a target="_blank" href="https://dashboard.servicebot.io/examples/signup-embed/0">this demo</a> and use the test card <code>4000002760003184</code> (any Expiration and CVC).</p>
<p><a href="https://servicebot.io"><img src="https://i.imgur.com/QJkpyHN.png" width="1600" height="753" alt="QJkpyHN" loading="lazy"></a></p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
