Older APIs
Accept a card payment

Accept a payment
Charges API

Accept online payments from U.S. and Canadian customers.

The Charges API is an older payments API that does not handle bank requests for card authentication. Try our new payments APIs and integrations instead.

Use Stripe Elements, our prebuilt UI components, to create a payment form that lets you securely collect a customer’s card details without handling the sensitive data. The card details are then converted to a representative Token that you can safely send to your servers. Your server can use that token to create a charge.

Set up Stripe

First, you need a Stripe account. Register now.

Use our official libraries for access to the Stripe API from your application:

# Available as a gem sudo gem install stripe
# If you use bundler, you can add this line to your Gemfile gem 'stripe'

Create your payment form

To securely collect card details from your customers, Stripe 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.

Set up Stripe Elements

To have Elements available in your webpage, add this script tag in the head of your HTML page:

<script src=""></script>

That script should always be loaded directly from

Create an instance of Elements with the following JavaScript on your payment page:

// Set your publishable key: remember to change this to your live publishable key in production // See your keys here: var stripe = Stripe(
); var elements = stripe.elements();

Once Elements is loaded, you can create an empty DOM container with a unique ID within your payment form wherever you want Elements to add its input field. We recommend placing that 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 a card 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');

The card Element simplifies the form and minimizes the number of required fields by inserting a single, flexible input field that securely collects all necessary card details.

Otherwise, combine cardNumber, cardExpiry, and cardCvc Elements for a flexible, multi-input card form.

Always collect a postal code to increase card acceptance rates and reduce fraud.

The single input card Element automatically collects and sends the customer's postal code to Stripe. If you build your payment form with multi-input card Elements (cardNumber, cardExpiry, cardCvc), add a separate input field for the customer's postal code.

Refer to our Stripe.js reference documentation for a full list of supported Element types.

Create a token

Add an event listener for when your customer submits their card information and use stripe.createToken(card) to tokenize that information:

// 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); } }); });

createToken also accepts an optional second parameter containing additional card 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.

If the object contains a result.token, send it to your server. Otherwise, show the customer an error.

Submit the token to your server

Send the token to your server along with any additional information that has been collected:

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',; form.appendChild(hiddenInput); // Submit the form form.submit(); }

Create a charge with the token

After the client posts the token to your server, you can use it to create a charge. On your server, grab the Stripe token in the POST parameters submitted by your form. From there, it’s one API call to charge the card:

curl \ -u
\ -d amount=999 \ -d currency=usd \ -d description="Example charge" \ -d source=tok_visa

The response from creating a charge will either be a charge or an error with an error code. If the response succeeds, fulfill the customer’s order and show them a success page. Otherwise, show them an error page.

Test your integration

If you can reliably enter a test card in your HTML form, submit it to the server, and see that your server created the charge, then your integration is finished.

Congratulations! You completed a basic payments integration with the Charges API. This API does not support scaling businesses or customers outside of the U.S. and Canada. For more robust and global payments, learn to accept a payment with the Payment Intents API.

See also

You can learn more about Elements and how to save cards with the Charges API.

Was this page helpful?
Questions? Contact us.
Developer tutorials on YouTube.