Link Search Menu Expand Document

Collect and Charge Credit Cards with JavaScript

Once you’ve completed this guide, you will have learned how any website or frontend application can use our Elements to collect, store, and use credit card information with the Basis Theory platform. You’ll also have a foundational understanding of how you can use your credit card data with multiple third-parties as if you had a PCI Level 1 system and were able to store the data within your own database.

If you’d like to follow along with this guide from scratch, we suggest creating a new Vanilla JS sandbox using and getting started from there! Want to jump right into our sample app? Find it here!

Using React? Check out the Collect Credit Cards with React Guide.

This guide is for collecting cards using the single CardElement. In case you prefer to have the card number, expiration date and cvc each in separate elements, check the docs on how to use them here or check out our sample app here.

Table of contents

  1. Add Elements to your website
  2. Setup and Use a Token Reactor
  3. Using your new Reactor
  4. Use the reaction data to charge a customer
  5. Use the raw card data whenever you need

Add Elements to your website

To start, you’ll need a new Elements Application with the token:pci:create permission. Click here to create one.

Using our hosted elements, you can collect cards on any webpage you need to, while maintaining the lowest possible PCI compliance level.

    <script src=""></script>
      let card;
      async function submitCard() {    
        const cardToken = await BasisTheory.tokens.create({
          type: 'card',
          data: card

      window.addEventListener("load", async () => {
        await BasisTheory.init(<ELEMENTS_API_KEY>, {
          elements: true

        card = BasisTheory.createElement("card", style);

        await card.mount("#card");

        card.on("change", (e) => {
          const button = document.getElementById("submit_button");
          button.disabled = !e.complete;
    <div class="container">
      <div id="form">
        <div class="row" id="card"></div>
        <button id="submit_button" type="button" onclick="submitCard()">

Setup and Use a Token Reactor

Configure one of our pre-built Reactor Formulas, enabling you to quickly exchange raw card data for a processor token (e.g. Stripe).

To set up a Reactor, head over to our Portal and set up a new Stripe Reactor. If you’re looking for step-by-step guide on how to set up a Reactor, head over to our guide.

Using your new Reactor

To use your Stripe Reactor, you’ll need a server-to-server application with the following permissions token:pci:read:low, token:pci:create and token:pci:use:reactor. Click here to create one.

Once you’ve created your Stripe Reactor, use the reactor_id and your Card token’s ID to exchange for a Stripe token, which you’ll be able to use to charge your customer.

const reactorResponse = await bt.reactors.react(REACTOR_ID, {
  args: {
    card: `{{${}}}`


Now that you have your Stripe Payment Method, you can store this within your own platform and avoid becoming dependent on Basis Theory for your future transactions. As soon as you need a new Stripe Payment Method, just call the /react endpoint for that reactor with your card token id, and you’ll have a newly attached token.

Use the reaction data to charge a customer

Now, you’re able to access the token created by your Reactor. You may be using this for analytical BIN information, fraud analytics, or to charge a card using the processor token you’ve created.

const stripe = require("stripe")(STRIPE_API_KEY);

const paymentIntent = await stripe.paymentIntents.create({
  amount: 1099,
  currency: "usd",
  payment_method: paymentMethodId, // Payment Method from Stripe Reaction in step 2
  confirm: true

return paymentIntent;

Use the raw card data whenever you need

With Basis Theory, we enable the highest level of usability for your card data possible. Is your primary processor down? react with a back-up processor. Soft decline and want to reprocess? react with another processor. Want to understand your customers card analytics? react with a BIN List like Parrot.

Anything is possible when you store your card data with us. To expand your possibilities, just configure a new Reactor.

See it in action

See a sample and the code that drives it below. Want to experience the sandbox yourself? Check it out here. `