Collecting Card Details on the Web

    Securely collect sensitive card details, then charge or save the card for later.

    The following guide walks through the creation of this payment form.

    <script src="https://js.stripe.com/v3/"></script>
    
    <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>
    
      <button>Submit Payment</button>
    </form>
    /**
     * The CSS shown here will not be introduced in the Quickstart guide, but shows
     * how you can use CSS to style your Element's container.
     */
    .StripeElement {
      box-sizing: border-box;
    
      height: 40px;
    
      padding: 10px 12px;
    
      border: 1px solid transparent;
      border-radius: 4px;
      background-color: white;
    
      box-shadow: 0 1px 3px 0 #e6ebf1;
      -webkit-transition: box-shadow 150ms ease;
      transition: box-shadow 150ms ease;
    }
    
    .StripeElement--focus {
      box-shadow: 0 1px 3px 0 #cfd7df;
    }
    
    .StripeElement--invalid {
      border-color: #fa755a;
    }
    
    .StripeElement--webkit-autofill {
      background-color: #fefde5 !important;
    See all 31 lines }
    // Create a Stripe client.
    var stripe = Stripe('pk_test_TYooMQauvdEDq54NiTphI7jx');
    
    // Create an instance of Elements.
    var elements = stripe.elements();
    
    // Custom styling can be passed to options when creating an Element.
    // (Note that this demo uses a wider set of styles than the guide below.)
    var style = {
      base: {
        color: '#32325d',
        fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
        fontSmoothing: 'antialiased',
        fontSize: '16px',
        '::placeholder': {
          color: '#aab7c4'
        }
      },
      invalid: {
        color: '#fa755a',
        iconColor: '#fa755a'
      }
    };
    
    // Create an instance of the card Element.
    var card = elements.create('card', {style: style});
    
    // Add an instance of the card Element into the `card-element` <div>.
    card.mount('#card-element');
    
    See all 70 lines // Handle real-time validation errors from the card Element. card.addEventListener('change', function(event) { var displayError = document.getElementById('card-errors'); if (event.error) { displayError.textContent = event.error.message; } else { displayError.textContent = ''; } }); // Handle form submission. var form = document.getElementById('payment-form'); form.addEventListener('submit', function(event) { event.preventDefault(); 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); } }); }); // Submit the form with the token ID. 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(); }

    Try it out using the test card number 4242 4242 4242 4242, a random three-digit CVC number, any expiration date in the future, and a random five-digit U.S. ZIP code.

    Note that ZIP and postal code validation depends on your customer’s billing country. Use our international test cards to experiment with other postal code formats.

    Using Stripe Elements with React? Use react-stripe-elements, our open source library that wraps Stripe Elements in a set of convenient React components.

    Processing payments with Stripe has two parts:

    1. Securely collecting payment details from your customer
    2. Using the collected payment method in a charge request

    You can make use of Stripe Elements, our pre-built UI components, to create a payment form that securely collects your customer’s card information without you needing to handle sensitive card data. The card details are then converted to a representative Token that you can safely send to your servers.

    After setting up Stripe.js and Stripe Elements, collect card details in three steps:

    1. Create your payment form
    2. Create a token to securely transmit card information
    3. Submit the token and the rest of your form to your server

    Step 1: Create your payment form

    To securely collect card details from your customers, Elements creates UI components for you that are hosted by Stripe. They are then placed into your payment form, rather than you creating them directly.

    To determine where to insert these components, create empty DOM elements (containers) with unique IDs within your payment form. We recommend placing your container within a <label> or next to a <label> with a for attribute that matches the unique id of the Element container. By doing so, the Element automatically gains focus when the customer clicks on the corresponding label.

    For example:

    <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 Element errors. -->
        <div id="card-errors" role="alert"></div>
      </div>
    
      <button>Submit Payment</button>
    </form>

    When the form above has loaded, create an instance of an Element and mount it to the Element container created above:

    // Custom styling can be passed to options when creating an Element.
    var style = {
      base: {
        // Add your base input styles here. For example:
        fontSize: '16px',
        color: "#32325d",
      }
    };
    
    // Create an instance of the card Element.
    var card = elements.create('card', {style: style});
    
    // Add an instance of the card Element into the `card-element` <div>.
    card.mount('#card-element');
    // Custom styling can be passed to options when creating an Element.
    const style = {
      base: {
        // Add your base input styles here. For example:
        fontSize: '16px',
        color: "#32325d",
      },
    };
    
    // Create an instance of the card Element.
    const card = elements.create('card', {style});
    
    // Add an instance of the card Element into the `card-element` <div>.
    card.mount('#card-element');

    The card Element simplifies the form and minimizes the number of fields required by inserting a single, flexible input field that securely collects all necessary card details. Refer to our Stripe.js reference documentation for a full list of Element types that are supported.

    Elements validates user input as it is typed. To help your customers catch mistakes, you should listen to change events on the card Element and display any errors:

    card.addEventListener('change', function(event) {
      var displayError = document.getElementById('card-errors');
      if (event.error) {
        displayError.textContent = event.error.message;
      } else {
        displayError.textContent = '';
      }
    });
    
    card.addEventListener('change', ({error}) => {
      const displayError = document.getElementById('card-errors');
      if (error) {
        displayError.textContent = error.message;
      } else {
        displayError.textContent = '';
      }
    });

    Step 2: Create a token to securely transmit card information

    The payment details collected using Elements can then be converted into a token. Create an event handler that handles the submit event on the form. The handler sends the fields to Stripe for tokenization and prevents the form’s submission (the form is submitted by JavaScript in the next step).

    // Create a token or display an error when the form is submitted.
    var form = document.getElementById('payment-form');
    form.addEventListener('submit', function(event) {
      event.preventDefault();
    
      stripe.createToken(card).then(function(result) {
        if (result.error) {
          // Inform the customer that 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 or display an error when the form is submitted.
    const form = document.getElementById('payment-form');
    form.addEventListener('submit', async (event) => {
      event.preventDefault();
    
      const {token, error} = await stripe.createToken(card);
    
      if (error) {
        // Inform the customer that there was an error.
        const errorElement = document.getElementById('card-errors');
        errorElement.textContent = error.message;
      } else {
        // Send the token to your server.
        stripeTokenHandler(token);
      }
    });

    Call createToken and pass it the card element. The function also accepts an optional second parameter containing additional payment information collected from the customer, which is not used in this example. The function returns a Promise which resolves with a result object. This object has either:

    • result.token: a Token was created successfully.
    • result.error: there was an error. This includes client-side validation errors. Refer to the API reference for all possible errors.

    Step 3: Submit the token and the rest of your form to your server

    The last step is to submit the token, along with any additional information that has been collected, to your server.

    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();
    }
    const stripeTokenHandler = (token) => {
      // Insert the token ID into the form so it gets submitted to the server
      const form = document.getElementById('payment-form');
      const 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();
    }

    Viewport meta tag requirements

    In order to provide a great user experience for 3D Secure on all devices, you should set your page’s viewport width to device-width with the the viewport meta tag. There are several other viewport settings, and you can configure those based on your needs. Just make sure you include width=device-width somewhere in your configuration.

    For instance the following will work with Elements:

    <meta name="viewport" content="width=device-width, initial-scale=1" />

    If you already have this tag on your page and it includes width=device-width, then you are all set.

    Next steps

    Now you have a complete iOS integration built with the Charges API and tokenization. Next, create a charge.

    Was this page helpful?

    Thank you for helping improve Stripe's documentation. If you need help or have any questions, please consider contacting support.

    Questions?

    We're always happy to help with code or other questions you might have. Search our documentation, contact support, or connect with our sales team. You can also chat live with other developers in #stripe on freenode.

    On this page