Global Payments JavaScript Library
PCI Friendly Tokenization
This plugin allows you to use online payments (eCommerce) features of a variety of Global Payments brands — Heartland, Global Payments eCommerce, Cayan/Genius, TSYS, Global Payments Integration (fka OpenEdge) — to convert a credit card, gift card, or ACH/eCheck account into a secure token value which can be charged in a PCI friendly way.
Table of Contents
Usage
<script src="https://js.globalpay.com/4.1.1/globalpayments.js"></script>
Note: Installing via NPM will only provide TypeScript types for type-checking.
Configuration
Options
publicApiKey
- string
(Optional)
Note: Applies to Heartland Online Payments only.
The public API key associated with the merchant account. This API key is tied to a specific merchant/teminal account combination at Heartland and requires a matching secret API key to consume this value.
binCheck
- object
(Optional)
Note: Applies to Heartland Online Payments only.
Enables a BIN check for various capabilities.
Key | Type | Default | Description |
---|
hsaFsa | boolean | false | Determines if the supplied card is for healthcare use (HSA/FSA). |
surcharge | boolean | false | Deterimines if the supplied card can be surcharged. |
merchantId
- string
(Optional)
Note: Applies to Global Payments eCommerce and GP API only.
For Global Payments eCommerce integrations, the merchant ID value supplied for the account.
For GP API integrations using multi-merchant support, the merchant ID value for a specific merchant account supported by the partner.
account
- string
(Optional)
Note: Applies to Global Payments eCommerce only.
The account ID value supplied by Global Payments eCommerce.
env
- string
(Optional)
Supported values:
production
sandbox
(default)
Note: For Heartland eCommerce, this value is inferred from the configured publicApiKey
.
hash
- (object) => Promise<object>
(Optional)
Note: Applies to Global Payments eCommerce only.
- input: JS object for the request
- output: A promise value that resolves to the into JS object with the correct SHA1 hash
The hash
property depends on an asynchronous call to your backend to add the SHA1 hash to the JSON request using your account's shared secret. The Global Payments eCommerce configuration example below uses the Fetch API along with a PHP script, but this can use any other option as long as you are able to achieve the same result. This is required to prevent your shared secret from being exposed to unauthorized parties.
customerExists
- boolean
(Optional)
Note: Applies to Global Payments eCommerce only.
If the consumer already has a customer record stored with Global Payments eCommerce, this value should be set to true
.
customerReference
- string
(Optional)
Note: Applies to Global Payments eCommerce only.
If customerExists
is true
, this should be set to the customer's reference value/ID (PAYER_REF
).
webApiKey
- string
(Optional)
Note: Applies to Genius Checkout only.
The API key associated with a given merchant account.
deviceId
- string
(Optional)
Note: Applies to TransIT / TSEP only.
The device ID associated with a given account.
manifest
- string
(Optional)
Note: Applies to TransIT / TSEP only.
An encrypted value generated by the integrating partner using the merchant ID, device ID, transaction amount, and transaction key.
X-GP-Api-Key
- string
(Optional)
Note: Applies to OpenEdge / Global Payments Integrated only.
The API key associated with the account.
X-GP-Environment
- string
(Optional)
Note: Applies to OpenEdge / Global Payments Integrated only.
The OpenEdge / Global Payments Integrated environment.
merchantName
- string
(Optional)
Note: Applies to Heartland Bill Pay only.
The merchant name associated with a given account.
accessToken
- string
(Optional)
Note: Applies to GP API only.
An access token created for an application. Requires the PMT_POST_Create_Single
permission.
accountName
- string
(Optional)
Note: Applies to GP API only.
The tokenization account name for the given merchant account. Only required if there are more than one tokenization account associated with the merchant account
apiVersion
- string
(Optional)
Note: Applies to GP API only.
The target API version. Default is 2021-03-22
.
reference
- string
(Optional)
Note: Applies to GP API only.
The transaction reference for the tokenization request. If not provided, a GUID is created and sent in the request.
enableAutocomplete
- boolean
(Optional)
Enables autocomplete / autofill features. Default is false
.
language
- string
(Optional)
Value for the html
element's lang
attribute within the iframes. Default is en
.
requireCardHolderName
- boolean
(Optional)
Note: Applies to GP API only.
Enables a mandatory restriction for card holdername field
enableCardFingerPrinting
- boolean
(Optional)
Note: Applies to GP API only.
enables the use of the fingerprint mode with "ALWAYS" value
fieldValidation
- object
(Optional)
Note: Applies to GP API only.
enables the use of the HF Built-in Validations. The object structure is:
fieldValidation?: {
enabled?: boolean,
characterValidation?: string
}
The optional characterValidation
string config can be set as englishOnly
or none
and this will indicate if the Card Holder name contains or not English characters.
qrCodePayments
- object
(Optional - under apms
configs)
Note: Applies to GP API only.
enables the use of the QR Code Payments. The object structure is:
apms.qrCodePayments?: {
enabled?: boolean,
allowedPaymentMethods?: [
{
provider: string,
image: string,
},
]
}
The optional allowedPaymentMethods
object config can be set to manually add the preferred Payment methods.
Examples
Heartland eCommerce
GlobalPayments.configure({
publicApiKey: "pkapi_cert_dNpEYIISXCGDDyKJiV"
});
Global Payments eCommerce
GlobalPayments.configure({
merchantId: "merchant_id",
account: "hpp",
hash: (request) => {
return fetch("/hash.php", {
body: JSON.stringify(request),
credentials: "omit",
headers: new Headers({
"Content-Type": "application/json",
}),
method: "POST",
})
.then((resp) => resp.json());
},
env: "sandbox"
});
Genius Checkout
GlobalPayments.configure({
webApiKey: "YU8PX7668FGMSH5L",
env: "sandbox",
});
TransIT / TSEP
GlobalPayments.configure({
deviceId: "88700000322602",
manifest: "3c26272b6769cfa8b0c3c5a14dda4fc5365ed75c7330233a221a6e82aec667f35513c70862dc34f4ca31de7b4c824e129d23f8bce035fbbaa55aeb9da07b5d90bfe5d53c",
env: "sandbox",
});
OpenEdge / Global Payments Integrated
GlobalPayments.configure({
"X-GP-Api-Key": "oljHkRy0mAK9wqbQuUGZ9AUoe3ZtDrH7",
"X-GP-Environment": "dev",
});
Heartland Bill Pay
GlobalPayments.configure({
merchantName: "IntegrationTesting",
env: "sandbox",
});
Handling Global Errors
The GlobalPayments
global variable exposes an on
function to attach event listeners for an internal event emitter. Global and/or parent window runtime errors are exposed through this, and error
event handlers should follow the form:
type ErrorEventHandler = (error: IErrorEvent) => void;
where IErrorEvent
follows the form:
{
error: true,
reasons: [{
code,
message,
}],
}
Example
GlobalPayments.on("error", (error) => {
console.error(error);
});
Payment Request API
The Payment Request API defines a consistent user experience across payment methods, payment systems, platforms, and merchants. It is not a new payment method; rather, it is a conduit from the user's preferred payment method to a merchant. This functionality is driven by the user's browser and gives access to stored payment information associated with the user's browser session.
Here's a minimal example using a button and a simple $10 USD payment amount:
<div>
<button type="button" id="paymentRequestPlainButton" style="display: none">Pay</button>
</div>
var paymentRequestForm = GlobalPayments.paymentRequest.setup("#paymentRequestPlainButton", {
total: {
label: "Total",
amount: { value: 10, currency: "USD" }
}
});
paymentRequestForm.on("token-success", function (resp) {
console.log(response);
GlobalPayments.paymentRequest.complete("success");
});
paymentRequestForm.on("token-error", function (resp) {
console.log(resp);
});
paymentRequestForm.on("error", function (resp) {
console.log(resp);
});
No additional styles are applied:
This will attach the necessary event handlers to start the Payment Request payment flow once the button is clicked:
Payment Methods
This library currently supports:
Credit/Debit Cards
The drop-in credit/debit card form makes it easy to get started. Your integration will need a HTML form with a target for the drop-in form:
<form id="payment-form" action="/charge" method="get">
<label for="billing-zip">Billing Zip Code</label>
<input id="billing-zip" name="billing-zip" type="tel" />
<div id="credit-card"></div>
</form>
and some JavaScript to setup the form:
const cardForm = GlobalPayments.creditCard.form("#credit-card");
cardForm.ready(() => {
console.log("Registration of all credit card fields occurred");
});
cardForm.on("token-success", (resp) => {
const token = document.createElement("input");
token.type = "hidden";
token.name = "payment-reference";
token.value = resp.paymentReference;
const form = document.getElementById("payment-form");
form.appendChild(token);
form.submit();
});
cardForm.on("token-error", (resp) => {
});
cardForm.on("card-number", "register", () => {
console.log("Registration of Card Number occurred");
});
This will create a form with our default styles on page load:
See demo on JSFiddle
If the default styles conflict with your desired UI/UX, you can opt-out by specifying the blank
style:
const cardForm = GlobalPayments.creditCard.form("#credit-card", { style: "blank" });
See demo on JSFiddle
Styles can then be pushed to the form's fields as your integration requires:
cardForm.addStylesheet({
});
Need even more control/flexibility? Your integration can leverage the raw card form builder:
<form id="payment-form" action="/charge" method="get">
<label for="billing-zip">Billing Zip Code</label>
<input id="billing-zip" name="billing-zip" type="tel" />
<div id="credit-card-card-holder"></div>
<div id="credit-card-card-number"></div>
<div id="credit-card-card-cvv"></div>
<div id="credit-card-card-expiration"></div>
<div id="credit-card-submit"></div>
</form>
const cardForm = GlobalPayments.ui.form({
fields: {
"card-holder-name": {
placeholder: "Jane Smith",
target: "#credit-card-card-holder",
validationMessages: {
NotValidCardHolderName: 'Please enter a valid Card Holder Name',
CharactersMoreThan100: 'Card Holder Name can be at most 100 characters'
}
},
"card-number": {
placeholder: "•••• •••• •••• ••••",
target: "#credit-card-card-number",
validationMessages: {
Required: 'A Card Number is required',
CharactersLessThan12: 'The Card Number must consist of at least 12 digits',
NumberIsNotValid: 'The Card Number is not valid',
NotAllowedCardType: 'Cannot process this card type, please use another Card'
},
},
"card-expiration": {
placeholder: "MM / YYYY",
target: "#credit-card-card-expiration",
validationMessages: {
NotCompleted: 'Please enter a valid month/year',
YearNotValid: 'The year is not valid',
MonthNotValid: 'The month is not valid',
ExpiryDateNotValid: 'The Expiry Date is not valid',
}
},
"card-cvv": {
placeholder: "•••",
target: "#credit-card-card-cvv",
validationMessages: {
CodeIsNotValid: 'The Card CVV is not valid',
CodeIsLessThan3Digits: 'Card CVV is too short',
CodeMustBe3Digits: 'Card CVV must be 3 digits',
AmexCodeMustBe4Digits: 'Card CVV for Amex must be 4 digits',
}
},
"submit": {
value: "Submit",
}
},
styles: {
}
});
Adding Multiple Custom Fonts
To add multiple custom fonts, you can use the following configurations:
const cardForm = GlobalPayments.ui.form({
fields: { ... },
styles: {
"@font-face": [
{
"font-family": "'Font 1'",
"src": "url('url/font1.woff2') format('woff2')"
},
{
"font-family": "'Font 2'",
"src": "url('url/font2.woff2') format('woff2')"
}]
// Your styles
}
});
or
cardForm.addStylesheet({
"@font-face": [
{
"font-family": "'Font 1'",
"src": "url('url/font1.woff2') format('woff2')"
},
{
"font-family": "'Font 2'",
"src": "url('url/font2.woff2') format('woff2')"
}]
});
Validation Messages
The list of validation messages is accessible at /packages/globalpayments-js/src/internal/lib/translations/en.ts
See demo on JSFiddle
Gift/Loyalty Cards
Note: Applies to Heartland eCommerce only.
The drop-in gift/loyalty card form makes it easy to get started. Your integration will need a HTML form with a target for the drop-in form:
<form id="payment-form" action="/charge" method="get">
<label for="billing-zip">Billing Zip Code</label>
<input id="billing-zip" name="billing-zip" type="tel" />
<div id="gift-card"></div>
</form>
and some JavaScript to setup the form:
const cardForm = GlobalPayments.giftAndLoyalty.form("#gift-card");
cardForm.ready(() => {
console.log("Registration of all gift/loyalty card fields occurred");
});
cardForm.on("token-success", (resp) => {
const token = document.createElement("input");
token.type = "hidden";
token.name = "payment-reference";
token.value = resp.paymentReference;
const form = document.getElementById("payment-form");
form.appendChild(token);
form.submit();
});
cardForm.on("token-error", (resp) => {
});
cardForm.on("card-number", "register", () => {
console.log("Registration of Card Number occurred");
});
This will create a form with our default styles on page load:
See demo on JSFiddle
If the default styles conflict with your desired UI/UX, you can opt-out by specifying the blank
style:
const cardForm = GlobalPayments.giftAndLoyalty.form("#gift-card", { style: "blank" });
See demo on JSFiddle
Styles can then be pushed to the form's fields as your integration requires:
cardForm.addStylesheet({
});
Need even more control/flexibility? Your integration can leverage the raw card form builder:
<form id="payment-form" action="/charge" method="get">
<label for="billing-zip">Billing Zip Code</label>
<input id="billing-zip" name="billing-zip" type="tel" />
<div id="gift-card-card-number"></div>
<div id="gift-card-submit"></div>
</form>
const cardForm = GlobalPayments.ui.form({
fields: {
"card-number": {
placeholder: "•••• •••• •••• ••••",
target: "#gift-card-card-number"
},
"submit": {
value: "Submit",
target: "#gift-card-submit"
}
},
styles: {
}
});
See demo on JSFiddle
ACH/eCheck Accounts
Note: Applies to Heartland eCommerce only.
The drop-in ACH/eCheck form makes it easy to get started. Your integration will need a HTML form with a target for the drop-in form:
<form id="payment-form" action="/charge" method="get">
<label for="billing-zip">Billing Zip Code</label>
<input id="billing-zip" name="billing-zip" type="tel" />
<div id="eCheck"></div>
</form>
and some JavaScript to setup the form:
const eCheckForm = GlobalPayments.eCheck.form("#eCheck");
eCheckForm.ready(() => {
console.log("Registration of all ACH/eCheck fields occurred");
});
eCheckForm.on("token-success", (resp) => {
const token = document.createElement("input");
token.type = "hidden";
token.name = "payment-reference";
token.value = resp.paymentReference;
const form = document.getElementById("payment-form");
form.appendChild(token);
form.submit();
});
eCheckForm.on("token-error", (resp) => {
});
eCheckForm.on("account-number", "register", () => {
console.log("Registration of Account Number occurred");
});
This will create a form with our default styles on page load:
See demo on JSFiddle
If the default styles conflict with your desired UI/UX, you can opt-out by specifying the blank
style:
const eCheckForm = GlobalPayments.eCheck.form("#eCheck", { style: "blank" });
See demo on JSFiddle
Styles can then be pushed to the form's fields as your integration requires:
eCheckForm.addStylesheet({
});
Need even more control/flexibility? Your integration can leverage the raw form builder:
<form id="payment-form" action="/charge" method="get">
<label for="billing-zip">Billing Zip Code</label>
<input id="billing-zip" name="billing-zip" type="tel" />
<div id="eCheck-account-number"></div>
<div id="eCheck-routing-number"></div>
<div>
<select name="eCheck-check-type">
<option> -- Check Type -- </option>
<option>Checking</option>
<option>Savings</option>
</select>
</div>
<div>
<select name="eCheck-account-type">
<option> -- Account Type -- </option>
<option>Personal</option>
<option>Business</option>
</select>
</div>
<div id="eCheck-submit"></div>
</form>
const eCheckForm = GlobalPayments.ui.form({
fields: {
"account-number": {
placeholder: "Account Number",
target: "#eCheck-account-number"
},
"routing-number": {
placeholder: "•••••••••",
target: "#eCheck-routing-number"
},
"submit": {
value: "Submit",
target: "#eCheck-submit"
}
},
styles: {
}
});
See demo on JSFiddle
Building from source
yarn install
yarn run build
yarn run build
will perform the following tasks:
- Clean the
./dist/
directory. - Lints the Typescript files according to
tslint.json
. - Builds the Typescript files into
./dist/securesubmit.js
using tsconfig.json
. - Minifies
./dist/securesubmit.js
into ./dist/securesubmit.min.js
. - Copies the needed asset files into
./dist/
.
Development
The tokenization library is built in Typescript. The Typescript compiler is available as an add-on for Visual Studio, but it can also be installed independently. This library's package.json
file also pulls down a copy of the Typescript compiler on yarn install
, which allows it to be used by calling ./node_modules/bin/tsc
.
Watch files during development
yarn run build -w
Testing
Integration tests are ran with Cypress, which expects a running web server to host the built files as well as the test runners. To facilitate this, leverage the appropriate Bash script:
./test/run.sh
or PowerShell script:
.\test\run.ps1
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request
LICENSE
This project is licensed under the GPLv2 License. See LICENSE.md for details.