Migrating to Stripe ElementsDeprecated guide
Follow our up-to-date guide on using Elements to build a custom payment flow.
If you’re already migrating to Payment Intents, feel free to continue using this guide as a first step towards upgrading your client-side integration.
If you’re using Stripe.js v2 to securely collect card information, you’ve needed to build and configure your own input fields, validation, and formatting when creating your payment form. With Stripe Elements, our prebuilt UI components, this is all handled by Stripe. Elements is fully customizable and seamlessly integrates into your checkout flow.
Using Elements, you can create UI components and insert them into your payment form. These components securely collect card information from your customers. When the payment form is submitted, the information is passed directly to Stripe. If you’re using the Charges API, a Token
is returned that is then used to make a charge request or save the payment details for later. If you’re using the Payment Intents API, you can directly call confirmCardPayment to complete the payment or use createPaymentMethod to retrieve a Payment Method that can be passed to your server.
Migrating to Elements requires the following steps:
- Initial setup of Elements
- Convert your existing payment form
- Securely collect card information
- Handle events and errors
- Customize style and formatting
Initial setup of Elements
Include the following script in the head section on every page on your site. This script must always load directly from js.stripe.com to remain PCI compliant. You can’t include the script in a bundle or host a copy of it yourself.
<script src="https://js.stripe.com/v3/"></script>
If you need to use both versions of Stripe.js for some period of time, they can be loaded and used on the same page. For example:
<script src="https://js.stripe.com/v2/"></script> <script src="https://js.stripe.com/v3/"></script>
Convert your existing payment form
At the moment, your existing payment form might look something like this:
<form action="/charge" method="post" id="payment-form"> <div class="card-errors"></div> <div class="form-row"> <label> <span>Card number</span> <input type="text" size="20" data-stripe="number"> </label> </div> <div class="form-row"> <label> <span>Expiration (MM/YY)</span> <input type="text" size="2" data-stripe="exp_month"> </label> <span> / </span> <input type="text" size="2" data-stripe="exp_year"> </div> <div class="form-row"> <label> <span>CVC</span> <input type="text" size="4" data-stripe="cvc"> </label> </div> <div class="form-row"> <label> <span>Billing Zip</span> <input type="text" size="6" data-stripe="address_zip"> </label> </div> <input type="submit" class="submit" value="Submit Payment"> </form>
To use Elements, you create empty DOM elements (containers) instead of directly using DOM <input>
s. Elements inserts a Stripe-hosted UI component within your container. Migrating to Elements allows you to make use of the card Element. This flexible UI component simplifies your form by minimizing the number of fields you need, requiring much less markup.
<form action="/charge" method="post" id="payment-form"> <div class="form-row"> <label for="card-element"> Credit or debit card </label> <div id="card-element"> <!-- a Stripe Element will be inserted here. --> </div> <!-- Used to display form errors --> <div id="card-errors" role="alert"></div> </div> <input type="submit" class="submit" value="Submit Payment"> </form>
Next, initialize the Stripe client by providing your publishable API key, and create an instance of Elements.
var stripe = Stripe(
); var elements = stripe.elements();'pk_test_TYooMQauvdEDq54NiTphI7jx'
You can now create a card Element and add it to your page using the mount()
method.
var card = elements.create('card'); // Add an instance of the card UI component into the `card-element` <div> card.mount('#card-element');
Use the available style options of Elements when customizing the design of your payment form. You can also apply custom CSS to the container DOM element. No CSS styles should be applied directly to anything Elements inserts inside your container DOM element. Style the container DOM element instead.
This example uses the card
Element type to collect all card information using a single Element. Stripe recommends that you use the card
Element, but you can also use individual cardNumber
, cardCvc
, and cardExpiry
Elements. See the Stripe.js reference for details.
Securely collect card details
Using Elements to collect payment information is very similar to your current approach. The difference is that you’re passing a Stripe Element to the appropriate method, rather than a form or set of input fields.
Your current payment form submission might look like this:
var stripeResponseHandler = function(status, response) { // Grab the form: var form = document.getElementById('payment-form'); if (response.error) { // Problem! // Show the errors on the form: } else { // Token was created! // Get the token ID: var token = response.id; // Insert the token ID into the form so it gets submitted to the server var form = document.getElementById('payment-form'); var hiddenInput = document.createElement('input'); hiddenInput.setAttribute('type', 'hidden'); hiddenInput.setAttribute('name', 'stripeToken'); hiddenInput.setAttribute('value', token); form.appendChild(hiddenInput); // Submit the form form.submit(); } }; // Create a token when the form is submitted var form = document.getElementById('payment-form'); form.addEventListener('submit', function(e) { e.preventDefault(); Stripe.card.createToken(form, stripeResponseHandler); });
Switching to Elements requires two key changes:
- Pass the createToken() method a Stripe Element as its first argument (instead of a form or values)
- Use the Elements API to simplify the response handling logic
function stripeTokenHandler(token) { // Insert the token ID into the form so it gets submitted to the server var form = document.getElementById('payment-form'); var hiddenInput = document.createElement('input'); hiddenInput.setAttribute('type', 'hidden'); hiddenInput.setAttribute('name', 'stripeToken'); hiddenInput.setAttribute('value', token.id); form.appendChild(hiddenInput); // Submit the form form.submit(); } function createToken() { stripe.createToken(card).then(function(result) { if (result.error) { // Inform the user if there was an error var errorElement = document.getElementById('card-errors'); errorElement.textContent = result.error.message; } else { // Send the token to your server stripeTokenHandler(result.token); } }); }; // Create a token when the form is submitted. var form = document.getElementById('payment-form'); form.addEventListener('submit', function(e) { e.preventDefault(); createToken(); });
Handle events and errors
Elements includes real-time input validation that helps facilitate your users’ checkout flow, increasing conversion. If you’re not doing any validation today, you can just rely on the default visual validation indicators of Elements to alert users of errors.
Elements also provides specific information about validation errors in real-time, helping you communicate them to your users.
Customize style and formatting
Elements comes with built-in formatting and masking for all inputs. If you have been using Stripe’s jquery.payment
library or something that you have built in-house, you should be able to safely remove these from your integration.
Card elements can be customized to fit perfectly within your checkout page. For instance, you can make sure that the font is styled correctly by providing some additional options when creating the component:
var stripe = Stripe(
); var elements = stripe.elements(); // Create an instance of the card UI component var card = elements.create('card', { 'style': { 'base': { 'fontFamily': 'Arial, sans-serif', 'fontSize': '8px', 'color': '#C1C7CD', }, 'invalid': { 'color': 'red', }, } }); // Mount the UI card component into the `card-element` <div> card.mount('#card-element');'pk_test_TYooMQauvdEDq54NiTphI7jx'
You can find a full list of supported CSS properties that can be used as style
parameters in our Stripe.js reference documentation.
Next steps
Now you have all the information you need to migrate from Stripe.js v2 to Stripe Elements. To learn more, continue reading: