neonpay.js

v3.2

neonpay.js is used to provide client-side tokenization of credit card data for NeonPay. In this guide, we explain how to implement this in your web application.

New Feature:
- Add Chariot integration to support DAF Donations

Quick Start


Generate a public API key for your app in NeonPay

As a application administrator, you can generate and revoke public API keys from the Developer Tools page in the NeonPay portal. This public API key is different from the private API key you use to access the NeonPay Charge API.

When starting development, you will need a public API key from NeonPay Sandbox (https://sandbox.neononepay.com/) to develop against the development version of the tokenization library.

For your production script, you will need a public API key from NeonPay (https://app.neononepay.com/)

Sample Script

We strongly recommend that you include fields in your payment form to collect your customer’s first name, last name, and address. Once you have that information collected, you can pass it as part of the tokenData parameter in .createToken() API method to create a more complete payment token.

Quickstart Example
<form id="paymentForm" action="#" method="POST"> <h2>Payment Form</h2> <div id="cardFields"></div> <input type="hidden" id="token" value="" /> <input id="paymentSubmit" type="submit" value="Process Payment" /> <button id="swipe" type="button" name="button">Swipe</button> </form> <script src="https://cdn.sbx.neononepay.com/3.0/neonpay.js"></script> <script type="text/javascript"> // Set up the NeonPay fields on your form var neonpay = new NeonPay('public_f8564752122b08cc9c20c374562d5cc7', '19', {swipe: true}); var card = neonpay.createField('card'); (async () => { // Check if merchant can process payments first const result = await neonpay.canMakePayments(); if (result) { card.mount('#cardFields'); } else { // There was an error and the payment is not possible for this configuration document.querySelector('#cardFields').style.display = 'none'; } })(); var paymentForm = document.getElementById('paymentForm'); var tokenField = document.getElementById('token'); // Intercept form submission and retrieve token paymentForm.addEventListener('submit', function (event) { event.preventDefault(); var tokenData = { first_name: 'Robert', middle_name: 'Norman', last_name: 'Ross', email: 'bob@ross.net', phone: '+18888606366', address_line_1: '4545 N. Ravenswood Ave.', address_line_2: '2nd Floor', address_city: 'Chicago', address_state: 'IL', address_zip: '60640', address_country: 'US' }; var token = neonpay.createToken(card, tokenData).then(function(result) { // Pass the token to your Charge API call using // a hidden input that your form will serialize // or to an intermediary API on your server if (result.token) { tokenField.value = result.token; } }); }); </script>
Google Pay Example
<form id="paymentForm" action="#" method="POST"> <h2>Payment Form</h2> <div id="googlePayButton"></div> <input type="hidden" id="token" value="" /> <input id="paymentSubmit" type="submit" value="Process Payment" /> </form> <script src="https://cdn.sbx.neononepay.com/3.0/neonpay.js"></script> <script type="text/javascript"> // Set up the NeonPay fields on your form var neonpay = new NeonPay('public_f8564752122b08cc9c20c374562d5cc7', '19', {swipe: true}); var googlepay = neonpay.createField('googlepay', {price: '25.00'}); (async () => { // Check if merchant can process payments first const result = await neonpay.canMakePayments(); if (result) { googlepay.mount('#googlePayButton'); } else { // There was an error and the payment is not possible for this configuration document.querySelector('#googlePayButton').style.display = 'none'; } })(); var paymentForm = document.getElementById('paymentForm'); var tokenField = document.getElementById('token'); // Intercept form submission and retrieve token paymentForm.addEventListener('submit', function (event) { event.preventDefault(); var tokenData = { first_name: 'Robert', middle_name: 'Norman', last_name: 'Ross', email: 'bob@ross.net', phone: '+18888606366', address_line_1: '4545 N. Ravenswood Ave.', address_line_2: '2nd Floor', address_city: 'Chicago', address_state: 'IL', address_zip: '60640', address_country: 'US' }; var token = neonpay.createToken(googlepay, tokenData).then(function(result) { // Pass the token to your Charge API call using // a hidden input that your form will serialize // or to an intermediary API on your server if (result.token) { tokenField.value = result.token; } }); }); </script>
DAFPay Example
<form id="paymentForm" action="#" method="POST"> <h2>Payment Form</h2> <div id="dafButton"></div> <textarea type="hidden" id="token" value=""></textarea> </form> <script src="https://cdn.sbx.neononepay.com/3.2/neonpay.js"></script> <script type="text/javascript"> // Set up the NeonPay fields on your form var neonpay = new NeonPay('public_f8564752122b08cc9c20c374562d5cc7', '19'); var daf = neonpay.createField('daf', {customerDetail: {firstName: 'John', lastName: 'Doe', amount: 1000.00}); (async () => { // Check if merchant can process payments first const result = await neonpay.canMakePayments(); if (result) { daf.mount('#dafButton'); } else { // There was an error and the payment is not possible for this configuration document.querySelector('#dafButton').style.display = 'none'; } })(); var paymentForm = document.getElementById('paymentForm'); var tokenField = document.getElementById('token'); // Catch the 'dafAuthorized' event and retrieve grant information to call NeonPay's /dafDonations endpoint // https://docs.neononepay.com/api/#/DAF%20Donations/post_dafDonations // You will receive either a 'workflowSessionId' or a 'grantId' to be passed as part of the request body daf.on('dafAuthorized', function (event) { document.querySelector('#token').innerHTML = JSON.stringify(event); }); </script>

Step-by-Step Guide

1. Include neonpay.js

Include the NeonPay JS library in your payment form.

Include NeonPay.js
<script src="https://cdn.app.neononepay.com/3.0/neonpay.js"></script>

If you are developing in the Sandbox environment, your script will be:

NeonPay.js for Sandbox
<script src="https://cdn.sbx.neononepay.com/3.0/neonpay.js"></script>

2. Create DOM Elements

Add a container field where you wish NeonPay to populate the payment fields on your page. Be sure to give it a unique HTML id attribute so that you can target it directly.

Create DOM Elements
<div id="cardFields"></div>

3. Generate the NeonPay class

In a <script> that runs on page load, create an instance of the NeonPay object. You must provide your Public API Key and your Merchant ID, which can be retrieved from the NeonPay merchant portal.

For each separate payment type you may want to use, you must initialize separate instances of the NeonPay class.

Argument: options

Object
The object may contain the keys defined below:
Values
swipe
boolean
Allows for transactions via the use of a supported magnetic card swiper/reader. You must have a button with the id of "swipe" inside your payment form.
Generate NeonPay Class
var neonpay = new NeonPay(apiKey, merchantId[, options]);
Example With Swiper On
var neonpay = new NeonPay(apiKey, merchantId, {swipe: true});
Example For Multiple Payment Types
var neonpayWithSwiper = new NeonPay(apiKey, merchantId, {swipe: true}); var neonpayAch = new NeonPay(apiKey, merchantId[, options]);

4. Define Payment Fields

In the same script as above, declare which payment fields should appear using this method:

Define Payment Fields
var card = neonpay.createField('card');

5. Retrieve Merchant Data and Mount Payment Fields

Use canMakePayments() to retrieve merchant information necessary for making tokens. It is recommended that this be done in an async method before mounting. Mounting will place your payment fields inside the previously created DOM element. The fields will be added as iFrames to your page.

Mount NeonPay Fields
(async () => { // Check if merchant can process payments first const result = await neonpay.canMakePayments(); if (result) { card.mount('#cardFields'); } else { // There was an error and the payment is not possible for this configuration // Handle this error state as your application sees fit document.querySelector('#cardFields').style.display = 'none'; } })(); // Alternatively, you may pass a DOM object reference instead var container = document.querySelector('#cardFields'); (async () => { // Check if merchant can process payments first const result = await neonpay.canMakePayments(); if (result) { card.mount(container); } else { // There was an error and the payment is not possible for this configuration // Handle this error state as your application sees fit container.style.display = 'none'; } })();

6. Set up Callback Method

Use the neonpay.createToken() method to catch the payment token and complete your charges with NeonPay.

Set up Callback
neonpay.createToken(card).then(function(result) { // callback methods to handle result.error or result.token });

API Documentation

canMakePayments()

Ensures that the current merchant can process payments. Also retrieves other information about the merchant necessary for rendering the correct payment fields later.

Method
neonpay.canMakePayments();
Example
(async () => { const result = await neonpay.canMakePayments(); })();

createField()

When displaying card fields using this method, you can choose either to use the type of card to display a single consolidated field that collects card number, expiration, and cvc, or else you can display those fields individually by calling this method three times with a different type.

If you are trying to create multiple payment fields on the same page, they must be made with separate instances of the NeonPay class.

Method
var field = neonpay.createField(type, options);

Argument: type

Required String
Use one of the values below:
Values
card A set of fields for credit card entry, including card number, card expiration, card CVC, and postal code.
cardNumber Credit card number field
cardExpiration Credit card expiration field
cardCvc Credit card CVC number field
applepay Apple Pay Button
googlepay Google Pay Button
bankaccount Bank account form for ACH transfers, presentation will differ depending on if the merchant is with Payrix or Stripe
acssDebit Form for Canadian pre-authorized debit payments, only available for Canadian merchants
daf Form for processing DAF Donations, powered by Chariot, only available for US non-profit merchants

Argument: options

Object
The object may contain the keys defined below:
Values
cardNetworks
array
Available if type parameter is applepay or googlepay. Specifies what card networks are allowed to be processed for Apple and Google Pay methods. By default, AMEX, DISCOVER, JCB, MASTERCARD, and VISA are enabled if nothing is defined here. (Other networks not listed here are not available at this time). Merchants processed through Stripe will not honor this configuration.
buttonSizeMode
string
Available if type parameter is applepay or googlepay.

default The button is rendered with the minimum height and width (186x40 pixels). The maximum height for Apple Pay buttons is 64px.

fill The button fills its parent container.

price
string
Available if type parameter is applepay or googlepay. Specifies the price to be shown in the Google or Apple Pay payment sheet.
label
string
Available if type parameter is applepay. Specifies the label for the item to be shown in the Apple Pay payment sheet.
storeName
string
Available if type parameter is applepay. Specifies the store name to be shown in the Apple Pay payment sheet.
style
object

Customize credit card fields’ appearances with CSS. Not available for Google Pay or Apple Pay buttons, which are strictly styled to their respective brand guidelines. To customize the bank account form for Payrix merchants, jump to the styling guide for more information.

Style is specified as an object for the variants below:

  • base: all variants inherit from this style
  • complete: applied when the field has valid input
  • empty: applied when the field has no input
  • invalid: applied when the field has invalid input

For each of the above, the following styles can be customized.

  • color
  • fontFamily
  • fontSize
  • fontSmoothing
  • fontStyle
  • fontVariant
  • fontWeight
  • letterSpacing
  • textAlign
  • textDecoration
  • textShadow
  • textTransform

The following pseudo-classes and pseudo-elements can also be styled with the above properties, as a nested object inside the variant.

  • :hover
  • :focus
  • ::placeholder
  • :disabled
value
object
Available if type parameter is card. You may pre-fill field values (e.g., {postalCode: ‘90210’}). You may not prefill card data like number and expiration date due to data protection concerns.
hidePostalCode
boolean
Only available if type parameter is card. Hide the postal code field. Defaults to false. If you are collecting full billing information elsewhere on your payment form, you can set this to true.
hideBorders
boolean
Hides the default border styling for card fields.
disabled
boolean
Applies a disabled state to the field so that it prevents user input. Defaults to false.
customizeFields
object

Available if type parameter is bankaccount only. Customize the field’s label and placeholder text.

The fields available for customization are:

  • account_holder_first_name
  • account_holder_last_name
  • email
  • account_type
  • account_number
  • routing_number
customerDetail
object

Available if type parameter is daf only. Pass information about the customer to pre-populate the DAF Donation modal. All info is optional. This only affects the modal display and can be further modified by customers. The details saved in NeonPay are based on the equivalent value passed when creating the donation.

The fields available for pre-population are:

  • amount
    number (optional)

    The donation amount in dollars and cents, i.e., 20.00.

  • firstName
    string (optional)

    The customer's first name.

  • lastName
    string (optional)

    The customer's last name.

  • email
    string (optional)

    The customer's email address.

  • phone
    string (optional)

    The customer's phone number

  • note
    string (optional)

    A note the customer wants to send to the nonprofit

  • address
    object (optional)

    The donor's address: line1, line2, city, state, postalCode

  • metadata
    object (optional)

    An object with a set of name-value pairs. You can use this object to include any miscellaneous information you want to tie to the DAF donation.

  • anonymous
    boolean (optional)

    Indicates if this donation should be sent anonymously (default: false).

Example with Options
var card = neonpay.createField('card', { style: { base: { color: '#46a0ba', '::placeholder': { color: '#000' } }, invalid: { color: 'yellow' } }, value: { postalCode: '60613' }, hidePostalCode: false, disabled: false }); var googlepay = neonpay.createField('googlepay');
Example with separate card fields
var styleObject = { base: { fontFamily: 'Open Sans, sans-serif', color: '#46a0ba' } }; var cardNumberField = neonpay.createField('cardNumber', { style: styleObject, placeholder: 'Enter card number', disabled: false }); var cardExpirationField = neonpay.createField('cardExpiration', { style: styleObject }); var cardCvcField = neonpay.createField('cardCvc', { style: styleObject });
Apple Pay example
var applepay = neonpay.createField('applepay', { applepayElement: '#applePayButton', price: '1.00', label: 'Donation for 2021 Gala', storeName: 'My Non-Profit' });
Google Pay example
var googlepay = neonpay.createField('googlepay', { googlepayElement: '#googlePayButton', price: '1.00' });
ACH Bank Transfer example
var googlepay = neonpay.createField('bankaccount', { style: styleObject, customizeFields: { account_holder_first_name: { label: "First Name", placeholder: "First Name", }, }, });

updateField()

Updates the configuration for a field. Updates are merged into any existing configuration.

Method
field.updateField(options);
Example Usage
var options = { style: { base: { fontSize: '13px' } } }; card.on('ready', function(event) { card.updateField( options ); });

mount()

IMPORTANT: You must use canMakePayments() first to retrieve information about the merchant. Otherwise, the field will not mount or render.

You need to first create a container DOM element to mount a Field. After mounting, the method will attach the Field to the specified DOM element, causing the field to display on your page.

Method
field.mount(domElement)
Example Usage
(async () => { // Check if merchant can process payments first const result = await neonpay.canMakePayments(); if (result) { card.mount('#paymentForm'); } else { // There was an error and the payment is not possible for this configuration // Handle this error state as your application sees fit document.querySelector('#paymentForm').style.display = 'none'; } })(); // Alternatively, you may pass a DOM object reference instead var container = document.querySelector('#paymentForm'); card.mount(container);

unmountField()

Unmounts the Field from the DOM. You will need to call .mount() again to re-attach fields to the DOM.

Method
field.unmountField(domElement)
Example Usage
card.unmountField('#paymentForm'); // Alternatively, you may pass a DOM object reference instead var container = document.querySelector('#paymentForm'); card.unmountField(container);

createToken()

Use the createToken() method to convert the information collected by the payment fields into a payment token that you can safely pass to your server to use in a Charge API call.

Argument: field

Required object
This object is the payment field(s) previously declared and mounted by your script. The information from field will be tokenized in preparation for charging.

Argument: tokenData

object
This object contains additional payment information you may have collected in the rest of your payment form. It may contain the following information:
Values (Credit Card, Apple Pay, Google Pay)
first_name
string
Cardholder first name. For Apple and Google Pay, value is provided automatically via that service.
middle_name
string
Cardholder middle name
last_name
string
Cardholder last name. For Apple and Google Pay, value is provided automatically via that service.
address_line_1
string
Cardholder billing address line 1. For Apple and Google Pay, value is provided automatically via that service.
address_line_2
string
Cardholder billing address line 2. For Apple and Google Pay, value is provided automatically via that service.
address_city
string
Cardholder billing address city. For Apple and Google Pay, value is provided automatically via that service.
address_state
string
Cardholder billing address state/province. For Apple and Google Pay, value is provided automatically via that service.
address_zip
string
Cardholder billing address zip code. For Apple and Google Pay, value is provided automatically via that service.
address_country
string
Cardholder billing address country. Two character ISO country code (e.g., ‘US’). For Apple and Google Pay, value is provided automatically via that service.
email
string
Cardholder email address. For Apple and Google Pay, value is provided automatically via that service.
phone Cardholder phone number
Values (Bank Accounts Only)
country
string
Two character ISO country code (e.g., ‘US’)
Method
neonpay.createToken(field, tokenData)
Example Usage
neonpay.createToken(field).then(function(result) { // callback methods to handle result.error or result.token });
Example with Token Data
var tokenData = { first_name: 'Robert', middle_name: 'Norman', last_name: 'Ross', email: 'bob@ross.net', phone: '+18888606366', address_line_1: '4545 N. Ravenswood Ave.', address_line_2: '2nd Floor', address_city: 'Chicago', address_state: 'IL', address_zip: '60640', address_country: 'US' } neonpay.createToken(field,tokenData).then(function(result) { // callback methods to handle result.error or result.token });

setPrice() (Apple Pay, Google Pay, or DAF Pay)

A price must be set for transactions to be tokenized through Apple or Google Pay.

Argument: price

Required string
Price should be formatted in as xx.xx. For example, $10 should be passed as 10.00.
Method
field.setPrice(price)
Example Usage
field.on('ready', function(event) { field.setPrice('10.00'); });

You can set event listeners to catch events emitted by your fields.

Argument: event

Required object
We attempt to validate customer input upon input. To help your customers, listen for the change event to display any errors.
Values
blur Triggers when the Field loses focus.
change Triggers when any of the following values has changed in the field:
  • empty {boolean}
  • complete {boolean}
  • error {object} - contains error message, code, and type
focus Triggers when the Field gains focus.
ready Triggers when the Field is rendered and available for interaction.
cardbrand Triggers when the card number field is blurred and has determined a card brand in the form an event object: {brand: 'brand name'}. The brands returned come the following list:
  • amex
  • discover
  • diners_club
  • jcb
  • mastercard
  • visa
  • none
applepayButtonClick Triggers when the customer has clicked on the Apple Pay button and the payment sheet is displayed.
applepayAuthorized Triggers when there is a Apple Pay is set up to allow for tokenization through the createToken method.
applepayCanceled Triggers when the Apple Pay payment sheet errors or is canceled out.
applepayIncompatible Triggers if the Apple Pay API is not supported by the current device/browser.
googlepayReady Triggers when the Google Pay integration has been loaded. The Google Pay button may not be fully initialized at this point though, use the googlepayButtonReady event instead.
googlepayButtonReady Triggers when the Google Pay Button has been rendered and is ready for customer interaction.
googlepayButtonClick Triggers when the customer has clicked on the Google Pay button and the payment sheet is displayed.
googlepayAuthorized Triggers when there is a Google Pay is set up to allow for tokenization through the createToken method.
googlepayIncompatible Triggers if the Google Pay API is not supported by the current device/browser.
achAuthorized Only for Stripe merchant accounts. Triggers after the customer provides either a verified bank account and/or accepts the mandate for ACH transfer.
acssAuthorized Only for Canadian merchant accounts. Triggers after the customer provides either a verified bank account and/or accepts the mandate for ACSS debits.
dafAuthorized

Only for DAF donations. Triggers after the customer provides information and completes a DAF donation. An object of the information customers provided within Chariot's modal will be returned with this event. It contains required information to be passed as part of the request body to Neon Pay's /dafDonations endpoint in order to complete and store the donation record in our system.

Here is an example of the object returned. The object will contain either workflowSessionId or grantId. Never both.

{ workflowSessionId: '0bb97652-9eeb-4089-b2e0-e8f4f3d13b7f', grantId: '0bb97652-9eeb-4089-b2e0-e8f4f3d13b7g', amount: 50000, // returned in cents user: { firstName: 'John', lastName: 'Doe', email: 'jodoe@example.com', note: '', } }
dafCanceled Triggers when the DAF donation modal is canceled out by the customer.

Argument: handler

Required function
This is the callback function that is called upon an emitted event.
Method
field.on(event, handler)
Example Error Handling
card.on('change', function(event) { var displayError = document.getElementById('card-errors'); if (event.error) { displayError.innerHTML = event.error.message; } else { displayError.innerHTML = ''; } });

Bank Account Form Styling Guide

The bank account forms for Payrix merchants can be customized through CSS. NeonPayJS inserts the fields into your payment form so they can be directly accessed. Here are a few examples of how you can style the form to match your payment form's style.

Customize into a grid layout

By default, the bank account fields are presented as a one column of full-width display blocks.

Utilizing CSS flexbox, the container element that the bank account form is mounted within and the NeonPay__field class can be modified to transform the form into a multi-column form.

Example CSS for a Two Column Grid
#achAccount { display: flex; flex-wrap: wrap; } #achAccount .NeonPay__field { flex: 1 0 calc(50% - 10px); margin-right: 10px; }

Change the field order

Use flex order on the child .NeonPay__field classes to rearrange what order the fields appear in.

Example CSS to move email to the top
#achAccount { display: flex; flex-direction: column; } #achAccount div[class*="email"].NeonPay__field { order: -1; }

Style the inputs and error messaging

By default, the form has minimal styling. The form can be styled directly with standard CSS.

Example CSS to style labels and inputs
#achAccount .NeonPay__field label { color: #54698d; font-size: 0.75rem; } #achAccount .NeonPay__field input, #achAccount .NeonPay__field select { border: 1px solid #54698d; border-radius: 15px; color: #002d41; outline: 0; } #achAccount .NeonPay__field.--error label { color: #dc143c; } #achAccount .NeonPay__field.--error input, #achAccount.--error .NeonPay__field select { border: 1px solid #dc143c; outline: 0; } #achAccount .NeonPay__field label:focus-within { color: #0074d9; } #achAccount .NeonPay__field input:focus, #achAccount .NeonPay__field select:focus { border: 1px solid #0074d9; outline: 0; } #achAccount .NeonPay__field .neonpay__bank-error { font-weight: bold; text-transform: uppercase; }