@globalpayments/js 1.8.3 → 1.8.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/.prettierrc +4 -4
  2. package/LICENSE.md +264 -264
  3. package/README.md +733 -700
  4. package/TODO +5 -5
  5. package/bin/replace-gp-ref.js +17 -17
  6. package/bin/update-version.js +19 -18
  7. package/config/rollup.js +67 -67
  8. package/cypress.json +11 -11
  9. package/package.json +51 -36
  10. package/types/credit-card/index.d.ts +16 -0
  11. package/types/echeck/index.d.ts +8 -0
  12. package/types/gift-and-loyalty/index.d.ts +8 -0
  13. package/types/global-type.d.ts +7 -7
  14. package/types/internal/gateways/index.d.ts +2 -0
  15. package/types/internal/lib/card.d.ts +1 -1
  16. package/types/internal/lib/dot-placeholders.d.ts +2 -0
  17. package/types/internal/lib/events.d.ts +3 -0
  18. package/types/internal/lib/styles/gp-default.d.ts +9 -0
  19. package/types/lib/version.d.ts +1 -1
  20. package/types/payment-request/complete.d.ts +6 -0
  21. package/types/payment-request/setup.d.ts +18 -0
  22. package/types/tools/configure.d.ts +16 -5
  23. package/types/ui/form/index.d.ts +57 -1
  24. package/types/ui/iframe-field/action-accumulate-data-and-tokenize.d.ts +6 -0
  25. package/types/ui/iframe-field/action-card-track-button-click.d.ts +6 -0
  26. package/types/ui/iframe-field/action-get-cvv.d.ts +7 -0
  27. package/types/ui/iframe-field/action-payment-request-complete.d.ts +10 -0
  28. package/types/ui/iframe-field/action-payment-request-start.d.ts +11 -0
  29. package/types/ui/iframe-field/action-request-data.d.ts +9 -0
  30. package/types/ui/iframe-field/action-set-card-type.d.ts +9 -0
  31. package/types/ui/iframe-field/action-set-focus.d.ts +3 -0
  32. package/types/ui/iframe-field/action-set-label.d.ts +5 -0
  33. package/types/ui/iframe-field/action-set-placeholder.d.ts +5 -0
  34. package/types/ui/iframe-field/action-set-text.d.ts +5 -0
  35. package/types/ui/iframe-field/action-set-type-cvv.d.ts +10 -0
  36. package/types/ui/iframe-field/action-set-value.d.ts +5 -0
  37. package/types/ui/iframe-field/index.d.ts +79 -2
  38. package/types/ui/index.d.ts +7 -0
  39. package/dist/field.html +0 -45
  40. package/dist/globalpayments.js +0 -5811
  41. package/dist/globalpayments.js.map +0 -1
  42. package/dist/globalpayments.min.js +0 -2
  43. package/dist/globalpayments.min.js.map +0 -1
  44. package/dist/images/amex.svg +0 -1
  45. package/dist/images/cvv-amex.png +0 -0
  46. package/dist/images/cvv.png +0 -0
  47. package/dist/images/discover.svg +0 -1
  48. package/dist/images/gp-cc-amex.svg +0 -6
  49. package/dist/images/gp-cc-dinnersclub.svg +0 -33
  50. package/dist/images/gp-cc-discover.svg +0 -14
  51. package/dist/images/gp-cc-generic.svg +0 -4
  52. package/dist/images/gp-cc-jcb.svg +0 -12
  53. package/dist/images/gp-cc-maestro.svg +0 -14
  54. package/dist/images/gp-cc-mastercard.svg +0 -11
  55. package/dist/images/gp-cc-visa.svg +0 -6
  56. package/dist/images/gp-fa-question-circle.svg +0 -3
  57. package/dist/images/gp-lock.svg +0 -7
  58. package/dist/images/gp-secure-logo.svg +0 -8
  59. package/dist/images/gp-secure-ssl-logo.svg +0 -8
  60. package/dist/images/jcb.svg +0 -1
  61. package/dist/images/logo-amex@2x.png +0 -0
  62. package/dist/images/logo-discover@2x.png +0 -0
  63. package/dist/images/logo-jcb@2x.png +0 -0
  64. package/dist/images/logo-mastercard@2x.png +0 -0
  65. package/dist/images/logo-unknown@2x.png +0 -0
  66. package/dist/images/logo-visa@2x.png +0 -0
  67. package/dist/images/mastercard.svg +0 -1
  68. package/dist/images/shield-and-logos@2x.png +0 -0
  69. package/dist/images/visa.svg +0 -1
  70. package/examples/accessibility.html +0 -100
  71. package/examples/billpay.html +0 -181
  72. package/examples/genius.html +0 -80
  73. package/examples/globalpayments/hash.php +0 -19
  74. package/examples/globalpayments.html +0 -94
  75. package/examples/gp-api.php +0 -60
  76. package/examples/heartland.html +0 -247
  77. package/examples/index.html +0 -22
  78. package/examples/openedge.html +0 -61
  79. package/examples/transit/create-manifest.php +0 -80
  80. package/examples/transit/curl.php +0 -40
  81. package/examples/transit/index.php +0 -83
package/README.md CHANGED
@@ -1,700 +1,733 @@
1
- # Global Payments JavaScript Library
2
-
3
- #### PCI Friendly Tokenization
4
-
5
- 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.
6
-
7
- ## Table of Contents
8
-
9
- - [Usage](#usage)
10
- - [Configuration](#configuration)
11
- - [Options](#options)
12
- - [Examples](#examples)
13
- - [Handling Global Errors](#handling-global-errors)
14
- - [Payment Request API](#payment-request-api)
15
- - [Payment Methods](#payment-methods)
16
- - [Credit/Debit Cards](#creditdebit-cards)
17
- - [Gift/Loyalty Cards](#giftloyalty-cards)
18
- - [ACH/eCheck Accounts](#achecheck-accounts)
19
- - [Building from source](#building-from-source)
20
- - [Development](#development)
21
- - [Contributing](#contributing)
22
- - [LICENSE](#license)
23
-
24
- ## Usage
25
-
26
- ```html
27
- <script src="https://js.globalpay.com/v1/globalpayments.js"></script>
28
- ```
29
-
30
- > Note: Installing via NPM will only provide TypeScript types for type-checking.
31
-
32
- ### Configuration
33
-
34
- #### Options
35
-
36
- ##### `publicApiKey` - `string`
37
-
38
- > Note: Applies to Heartland eCommerce only.
39
-
40
- 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.
41
-
42
- ##### `merchantId` - `string`
43
-
44
- > Note: Applies to Global Payments eCommerce only.
45
-
46
- The merchant ID value supplied by Global Payments eCommerce.
47
-
48
- ##### `account` - `string`
49
-
50
- > Note: Applies to Global Payments eCommerce only.
51
-
52
- The account ID value supplied by Global Payments eCommerce.
53
-
54
- ##### `env` - `string`
55
-
56
- Supported values:
57
-
58
- - `production`
59
- - `sandbox` (default)
60
-
61
- > Note: For Heartland eCommerce, this value is inferred from the configured `publicApiKey`.
62
-
63
- ##### `hash` - `(object) => Promise<object>`
64
-
65
- > Note: Applies to Global Payments eCommerce only.
66
-
67
- - input: JS object for the request
68
- - output: A promise value that resolves to the into JS object with the correct SHA1 hash
69
-
70
- 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.
71
-
72
- ##### `customerExists` - `boolean` (Optional)
73
-
74
- > Note: Applies to Global Payments eCommerce only.
75
-
76
- If the consumer already has a customer record stored with Global Payments eCommerce, this value should be set to `true`.
77
-
78
- ##### `customerReference` - `string` (Optional)
79
-
80
- > Note: Applies to Global Payments eCommerce only.
81
-
82
- If `customerExists` is `true`, this should be set to the customer's reference value/ID (`PAYER_REF`).
83
-
84
- ##### `webApiKey` - `string` (Optional)
85
-
86
- > Note: Applies to Genius Checkout only.
87
-
88
- The API key associated with a given merchant account.
89
-
90
- ##### `deviceId` - `string` (Optional)
91
-
92
- > Note: Applies to TransIT / TSEP only.
93
-
94
- The device ID associated with a given account.
95
-
96
- ##### `manifest` - `string` (Optional)
97
-
98
- > Note: Applies to TransIT / TSEP only.
99
-
100
- An encrypted value generated by the integrating partner using the merchant ID, device ID, transaction amount, and transaction key.
101
-
102
- ##### `X-GP-Api-Key` - `string` (Optional)
103
-
104
- > Note: Applies to OpenEdge / Global Payments Integrated only.
105
-
106
- The API key associated with the account.
107
-
108
- ##### `X-GP-Environment` - `string` (Optional)
109
-
110
- > Note: Applies to OpenEdge / Global Payments Integrated only.
111
-
112
- The OpenEdge / Global Payments Integrated environment.
113
-
114
- ##### `merchantName` - `string` (Optional)
115
-
116
- > Note: Applies to Heartland Bill Pay only.
117
-
118
- The merchant name associated with a given account.
119
-
120
- ##### `accessToken` - `string` (Optional)
121
-
122
- > Note: Applies to GP API only.
123
-
124
- An access token created for an application. Requires the `PMT_POST_Create_Single` permission.
125
-
126
- ##### `accountName` - `string` (Optional)
127
-
128
- > Note: Applies to GP API only.
129
-
130
- The tokenization account name for the given merchant account. Only required if there are more than one tokenization account associated with the merchant account
131
-
132
- ##### `apiVersion` - `string` (Optional)
133
-
134
- > Note: Applies to GP API only.
135
-
136
- The target API version. Default is `2020-10-22`.
137
-
138
- ##### `reference` - `string` (Optional)
139
-
140
- > Note: Applies to GP API only.
141
-
142
- The transaction reference for the tokenization request. If not provided, a GUID is created and sent in the request.
143
-
144
- #### Examples
145
-
146
- ##### Heartland eCommerce
147
-
148
- ```javascript
149
- GlobalPayments.configure({
150
- publicApiKey: "pkapi_cert_dNpEYIISXCGDDyKJiV"
151
- });
152
- ```
153
-
154
- ##### Global Payments eCommerce
155
-
156
- ```javascript
157
- GlobalPayments.configure({
158
- merchantId: "merchant_id",
159
- account: "hpp",
160
- hash: (request) => {
161
- return fetch("/hash.php", {
162
- body: JSON.stringify(request),
163
- credentials: "omit",
164
- headers: new Headers({
165
- "Content-Type": "application/json",
166
- }),
167
- method: "POST",
168
- })
169
- .then((resp) => resp.json());
170
- },
171
- env: "sandbox"
172
- });
173
- ```
174
-
175
- #### Genius Checkout
176
-
177
- ```javascript
178
- GlobalPayments.configure({
179
- webApiKey: "YU8PX7668FGMSH5L",
180
- env: "sandbox",
181
- });
182
- ```
183
-
184
- #### TransIT / TSEP
185
-
186
- ```javascript
187
- GlobalPayments.configure({
188
- deviceId: "88700000322602",
189
- manifest: "3c26272b6769cfa8b0c3c5a14dda4fc5365ed75c7330233a221a6e82aec667f35513c70862dc34f4ca31de7b4c824e129d23f8bce035fbbaa55aeb9da07b5d90bfe5d53c",
190
- env: "sandbox",
191
- });
192
- ```
193
-
194
- #### OpenEdge / Global Payments Integrated
195
-
196
- ```javascript
197
- GlobalPayments.configure({
198
- "X-GP-Api-Key": "oljHkRy0mAK9wqbQuUGZ9AUoe3ZtDrH7",
199
- "X-GP-Environment": "dev",
200
- });
201
- ```
202
-
203
- #### Heartland Bill Pay
204
-
205
- ```javascript
206
- GlobalPayments.configure({
207
- merchantName: "IntegrationTesting",
208
- env: "sandbox",
209
- });
210
- ```
211
-
212
- ### Handling Global Errors
213
-
214
- 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:
215
-
216
- ```typescript
217
- type ErrorEventHandler = (error: IErrorEvent) => void;
218
- ```
219
-
220
- where `IErrorEvent` follows the form:
221
-
222
- ```javascript
223
- {
224
- error: true,
225
- reasons: [{
226
- code,
227
- message,
228
- }],
229
- }
230
- ```
231
-
232
- #### Example
233
-
234
- ```javascript
235
- GlobalPayments.on("error", (error) => {
236
- console.error(error);
237
- });
238
- ```
239
-
240
- ### Payment Request API
241
-
242
- The [Payment Request API](https://developer.mozilla.org/en-US/docs/Web/API/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.
243
-
244
- Here's a minimal example using a button and a simple $10 USD payment amount:
245
-
246
- ```html
247
- <div>
248
- <button type="button" id="paymentRequestPlainButton" style="display: none">Pay</button>
249
- </div>
250
- ```
251
-
252
- ```javascript
253
- var paymentRequestForm = GlobalPayments.paymentRequest.setup("#paymentRequestPlainButton", {
254
- total: {
255
- label: "Total",
256
- amount: { value: 10, currency: "USD" }
257
- }
258
- });
259
-
260
- paymentRequestForm.on("token-success", function (resp) {
261
- // Payment data was successfully tokenized
262
- console.log(response);
263
-
264
- // TODO: POST data to backend for processing
265
-
266
- // Mark the payment as `success`, `fail`, or `unknown`
267
- // after processing response is known
268
- GlobalPayments.paymentRequest.complete("success");
269
- });
270
- paymentRequestForm.on("token-error", function (resp) {
271
- // An error occurred during tokenization
272
- console.log(resp);
273
- });
274
- paymentRequestForm.on("error", function (resp) {
275
- // An error occurred during setup or tokenization
276
- console.log(resp);
277
- });
278
- ```
279
-
280
- No additional styles are applied:
281
-
282
- ![Example: Raw Payment Request API button](docs/images/example-raw-payment-request.png)
283
-
284
- This will attach the necessary event handlers to start the Payment Request payment flow once the button is clicked:
285
-
286
- ![Example: Payment Request API review screen](docs/images/example-raw-payment-request-review.png)
287
-
288
- ### Payment Methods
289
-
290
- This library currently supports:
291
-
292
- - [Credit/Debit Cards](#creditdebit-cards)
293
- - [Gift/Loyalty Cards](#giftloyalty-cards) (Heartland eCommerce only)
294
- - [ACH/eCheck Accounts](#achecheck-accounts) (Heartland eCommerce only)
295
-
296
- #### Credit/Debit Cards
297
-
298
- 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:
299
-
300
- ```html
301
- <form id="payment-form" action="/charge" method="get">
302
- <!-- Other input fields to capture relevant data -->
303
- <label for="billing-zip">Billing Zip Code</label>
304
- <input id="billing-zip" name="billing-zip" type="tel" />
305
-
306
- <!-- Target for the credit card form -->
307
- <div id="credit-card"></div>
308
- </form>
309
- ```
310
-
311
- and some JavaScript to setup the form:
312
-
313
- ```javascript
314
- const cardForm = GlobalPayments.creditCard.form("#credit-card");
315
-
316
- // form-level event handlers. examples:
317
- cardForm.ready(() => {
318
- console.log("Registration of all credit card fields occurred");
319
- });
320
- cardForm.on("token-success", (resp) => {
321
- // add payment token to form as a hidden input
322
- const token = document.createElement("input");
323
- token.type = "hidden";
324
- token.name = "payment-reference";
325
- token.value = resp.paymentReference;
326
-
327
- // submit data to the integration's backend for processing
328
- const form = document.getElementById("payment-form");
329
- form.appendChild(token);
330
- form.submit();
331
- });
332
- cardForm.on("token-error", (resp) => {
333
- // show error to the consumer
334
- });
335
-
336
- // field-level event handlers. example:
337
- cardForm.on("card-number", "register", () => {
338
- console.log("Registration of Card Number occurred");
339
- });
340
- ```
341
-
342
- This will create a form with our default styles on page load:
343
-
344
- ![Example: Drop-in credit card form](docs/images/example-drop-in-credit-card.png)
345
-
346
- > See demo on [JSFiddle](https://jsfiddle.net/71bs39xu/2/)
347
-
348
- If the default styles conflict with your desired UI/UX, you can opt-out by specifying the `blank` style:
349
-
350
- ```javascript
351
- const cardForm = GlobalPayments.creditCard.form("#credit-card", { style: "blank" });
352
- ```
353
-
354
- ![Example: Drop-in credit card form (blank)](docs/images/example-drop-in-blank-credit-card.png)
355
-
356
- > See demo on [JSFiddle](https://jsfiddle.net/nvq26y4s/2/)
357
-
358
- Styles can then be pushed to the form's fields as your integration requires:
359
-
360
- ```javascript
361
- cardForm.addStylesheet({
362
- // You styles
363
- });
364
- ```
365
-
366
- Need even more control/flexibility? Your integration can leverage the raw card form builder:
367
-
368
- ```html
369
- <form id="payment-form" action="/charge" method="get">
370
- <!-- Other input fields to capture relevant data -->
371
- <label for="billing-zip">Billing Zip Code</label>
372
- <input id="billing-zip" name="billing-zip" type="tel" />
373
-
374
- <!-- Targets for the credit card form's fields -->
375
- <div id="credit-card-card-holder"></div>
376
- <div id="credit-card-card-number"></div>
377
- <div id="credit-card-card-cvv"></div>
378
- <div id="credit-card-card-expiration"></div>
379
- <div id="credit-card-submit"></div>
380
- </form>
381
- ```
382
-
383
- ```javascript
384
- const cardForm = GlobalPayments.ui.form({
385
- fields: {
386
- "card-holder-name": {
387
- placeholder: "Jane Smith",
388
- target: "#credit-card-card-holder"
389
- },
390
- "card-number": {
391
- placeholder: "•••• •••• •••• ••••",
392
- target: "#credit-card-card-number"
393
- },
394
- "card-expiration": {
395
- placeholder: "MM / YYYY",
396
- target: "#credit-card-card-expiration"
397
- },
398
- "card-cvv": {
399
- placeholder: "•••",
400
- target: "#credit-card-card-cvv"
401
- },
402
- "submit": {
403
- value: "Submit",
404
- }
405
- },
406
- styles: {
407
- // Your styles
408
- }
409
- });
410
- ```
411
-
412
- ![Example: Raw credit card form](docs/images/example-raw-credit-card.png)
413
-
414
- > See demo on [JSFiddle](https://jsfiddle.net/dcy5wz2k/2/)
415
-
416
- #### Gift/Loyalty Cards
417
-
418
- > Note: Applies to Heartland eCommerce only.
419
-
420
- 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:
421
-
422
- ```html
423
- <form id="payment-form" action="/charge" method="get">
424
- <!-- Other input fields to capture relevant data -->
425
- <label for="billing-zip">Billing Zip Code</label>
426
- <input id="billing-zip" name="billing-zip" type="tel" />
427
-
428
- <!-- Target for the gift/loyalty card form -->
429
- <div id="gift-card"></div>
430
- </form>
431
- ```
432
-
433
- and some JavaScript to setup the form:
434
-
435
- ```javascript
436
- const cardForm = GlobalPayments.giftAndLoyalty.form("#gift-card");
437
-
438
- // form-level event handlers. examples:
439
- cardForm.ready(() => {
440
- console.log("Registration of all gift/loyalty card fields occurred");
441
- });
442
- cardForm.on("token-success", (resp) => {
443
- // add payment token to form as a hidden input
444
- const token = document.createElement("input");
445
- token.type = "hidden";
446
- token.name = "payment-reference";
447
- token.value = resp.paymentReference;
448
-
449
- // submit data to the integration's backend for processing
450
- const form = document.getElementById("payment-form");
451
- form.appendChild(token);
452
- form.submit();
453
- });
454
- cardForm.on("token-error", (resp) => {
455
- // show error to the consumer
456
- });
457
-
458
- // field-level event handlers. example:
459
- cardForm.on("card-number", "register", () => {
460
- console.log("Registration of Card Number occurred");
461
- });
462
- ```
463
-
464
- This will create a form with our default styles on page load:
465
-
466
- ![Example: Drop-in gift/loyalty form](docs/images/example-drop-in-gift.png)
467
-
468
- > See demo on [JSFiddle](https://jsfiddle.net/1ajrtd7h/3/)
469
-
470
- If the default styles conflict with your desired UI/UX, you can opt-out by specifying the `blank` style:
471
-
472
- ```javascript
473
- const cardForm = GlobalPayments.giftAndLoyalty.form("#gift-card", { style: "blank" });
474
- ```
475
-
476
- ![Example: Drop-in gift/loyalty form (blank)](docs/images/example-drop-in-blank-gift.png)
477
-
478
- > See demo on [JSFiddle](https://jsfiddle.net/6412jupd/4/)
479
-
480
- Styles can then be pushed to the form's fields as your integration requires:
481
-
482
- ```javascript
483
- cardForm.addStylesheet({
484
- // You styles
485
- });
486
- ```
487
-
488
- Need even more control/flexibility? Your integration can leverage the raw card form builder:
489
-
490
- ```html
491
- <form id="payment-form" action="/charge" method="get">
492
- <!-- Other input fields to capture relevant data -->
493
- <label for="billing-zip">Billing Zip Code</label>
494
- <input id="billing-zip" name="billing-zip" type="tel" />
495
-
496
- <!-- Targets for the gift/loyalty card form's fields -->
497
- <div id="gift-card-card-number"></div>
498
- <div id="gift-card-submit"></div>
499
- </form>
500
- ```
501
-
502
- ```javascript
503
- const cardForm = GlobalPayments.ui.form({
504
- fields: {
505
- "card-number": {
506
- placeholder: "•••• •••• •••• ••••",
507
- target: "#gift-card-card-number"
508
- },
509
- "submit": {
510
- value: "Submit",
511
- target: "#gift-card-submit"
512
- }
513
- },
514
- styles: {
515
- // Your styles
516
- }
517
- });
518
- ```
519
-
520
- ![Example: Raw gift/loyalty form](docs/images/example-raw-gift.png)
521
-
522
- > See demo on [JSFiddle](https://jsfiddle.net/yw0fh94t/3/)
523
-
524
- #### ACH/eCheck Accounts
525
-
526
- > Note: Applies to Heartland eCommerce only.
527
-
528
- 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:
529
-
530
- ```html
531
- <form id="payment-form" action="/charge" method="get">
532
- <!-- Other input fields to capture relevant data -->
533
- <label for="billing-zip">Billing Zip Code</label>
534
- <input id="billing-zip" name="billing-zip" type="tel" />
535
-
536
- <!-- Target for the ACH/eCheck form -->
537
- <div id="eCheck"></div>
538
- </form>
539
- ```
540
-
541
- and some JavaScript to setup the form:
542
-
543
- ```javascript
544
- const eCheckForm = GlobalPayments.eCheck.form("#eCheck");
545
-
546
- // form-level event handlers. examples:
547
- eCheckForm.ready(() => {
548
- console.log("Registration of all ACH/eCheck fields occurred");
549
- });
550
- eCheckForm.on("token-success", (resp) => {
551
- // add payment token to form as a hidden input
552
- const token = document.createElement("input");
553
- token.type = "hidden";
554
- token.name = "payment-reference";
555
- token.value = resp.paymentReference;
556
-
557
- // submit data to the integration's backend for processing
558
- const form = document.getElementById("payment-form");
559
- form.appendChild(token);
560
- form.submit();
561
- });
562
- eCheckForm.on("token-error", (resp) => {
563
- // show error to the consumer
564
- });
565
-
566
- // field-level event handlers. example:
567
- eCheckForm.on("account-number", "register", () => {
568
- console.log("Registration of Account Number occurred");
569
- });
570
- ```
571
-
572
- This will create a form with our default styles on page load:
573
-
574
- ![Example: Drop-in ACH/eCheck form](docs/images/example-drop-in-echeck.png)
575
-
576
- > See demo on [JSFiddle](https://jsfiddle.net/abjv3q1m/2/)
577
-
578
- If the default styles conflict with your desired UI/UX, you can opt-out by specifying the `blank` style:
579
-
580
- ```javascript
581
- const eCheckForm = GlobalPayments.eCheck.form("#eCheck", { style: "blank" });
582
- ```
583
-
584
- ![Example: Drop-in ACH/eCheck form (blank)](docs/images/example-drop-in-blank-echeck.png)
585
-
586
- > See demo on [JSFiddle](https://jsfiddle.net/vh87suwp/)
587
-
588
- Styles can then be pushed to the form's fields as your integration requires:
589
-
590
- ```javascript
591
- eCheckForm.addStylesheet({
592
- // You styles
593
- });
594
- ```
595
-
596
- Need even more control/flexibility? Your integration can leverage the raw form builder:
597
-
598
- ```html
599
- <form id="payment-form" action="/charge" method="get">
600
- <!-- Other input fields to capture relevant data -->
601
- <label for="billing-zip">Billing Zip Code</label>
602
- <input id="billing-zip" name="billing-zip" type="tel" />
603
-
604
- <!-- Targets for the gift/loyalty card form's fields -->
605
- <div id="eCheck-account-number"></div>
606
- <div id="eCheck-routing-number"></div>
607
- <div>
608
- <select name="eCheck-check-type">
609
- <option> -- Check Type -- </option>
610
- <option>Checking</option>
611
- <option>Savings</option>
612
- </select>
613
- </div>
614
- <div>
615
- <select name="eCheck-account-type">
616
- <option> -- Account Type -- </option>
617
- <option>Personal</option>
618
- <option>Business</option>
619
- </select>
620
- </div>
621
- <div id="eCheck-submit"></div>
622
- </form>
623
- ```
624
-
625
- ```javascript
626
- const eCheckForm = GlobalPayments.ui.form({
627
- fields: {
628
- "account-number": {
629
- placeholder: "Account Number",
630
- target: "#eCheck-account-number"
631
- },
632
- "routing-number": {
633
- placeholder: "•••••••••",
634
- target: "#eCheck-routing-number"
635
- },
636
- "submit": {
637
- value: "Submit",
638
- target: "#eCheck-submit"
639
- }
640
- },
641
- styles: {
642
- // Your styles
643
- }
644
- });
645
- ```
646
-
647
- ![Example: Raw ACH/eCheck form](docs/images/example-raw-echeck.png)
648
-
649
- > See demo on [JSFiddle](https://jsfiddle.net/zvn36p48/3/)
650
-
651
- ## Building from source
652
-
653
- ```bash
654
- yarn install
655
- yarn run build
656
- ```
657
-
658
- `yarn run build` will perform the following tasks:
659
-
660
- 1. Clean the `./dist/` directory.
661
- 2. Lints the Typescript files according to `tslint.json`.
662
- 3. Builds the Typescript files into `./dist/securesubmit.js` using `tsconfig.json`.
663
- 4. Minifies `./dist/securesubmit.js` into `./dist/securesubmit.min.js`.
664
- 5. Copies the needed asset files into `./dist/`.
665
-
666
- ## Development
667
-
668
- 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`.
669
-
670
- ### Watch files during development
671
-
672
- ```bash
673
- yarn run build -w
674
- ```
675
-
676
- ### Testing
677
-
678
- 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:
679
-
680
- ```
681
- ./test/run.sh
682
- ```
683
-
684
- or PowerShell script:
685
-
686
- ```
687
- .\test\run.ps1
688
- ```
689
-
690
- ## Contributing
691
-
692
- 1. Fork it
693
- 2. Create your feature branch (`git checkout -b my-new-feature`)
694
- 3. Commit your changes (`git commit -am 'Add some feature'`)
695
- 4. Push to the branch (`git push origin my-new-feature`)
696
- 5. Create new Pull Request
697
-
698
- ## LICENSE
699
-
700
- This project is licensed under the GPLv2 License. See [LICENSE.md](LICENSE.md) for details.
1
+ # Global Payments JavaScript Library
2
+
3
+ #### PCI Friendly Tokenization
4
+
5
+ This plugin allows you to use online payments (eCommerce) features of a variety of Global Payments brands &mdash; Heartland, Global Payments eCommerce, Cayan/Genius, TSYS, Global Payments Integration (fka OpenEdge) &mdash; 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.
6
+
7
+ ## Table of Contents
8
+
9
+ - [Usage](#usage)
10
+ - [Configuration](#configuration)
11
+ - [Options](#options)
12
+ - [Examples](#examples)
13
+ - [Handling Global Errors](#handling-global-errors)
14
+ - [Payment Request API](#payment-request-api)
15
+ - [Payment Methods](#payment-methods)
16
+ - [Credit/Debit Cards](#creditdebit-cards)
17
+ - [Gift/Loyalty Cards](#giftloyalty-cards)
18
+ - [ACH/eCheck Accounts](#achecheck-accounts)
19
+ - [Building from source](#building-from-source)
20
+ - [Development](#development)
21
+ - [Contributing](#contributing)
22
+ - [LICENSE](#license)
23
+
24
+ ## Usage
25
+
26
+ ```html
27
+ <script src="https://js.globalpay.com/v1/globalpayments.js"></script>
28
+ ```
29
+
30
+ > Note: Installing via NPM will only provide TypeScript types for type-checking.
31
+
32
+ ### Configuration
33
+
34
+ #### Options
35
+
36
+ ##### `publicApiKey` - `string` (Optional)
37
+
38
+ > Note: Applies to Heartland Online Payments only.
39
+
40
+ 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.
41
+
42
+ ##### `binCheck` - `object` (Optional)
43
+
44
+ > Note: Applies to Heartland Online Payments only.
45
+
46
+ Enables a BIN check for various capabilities.
47
+
48
+ | Key | Type | Default | Description |
49
+ |-----|------|---------|-------------|
50
+ | `hsaFsa` | `boolean` | `false` | Determines if the supplied card is for healthcare use (HSA/FSA). |
51
+ | `surcharge` | `boolean` | `false` | Deterimines if the supplied card can be surcharged. |
52
+
53
+ ##### `merchantId` - `string` (Optional)
54
+
55
+ > Note: Applies to Global Payments eCommerce and GP API only.
56
+
57
+ For Global Payments eCommerce integrations, the merchant ID value supplied for the account.
58
+
59
+ For GP API integrations using multi-merchant support, the merchant ID value for a specific merchant account supported by the partner.
60
+
61
+ ##### `account` - `string` (Optional)
62
+
63
+ > Note: Applies to Global Payments eCommerce only.
64
+
65
+ The account ID value supplied by Global Payments eCommerce.
66
+
67
+ ##### `env` - `string` (Optional)
68
+
69
+ Supported values:
70
+
71
+ - `production`
72
+ - `sandbox` (default)
73
+
74
+ > Note: For Heartland eCommerce, this value is inferred from the configured `publicApiKey`.
75
+
76
+ ##### `hash` - `(object) => Promise<object>` (Optional)
77
+
78
+ > Note: Applies to Global Payments eCommerce only.
79
+
80
+ - input: JS object for the request
81
+ - output: A promise value that resolves to the into JS object with the correct SHA1 hash
82
+
83
+ 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.
84
+
85
+ ##### `customerExists` - `boolean` (Optional)
86
+
87
+ > Note: Applies to Global Payments eCommerce only.
88
+
89
+ If the consumer already has a customer record stored with Global Payments eCommerce, this value should be set to `true`.
90
+
91
+ ##### `customerReference` - `string` (Optional)
92
+
93
+ > Note: Applies to Global Payments eCommerce only.
94
+
95
+ If `customerExists` is `true`, this should be set to the customer's reference value/ID (`PAYER_REF`).
96
+
97
+ ##### `webApiKey` - `string` (Optional)
98
+
99
+ > Note: Applies to Genius Checkout only.
100
+
101
+ The API key associated with a given merchant account.
102
+
103
+ ##### `deviceId` - `string` (Optional)
104
+
105
+ > Note: Applies to TransIT / TSEP only.
106
+
107
+ The device ID associated with a given account.
108
+
109
+ ##### `manifest` - `string` (Optional)
110
+
111
+ > Note: Applies to TransIT / TSEP only.
112
+
113
+ An encrypted value generated by the integrating partner using the merchant ID, device ID, transaction amount, and transaction key.
114
+
115
+ ##### `X-GP-Api-Key` - `string` (Optional)
116
+
117
+ > Note: Applies to OpenEdge / Global Payments Integrated only.
118
+
119
+ The API key associated with the account.
120
+
121
+ ##### `X-GP-Environment` - `string` (Optional)
122
+
123
+ > Note: Applies to OpenEdge / Global Payments Integrated only.
124
+
125
+ The OpenEdge / Global Payments Integrated environment.
126
+
127
+ ##### `merchantName` - `string` (Optional)
128
+
129
+ > Note: Applies to Heartland Bill Pay only.
130
+
131
+ The merchant name associated with a given account.
132
+
133
+ ##### `accessToken` - `string` (Optional)
134
+
135
+ > Note: Applies to GP API only.
136
+
137
+ An access token created for an application. Requires the `PMT_POST_Create_Single` permission.
138
+
139
+ ##### `accountName` - `string` (Optional)
140
+
141
+ > Note: Applies to GP API only.
142
+
143
+ The tokenization account name for the given merchant account. Only required if there are more than one tokenization account associated with the merchant account
144
+
145
+ ##### `apiVersion` - `string` (Optional)
146
+
147
+ > Note: Applies to GP API only.
148
+
149
+ The target API version. Default is `2020-10-22`.
150
+
151
+ ##### `reference` - `string` (Optional)
152
+
153
+ > Note: Applies to GP API only.
154
+
155
+ The transaction reference for the tokenization request. If not provided, a GUID is created and sent in the request.
156
+
157
+ ##### `enableAutocomplete` - `boolean` (Optional)
158
+
159
+ Enables autocomplete / autofill features. Default is `false`.
160
+
161
+ ##### `language` - `string` (Optional)
162
+
163
+ Value for the `html` element's `lang` attribute within the iframes. Default is `en`.
164
+
165
+ ##### `requireCardHolderName` - `boolean` (Optional)
166
+
167
+ > Note: Applies to GP API only.
168
+
169
+ Enables a mandatory restriction for card holdername field
170
+
171
+ ##### `enableCardFingerPrinting` - `boolean` (Optional)
172
+
173
+ > Note: Applies to GP API only.
174
+
175
+ enables the use of the fingerprint mode with "ALWAYS" value
176
+
177
+ #### Examples
178
+
179
+ ##### Heartland eCommerce
180
+
181
+ ```javascript
182
+ GlobalPayments.configure({
183
+ publicApiKey: "pkapi_cert_dNpEYIISXCGDDyKJiV"
184
+ });
185
+ ```
186
+
187
+ ##### Global Payments eCommerce
188
+
189
+ ```javascript
190
+ GlobalPayments.configure({
191
+ merchantId: "merchant_id",
192
+ account: "hpp",
193
+ hash: (request) => {
194
+ return fetch("/hash.php", {
195
+ body: JSON.stringify(request),
196
+ credentials: "omit",
197
+ headers: new Headers({
198
+ "Content-Type": "application/json",
199
+ }),
200
+ method: "POST",
201
+ })
202
+ .then((resp) => resp.json());
203
+ },
204
+ env: "sandbox"
205
+ });
206
+ ```
207
+
208
+ #### Genius Checkout
209
+
210
+ ```javascript
211
+ GlobalPayments.configure({
212
+ webApiKey: "YU8PX7668FGMSH5L",
213
+ env: "sandbox",
214
+ });
215
+ ```
216
+
217
+ #### TransIT / TSEP
218
+
219
+ ```javascript
220
+ GlobalPayments.configure({
221
+ deviceId: "88700000322602",
222
+ manifest: "3c26272b6769cfa8b0c3c5a14dda4fc5365ed75c7330233a221a6e82aec667f35513c70862dc34f4ca31de7b4c824e129d23f8bce035fbbaa55aeb9da07b5d90bfe5d53c",
223
+ env: "sandbox",
224
+ });
225
+ ```
226
+
227
+ #### OpenEdge / Global Payments Integrated
228
+
229
+ ```javascript
230
+ GlobalPayments.configure({
231
+ "X-GP-Api-Key": "oljHkRy0mAK9wqbQuUGZ9AUoe3ZtDrH7",
232
+ "X-GP-Environment": "dev",
233
+ });
234
+ ```
235
+
236
+ #### Heartland Bill Pay
237
+
238
+ ```javascript
239
+ GlobalPayments.configure({
240
+ merchantName: "IntegrationTesting",
241
+ env: "sandbox",
242
+ });
243
+ ```
244
+
245
+ ### Handling Global Errors
246
+
247
+ 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:
248
+
249
+ ```typescript
250
+ type ErrorEventHandler = (error: IErrorEvent) => void;
251
+ ```
252
+
253
+ where `IErrorEvent` follows the form:
254
+
255
+ ```javascript
256
+ {
257
+ error: true,
258
+ reasons: [{
259
+ code,
260
+ message,
261
+ }],
262
+ }
263
+ ```
264
+
265
+ #### Example
266
+
267
+ ```javascript
268
+ GlobalPayments.on("error", (error) => {
269
+ console.error(error);
270
+ });
271
+ ```
272
+
273
+ ### Payment Request API
274
+
275
+ The [Payment Request API](https://developer.mozilla.org/en-US/docs/Web/API/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.
276
+
277
+ Here's a minimal example using a button and a simple $10 USD payment amount:
278
+
279
+ ```html
280
+ <div>
281
+ <button type="button" id="paymentRequestPlainButton" style="display: none">Pay</button>
282
+ </div>
283
+ ```
284
+
285
+ ```javascript
286
+ var paymentRequestForm = GlobalPayments.paymentRequest.setup("#paymentRequestPlainButton", {
287
+ total: {
288
+ label: "Total",
289
+ amount: { value: 10, currency: "USD" }
290
+ }
291
+ });
292
+
293
+ paymentRequestForm.on("token-success", function (resp) {
294
+ // Payment data was successfully tokenized
295
+ console.log(response);
296
+
297
+ // TODO: POST data to backend for processing
298
+
299
+ // Mark the payment as `success`, `fail`, or `unknown`
300
+ // after processing response is known
301
+ GlobalPayments.paymentRequest.complete("success");
302
+ });
303
+ paymentRequestForm.on("token-error", function (resp) {
304
+ // An error occurred during tokenization
305
+ console.log(resp);
306
+ });
307
+ paymentRequestForm.on("error", function (resp) {
308
+ // An error occurred during setup or tokenization
309
+ console.log(resp);
310
+ });
311
+ ```
312
+
313
+ No additional styles are applied:
314
+
315
+ ![Example: Raw Payment Request API button](docs/images/example-raw-payment-request.png)
316
+
317
+ This will attach the necessary event handlers to start the Payment Request payment flow once the button is clicked:
318
+
319
+ ![Example: Payment Request API review screen](docs/images/example-raw-payment-request-review.png)
320
+
321
+ ### Payment Methods
322
+
323
+ This library currently supports:
324
+
325
+ - [Credit/Debit Cards](#creditdebit-cards)
326
+ - [Gift/Loyalty Cards](#giftloyalty-cards) (Heartland eCommerce only)
327
+ - [ACH/eCheck Accounts](#achecheck-accounts) (Heartland eCommerce only)
328
+
329
+ #### Credit/Debit Cards
330
+
331
+ 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:
332
+
333
+ ```html
334
+ <form id="payment-form" action="/charge" method="get">
335
+ <!-- Other input fields to capture relevant data -->
336
+ <label for="billing-zip">Billing Zip Code</label>
337
+ <input id="billing-zip" name="billing-zip" type="tel" />
338
+
339
+ <!-- Target for the credit card form -->
340
+ <div id="credit-card"></div>
341
+ </form>
342
+ ```
343
+
344
+ and some JavaScript to setup the form:
345
+
346
+ ```javascript
347
+ const cardForm = GlobalPayments.creditCard.form("#credit-card");
348
+
349
+ // form-level event handlers. examples:
350
+ cardForm.ready(() => {
351
+ console.log("Registration of all credit card fields occurred");
352
+ });
353
+ cardForm.on("token-success", (resp) => {
354
+ // add payment token to form as a hidden input
355
+ const token = document.createElement("input");
356
+ token.type = "hidden";
357
+ token.name = "payment-reference";
358
+ token.value = resp.paymentReference;
359
+
360
+ // submit data to the integration's backend for processing
361
+ const form = document.getElementById("payment-form");
362
+ form.appendChild(token);
363
+ form.submit();
364
+ });
365
+ cardForm.on("token-error", (resp) => {
366
+ // show error to the consumer
367
+ });
368
+
369
+ // field-level event handlers. example:
370
+ cardForm.on("card-number", "register", () => {
371
+ console.log("Registration of Card Number occurred");
372
+ });
373
+ ```
374
+
375
+ This will create a form with our default styles on page load:
376
+
377
+ ![Example: Drop-in credit card form](docs/images/example-drop-in-credit-card.png)
378
+
379
+ > See demo on [JSFiddle](https://jsfiddle.net/71bs39xu/2/)
380
+
381
+ If the default styles conflict with your desired UI/UX, you can opt-out by specifying the `blank` style:
382
+
383
+ ```javascript
384
+ const cardForm = GlobalPayments.creditCard.form("#credit-card", { style: "blank" });
385
+ ```
386
+
387
+ ![Example: Drop-in credit card form (blank)](docs/images/example-drop-in-blank-credit-card.png)
388
+
389
+ > See demo on [JSFiddle](https://jsfiddle.net/nvq26y4s/2/)
390
+
391
+ Styles can then be pushed to the form's fields as your integration requires:
392
+
393
+ ```javascript
394
+ cardForm.addStylesheet({
395
+ // You styles
396
+ });
397
+ ```
398
+
399
+ Need even more control/flexibility? Your integration can leverage the raw card form builder:
400
+
401
+ ```html
402
+ <form id="payment-form" action="/charge" method="get">
403
+ <!-- Other input fields to capture relevant data -->
404
+ <label for="billing-zip">Billing Zip Code</label>
405
+ <input id="billing-zip" name="billing-zip" type="tel" />
406
+
407
+ <!-- Targets for the credit card form's fields -->
408
+ <div id="credit-card-card-holder"></div>
409
+ <div id="credit-card-card-number"></div>
410
+ <div id="credit-card-card-cvv"></div>
411
+ <div id="credit-card-card-expiration"></div>
412
+ <div id="credit-card-submit"></div>
413
+ </form>
414
+ ```
415
+
416
+ ```javascript
417
+ const cardForm = GlobalPayments.ui.form({
418
+ fields: {
419
+ "card-holder-name": {
420
+ placeholder: "Jane Smith",
421
+ target: "#credit-card-card-holder"
422
+ },
423
+ "card-number": {
424
+ placeholder: "•••• •••• •••• ••••",
425
+ target: "#credit-card-card-number"
426
+ },
427
+ "card-expiration": {
428
+ placeholder: "MM / YYYY",
429
+ target: "#credit-card-card-expiration"
430
+ },
431
+ "card-cvv": {
432
+ placeholder: "•••",
433
+ target: "#credit-card-card-cvv"
434
+ },
435
+ "submit": {
436
+ value: "Submit",
437
+ }
438
+ },
439
+ styles: {
440
+ // Your styles
441
+ }
442
+ });
443
+ ```
444
+
445
+ ![Example: Raw credit card form](docs/images/example-raw-credit-card.png)
446
+
447
+ > See demo on [JSFiddle](https://jsfiddle.net/dcy5wz2k/2/)
448
+
449
+ #### Gift/Loyalty Cards
450
+
451
+ > Note: Applies to Heartland eCommerce only.
452
+
453
+ 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:
454
+
455
+ ```html
456
+ <form id="payment-form" action="/charge" method="get">
457
+ <!-- Other input fields to capture relevant data -->
458
+ <label for="billing-zip">Billing Zip Code</label>
459
+ <input id="billing-zip" name="billing-zip" type="tel" />
460
+
461
+ <!-- Target for the gift/loyalty card form -->
462
+ <div id="gift-card"></div>
463
+ </form>
464
+ ```
465
+
466
+ and some JavaScript to setup the form:
467
+
468
+ ```javascript
469
+ const cardForm = GlobalPayments.giftAndLoyalty.form("#gift-card");
470
+
471
+ // form-level event handlers. examples:
472
+ cardForm.ready(() => {
473
+ console.log("Registration of all gift/loyalty card fields occurred");
474
+ });
475
+ cardForm.on("token-success", (resp) => {
476
+ // add payment token to form as a hidden input
477
+ const token = document.createElement("input");
478
+ token.type = "hidden";
479
+ token.name = "payment-reference";
480
+ token.value = resp.paymentReference;
481
+
482
+ // submit data to the integration's backend for processing
483
+ const form = document.getElementById("payment-form");
484
+ form.appendChild(token);
485
+ form.submit();
486
+ });
487
+ cardForm.on("token-error", (resp) => {
488
+ // show error to the consumer
489
+ });
490
+
491
+ // field-level event handlers. example:
492
+ cardForm.on("card-number", "register", () => {
493
+ console.log("Registration of Card Number occurred");
494
+ });
495
+ ```
496
+
497
+ This will create a form with our default styles on page load:
498
+
499
+ ![Example: Drop-in gift/loyalty form](docs/images/example-drop-in-gift.png)
500
+
501
+ > See demo on [JSFiddle](https://jsfiddle.net/1ajrtd7h/3/)
502
+
503
+ If the default styles conflict with your desired UI/UX, you can opt-out by specifying the `blank` style:
504
+
505
+ ```javascript
506
+ const cardForm = GlobalPayments.giftAndLoyalty.form("#gift-card", { style: "blank" });
507
+ ```
508
+
509
+ ![Example: Drop-in gift/loyalty form (blank)](docs/images/example-drop-in-blank-gift.png)
510
+
511
+ > See demo on [JSFiddle](https://jsfiddle.net/6412jupd/4/)
512
+
513
+ Styles can then be pushed to the form's fields as your integration requires:
514
+
515
+ ```javascript
516
+ cardForm.addStylesheet({
517
+ // You styles
518
+ });
519
+ ```
520
+
521
+ Need even more control/flexibility? Your integration can leverage the raw card form builder:
522
+
523
+ ```html
524
+ <form id="payment-form" action="/charge" method="get">
525
+ <!-- Other input fields to capture relevant data -->
526
+ <label for="billing-zip">Billing Zip Code</label>
527
+ <input id="billing-zip" name="billing-zip" type="tel" />
528
+
529
+ <!-- Targets for the gift/loyalty card form's fields -->
530
+ <div id="gift-card-card-number"></div>
531
+ <div id="gift-card-submit"></div>
532
+ </form>
533
+ ```
534
+
535
+ ```javascript
536
+ const cardForm = GlobalPayments.ui.form({
537
+ fields: {
538
+ "card-number": {
539
+ placeholder: "•••• •••• •••• ••••",
540
+ target: "#gift-card-card-number"
541
+ },
542
+ "submit": {
543
+ value: "Submit",
544
+ target: "#gift-card-submit"
545
+ }
546
+ },
547
+ styles: {
548
+ // Your styles
549
+ }
550
+ });
551
+ ```
552
+
553
+ ![Example: Raw gift/loyalty form](docs/images/example-raw-gift.png)
554
+
555
+ > See demo on [JSFiddle](https://jsfiddle.net/yw0fh94t/3/)
556
+
557
+ #### ACH/eCheck Accounts
558
+
559
+ > Note: Applies to Heartland eCommerce only.
560
+
561
+ 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:
562
+
563
+ ```html
564
+ <form id="payment-form" action="/charge" method="get">
565
+ <!-- Other input fields to capture relevant data -->
566
+ <label for="billing-zip">Billing Zip Code</label>
567
+ <input id="billing-zip" name="billing-zip" type="tel" />
568
+
569
+ <!-- Target for the ACH/eCheck form -->
570
+ <div id="eCheck"></div>
571
+ </form>
572
+ ```
573
+
574
+ and some JavaScript to setup the form:
575
+
576
+ ```javascript
577
+ const eCheckForm = GlobalPayments.eCheck.form("#eCheck");
578
+
579
+ // form-level event handlers. examples:
580
+ eCheckForm.ready(() => {
581
+ console.log("Registration of all ACH/eCheck fields occurred");
582
+ });
583
+ eCheckForm.on("token-success", (resp) => {
584
+ // add payment token to form as a hidden input
585
+ const token = document.createElement("input");
586
+ token.type = "hidden";
587
+ token.name = "payment-reference";
588
+ token.value = resp.paymentReference;
589
+
590
+ // submit data to the integration's backend for processing
591
+ const form = document.getElementById("payment-form");
592
+ form.appendChild(token);
593
+ form.submit();
594
+ });
595
+ eCheckForm.on("token-error", (resp) => {
596
+ // show error to the consumer
597
+ });
598
+
599
+ // field-level event handlers. example:
600
+ eCheckForm.on("account-number", "register", () => {
601
+ console.log("Registration of Account Number occurred");
602
+ });
603
+ ```
604
+
605
+ This will create a form with our default styles on page load:
606
+
607
+ ![Example: Drop-in ACH/eCheck form](docs/images/example-drop-in-echeck.png)
608
+
609
+ > See demo on [JSFiddle](https://jsfiddle.net/abjv3q1m/2/)
610
+
611
+ If the default styles conflict with your desired UI/UX, you can opt-out by specifying the `blank` style:
612
+
613
+ ```javascript
614
+ const eCheckForm = GlobalPayments.eCheck.form("#eCheck", { style: "blank" });
615
+ ```
616
+
617
+ ![Example: Drop-in ACH/eCheck form (blank)](docs/images/example-drop-in-blank-echeck.png)
618
+
619
+ > See demo on [JSFiddle](https://jsfiddle.net/vh87suwp/)
620
+
621
+ Styles can then be pushed to the form's fields as your integration requires:
622
+
623
+ ```javascript
624
+ eCheckForm.addStylesheet({
625
+ // You styles
626
+ });
627
+ ```
628
+
629
+ Need even more control/flexibility? Your integration can leverage the raw form builder:
630
+
631
+ ```html
632
+ <form id="payment-form" action="/charge" method="get">
633
+ <!-- Other input fields to capture relevant data -->
634
+ <label for="billing-zip">Billing Zip Code</label>
635
+ <input id="billing-zip" name="billing-zip" type="tel" />
636
+
637
+ <!-- Targets for the gift/loyalty card form's fields -->
638
+ <div id="eCheck-account-number"></div>
639
+ <div id="eCheck-routing-number"></div>
640
+ <div>
641
+ <select name="eCheck-check-type">
642
+ <option> -- Check Type -- </option>
643
+ <option>Checking</option>
644
+ <option>Savings</option>
645
+ </select>
646
+ </div>
647
+ <div>
648
+ <select name="eCheck-account-type">
649
+ <option> -- Account Type -- </option>
650
+ <option>Personal</option>
651
+ <option>Business</option>
652
+ </select>
653
+ </div>
654
+ <div id="eCheck-submit"></div>
655
+ </form>
656
+ ```
657
+
658
+ ```javascript
659
+ const eCheckForm = GlobalPayments.ui.form({
660
+ fields: {
661
+ "account-number": {
662
+ placeholder: "Account Number",
663
+ target: "#eCheck-account-number"
664
+ },
665
+ "routing-number": {
666
+ placeholder: "•••••••••",
667
+ target: "#eCheck-routing-number"
668
+ },
669
+ "submit": {
670
+ value: "Submit",
671
+ target: "#eCheck-submit"
672
+ }
673
+ },
674
+ styles: {
675
+ // Your styles
676
+ }
677
+ });
678
+ ```
679
+
680
+ ![Example: Raw ACH/eCheck form](docs/images/example-raw-echeck.png)
681
+
682
+ > See demo on [JSFiddle](https://jsfiddle.net/zvn36p48/3/)
683
+
684
+ ## Building from source
685
+
686
+ ```bash
687
+ yarn install
688
+ yarn run build
689
+ ```
690
+
691
+ `yarn run build` will perform the following tasks:
692
+
693
+ 1. Clean the `./dist/` directory.
694
+ 2. Lints the Typescript files according to `tslint.json`.
695
+ 3. Builds the Typescript files into `./dist/securesubmit.js` using `tsconfig.json`.
696
+ 4. Minifies `./dist/securesubmit.js` into `./dist/securesubmit.min.js`.
697
+ 5. Copies the needed asset files into `./dist/`.
698
+
699
+ ## Development
700
+
701
+ 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`.
702
+
703
+ ### Watch files during development
704
+
705
+ ```bash
706
+ yarn run build -w
707
+ ```
708
+
709
+ ### Testing
710
+
711
+ 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:
712
+
713
+ ```
714
+ ./test/run.sh
715
+ ```
716
+
717
+ or PowerShell script:
718
+
719
+ ```
720
+ .\test\run.ps1
721
+ ```
722
+
723
+ ## Contributing
724
+
725
+ 1. Fork it
726
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
727
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
728
+ 4. Push to the branch (`git push origin my-new-feature`)
729
+ 5. Create new Pull Request
730
+
731
+ ## LICENSE
732
+
733
+ This project is licensed under the GPLv2 License. See [LICENSE.md](LICENSE.md) for details.