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
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/)
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>
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>
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>
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.
options
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 Classvar neonpay = new NeonPay(apiKey, merchantId[, options]);
Example With Swiper Onvar neonpay = new NeonPay(apiKey, merchantId, {swipe: true});
Example For Multiple Payment Typesvar neonpayWithSwiper = new NeonPay(apiKey, merchantId, {swipe: true}); var neonpayAch = new NeonPay(apiKey, merchantId[, options]);
In the same script as above, declare which payment fields should appear using this method:
Define Payment Fieldsvar card = neonpay.createField('card');
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'; } })();
Use the neonpay.createToken()
method to catch the payment token and complete your charges with NeonPay.
Set up Callbackneonpay.createToken(card).then(function(result) { // callback methods to handle result.error or result.token });
canMakePayments()
Ensures that the current merchant can process payments. Also retrieves other information about the merchant necessary for rendering the correct payment fields later.
Methodneonpay.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.
Methodvar field = neonpay.createField(type, options);
type
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 |
options
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 .
|
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:
For each of the above, the following styles can be customized.
The following pseudo-classes and pseudo-elements can also be styled with the above properties, as a nested object inside the variant.
|
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 The fields available for customization are:
|
customerDetail object |
Available if type parameter is The fields available for pre-population are:
|
Example with Optionsvar 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 fieldsvar 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 examplevar applepay = neonpay.createField('applepay', { applepayElement: '#applePayButton', price: '1.00', label: 'Donation for 2021 Gala', storeName: 'My Non-Profit' });
Google Pay examplevar googlepay = neonpay.createField('googlepay', { googlepayElement: '#googlePayButton', price: '1.00' });
ACH Bank Transfer examplevar 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.
Methodfield.updateField(options);
Example Usagevar 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.
Methodfield.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.
Methodfield.unmountField(domElement)
Example Usagecard.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.
field
tokenData
Values (Credit Card, Apple Pay, Google Pay) | |
---|---|
first_name string recommended |
Cardholder first name. For Apple and Google Pay, value is provided automatically via that service. |
middle_name string |
Cardholder middle name |
last_name string recommended |
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 recommended |
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’) |
Methodneonpay.createToken(field, tokenData)
Example Usageneonpay.createToken(field).then(function(result) { // callback methods to handle result.error or result.token });
Example with Token Datavar 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.
price
xx.xx
. For example, $10 should be passed as 10.00
.Methodfield.setPrice(price)
Example Usagefield.on('ready', function(event) { field.setPrice('10.00'); });
You can set event listeners to catch events emitted by your fields.
event
Values | |
---|---|
blur | Triggers when the Field loses focus. |
change | Triggers when any of the following values has changed in the field:
|
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:
|
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: '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. |
handler
Methodfield.on(event, handler)
Example Error Handlingcard.on('change', function(event) { var displayError = document.getElementById('card-errors'); if (event.error) { displayError.innerHTML = event.error.message; } else { displayError.innerHTML = ''; } });
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.
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; }
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; }
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; }