hps 2.2.2 → 2.2.5
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.
- checksums.yaml +4 -4
- data/examples/sinatra-verify-only/Gemfile +4 -0
- data/examples/sinatra-verify-only/app.rb +32 -0
- data/examples/sinatra-verify-only/public/images/cvv.png +0 -0
- data/examples/sinatra-verify-only/public/images/cvv1.png +0 -0
- data/examples/sinatra-verify-only/public/images/cvv2.png +0 -0
- data/examples/sinatra-verify-only/public/images/ss-cvv@2x.png +0 -0
- data/examples/sinatra-verify-only/public/images/ss-inputcard-blank@2x.png +0 -0
- data/examples/sinatra-verify-only/public/images/ss-saved-amex@2x.png +0 -0
- data/examples/sinatra-verify-only/public/images/ss-saved-discover@2x.png +0 -0
- data/examples/sinatra-verify-only/public/images/ss-saved-jcb@2x.png +0 -0
- data/examples/sinatra-verify-only/public/images/ss-saved-mastercard.png +0 -0
- data/examples/sinatra-verify-only/public/images/ss-saved-mastercard@2x.png +0 -0
- data/examples/sinatra-verify-only/public/images/ss-saved-visa@2x.png +0 -0
- data/examples/sinatra-verify-only/public/images/ss-savedcards-amex@2x.png +0 -0
- data/examples/sinatra-verify-only/public/images/ss-shield-ie.png +0 -0
- data/examples/sinatra-verify-only/public/images/ss-shield@1x.png +0 -0
- data/examples/sinatra-verify-only/public/images/ss-shield@2x.png +0 -0
- data/examples/sinatra-verify-only/views/index.erb +478 -0
- data/examples/sinatra-verify-only/views/result.erb +39 -0
- data/lib/hps.rb +1 -0
- data/lib/hps/entities/hps_manage_tokens.rb +9 -0
- data/lib/hps/services/hps_charge_service.rb +38 -0
- data/lib/hps/version.rb +1 -1
- data/tests/general_tests.rb +94 -19
- metadata +23 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 76db4e4f82ebe0a3399a498fc68055353cf82a7f
|
4
|
+
data.tar.gz: e61ba75e59c12b39e293faf121c4852895f38895
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 59b397a58ee800edac5b043b0f6208120e45a4f539674b816a21b5b46cc8bbfd495ee86e146b32e502b09dae6c27ca3affd4a50c022901cf86a2b07997a100b7
|
7
|
+
data.tar.gz: 789fdfd04c540a00cb620749419c2632527f25b4f8d89216ebee189209c4daf2a90269370da5efa9d9b40d9094b74d8bba69a57ecf725fe8b0a8ceff6267f23f
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
require 'hps'
|
3
|
+
|
4
|
+
Hps.configure do |config|
|
5
|
+
config.secret_api_key = 'skapi_cert_MTyMAQBiHVEAewvIzXVFcmUd2UcyBge_eCpaASUp0A'
|
6
|
+
end
|
7
|
+
|
8
|
+
service = Hps::HpsChargeService.new
|
9
|
+
|
10
|
+
get '/' do
|
11
|
+
erb :index
|
12
|
+
end
|
13
|
+
|
14
|
+
post '/charge' do
|
15
|
+
card_holder = Hps::HpsCardHolder.new
|
16
|
+
card_holder.first_name = request['FirstName']
|
17
|
+
card_holder.last_name = request['LastName']
|
18
|
+
card_holder.address = Hps::HpsAddress.new
|
19
|
+
card_holder.address.address = request['Address']
|
20
|
+
card_holder.address.city = request['City']
|
21
|
+
card_holder.address.state = request['State']
|
22
|
+
card_holder.address.zip = request['Zip']
|
23
|
+
|
24
|
+
token = request['token_value']
|
25
|
+
|
26
|
+
logger.info card_holder
|
27
|
+
logger.info token
|
28
|
+
|
29
|
+
verification = service.verify(token, card_holder, true)
|
30
|
+
|
31
|
+
erb :result, :locals => { :verification => verification }
|
32
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +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>
|
@@ -0,0 +1,39 @@
|
|
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
|
+
<h2>Results</h2>
|
26
|
+
|
27
|
+
<table>
|
28
|
+
<tr>
|
29
|
+
<td>Response Code</td>
|
30
|
+
<td><%= verification.response_code %>
|
31
|
+
</tr>
|
32
|
+
<tr>
|
33
|
+
<td>Multi-use Token</td>
|
34
|
+
<td><%= verification.token_data.token_value unless verification.token_data.nil? %>
|
35
|
+
</tr>
|
36
|
+
</table>
|
37
|
+
</div>
|
38
|
+
</body>
|
39
|
+
</html>
|
data/lib/hps.rb
CHANGED
@@ -29,6 +29,7 @@ require "hps/entities/hps_check"
|
|
29
29
|
require "hps/entities/hps_check_holder"
|
30
30
|
require "hps/entities/hps_check_response"
|
31
31
|
require "hps/entities/hps_check_response_details"
|
32
|
+
require "hps/entities/hps_manage_tokens"
|
32
33
|
|
33
34
|
# Infrastructure
|
34
35
|
require "hps/infrastructure/hps_sdk_codes"
|
@@ -435,6 +435,30 @@ module Hps
|
|
435
435
|
|
436
436
|
submit_void(xml.target!)
|
437
437
|
end
|
438
|
+
|
439
|
+
def update_token_expiration(token_value, exp_month, exp_year)
|
440
|
+
xml = Builder::XmlMarkup.new
|
441
|
+
xml.hps :Transaction do
|
442
|
+
xml.hps :ManageTokens do
|
443
|
+
xml.hps :TokenValue, token_value
|
444
|
+
xml.hps :TokenActions do
|
445
|
+
xml.hps :Set do
|
446
|
+
xml.hps :Attribute do
|
447
|
+
xml.hps :Name, "ExpMonth"
|
448
|
+
xml.hps :Value, format('%02d', exp_month)
|
449
|
+
end
|
450
|
+
xml.hps :Attribute do
|
451
|
+
xml.hps :Name, "ExpYear"
|
452
|
+
xml.hps :Value, exp_year
|
453
|
+
end
|
454
|
+
end
|
455
|
+
end
|
456
|
+
end
|
457
|
+
end
|
458
|
+
|
459
|
+
submit_manage_tokens(xml.target!)
|
460
|
+
end
|
461
|
+
|
438
462
|
private
|
439
463
|
|
440
464
|
def check_amount(amount)
|
@@ -671,6 +695,20 @@ module Hps
|
|
671
695
|
result
|
672
696
|
end
|
673
697
|
|
698
|
+
def submit_manage_tokens(transaction)
|
699
|
+
response = doTransaction(transaction)
|
700
|
+
header = response["Header"]
|
701
|
+
unless header["GatewayRspCode"].eql? "0"
|
702
|
+
raise @exception_mapper.map_gateway_exception(header["GatewayTxnId"], header["GatewayRspCode"], header["GatewayRspMsg"])
|
703
|
+
end
|
704
|
+
|
705
|
+
result = HpsManageTokens.new(hydrate_transaction_header(header))
|
706
|
+
result.transaction_id = header["GatewayTxnId"]
|
707
|
+
result.response_code = "00"
|
708
|
+
result.response_text = ""
|
709
|
+
result
|
710
|
+
end
|
711
|
+
|
674
712
|
def process_charge_gateway_response(response_code, response_text, transaction_id, amount, currency)
|
675
713
|
|
676
714
|
if !response_code.eql? "0"
|
data/lib/hps/version.rb
CHANGED
data/tests/general_tests.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
require File.join( File.dirname(__FILE__), "test_helper.rb" )
|
2
2
|
|
3
3
|
describe "General Tests" do
|
4
|
-
|
4
|
+
|
5
5
|
before(:each) do
|
6
6
|
Hps::TestHelper.configure_hps_module()
|
7
7
|
@service = Hps::HpsChargeService.new()
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
it "SecretAPIKey with spaces on Visa charge should return OK" do
|
11
11
|
Hps::TestHelper.configure_hps_module_secret_key_with_spaces
|
12
12
|
@service = Hps::HpsChargeService.new()
|
@@ -14,53 +14,128 @@ describe "General Tests" do
|
|
14
14
|
expect(result.response_code).to eql("00")
|
15
15
|
end
|
16
16
|
|
17
|
-
|
17
|
+
|
18
18
|
it "charge when amount is less than zero should throw invalid request exception" do
|
19
19
|
expect {
|
20
|
-
@service.charge(-5, "usd", Hps::TestData::valid_visa, Hps::TestData::valid_cardholder)
|
20
|
+
@service.charge(-5, "usd", Hps::TestData::valid_visa, Hps::TestData::valid_cardholder)
|
21
21
|
}.to raise_error(Hps::InvalidRequestException)
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
it "charge when currency is empty should throw invalid request exception" do
|
25
25
|
expect {
|
26
|
-
@service.charge(50, "", Hps::TestData::valid_visa, Hps::TestData::valid_cardholder)
|
26
|
+
@service.charge(50, "", Hps::TestData::valid_visa, Hps::TestData::valid_cardholder)
|
27
27
|
}.to raise_error(Hps::InvalidRequestException)
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
it "charge when currency is not usd should throw invalid request exception" do
|
31
31
|
expect {
|
32
|
-
@service.charge(50, "eur", Hps::TestData::valid_visa, Hps::TestData::valid_cardholder)
|
32
|
+
@service.charge(50, "eur", Hps::TestData::valid_visa, Hps::TestData::valid_cardholder)
|
33
33
|
}.to raise_error(Hps::InvalidRequestException)
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
it "charge when configuration is invalid should throw hps exception" do
|
37
37
|
expect {
|
38
38
|
@service = Hps::HpsChargeService.new :service_uri => nil
|
39
|
-
@service.charge(50, "usd", Hps::TestData::valid_visa, Hps::TestData::valid_cardholder)
|
39
|
+
@service.charge(50, "usd", Hps::TestData::valid_visa, Hps::TestData::valid_cardholder)
|
40
40
|
}.to raise_error(Hps::HpsException)
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
it "charge when license_id is invalid should throw authentication exception" do
|
44
44
|
expect {
|
45
45
|
@service = Hps::HpsChargeService.new :license_id => 11111
|
46
|
-
@service.charge(50, "usd", Hps::TestData::valid_visa, Hps::TestData::valid_cardholder)
|
46
|
+
@service.charge(50, "usd", Hps::TestData::valid_visa, Hps::TestData::valid_cardholder)
|
47
47
|
}.to raise_error(Hps::AuthenticationException)
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
it "charge when card number is invalid should throw hps exception" do
|
51
51
|
expect {
|
52
|
-
@service.charge(50, "usd", Hps::TestData::invalid_card, Hps::TestData::valid_cardholder)
|
52
|
+
@service.charge(50, "usd", Hps::TestData::invalid_card, Hps::TestData::valid_cardholder)
|
53
53
|
}.to raise_error(Hps::HpsException)
|
54
54
|
end
|
55
|
-
|
56
|
-
it "list when charge is in filter range should show in list" do
|
55
|
+
|
56
|
+
it "list when charge is in filter range should show in list" do
|
57
57
|
start_date = DateTime.now - 12.hours
|
58
|
-
charge = @service.charge(50, "usd", Hps::TestData::valid_visa, Hps::TestData::valid_cardholder)
|
58
|
+
charge = @service.charge(50, "usd", Hps::TestData::valid_visa, Hps::TestData::valid_cardholder)
|
59
59
|
end_date = DateTime.now
|
60
60
|
|
61
61
|
charges = @service.list(start_date, end_date)
|
62
|
-
expect(charges).to have_at_least(1).items
|
62
|
+
expect(charges).to have_at_least(1).items
|
63
63
|
expect(charges.any? { |c| c.transaction_id = charge.transaction_id }).to be_true
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
|
+
it "updates multi-use token" do
|
67
|
+
Hps::TestHelper.valid_multi_use_config
|
68
|
+
service = Hps::HpsChargeService.new()
|
69
|
+
verify = service.verify(Hps::TestData::valid_visa, Hps::TestData.valid_cardholder, true)
|
70
|
+
expect(verify).not_to be_nil
|
71
|
+
expect(verify.response_code).to eql("85")
|
72
|
+
expect(verify.token_data).not_to be_nil
|
73
|
+
expect(verify.token_data.token_value).not_to be_nil
|
74
|
+
expect(verify.token_data.token_value).not_to be_empty
|
75
|
+
|
76
|
+
month = Time.now.strftime('%m')
|
77
|
+
year = (Time.now + 2.years).strftime('%Y')
|
78
|
+
result = service.update_token_expiration(verify.token_data.token_value, month, year)
|
79
|
+
expect(result).not_to be_nil
|
80
|
+
expect(result.response_code).to eql("00")
|
81
|
+
end
|
82
|
+
|
83
|
+
it "fails to update multi-use token with bad year" do
|
84
|
+
Hps::TestHelper.valid_multi_use_config
|
85
|
+
service = Hps::HpsChargeService.new()
|
86
|
+
verify = service.verify(Hps::TestData::valid_visa, Hps::TestData.valid_cardholder, true)
|
87
|
+
expect(verify).not_to be_nil
|
88
|
+
expect(verify.response_code).to eql("85")
|
89
|
+
expect(verify.token_data).not_to be_nil
|
90
|
+
expect(verify.token_data.token_value).not_to be_nil
|
91
|
+
expect(verify.token_data.token_value).not_to be_empty
|
92
|
+
|
93
|
+
month = nil
|
94
|
+
year = 19
|
95
|
+
|
96
|
+
expect {
|
97
|
+
service.update_token_expiration(verify.token_data.token_value, month, year)
|
98
|
+
}.to raise_error(TypeError)
|
99
|
+
end
|
100
|
+
|
101
|
+
it "fails to update multi-use token with nil date" do
|
102
|
+
Hps::TestHelper.valid_multi_use_config
|
103
|
+
service = Hps::HpsChargeService.new()
|
104
|
+
verify = service.verify(Hps::TestData::valid_visa, Hps::TestData.valid_cardholder, true)
|
105
|
+
expect(verify).not_to be_nil
|
106
|
+
expect(verify.response_code).to eql("85")
|
107
|
+
expect(verify.token_data).not_to be_nil
|
108
|
+
expect(verify.token_data.token_value).not_to be_nil
|
109
|
+
expect(verify.token_data.token_value).not_to be_empty
|
110
|
+
|
111
|
+
month = nil
|
112
|
+
year = nil
|
113
|
+
|
114
|
+
expect {
|
115
|
+
service.update_token_expiration(verify.token_data.token_value, month, year)
|
116
|
+
}.to raise_error(TypeError)
|
117
|
+
end
|
118
|
+
|
119
|
+
it "fails to update multi-use token with invalid token" do
|
120
|
+
Hps::TestHelper.valid_multi_use_config
|
121
|
+
service = Hps::HpsChargeService.new()
|
122
|
+
month = Time.now.strftime('%m')
|
123
|
+
year = (Time.now + 2.years).strftime('%Y')
|
124
|
+
|
125
|
+
expect {
|
126
|
+
service.update_token_expiration("abcdefg", month, year)
|
127
|
+
}.to raise_error(Hps::HpsException)
|
128
|
+
end
|
129
|
+
|
130
|
+
it "fails to update multi-use token with nil token" do
|
131
|
+
Hps::TestHelper.valid_multi_use_config
|
132
|
+
service = Hps::HpsChargeService.new()
|
133
|
+
month = Time.now.strftime('%m')
|
134
|
+
year = (Time.now + 2.years).strftime('%Y')
|
135
|
+
|
136
|
+
expect {
|
137
|
+
service.update_token_expiration(nil, month, year)
|
138
|
+
}.to raise_error(Hps::HpsException)
|
139
|
+
end
|
140
|
+
|
66
141
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hps
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.2.
|
4
|
+
version: 2.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Heartland Payment Systems
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-10-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -118,6 +118,25 @@ files:
|
|
118
118
|
- PRIVACY.txt
|
119
119
|
- README.md
|
120
120
|
- Rakefile
|
121
|
+
- examples/sinatra-verify-only/Gemfile
|
122
|
+
- examples/sinatra-verify-only/app.rb
|
123
|
+
- examples/sinatra-verify-only/public/images/cvv.png
|
124
|
+
- examples/sinatra-verify-only/public/images/cvv1.png
|
125
|
+
- examples/sinatra-verify-only/public/images/cvv2.png
|
126
|
+
- examples/sinatra-verify-only/public/images/ss-cvv@2x.png
|
127
|
+
- examples/sinatra-verify-only/public/images/ss-inputcard-blank@2x.png
|
128
|
+
- examples/sinatra-verify-only/public/images/ss-saved-amex@2x.png
|
129
|
+
- examples/sinatra-verify-only/public/images/ss-saved-discover@2x.png
|
130
|
+
- examples/sinatra-verify-only/public/images/ss-saved-jcb@2x.png
|
131
|
+
- examples/sinatra-verify-only/public/images/ss-saved-mastercard.png
|
132
|
+
- examples/sinatra-verify-only/public/images/ss-saved-mastercard@2x.png
|
133
|
+
- examples/sinatra-verify-only/public/images/ss-saved-visa@2x.png
|
134
|
+
- examples/sinatra-verify-only/public/images/ss-savedcards-amex@2x.png
|
135
|
+
- examples/sinatra-verify-only/public/images/ss-shield-ie.png
|
136
|
+
- examples/sinatra-verify-only/public/images/ss-shield@1x.png
|
137
|
+
- examples/sinatra-verify-only/public/images/ss-shield@2x.png
|
138
|
+
- examples/sinatra-verify-only/views/index.erb
|
139
|
+
- examples/sinatra-verify-only/views/result.erb
|
121
140
|
- hps.gemspec
|
122
141
|
- lib/.DS_Store
|
123
142
|
- lib/hps.rb
|
@@ -136,6 +155,7 @@ files:
|
|
136
155
|
- lib/hps/entities/hps_credit_card.rb
|
137
156
|
- lib/hps/entities/hps_direct_market_data.rb
|
138
157
|
- lib/hps/entities/hps_encryption_data.rb
|
158
|
+
- lib/hps/entities/hps_manage_tokens.rb
|
139
159
|
- lib/hps/entities/hps_refund.rb
|
140
160
|
- lib/hps/entities/hps_report_transaction_details.rb
|
141
161
|
- lib/hps/entities/hps_report_transaction_summary.rb
|
@@ -203,7 +223,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
203
223
|
version: '0'
|
204
224
|
requirements: []
|
205
225
|
rubyforge_project:
|
206
|
-
rubygems_version: 2.6.
|
226
|
+
rubygems_version: 2.6.13
|
207
227
|
signing_key:
|
208
228
|
specification_version: 4
|
209
229
|
summary: Heartland Payment Systems - Portico Gateway SDK
|