hps 2.3.2 → 2.4.0

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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +4 -4
  3. data/Gemfile.lock +59 -0
  4. data/LICENSE.md +264 -264
  5. data/PRIVACY.txt +65 -65
  6. data/README.md +213 -213
  7. data/Rakefile +15 -15
  8. data/examples/sinatra-verify-only/Gemfile +4 -4
  9. data/examples/sinatra-verify-only/app.rb +32 -32
  10. data/examples/sinatra-verify-only/views/index.erb +478 -478
  11. data/examples/sinatra-verify-only/views/result.erb +39 -39
  12. data/hps.gemspec +28 -27
  13. data/lib/hps/configuration.rb +17 -17
  14. data/lib/hps/entities/hps_account_verify.rb +8 -8
  15. data/lib/hps/entities/hps_address.rb +6 -6
  16. data/lib/hps/entities/hps_authorization.rb +12 -12
  17. data/lib/hps/entities/hps_batch.rb +6 -6
  18. data/lib/hps/entities/hps_cardholder.rb +6 -6
  19. data/lib/hps/entities/hps_charge.rb +8 -8
  20. data/lib/hps/entities/hps_charge_exceptions.rb +6 -6
  21. data/lib/hps/entities/hps_check.rb +18 -18
  22. data/lib/hps/entities/hps_check_holder.rb +10 -10
  23. data/lib/hps/entities/hps_check_response.rb +45 -45
  24. data/lib/hps/entities/hps_check_response_details.rb +9 -9
  25. data/lib/hps/entities/hps_credit_card.rb +34 -34
  26. data/lib/hps/entities/hps_direct_market_data.rb +5 -5
  27. data/lib/hps/entities/hps_encryption_data.rb +6 -6
  28. data/lib/hps/entities/hps_gift_card.rb +133 -133
  29. data/lib/hps/entities/hps_manage_tokens.rb +8 -8
  30. data/lib/hps/entities/hps_refund.rb +8 -8
  31. data/lib/hps/entities/hps_report_transaction_details.rb +10 -10
  32. data/lib/hps/entities/hps_report_transaction_summary.rb +6 -6
  33. data/lib/hps/entities/hps_reversal.rb +10 -10
  34. data/lib/hps/entities/hps_token_data.rb +10 -10
  35. data/lib/hps/entities/hps_track_data.rb +5 -5
  36. data/lib/hps/entities/hps_transaction.rb +161 -161
  37. data/lib/hps/entities/hps_transaction_details.rb +6 -6
  38. data/lib/hps/entities/hps_transaction_header.rb +8 -8
  39. data/lib/hps/entities/hps_transaction_type.rb +16 -16
  40. data/lib/hps/entities/hps_void.rb +8 -8
  41. data/lib/hps/infrastructure/api_connection_exception.rb +11 -11
  42. data/lib/hps/infrastructure/authentication_exception.rb +11 -11
  43. data/lib/hps/infrastructure/card_exception.rb +15 -15
  44. data/lib/hps/infrastructure/exceptions.json +547 -547
  45. data/lib/hps/infrastructure/hps_account_type.rb +11 -11
  46. data/lib/hps/infrastructure/hps_check_exception.rb +13 -13
  47. data/lib/hps/infrastructure/hps_check_type.rb +11 -11
  48. data/lib/hps/infrastructure/hps_data_entry_mode.rb +11 -11
  49. data/lib/hps/infrastructure/hps_exception.rb +25 -25
  50. data/lib/hps/infrastructure/hps_exception_mapper.rb +145 -145
  51. data/lib/hps/infrastructure/hps_gateway_response_validation.rb +20 -20
  52. data/lib/hps/infrastructure/hps_input_validation.rb +13 -13
  53. data/lib/hps/infrastructure/hps_sdk_codes.rb +48 -48
  54. data/lib/hps/infrastructure/hps_sec_code.rb +27 -27
  55. data/lib/hps/infrastructure/hps_track_data_method.rb +6 -6
  56. data/lib/hps/infrastructure/invalid_request_exception.rb +15 -15
  57. data/lib/hps/services/hps_batch_service.rb +29 -29
  58. data/lib/hps/services/hps_charge_service.rb +773 -773
  59. data/lib/hps/services/hps_check_service.rb +110 -110
  60. data/lib/hps/services/hps_gift_card_service.rb +301 -301
  61. data/lib/hps/services/hps_service.rb +141 -136
  62. data/lib/hps/version.rb +3 -3
  63. data/lib/hps.rb +63 -63
  64. data/tests/amex_tests.rb +292 -292
  65. data/tests/cert_tests.rb +80 -80
  66. data/tests/certification/card_present_spec.rb +320 -320
  67. data/tests/certification/gift_card_certification_test.rb +106 -106
  68. data/tests/certification/gift_card_certification_tests.rb +107 -107
  69. data/tests/check_tests.rb +50 -50
  70. data/tests/discover_tests.rb +386 -386
  71. data/tests/exception_mapper_tests.rb +311 -311
  72. data/tests/general_tests.rb +140 -140
  73. data/tests/giftcard_tests.rb +212 -212
  74. data/tests/hps_token_service.rb +56 -56
  75. data/tests/mastercard_tests.rb +387 -387
  76. data/tests/secret_key.rb +11 -11
  77. data/tests/test_check.rb +77 -77
  78. data/tests/test_data.rb +138 -138
  79. data/tests/test_helper.rb +179 -179
  80. data/tests/token_tests.rb +512 -512
  81. data/tests/visa_tests.rb +445 -445
  82. metadata +31 -11
@@ -1,478 +1,478 @@
1
- <!--[if IE]><![endif]-->
2
- <!--[if lt IE 7 ]> <html lang="en" class="ie6"> <![endif]-->
3
- <!--[if IE 7 ]> <html lang="en" class="ie7"> <![endif]-->
4
- <!--[if IE 8 ]> <html lang="en" class="ie8"> <![endif]-->
5
- <!--[if IE 9 ]> <html lang="en" class="ie9"> <![endif]-->
6
- <!--[if (gt IE 9)|!(IE)]><!-->
7
- <html lang="en"><!--<![endif]-->
8
- <head>
9
- <meta charset="utf-8">
10
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
11
- <meta name="viewport" content="width=device-width, initial-scale=1">
12
- <meta name="description" content="SecureSubmit Ruby end-to-end payment example using tokenization.">
13
- <meta name="author" content="Mark Hagan">
14
- <title>Simple Payment Form Demo</title>
15
-
16
- <link src="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.css">
17
- <script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js"></script>
18
- </head>
19
- <body>
20
- <div class="container">
21
- <div class="row col-xs-12">
22
- <h1>Ruby SecureSubmit Example</h1>
23
- </div>
24
-
25
- <form class="payment_form form-horizontal" id="payment_form" action="/charge" method="POST">
26
- <div class="form-group row">
27
- <label for="FirstName" class="col-sm-2 control-label">First Name</label>
28
- <div class="col-sm-10">
29
- <input type="text" name="FirstName" />
30
- </div>
31
- </div>
32
- <div class="form-group row">
33
- <label for="LastName" class="col-sm-2 control-label">Last Name</label>
34
- <div class="col-sm-10">
35
- <input type="text" name="LastName" />
36
- </div>
37
- </div>
38
- <div class="form-group row">
39
- <label for="Address" class="col-sm-2 control-label">Address</label>
40
- <div class="col-sm-10">
41
- <input type="text" name="Address" />
42
- </div>
43
- </div>
44
- <div class="form-group row">
45
- <label for="City" class="col-sm-2 control-label">City</label>
46
- <div class="col-sm-10">
47
- <input type="text" name="City" />
48
- </div>
49
- </div>
50
- <div class="form-group row">
51
- <label for="State" class="col-sm-2 control-label">State</label>
52
- <div class="col-sm-10">
53
- <select Name="State">
54
- <option value="AL">Alabama</option>
55
- <option value="AK">Alaska</option>
56
- <option value="AZ">Arizona</option>
57
- <option value="AR">Arkansas</option>
58
- <option value="CA">California</option>
59
- <option value="CO">Colorado</option>
60
- <option value="CT">Connecticut</option>
61
- <option value="DE">Delaware</option>
62
- <option value="DC">District Of Columbia</option>
63
- <option value="FL">Florida</option>
64
- <option value="GA">Georgia</option>
65
- <option value="HI">Hawaii</option>
66
- <option value="ID">Idaho</option>
67
- <option value="IL">Illinois</option>
68
- <option value="IN">Indiana</option>
69
- <option value="IA">Iowa</option>
70
- <option value="KS">Kansas</option>
71
- <option value="KY">Kentucky</option>
72
- <option value="LA">Louisiana</option>
73
- <option value="ME">Maine</option>
74
- <option value="MD">Maryland</option>
75
- <option value="MA">Massachusetts</option>
76
- <option value="MI">Michigan</option>
77
- <option value="MN">Minnesota</option>
78
- <option value="MS">Mississippi</option>
79
- <option value="MO">Missouri</option>
80
- <option value="MT">Montana</option>
81
- <option value="NE">Nebraska</option>
82
- <option value="NV">Nevada</option>
83
- <option value="NH">New Hampshire</option>
84
- <option value="NJ">New Jersey</option>
85
- <option value="NM">New Mexico</option>
86
- <option value="NY">New York</option>
87
- <option value="NC">North Carolina</option>
88
- <option value="ND">North Dakota</option>
89
- <option value="OH">Ohio</option>
90
- <option value="OK">Oklahoma</option>
91
- <option value="OR">Oregon</option>
92
- <option value="PA">Pennsylvania</option>
93
- <option value="RI">Rhode Island</option>
94
- <option value="SC">South Carolina</option>
95
- <option value="SD">South Dakota</option>
96
- <option value="TN">Tennessee</option>
97
- <option value="TX">Texas</option>
98
- <option value="UT">Utah</option>
99
- <option value="VT">Vermont</option>
100
- <option value="VA">Virginia</option>
101
- <option value="WA">Washington</option>
102
- <option value="WV">West Virginia</option>
103
- <option value="WI">Wisconsin</option>
104
- <option value="WY">Wyoming</option>
105
- </select>
106
- </div>
107
- </div>
108
- <div class="form-group row">
109
- <label for="Zip" class="col-sm-2 control-label">Zip</label>
110
- <div class="col-sm-10">
111
- <input type="text" name="Zip" />
112
- </div>
113
- </div>
114
-
115
- <div class="container">
116
- <div class="row col-xs-12">
117
- <h2>Card Information</h2>
118
- <div id="ss-banner">
119
- </div>
120
- </div>
121
- <!-- make iframes styled like other form -->
122
- <style type="text/css">
123
- body {
124
- font-family:sans-serif;
125
- }
126
- #iframes iframe{
127
- float:left;
128
- width:100%;
129
- }
130
- .form-group {
131
- height:40px;
132
- }
133
- h2 {
134
- margin:7px 0;
135
- }
136
- #ss-card,
137
- #ss-date,
138
- #ss-cvv {
139
- height:85px;
140
- }
141
- #ss-card {
142
- margin-bottom:55px;
143
- display:block;
144
- }
145
- #ss-date {
146
- float:left;
147
- display:block;
148
- }
149
- #ss-cvv.form-group {
150
- float:right;
151
- }
152
- .ie8 form .iframeholder {
153
- padding:10px;
154
- }
155
- .iframeholder::after{
156
- content:'';
157
- display:block;
158
- width:100%;
159
- height:0px;
160
- clear:both;
161
- position:relative;
162
- }
163
- .ie8 form .form-group {
164
- margin-bottom:5px;
165
- }
166
- textarea {
167
- padding:10px;
168
- font-family:sans-serif;
169
- }
170
- label[for=iframesCardNumber],
171
- label[for=iframesCardExpiration],
172
- label[for=iframesCardCvv]{
173
- text-transform:uppercase;
174
- font-weight:500;
175
- font-size:13px;
176
- color:#555;
177
- line-height:1.5;
178
- }
179
- .ie8 form label {
180
- padding-left:10px;
181
- margin:0px;
182
- }
183
- #heartland-frame-cardExpiration,
184
- #heartland-frame-cardCvv,
185
- #heartland-frame-cardNumber,
186
- .ie8 #heartland-frame-cardExpiration,
187
- .ie8 #heartland-frame-cardCvv,
188
- .ie8 #heartland-frame-cardNumber {
189
- width:100%;
190
- }
191
- iframe {
192
- margin:0;
193
- padding:0;
194
- border:none;
195
- width:value;
196
- height:value;
197
- }
198
- #ss-banner {
199
- background:transparent url(/images/ss-shield@2x.png) no-repeat left center;
200
- height:40px;
201
- background-size:280px 34px;
202
- margin-bottom:7px;
203
- }
204
- .ie8 #ss-banner {
205
- background:transparent url(/images/ss-shield-ie.png) no-repeat left center;
206
- }
207
- .btn-primary{
208
- display:block;
209
- border-radius:0px;
210
- font-size:18px;
211
- float:right;
212
- background-color:#36b46e;
213
- border:1px solid #2a8d56;
214
- margin-bottom:10px;
215
- height:50px;
216
- color:#ffffff;
217
- width:100%;
218
- }
219
- .btn-primary:hover,
220
- .btn-primary:focus{
221
- color: #fff;
222
- background-color: #2a8d56;
223
- }
224
- .ie8 .btn-primary {
225
- width:15%;
226
- }
227
- .red {
228
- color:#ce2027;
229
- margin-left:2px;
230
- font-size:17px;
231
- }
232
- .container {
233
- margin:5px;
234
- }
235
- #ss-date.form-group,
236
- #ss-cvv.form-group{
237
- width:100%;
238
- }
239
-
240
-
241
- @media screen and (min-width:767px) {
242
-
243
- #heartland-frame-cardNumber {
244
- width : 100%;
245
- }
246
- }
247
- @media screen and (min-width:696px) {
248
- #ss-date.form-group,
249
- #ss-cvv.form-group{
250
- width:48%;
251
- }
252
- }
253
- @media screen and (min-width:636px) {
254
- #ss-card {
255
- margin-bottom:40px;
256
- }
257
- }
258
- @media screen and (min-width:450px) {
259
- .btn-primary,
260
- .ie8 .btn-primary {
261
- width:10em;
262
- }
263
- .container {
264
- margin:20px;
265
- }
266
- }
267
-
268
- </style>
269
-
270
- <!-- The Payment Form -->
271
- <form id="iframes" action="" method="GET">
272
- <!-- <div class="row col-xs-12">-->
273
- <div id="ss-card" class="form-group">
274
- <label for="iframesCardNumber">Card Number<span class="red">*</span><label>
275
- <div class="iframeholder" id="iframesCardNumber" style="height:50px; width:100%;"></div>
276
- </div>
277
- <div id="ss-date" class="form-group">
278
- <label for="iframesCardExpiration">Card Expiration<span class="red">*</span></label>
279
- <div class="iframeholder" id="iframesCardExpiration" style="height:50px; width:100%;"></div>
280
- </div>
281
- <div id="ss-cvv" class="form-group">
282
- <label for="iframesCardCvv">Card CVV<span class="red">*</span></label>
283
- <div class="iframeholder" id="iframesCardCvv" style="height:50px; width:100%;" /></div>
284
- </div>
285
- <div style="clear:both"></div>
286
- <input id="iframesSubmit" type="submit" class="btn btn-lg btn-primary" value="Submit" />
287
- </form>
288
-
289
- <!-- The SecureSubmit Javascript Library -->
290
- <script type="text/javascript" src="https://api2.heartlandportico.com/SecureSubmit.v1/token/2.1/securesubmit.js" href="assets/securesubmit.js"></script>
291
-
292
- <input type="hidden" name="token_value">
293
- </form>
294
-
295
- </div>
296
- <!-- The Integration Code -->
297
- <script type="text/javascript">
298
- (function (document, Heartland) {
299
- // Create a new `HPS` object with the necessary configuration
300
- var hps = new Heartland.HPS({
301
- publicKey: 'pkapi_cert_jKc1FtuyAydZhZfbB3',
302
- type: 'iframe',
303
- // Configure the iframe fields to tell the library where
304
- // the iframe should be inserted into the DOM and some
305
- // basic options
306
- fields: {
307
- cardNumber: {
308
- target: 'iframesCardNumber',
309
- placeholder: '•••• •••• •••• ••••'
310
- },
311
- cardExpiration: {
312
- target: 'iframesCardExpiration',
313
- placeholder: 'MM / YYYY'
314
- },
315
- cardCvv: {
316
- target: 'iframesCardCvv',
317
- placeholder: 'CVV'
318
- }
319
- },
320
- // Collection of CSS to inject into the iframes.
321
- // These properties can match the site's styles
322
- // to create a seamless experience.
323
- style: {
324
- 'input': {
325
- 'background': '#fff',
326
- 'border': '1px solid',
327
- 'border-color': '#bbb3b9 #c7c1c6 #c7c1c6',
328
- 'box-sizing': 'border-box',
329
- 'font-family': 'serif',
330
- 'font-size': '16px',
331
- 'line-height': '1',
332
- 'margin': '0 .5em 0 0',
333
- 'max-width': '100%',
334
- 'outline': '0',
335
- 'padding': '0.5278em',
336
- 'vertical-align': 'baseline',
337
- },
338
- '#heartland-field': {
339
- 'font-family':'sans-serif',
340
- 'box-sizing':'border-box',
341
- 'display': 'block',
342
- 'height': '50px',
343
- 'padding': '6px 12px',
344
- 'font-size': '14px',
345
- 'line-height': '1.42857143',
346
- 'color': '#555',
347
- 'background-color': '#fff',
348
- 'border': '1px solid #ccc',
349
- 'border-radius': '0px',
350
- '-webkit-box-shadow': 'inset 0 1px 1px rgba(0,0,0,.075)',
351
- 'box-shadow': 'inset 0 1px 1px rgba(0,0,0,.075)',
352
- '-webkit-transition': 'border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s',
353
- '-o-transition': 'border-color ease-in-out .15s,box-shadow ease-in-out .15s',
354
- 'transition': 'border-color ease-in-out .15s,box-shadow ease-in-out .15s',
355
- 'width':'100%'
356
- },
357
- 'input#heartland-field:focus' : {
358
- 'border':'1px solid #3989e3',
359
- 'outline':'none',
360
- 'box-shadow':'none'
361
- },
362
- 'input[type=submit]' : {
363
- 'box-sizing':'border-box',
364
- 'display': 'inline-block',
365
- 'padding': '6px 12px',
366
- 'margin-bottom': '0',
367
- 'font-size': '14px',
368
- 'font-weight': '400',
369
- 'line-height': '1.42857143',
370
- 'text-align': 'center',
371
- 'white-space': 'nowrap',
372
- 'vertical-align': 'middle',
373
- '-ms-touch-action': 'manipulation',
374
- 'touch-action': 'manipulation',
375
- 'cursor': 'pointer',
376
- '-webkit-user-select': 'none',
377
- '-moz-user-select': 'none',
378
- '-ms-user-select': 'none',
379
- 'user-select': 'none',
380
- 'background-image': 'none',
381
- 'border': '1px solid transparent',
382
- 'border-radius': '4px',
383
- 'color': '#fff',
384
- 'background-color': '#337ab7',
385
- 'border-color': '#2e6da4'
386
- },
387
- '#heartland-field[placeholder]' :{
388
- 'letter-spacing':'3px'
389
- },
390
- '#heartland-field[name=cardCvv]' :{
391
- 'background':'transparent url('+location.href+ 'images/cvv1.png) no-repeat right',
392
- 'background-size' :'63px 40px',
393
- },
394
- 'input#heartland-field[name=cardNumber]' : {
395
- 'background':'transparent url('+location.href+ 'images/ss-inputcard-blank@2x.png) no-repeat right',
396
- 'background-size' :'55px 35px'},
397
- '#heartland-field.invalid.card-type-visa' :{
398
- 'background':'transparent url('+location.href+ 'images/ss-saved-visa@2x.png) no-repeat right',
399
- 'background-size' :'83px 88px',
400
- 'background-position-y':'-44px'
401
- },
402
- '#heartland-field.valid.card-type-visa' :{
403
- 'background':'transparent url('+location.href+ 'images/ss-saved-visa@2x.png) no-repeat right top',
404
- 'background-size' :'82px 86px'
405
- },
406
- '#heartland-field.invalid.card-type-discover' :{
407
- 'background':'transparent url('+location.href+ 'images/ss-saved-discover@2x.png) no-repeat right',
408
- 'background-size' :'85px 90px',
409
- 'background-position-y' : '-44px'
410
- },
411
- '#heartland-field.valid.card-type-discover' :{
412
- 'background':'transparent url('+location.href+ 'images/ss-saved-discover@2x.png) no-repeat right',
413
- 'background-size' :'85px 90px',
414
- 'background-position-y' : '1px'
415
- },
416
- '#heartland-field.invalid.card-type-amex' :{
417
- 'background':'transparent url('+location.href+ 'images/ss-savedcards-amex@2x.png) no-repeat right',
418
- 'background-size' :'50px 90px',
419
- 'background-position-y':'-44px'
420
- },
421
- '#heartland-field.valid.card-type-amex' :{
422
- 'background':'transparent url('+location.href+ 'images/ss-savedcards-amex@2x.png) no-repeat right top',
423
- 'background-size' :'50px 90px'
424
- },
425
- '#heartland-field.invalid.card-type-mastercard' :{
426
- 'background':'transparent url('+location.href+ 'images/ss-saved-mastercard.png) no-repeat right',
427
- 'background-size' :'62px 105px',
428
- 'background-position-y':'-52px'
429
- },
430
- '#heartland-field.valid.card-type-mastercard' :{
431
- 'background':'transparent url('+location.href+ 'images/ss-saved-mastercard.png) no-repeat right',
432
- 'background-size' :'62px 105px',
433
- 'background-position-y':'-1px'
434
- },
435
- '#heartland-field.invalid.card-type-jcb' :{
436
- 'background':'transparent url('+location.href+ 'images/ss-saved-jcb@2x.png) no-repeat right',
437
- 'background-size' :'55px 94px',
438
- 'background-position-y':'-44px'
439
- },
440
- '#heartland-field.valid.card-type-jcb' :{
441
- 'background':'transparent url('+location.href+ 'images/ss-saved-jcb@2x.png) no-repeat right top',
442
- 'background-size' :'55px 94px',
443
- 'background-position-y':'2px'
444
- },
445
- 'input#heartland-field[name=cardNumber]::-ms-clear' : {
446
- 'display':'none'
447
- }
448
- },
449
- // Callback when a token is received from the service
450
- onTokenSuccess: function (resp) {
451
- document.querySelector("input[name=token_value]").value=resp.token_value;
452
- Heartland.Events.removeHandler(document.getElementById('payment_form'), 'submit');
453
- document.getElementById('payment_form').submit()
454
- },
455
- // Callback when an error is received from the service
456
- onTokenError: function (resp) {
457
- alert('There was an error: ' + resp.error.message);
458
- }
459
- });
460
-
461
- // Attach a handler to interrupt the form submission
462
- Heartland.Events.addHandler(document.getElementById('payment_form'), 'submit', function (e) {
463
- // Prevent the form from continuing to the `action` address
464
- e.preventDefault();
465
- // Tell the iframes to tokenize the data
466
- hps.Messages.post(
467
- {
468
- accumulateData: true,
469
- action: 'tokenize',
470
- message: 'pkapi_cert_jKc1FtuyAydZhZfbB3'
471
- },
472
- 'cardNumber'
473
- );
474
- });
475
- }(document, Heartland));
476
- </script>
477
- </body>
478
- </html>
1
+ <!--[if IE]><![endif]-->
2
+ <!--[if lt IE 7 ]> <html lang="en" class="ie6"> <![endif]-->
3
+ <!--[if IE 7 ]> <html lang="en" class="ie7"> <![endif]-->
4
+ <!--[if IE 8 ]> <html lang="en" class="ie8"> <![endif]-->
5
+ <!--[if IE 9 ]> <html lang="en" class="ie9"> <![endif]-->
6
+ <!--[if (gt IE 9)|!(IE)]><!-->
7
+ <html lang="en"><!--<![endif]-->
8
+ <head>
9
+ <meta charset="utf-8">
10
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
11
+ <meta name="viewport" content="width=device-width, initial-scale=1">
12
+ <meta name="description" content="SecureSubmit Ruby end-to-end payment example using tokenization.">
13
+ <meta name="author" content="Mark Hagan">
14
+ <title>Simple Payment Form Demo</title>
15
+
16
+ <link src="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.css">
17
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js"></script>
18
+ </head>
19
+ <body>
20
+ <div class="container">
21
+ <div class="row col-xs-12">
22
+ <h1>Ruby SecureSubmit Example</h1>
23
+ </div>
24
+
25
+ <form class="payment_form form-horizontal" id="payment_form" action="/charge" method="POST">
26
+ <div class="form-group row">
27
+ <label for="FirstName" class="col-sm-2 control-label">First Name</label>
28
+ <div class="col-sm-10">
29
+ <input type="text" name="FirstName" />
30
+ </div>
31
+ </div>
32
+ <div class="form-group row">
33
+ <label for="LastName" class="col-sm-2 control-label">Last Name</label>
34
+ <div class="col-sm-10">
35
+ <input type="text" name="LastName" />
36
+ </div>
37
+ </div>
38
+ <div class="form-group row">
39
+ <label for="Address" class="col-sm-2 control-label">Address</label>
40
+ <div class="col-sm-10">
41
+ <input type="text" name="Address" />
42
+ </div>
43
+ </div>
44
+ <div class="form-group row">
45
+ <label for="City" class="col-sm-2 control-label">City</label>
46
+ <div class="col-sm-10">
47
+ <input type="text" name="City" />
48
+ </div>
49
+ </div>
50
+ <div class="form-group row">
51
+ <label for="State" class="col-sm-2 control-label">State</label>
52
+ <div class="col-sm-10">
53
+ <select Name="State">
54
+ <option value="AL">Alabama</option>
55
+ <option value="AK">Alaska</option>
56
+ <option value="AZ">Arizona</option>
57
+ <option value="AR">Arkansas</option>
58
+ <option value="CA">California</option>
59
+ <option value="CO">Colorado</option>
60
+ <option value="CT">Connecticut</option>
61
+ <option value="DE">Delaware</option>
62
+ <option value="DC">District Of Columbia</option>
63
+ <option value="FL">Florida</option>
64
+ <option value="GA">Georgia</option>
65
+ <option value="HI">Hawaii</option>
66
+ <option value="ID">Idaho</option>
67
+ <option value="IL">Illinois</option>
68
+ <option value="IN">Indiana</option>
69
+ <option value="IA">Iowa</option>
70
+ <option value="KS">Kansas</option>
71
+ <option value="KY">Kentucky</option>
72
+ <option value="LA">Louisiana</option>
73
+ <option value="ME">Maine</option>
74
+ <option value="MD">Maryland</option>
75
+ <option value="MA">Massachusetts</option>
76
+ <option value="MI">Michigan</option>
77
+ <option value="MN">Minnesota</option>
78
+ <option value="MS">Mississippi</option>
79
+ <option value="MO">Missouri</option>
80
+ <option value="MT">Montana</option>
81
+ <option value="NE">Nebraska</option>
82
+ <option value="NV">Nevada</option>
83
+ <option value="NH">New Hampshire</option>
84
+ <option value="NJ">New Jersey</option>
85
+ <option value="NM">New Mexico</option>
86
+ <option value="NY">New York</option>
87
+ <option value="NC">North Carolina</option>
88
+ <option value="ND">North Dakota</option>
89
+ <option value="OH">Ohio</option>
90
+ <option value="OK">Oklahoma</option>
91
+ <option value="OR">Oregon</option>
92
+ <option value="PA">Pennsylvania</option>
93
+ <option value="RI">Rhode Island</option>
94
+ <option value="SC">South Carolina</option>
95
+ <option value="SD">South Dakota</option>
96
+ <option value="TN">Tennessee</option>
97
+ <option value="TX">Texas</option>
98
+ <option value="UT">Utah</option>
99
+ <option value="VT">Vermont</option>
100
+ <option value="VA">Virginia</option>
101
+ <option value="WA">Washington</option>
102
+ <option value="WV">West Virginia</option>
103
+ <option value="WI">Wisconsin</option>
104
+ <option value="WY">Wyoming</option>
105
+ </select>
106
+ </div>
107
+ </div>
108
+ <div class="form-group row">
109
+ <label for="Zip" class="col-sm-2 control-label">Zip</label>
110
+ <div class="col-sm-10">
111
+ <input type="text" name="Zip" />
112
+ </div>
113
+ </div>
114
+
115
+ <div class="container">
116
+ <div class="row col-xs-12">
117
+ <h2>Card Information</h2>
118
+ <div id="ss-banner">
119
+ </div>
120
+ </div>
121
+ <!-- make iframes styled like other form -->
122
+ <style type="text/css">
123
+ body {
124
+ font-family:sans-serif;
125
+ }
126
+ #iframes iframe{
127
+ float:left;
128
+ width:100%;
129
+ }
130
+ .form-group {
131
+ height:40px;
132
+ }
133
+ h2 {
134
+ margin:7px 0;
135
+ }
136
+ #ss-card,
137
+ #ss-date,
138
+ #ss-cvv {
139
+ height:85px;
140
+ }
141
+ #ss-card {
142
+ margin-bottom:55px;
143
+ display:block;
144
+ }
145
+ #ss-date {
146
+ float:left;
147
+ display:block;
148
+ }
149
+ #ss-cvv.form-group {
150
+ float:right;
151
+ }
152
+ .ie8 form .iframeholder {
153
+ padding:10px;
154
+ }
155
+ .iframeholder::after{
156
+ content:'';
157
+ display:block;
158
+ width:100%;
159
+ height:0px;
160
+ clear:both;
161
+ position:relative;
162
+ }
163
+ .ie8 form .form-group {
164
+ margin-bottom:5px;
165
+ }
166
+ textarea {
167
+ padding:10px;
168
+ font-family:sans-serif;
169
+ }
170
+ label[for=iframesCardNumber],
171
+ label[for=iframesCardExpiration],
172
+ label[for=iframesCardCvv]{
173
+ text-transform:uppercase;
174
+ font-weight:500;
175
+ font-size:13px;
176
+ color:#555;
177
+ line-height:1.5;
178
+ }
179
+ .ie8 form label {
180
+ padding-left:10px;
181
+ margin:0px;
182
+ }
183
+ #heartland-frame-cardExpiration,
184
+ #heartland-frame-cardCvv,
185
+ #heartland-frame-cardNumber,
186
+ .ie8 #heartland-frame-cardExpiration,
187
+ .ie8 #heartland-frame-cardCvv,
188
+ .ie8 #heartland-frame-cardNumber {
189
+ width:100%;
190
+ }
191
+ iframe {
192
+ margin:0;
193
+ padding:0;
194
+ border:none;
195
+ width:value;
196
+ height:value;
197
+ }
198
+ #ss-banner {
199
+ background:transparent url(/images/ss-shield@2x.png) no-repeat left center;
200
+ height:40px;
201
+ background-size:280px 34px;
202
+ margin-bottom:7px;
203
+ }
204
+ .ie8 #ss-banner {
205
+ background:transparent url(/images/ss-shield-ie.png) no-repeat left center;
206
+ }
207
+ .btn-primary{
208
+ display:block;
209
+ border-radius:0px;
210
+ font-size:18px;
211
+ float:right;
212
+ background-color:#36b46e;
213
+ border:1px solid #2a8d56;
214
+ margin-bottom:10px;
215
+ height:50px;
216
+ color:#ffffff;
217
+ width:100%;
218
+ }
219
+ .btn-primary:hover,
220
+ .btn-primary:focus{
221
+ color: #fff;
222
+ background-color: #2a8d56;
223
+ }
224
+ .ie8 .btn-primary {
225
+ width:15%;
226
+ }
227
+ .red {
228
+ color:#ce2027;
229
+ margin-left:2px;
230
+ font-size:17px;
231
+ }
232
+ .container {
233
+ margin:5px;
234
+ }
235
+ #ss-date.form-group,
236
+ #ss-cvv.form-group{
237
+ width:100%;
238
+ }
239
+
240
+
241
+ @media screen and (min-width:767px) {
242
+
243
+ #heartland-frame-cardNumber {
244
+ width : 100%;
245
+ }
246
+ }
247
+ @media screen and (min-width:696px) {
248
+ #ss-date.form-group,
249
+ #ss-cvv.form-group{
250
+ width:48%;
251
+ }
252
+ }
253
+ @media screen and (min-width:636px) {
254
+ #ss-card {
255
+ margin-bottom:40px;
256
+ }
257
+ }
258
+ @media screen and (min-width:450px) {
259
+ .btn-primary,
260
+ .ie8 .btn-primary {
261
+ width:10em;
262
+ }
263
+ .container {
264
+ margin:20px;
265
+ }
266
+ }
267
+
268
+ </style>
269
+
270
+ <!-- The Payment Form -->
271
+ <form id="iframes" action="" method="GET">
272
+ <!-- <div class="row col-xs-12">-->
273
+ <div id="ss-card" class="form-group">
274
+ <label for="iframesCardNumber">Card Number<span class="red">*</span><label>
275
+ <div class="iframeholder" id="iframesCardNumber" style="height:50px; width:100%;"></div>
276
+ </div>
277
+ <div id="ss-date" class="form-group">
278
+ <label for="iframesCardExpiration">Card Expiration<span class="red">*</span></label>
279
+ <div class="iframeholder" id="iframesCardExpiration" style="height:50px; width:100%;"></div>
280
+ </div>
281
+ <div id="ss-cvv" class="form-group">
282
+ <label for="iframesCardCvv">Card CVV<span class="red">*</span></label>
283
+ <div class="iframeholder" id="iframesCardCvv" style="height:50px; width:100%;" /></div>
284
+ </div>
285
+ <div style="clear:both"></div>
286
+ <input id="iframesSubmit" type="submit" class="btn btn-lg btn-primary" value="Submit" />
287
+ </form>
288
+
289
+ <!-- The SecureSubmit Javascript Library -->
290
+ <script type="text/javascript" src="https://api2.heartlandportico.com/SecureSubmit.v1/token/2.1/securesubmit.js" href="assets/securesubmit.js"></script>
291
+
292
+ <input type="hidden" name="token_value">
293
+ </form>
294
+
295
+ </div>
296
+ <!-- The Integration Code -->
297
+ <script type="text/javascript">
298
+ (function (document, Heartland) {
299
+ // Create a new `HPS` object with the necessary configuration
300
+ var hps = new Heartland.HPS({
301
+ publicKey: 'pkapi_cert_jKc1FtuyAydZhZfbB3',
302
+ type: 'iframe',
303
+ // Configure the iframe fields to tell the library where
304
+ // the iframe should be inserted into the DOM and some
305
+ // basic options
306
+ fields: {
307
+ cardNumber: {
308
+ target: 'iframesCardNumber',
309
+ placeholder: '•••• •••• •••• ••••'
310
+ },
311
+ cardExpiration: {
312
+ target: 'iframesCardExpiration',
313
+ placeholder: 'MM / YYYY'
314
+ },
315
+ cardCvv: {
316
+ target: 'iframesCardCvv',
317
+ placeholder: 'CVV'
318
+ }
319
+ },
320
+ // Collection of CSS to inject into the iframes.
321
+ // These properties can match the site's styles
322
+ // to create a seamless experience.
323
+ style: {
324
+ 'input': {
325
+ 'background': '#fff',
326
+ 'border': '1px solid',
327
+ 'border-color': '#bbb3b9 #c7c1c6 #c7c1c6',
328
+ 'box-sizing': 'border-box',
329
+ 'font-family': 'serif',
330
+ 'font-size': '16px',
331
+ 'line-height': '1',
332
+ 'margin': '0 .5em 0 0',
333
+ 'max-width': '100%',
334
+ 'outline': '0',
335
+ 'padding': '0.5278em',
336
+ 'vertical-align': 'baseline',
337
+ },
338
+ '#heartland-field': {
339
+ 'font-family':'sans-serif',
340
+ 'box-sizing':'border-box',
341
+ 'display': 'block',
342
+ 'height': '50px',
343
+ 'padding': '6px 12px',
344
+ 'font-size': '14px',
345
+ 'line-height': '1.42857143',
346
+ 'color': '#555',
347
+ 'background-color': '#fff',
348
+ 'border': '1px solid #ccc',
349
+ 'border-radius': '0px',
350
+ '-webkit-box-shadow': 'inset 0 1px 1px rgba(0,0,0,.075)',
351
+ 'box-shadow': 'inset 0 1px 1px rgba(0,0,0,.075)',
352
+ '-webkit-transition': 'border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s',
353
+ '-o-transition': 'border-color ease-in-out .15s,box-shadow ease-in-out .15s',
354
+ 'transition': 'border-color ease-in-out .15s,box-shadow ease-in-out .15s',
355
+ 'width':'100%'
356
+ },
357
+ 'input#heartland-field:focus' : {
358
+ 'border':'1px solid #3989e3',
359
+ 'outline':'none',
360
+ 'box-shadow':'none'
361
+ },
362
+ 'input[type=submit]' : {
363
+ 'box-sizing':'border-box',
364
+ 'display': 'inline-block',
365
+ 'padding': '6px 12px',
366
+ 'margin-bottom': '0',
367
+ 'font-size': '14px',
368
+ 'font-weight': '400',
369
+ 'line-height': '1.42857143',
370
+ 'text-align': 'center',
371
+ 'white-space': 'nowrap',
372
+ 'vertical-align': 'middle',
373
+ '-ms-touch-action': 'manipulation',
374
+ 'touch-action': 'manipulation',
375
+ 'cursor': 'pointer',
376
+ '-webkit-user-select': 'none',
377
+ '-moz-user-select': 'none',
378
+ '-ms-user-select': 'none',
379
+ 'user-select': 'none',
380
+ 'background-image': 'none',
381
+ 'border': '1px solid transparent',
382
+ 'border-radius': '4px',
383
+ 'color': '#fff',
384
+ 'background-color': '#337ab7',
385
+ 'border-color': '#2e6da4'
386
+ },
387
+ '#heartland-field[placeholder]' :{
388
+ 'letter-spacing':'3px'
389
+ },
390
+ '#heartland-field[name=cardCvv]' :{
391
+ 'background':'transparent url('+location.href+ 'images/cvv1.png) no-repeat right',
392
+ 'background-size' :'63px 40px',
393
+ },
394
+ 'input#heartland-field[name=cardNumber]' : {
395
+ 'background':'transparent url('+location.href+ 'images/ss-inputcard-blank@2x.png) no-repeat right',
396
+ 'background-size' :'55px 35px'},
397
+ '#heartland-field.invalid.card-type-visa' :{
398
+ 'background':'transparent url('+location.href+ 'images/ss-saved-visa@2x.png) no-repeat right',
399
+ 'background-size' :'83px 88px',
400
+ 'background-position-y':'-44px'
401
+ },
402
+ '#heartland-field.valid.card-type-visa' :{
403
+ 'background':'transparent url('+location.href+ 'images/ss-saved-visa@2x.png) no-repeat right top',
404
+ 'background-size' :'82px 86px'
405
+ },
406
+ '#heartland-field.invalid.card-type-discover' :{
407
+ 'background':'transparent url('+location.href+ 'images/ss-saved-discover@2x.png) no-repeat right',
408
+ 'background-size' :'85px 90px',
409
+ 'background-position-y' : '-44px'
410
+ },
411
+ '#heartland-field.valid.card-type-discover' :{
412
+ 'background':'transparent url('+location.href+ 'images/ss-saved-discover@2x.png) no-repeat right',
413
+ 'background-size' :'85px 90px',
414
+ 'background-position-y' : '1px'
415
+ },
416
+ '#heartland-field.invalid.card-type-amex' :{
417
+ 'background':'transparent url('+location.href+ 'images/ss-savedcards-amex@2x.png) no-repeat right',
418
+ 'background-size' :'50px 90px',
419
+ 'background-position-y':'-44px'
420
+ },
421
+ '#heartland-field.valid.card-type-amex' :{
422
+ 'background':'transparent url('+location.href+ 'images/ss-savedcards-amex@2x.png) no-repeat right top',
423
+ 'background-size' :'50px 90px'
424
+ },
425
+ '#heartland-field.invalid.card-type-mastercard' :{
426
+ 'background':'transparent url('+location.href+ 'images/ss-saved-mastercard.png) no-repeat right',
427
+ 'background-size' :'62px 105px',
428
+ 'background-position-y':'-52px'
429
+ },
430
+ '#heartland-field.valid.card-type-mastercard' :{
431
+ 'background':'transparent url('+location.href+ 'images/ss-saved-mastercard.png) no-repeat right',
432
+ 'background-size' :'62px 105px',
433
+ 'background-position-y':'-1px'
434
+ },
435
+ '#heartland-field.invalid.card-type-jcb' :{
436
+ 'background':'transparent url('+location.href+ 'images/ss-saved-jcb@2x.png) no-repeat right',
437
+ 'background-size' :'55px 94px',
438
+ 'background-position-y':'-44px'
439
+ },
440
+ '#heartland-field.valid.card-type-jcb' :{
441
+ 'background':'transparent url('+location.href+ 'images/ss-saved-jcb@2x.png) no-repeat right top',
442
+ 'background-size' :'55px 94px',
443
+ 'background-position-y':'2px'
444
+ },
445
+ 'input#heartland-field[name=cardNumber]::-ms-clear' : {
446
+ 'display':'none'
447
+ }
448
+ },
449
+ // Callback when a token is received from the service
450
+ onTokenSuccess: function (resp) {
451
+ document.querySelector("input[name=token_value]").value=resp.token_value;
452
+ Heartland.Events.removeHandler(document.getElementById('payment_form'), 'submit');
453
+ document.getElementById('payment_form').submit()
454
+ },
455
+ // Callback when an error is received from the service
456
+ onTokenError: function (resp) {
457
+ alert('There was an error: ' + resp.error.message);
458
+ }
459
+ });
460
+
461
+ // Attach a handler to interrupt the form submission
462
+ Heartland.Events.addHandler(document.getElementById('payment_form'), 'submit', function (e) {
463
+ // Prevent the form from continuing to the `action` address
464
+ e.preventDefault();
465
+ // Tell the iframes to tokenize the data
466
+ hps.Messages.post(
467
+ {
468
+ accumulateData: true,
469
+ action: 'tokenize',
470
+ message: 'pkapi_cert_jKc1FtuyAydZhZfbB3'
471
+ },
472
+ 'cardNumber'
473
+ );
474
+ });
475
+ }(document, Heartland));
476
+ </script>
477
+ </body>
478
+ </html>