Switching to Stripe.js

If you're not already using Stripe.js, it takes only a few minutes to switch. Just make a few changes to your payment form and server-side Stripe code to reduce your compliance requirements. If you need help after reading this, check out our answers to common questions or chat live with other developers in #stripe on freenode.

Your payment form

First, we’ll make a few changes to your payment form. Let’s take a stripped-down example form that isn’t using Stripe.js:

<form action="" method="POST" id="payment-form">
  <!-- No Stripe.js used; more compliance requirements =( -->
  <input name="number"/>
  <input name="cvc"/>
  <input name="exp-month"/>
  <input name="exp-year"/>
  <button type="submit">Submit Payment</button>

We need to convert this form so that it no longer POSTs card details to your server. We’ll do this by including Stripe.js in the page and replacing the name attributes with data-stripe attributes. Removing the name attributes on our inputs is especially important so we prevent sensitive card data from being POSTed to our server. Now our sample form looks like this:

  <!-- Stripe.js used; fewer compliance requirements! -->
  <!-- Include Stripe.js, either in your <head> or as a direct descendant of <body>
  at the end of the page -->
  <script type="text/javascript" src="https://js.stripe.com/v2/"></script>

<!-- Now change all the name attributes on your credit card inputs to data-stripe instead -->
  <form action="" method="POST" id="payment-form">
      <!-- Add a section to display errors if you want -->
      <span class='payment-errors'></span>
      <input data-stripe="number"/>
      <input data-stripe="cvc"/>
      <input data-stripe="exp-month"/>
      <input data-stripe="exp-year"/>
      <button type="submit">Submit Payment</button>

Now, we just add another script section in our <head> to ask Stripe.js to send our card details to Stripe and get back a token:

  <script type="text/javascript" src="https://js.stripe.com/v2/"></script>
  <!-- jQuery is used only for this example; it isn't required to use Stripe -->
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

  <!-- New section -->
  <script type="text/javascript">
    // Fill in your publishable key

    var stripeResponseHandler = function(status, response) {
      var $form = $('#payment-form');

      if (response.error) {
        // Show the errors on the form
        $form.find('button').prop('disabled', false);
      } else {
        // token contains id, last4, and card type
        var token = response.id;
        // Insert the token into the form so it gets submitted to the server
        $form.append($('<input type="hidden" name="stripeToken" />').val(token));
        // and re-submit

    jQuery(function($) {
      $('#payment-form').submit(function(e) {
        var $form = $(this);

        // Disable the submit button to prevent repeated clicks
        $form.find('button').prop('disabled', true);

        Stripe.card.createToken($form, stripeResponseHandler);

        // Prevent the form from submitting with the default action
        return false;

In the example code, you’ll first set your publishable key, which you can find in your dashboard. Then you add an event handler to capture the form submit event and make a call to Stripe.card.createToken, which does the work of sending card details to Stripe and waiting for a token or error in response. Note that we use jQuery in our example, but it’s not required. If you’re interested in more line-by-line detail on the example code, see our form tutorial and full Stripe.js docs.

On your server

Great, now your payment form isn’t POSTing card details to your server! Once you verify that, all that’s left is a super simple change in your server code that’s handling the data from your payment form. Let’s look at an example of what your server-side code might look like before you switched to using Stripe.js on the client:

# Not using Stripe.js; server is seeing raw card details
Stripe.api_key = 'YOUR_SECRET_KEY'
charge = Stripe::Charge.create(
  :amount => 1000,
  :currency => "usd",
  :card => {
    # Params previously posted directly from your old, non-Stripe.js payment form
    :number => params[:number],
    :cvc => params[:cvc],
    :exp_month => params[:exp_month],
    :exp_year => params[:exp_year]

This example is Ruby, but the concept is the same no matter what library you’re using: you’ll see that you’re passing card details as a hash that consists of full untokenized parameters POSTed from your form. Now that we’re no longer sending these untokenized numbers and other card details, we just need to make a quick change to how we pass the card:

# Now with Stripe.js; server only gets a token!

Stripe.api_key = 'YOUR_SECRET_KEY'

charge = Stripe::Charge.create(
  :amount => 1000,
  :currency => "usd",
  :card => params[:stripeToken] # replace full card details with the string token from our params

All we did is switch out the card details for the stripeToken param we’re now getting from our form. That’s it! You’re now using Stripe.js to make sure your servers never see card details.

Next steps

By using Stripe.js you’ve made meeting your compliance requirements much easier. You now just need to make sure you’re using SSL.