Skip to content

Tokenizer

Tokenizer is a JavaScript library that injects a secure, hosted payment form into your website via an iframe. When a customer enters their card or bank account details, the information goes directly to our PCI-compliant servers—never touching your website—and you receive a token in return.

This token can then be used in place of the actual payment details for any API call, keeping your website out of PCI scope while giving you full control over the payment flow.

Tokenizer in action

Simple Example

A complete, working payment form in a single HTML file:

html
<!DOCTYPE html>
<html>
  <head>
    <title>Checkout</title>
    <script src="https://sandbox.gosparrowone.com/tokenizer/tokenizer.js"></script>
  </head>
  <body>
    <h1>Checkout</h1>
    <div id="payment-form"></div>
    <button onclick="tokenizer.submit()">Pay</button>

    <script>
      var tokenizer = new Tokenizer({
        url: 'https://sandbox.gosparrowone.com',
        apikey: 'pub_XXXXXXXXXXXXXX',
        container: '#payment-form',
        submission: function(resp) {
          if (resp.status === 'success') {
            // Send token to your server to complete payment
            // Token is valid for 2 minutes
            console.log('Token:', resp.token)
          }
        }
      })
    </script>
  </body>
</html>

That's it. The iframe renders a secure card form, and when the customer clicks "Pay", you receive a token to send to your server.

Why Use Tokenizer?

Without TokenizerWith Tokenizer
Card numbers pass through your serverCard numbers go directly to the gateway
Your site is in PCI scope (SAQ D)Your site stays out of PCI scope (SAQ A)
You must secure and audit your entire infrastructureSecurity burden shifts to the gateway
Complex compliance requirementsSimplified compliance

How It Works

Step-by-Step

  1. Page loads — Your checkout page includes the Tokenizer script
  2. Iframe appears — Tokenizer creates a secure iframe (hosted by us, not you)
  3. Customer types card info — Card data goes into the iframe, never your code
  4. You call submit() — Iframe sends card data directly to our servers
  5. You get a token — We return a token (good for 2 min) to your callback
  6. Your server charges it — Use the token in your API call instead of the card number

Token Expiration

Tokens expire after 2 minutes. Complete your API call right away.

Data Flow

DataWhere It Goes
Card number, CVV, expirationDirectly to the gateway via iframe (never touches your server)
TokenReturned to your JavaScript callback, then sent to your server
Name, address, email, phonePassed through to your callback (not tokenized, not sent to gateway until you make an API call)

Steps

1. Add Script

Load the Tokenizer JavaScript library in your HTML <head> or bottom of the body. This script provides the Tokenizer class that creates the secure payment form.

html
<head>
  <script src="https://sandbox.gosparrowone.com/tokenizer/tokenizer.js"></script>
</head>

2. Add Element

Add a container element where the payment form will render, plus a button to trigger submission. The container can be any element with an ID or class selector.

html
<!-- Tokenizer injects the secure iframe in here -->
<div id="payment-form"></div>

<!-- Your submit button triggers tokenization -->
<button onclick="tokenizer.submit()">Pay Now</button>

3. Initialize

Create a new Tokenizer instance with your configuration. The minimum required options are apikey, container, and a submission callback.

javascript
var tokenizer = new Tokenizer({

  // Your public API key (from Control Panel → Settings → API Keys)
  apikey: 'pub_XXXXXXXXXXXXXX',

  // CSS selector where the iframe will be injected
  container: '#payment-form',

  // Callback when tokenizer.submit() completes
  submission: (resp) => {

    // Token generated successfully
    if (resp.status === 'success') {
      console.log('Token:', resp.token)
      sendTokenToServer(resp.token)
    }

    // Form validation failed (empty or invalid fields)
    else if (resp.status === 'validation') {
      console.log('Invalid fields:', resp.invalid)
    }

    // Error occurred (network, invalid API key, etc.)
    else {
      console.log('Error:', resp.msg)
    }
  }
})

4. Use Token

Once your frontend receives the token, send it to your backend server. Your server then makes the actual API call using your secret key (never expose this in frontend code).

Frontend: Send token to your server

javascript
function sendTokenToServer(token) {
  fetch('/api/charge', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      token: token,
      amount: 1999  // $19.99 in cents
    })
  })
  .then(response => response.json())
  .then(data => {
    if (data.success) {
      window.location.href = '/thank-you'
    }
  })
}

Backend: Process the transaction

Your server receives the token and calls the gateway API with your secret key:

json
{
  "type": "sale",
  "amount": 1999,
  "payment_method": {
    "token": "the-token-from-tokenizer"
  }
}

See Transaction Processing for complete API documentation.

Public vs Secret Keys

  • Public key (pub_XXXX) — Used in Tokenizer on your frontend. Safe to expose in browser code.
  • Secret key — Used for server-side API calls. Never expose in frontend code.

Token Expiration

Tokens expire after 2 minutes. Complete your API call immediately after receiving the token.

Default Output

Default


Configuration

Local Dev

When developing locally, set the url option to point to the API:

javascript
var tokenizer = new Tokenizer({
  url: 'https://sandbox.gosparrowone.com',  // Required for localhost
  apikey: 'pub_XXXXXXXXXXXXXX',
  container: '#payment-form',
  submission: (resp) => { console.log(resp) }
})

API Key URL Restrictions

If your public API key has URL restrictions, add both your website URL and the url you set in Tokenizer to the allowed list. The iframe makes requests from the configured URL.

Payments

Tokenizer supports credit/debit cards and ACH. By default, only card is enabled.

javascript
var tokenizer = new Tokenizer({
  apikey: 'pub_XXXXXXXXXXXXXX',
  container: '#payment-form',
  submission: (resp) => { console.log(resp) },
  settings: {
    payment: {
      types: ['card', 'ach'],  // Enable both card and ACH
      card: {
        requireCVV: true,           // Require CVV entry
        strict_mode: false,         // Set true for 19-digit cards
        mask_number: true           // Mask card number as user types
      },
      ach: {
        sec_code: 'web',            // Default SEC code: web, ccd, ppd, tel
        showSecCode: false,         // Show SEC code dropdown to user
        verifyAccountRouting: true  // Validate routing numbers
      }
    }
  }
})

Extra Fields

Tokenizer can collect billing, shipping, and user information alongside payment details. This data is not tokenized—it's passed through to your callback for you to use in API calls.

javascript
var tokenizer = new Tokenizer({
  apikey: 'pub_XXXXXXXXXXXXXX',
  container: '#payment-form',
  submission: (resp) => {
    console.log(resp.token)     // Tokenized payment data
    console.log(resp.user)      // Name, email, phone (if enabled)
    console.log(resp.billing)   // Billing address (if enabled)
    console.log(resp.shipping)  // Shipping address (if enabled)
  },
  settings: {
    user: {
      showName: true,
      showEmail: true,
      showPhone: true,
      showTitle: true,
      showInline: true
    },
    billing: {
      show: true,
      showTitle: true
    },
    shipping: {
      show: true,
      showTitle: true
    }
  }
})

Fees

Automatically calculate surcharges or service fees based on the payment type and processor:

javascript
var tokenizer = new Tokenizer({
  apikey: 'pub_XXXXXXXXXXXXXX',
  container: '#payment-form',
  amount: 2500,  // Base amount in cents ($25.00)
  settings: {
    payment: {
      calculateFees: true,
      processorId: 'optional-processor-id'  // Uses default if not specified
    }
  },
  validCard: (card) => {
    // Called when a valid card is entered
    console.log('Service Fee:', card.ServiceFee)
    console.log('Surcharge:', card.Surcharge)
    console.log('Disclosure:', card.Disclosure)  // Text to show cardholder
  },
  submission: (resp) => { console.log(resp) }
})

Callbacks

CallbackWhen It FiresUse Case
submissionAfter submit() completesHandle token, errors, or validation failures
onLoadIframe finished loadingShow loading spinner until ready
onPaymentChangeUser switches between card/ACHUpdate UI or fee display
validCardValid card number enteredDisplay card type, check surchargeability, show fees
achOnChangeACH account type or SEC code changesUpdate UI based on ACH selection
magStripeSwipeCard swipe detectedHandle card reader input

Submission

javascript
submission: (resp) => {
  switch(resp.status) {
    case 'success':
      // Token generated successfully
      sendToServer(resp.token)
      break
    case 'validation':
      // Form validation failed - show errors to user
      resp.invalid.forEach(field => {
        console.log('Invalid field:', field)
      })
      break
    case 'error':
      // Server error occurred
      console.log('Error:', resp.msg)
      break
  }
}

Valid Card

javascript
validCard: (card) => {
  console.log(card.isValid)  // true if passes Luhn check
  console.log(card.bin)      // BIN data (card type, issuer, etc.)

  // If calculateFees is enabled:
  console.log(card.RequestedAmount)     // Base transaction amount
  console.log(card.ServiceFee)          // Service fee to add
  console.log(card.Surcharge)           // Surcharge amount
  console.log(card.PaymentAdjustment)   // { value, type }
  console.log(card.Disclosure)          // Surcharge disclosure text

  // Check if card is surchargeable in a specific state
  var canSurcharge = tokenizer.isSurchargeable('IL', card.bin)
}

Methods

MethodDescription
tokenizer.submit()Submit the form and generate a token
tokenizer.submit('5.00')Submit with amount (required for 3DS/Paay)
tokenizer.setError('cvv')Highlight a field as invalid
tokenizer.setExpDate('12/25')Programmatically set expiration date
tokenizer.isSurchargeable(state, bin)Check if card can be surcharged

Styling

Pass CSS styles to customize the iframe's appearance:

javascript
var tokenizer = new Tokenizer({
  apikey: 'pub_XXXXXXXXXXXXXX',
  container: '#payment-form',
  submission: (resp) => { console.log(resp) },
  settings: {
    styles: {
      body: {
        color: '#333333'
      },
      input: {
        'border-radius': '4px',
        'border': '1px solid #cccccc',
        'padding': '10px',
        'font-size': '16px'
      },
      'input:focus': {
        'border-color': '#0066cc',
        'outline': 'none'
      },
      '.payment .cvv input': {
        'width': '80px'
      }
    }
  }
})

Inspecting Elements

Use your browser's developer tools to inspect the iframe and identify CSS selectors for styling specific elements.

Examples

Default

Default

Dark Mode

Dark Mode

Purple

Purple


Advanced

3DS (Paay)

If 3DS is enabled on your account, Tokenizer handles authentication automatically:

javascript
var tokenizer = new Tokenizer({
  apikey: 'pub_XXXXXXXXXXXXXX',
  container: '#payment-form',
  submission: (resp) => {
    console.log(resp.paay)  // 3DS authentication results
  },
  settings: {
    paay: {
      sandbox: false,        // Use sandbox for testing
      forceDisabled: false,  // Set true to skip 3DS
      rejectChallenges: []   // Statuses to reject
    }
  }
})

// Amount is required for 3DS (otherwise runs as Non-Payment Authentication)
tokenizer.submit('25.00')

Card Readers

Tokenizer automatically detects card swipe input when the card number field is focused. The magStripeSwipe callback fires when a swipe is detected.

SPAs

For single page applications, Tokenizer outputs as UMD. Import it in your main file:

javascript
import './tokenizer.js'

// Now available globally
new Tokenizer({
  apikey: 'pub_XXXXXXXXXXXXXX',
  container: '#payment-form',
  submission: (resp) => { console.log(resp) }
})

Examples

Sale

See Transaction Processing for more details.

Add to Vault


Integrations

Konnektive

When using Tokenizer with Konnektive CRM, submit the token in the formCardNonce field to their Order Import API.


Troubleshooting

IssueSolution
Iframe not loadingVerify the container element exists before initializing Tokenizer
Token request fails on localhostSet the url option to your API endpoint
API key errorEnsure you're using a public key (pub_XXXX), not your secret key
Token expiredTokens last 2 minutes—complete your API call immediately after receiving it
Styles not applyingInspect the iframe to find correct CSS selectors
URL restriction errorAdd both your site URL and the Tokenizer url to your API key's allowed URLs