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,773 +1,773 @@
1
- module Hps
2
- class HpsChargeService < HpsService
3
-
4
- def get(transaction_id)
5
-
6
- if transaction_id.nil? or transaction_id == 0
7
- raise @exception_mapper.map_sdk_exception(SdkCodes.invalid_transaction_id)
8
- end
9
-
10
- xml = Builder::XmlMarkup.new
11
- xml.hps :Transaction do
12
- xml.hps :ReportTxnDetail do
13
- xml.hps :TxnId, transaction_id
14
- end
15
- end
16
-
17
- response = doTransaction(xml.target!)
18
- detail = response["Transaction"]["ReportTxnDetail"]
19
-
20
- header = hydrate_transaction_header(response["Header"])
21
- result = HpsReportTransactionDetails.new(header)
22
- result.transaction_id = detail["GatewayTxnId"]
23
- result.original_transaction_id = detail["OriginalGatewayTxnId"]
24
- result.authorized_amount = detail["Data"]["AuthAmt"]
25
- result.authorization_code = detail["Data"]["AuthCode"]
26
- result.avs_result_code = detail["Data"]["AVSRsltCode"]
27
- result.avs_result_text = detail["Data"]["AVSRsltText"]
28
- result.card_type = detail["Data"]["CardType"]
29
- result.masked_card_number = detail["Data"]["MaskedCardNbr"]
30
- result.transaction_type = Hps.service_name_to_transaction_type(detail["ServiceName"])
31
- result.transaction_date = detail["RspUtcDT"]
32
- result.cpc_indicator = detail["Data"]["CPCInd"]
33
- result.cvv_result_code = detail["Data"]["CVVRsltCode"]
34
- result.cvv_result_text = detail["Data"]["CVVRsltText"]
35
- result.reference_number = detail["Data"]["RefNbr"]
36
- result.response_code = detail["Data"]["RspCode"]
37
- result.response_text = detail["Data"]["RspText"]
38
-
39
- tokenization_message = detail["Data"]["TokenizationMsg"]
40
-
41
- unless tokenization_message.nil?
42
- result.token_data = HpsTokenData.new(tokenization_message)
43
- end
44
-
45
- header_response_code = response["Header"]["GatewayRspCode"]
46
- data_response_code = detail["Data"]["RspCode"]
47
-
48
- if header_response_code != "0" or data_response_code != "0" or data_response_code != "00"
49
-
50
- exceptions = HpsChargeExceptions.new()
51
-
52
- if header_response_code != "0"
53
- message = response["Header"]["GatewayRspMsg"]
54
- exceptions.hps_exception = @exception_mapper.map_gateway_exception(result.transaction_id, header_response_code, message)
55
- end
56
-
57
- if data_response_code != "0" || data_response_code != "00"
58
- message = detail["Data"]["RspText"]
59
- exceptions.card_exception = @exception_mapper.map_issuer_exception(transaction_id, data_response_code, message)
60
- end
61
-
62
- result.exceptions = exceptions
63
-
64
- end
65
-
66
- result
67
-
68
- end
69
-
70
- def list(start_date, end_date, filter_by = nil)
71
-
72
- if start_date > DateTime.now
73
- raise @exception_mapper.map_sdk_exception(SdkCodes.invalid_start_date)
74
- elsif end_date > DateTime.now
75
- raise @exception_mapper.map_sdk_exception(SdkCodes.invalid_end_date)
76
- end
77
-
78
- xml = Builder::XmlMarkup.new
79
- xml.hps :Transaction do
80
- xml.hps :ReportActivity do
81
- xml.hps :RptStartUtcDT, start_date.utc.iso8601
82
- xml.hps :RptEndUtcDT, end_date.utc.iso8601
83
- end
84
- end
85
-
86
- response = doTransaction(xml.target!)
87
-
88
- # Gateway exception
89
- if response["Header"]["GatewayRspCode"] != "0"
90
- transaction_id = response["Header"]["GatewayTxnId"]
91
- response_code = response["Header"]["GatewayRspCode"]
92
- response_message = response["Header"]["GatewayRspMsg"]
93
- raise @exception_mapper.map_gateway_exception(transaction_id, response_code, response_message)
94
- end
95
-
96
- result = Array.new
97
-
98
- if response["Transaction"]["ReportActivity"]["Header"]["TxnCnt"] == "0"
99
- return result
100
- end
101
-
102
- response["Transaction"]["ReportActivity"]["Details"].each { |charge|
103
-
104
- next if !filter_by.nil? and charge.serviceName != Hps.transaction_type_to_service_name(filter_by)
105
-
106
- summary = HpsReportTransactionSummary.new()
107
- summary.transaction_id = charge["GatewayTxnId"]
108
- summary.original_transaction_id = charge["OriginalGatewayTxnId"]
109
- summary.masked_card_number = charge["MaskedCardNbr"]
110
- summary.response_code = charge["IssuerRspCode"]
111
- summary.response_text = charge["IssuerRspText"]
112
- summary.transaction_type = Hps.transaction_type_to_service_name(charge["ServiceName"]) if filter_by.nil? == false
113
-
114
- gw_response_code = charge["GatewayRspCode"]
115
- issuer_response_code = charge["IssuerRspCode"]
116
-
117
- if gw_response_code != "0" or issuer_response_code != "0" or issuer_response_code != "00"
118
-
119
- exceptions = HpsChargeExceptions.new()
120
-
121
- if gw_response_code != "0"
122
- message = charge["GatewayRspMsg"]
123
- exceptions.hps_exception = @exception_mapper.map_gateway_exception(charge["GatewayTxnId"], gw_response_code, message)
124
- end
125
-
126
- if issuer_response_code != "0" || issuer_response_code != "00"
127
- message = charge["IssuerRspText"]
128
- exceptions.card_exception = @exception_mapper.map_issuer_exception(charge["GatewayTxnId"], issuer_response_code, message)
129
- end
130
-
131
- summary.exceptions = exceptions
132
-
133
- end
134
-
135
- result << summary
136
- }
137
-
138
- result
139
- end
140
-
141
- def charge(amount, currency, card, card_holder = nil, request_multi_use_token = false, details = nil, txn_descriptor = nil)
142
- check_amount(amount)
143
- check_currency(currency)
144
-
145
- xml = Builder::XmlMarkup.new
146
- xml.hps :Transaction do
147
- xml.hps :CreditSale do
148
- xml.hps :Block1 do
149
- xml.hps :AllowDup, "Y"
150
- xml.hps :Amt, amount
151
- xml << hydrate_cardholder_data(card_holder) if card_holder
152
- xml << hydrate_additional_txn_fields(details) if details
153
- xml.hps :TxnDescriptor, txn_descriptor if txn_descriptor
154
- xml.hps :CardData do
155
-
156
- # NOTE: Process as Manual Entry if they gave us a Credit Card
157
- if card.is_a? HpsCreditCard
158
- xml << hydrate_manual_entry(card)
159
- # Note: Otherwise, consider it a token
160
- else
161
- xml.hps :TokenData do
162
- xml.hps :TokenValue, card
163
- end
164
- end
165
-
166
- xml.hps :TokenRequest, request_multi_use_token ? "Y" : "N"
167
-
168
- end
169
- end
170
- end
171
- end
172
-
173
- submit_charge(xml.target!, amount, currency)
174
- end
175
-
176
- def charge_swipe(amount, currency, track_data, encryption_data = nil, gratuity = 0, allow_partial_auth = false, txn_descriptor = nil, request_multi_use_token = false, direct_market_data = nil)
177
- check_amount(amount)
178
- check_currency(currency)
179
-
180
- xml = Builder::XmlMarkup.new
181
- xml.hps :Transaction do
182
- xml.hps :CreditSale do
183
- xml.hps :Block1 do
184
- xml.hps :AllowDup, "Y"
185
- xml.hps :Amt, amount
186
- xml.hps :GratuityAmtInfo, gratuity if gratuity != 0
187
- xml.hps :TxnDescriptor, txn_descriptor if txn_descriptor
188
- xml.hps :AllowPartialAuth, allow_partial_auth ? "Y" : "N"
189
- xml.hps :CardData do
190
- xml << hydrate_card_track_data(track_data)
191
- xml << hydrate_encryption_data(encryption_data) if encryption_data
192
- xml.hps :TokenRequest, request_multi_use_token ? "Y" : "N"
193
- end
194
- xml << hydrate_direct_market_data(direct_market_data) if direct_market_data
195
- end
196
- end
197
- end
198
-
199
- submit_charge(xml.target!, amount, currency)
200
- end
201
-
202
- def verify(card, card_holder = nil, request_multi_use_token = false, client_txn_id = nil)
203
-
204
- xml = Builder::XmlMarkup.new
205
- xml.hps :Transaction do
206
- xml.hps :CreditAccountVerify do
207
- xml.hps :Block1 do
208
- xml << hydrate_cardholder_data(card_holder) if card_holder
209
- xml.hps :CardData do
210
-
211
- # NOTE: Process as Manual Entry if they gave us a Credit Card
212
- if card.is_a? HpsCreditCard
213
- xml << hydrate_manual_entry(card)
214
- # Note: Otherwise, consider it a token
215
- else
216
- xml.hps :TokenData do
217
- xml.hps :TokenValue, card
218
- end
219
- end
220
-
221
- xml.hps :TokenRequest, request_multi_use_token ? "Y" : "N"
222
-
223
- end
224
- end
225
- end
226
- end
227
-
228
- submit_verify(xml.target!)
229
- end
230
-
231
- def verify_swipe(track_data, card_holder = nil, encryption_data = nil, request_multi_use_token = false, client_txn_id = nil)
232
-
233
- xml = Builder::XmlMarkup.new
234
- xml.hps :Transaction do
235
- xml.hps :CreditAccountVerify do
236
- xml.hps :Block1 do
237
- xml << hydrate_cardholder_data(card_holder) if card_holder
238
- xml.hps :CardData do
239
- xml << hydrate_card_track_data(track_data)
240
- xml << hydrate_encryption_data(encryption_data) if encryption_data
241
-
242
- xml.hps :TokenRequest, request_multi_use_token ? "Y" : "N"
243
- end
244
- end
245
- end
246
- end
247
-
248
- submit_verify(xml.target!)
249
- end
250
-
251
- def authorize(amount, currency, card, card_holder = nil, request_multi_use_token = false, details = nil, txn_descriptor = nil)
252
-
253
- check_amount(amount)
254
- check_currency(currency)
255
-
256
- xml = Builder::XmlMarkup.new
257
- xml.hps :Transaction do
258
- xml.hps :CreditAuth do
259
- xml.hps :Block1 do
260
- xml.hps :AllowDup, "Y"
261
- xml.hps :Amt, amount
262
- xml << hydrate_cardholder_data(card_holder) if card_holder
263
- xml << hydrate_additional_txn_fields(details) if details
264
- xml.hps :TxnDescriptor, txn_descriptor if txn_descriptor
265
- xml.hps :CardData do
266
-
267
- # NOTE: Process as Manual Entry if they gave us a Credit Card
268
- if card.is_a? HpsCreditCard
269
- xml << hydrate_manual_entry(card)
270
- # Note: Otherwise, consider it a token
271
- else
272
- xml.hps :TokenData do
273
- xml.hps :TokenValue, card
274
- end
275
- end
276
-
277
- xml.hps :TokenRequest, request_multi_use_token ? "Y" : "N"
278
-
279
- end
280
- end
281
- end
282
- end
283
-
284
- submit_authorize(xml.target!, amount, currency)
285
- end
286
-
287
- def authorize_swipe(amount, currency, track_data, encryption_data = nil, gratuity = 0, allow_partial_auth = false, txn_descriptor = nil)
288
- check_amount(amount)
289
- check_currency(currency)
290
-
291
- xml = Builder::XmlMarkup.new
292
- xml.hps :Transaction do
293
- xml.hps :CreditAuth do
294
- xml.hps :Block1 do
295
- xml.hps :AllowDup, "Y"
296
- xml.hps :Amt, amount
297
- xml.hps :TxnDescriptor, txn_descriptor if txn_descriptor
298
- xml.hps :AllowPartialAuth, allow_partial_auth ? "Y" : "N"
299
- xml.hps :CardData do
300
- xml << hydrate_card_track_data(track_data)
301
- xml << hydrate_encryption_data(encryption_data) if encryption_data
302
- end
303
- end
304
- end
305
- end
306
-
307
- submit_authorize(xml.target!, amount, currency)
308
- end
309
-
310
- def capture(transaction_id, amount = nil)
311
-
312
- xml = Builder::XmlMarkup.new
313
- xml.hps :Transaction do
314
- xml.hps :CreditAddToBatch do
315
- xml.hps :GatewayTxnId, transaction_id
316
- xml.hps :Amt, amount if amount
317
- end
318
- end
319
-
320
- response = doTransaction(xml.target!)
321
- header = response["Header"]
322
-
323
- raise @exception_mapper.map_gateway_exception(transaction_id, header["GatewayRspCode"], header["GatewayRspMsg"]) unless header["GatewayRspCode"].eql? "0"
324
-
325
- get(transaction_id)
326
- end
327
-
328
- def reverse(card, amount, currency, details = nil)
329
- check_amount(amount)
330
- check_currency(currency)
331
-
332
- xml = Builder::XmlMarkup.new
333
- xml.hps :Transaction do
334
- xml.hps :CreditReversal do
335
- xml.hps :Block1 do
336
- xml.hps :Amt, amount
337
- xml << hydrate_additional_txn_fields(details) if details
338
- xml.hps :CardData do
339
-
340
- # NOTE: Process as Manual Entry if they gave us a Credit Card
341
- if card.is_a? HpsCreditCard
342
- xml << hydrate_manual_entry(card)
343
- # Note: Otherwise, consider it a token
344
- else
345
- xml.hps :TokenData do
346
- xml.hps :TokenValue, card
347
- end
348
- end
349
-
350
- end
351
- end
352
- end
353
- end
354
-
355
- submit_reverse(xml.target!)
356
- end
357
-
358
- def reverse_transaction(transaction_id, amount, currency, details = nil)
359
- check_amount(amount)
360
- check_currency(currency)
361
-
362
- xml = Builder::XmlMarkup.new
363
- xml.hps :Transaction do
364
- xml.hps :CreditReversal do
365
- xml.hps :Block1 do
366
- xml.hps :Amt, amount
367
- xml.hps :GatewayTxnId, transaction_id
368
- xml << hydrate_additional_txn_fields(details) if details
369
- end
370
- end
371
- end
372
-
373
- submit_reverse(xml.target!)
374
- end
375
-
376
- def refund(amount, currency, card, card_holder = nil, details = nil)
377
- check_amount(amount)
378
- check_currency(currency)
379
-
380
- xml = Builder::XmlMarkup.new
381
- xml.hps :Transaction do
382
- xml.hps :CreditReturn do
383
- xml.hps :Block1 do
384
- xml.hps :AllowDup, "Y"
385
- xml.hps :Amt, amount
386
- xml << hydrate_cardholder_data(card_holder) if card_holder
387
- xml << hydrate_additional_txn_fields(details) if details
388
- xml.hps :CardData do
389
-
390
- # NOTE: Process as Manual Entry if they gave us a Credit Card
391
- if card.is_a? HpsCreditCard
392
- xml << hydrate_manual_entry(card)
393
- # Note: Otherwise, consider it a token
394
- else
395
- xml.hps :TokenData do
396
- xml.hps :TokenValue, card
397
- end
398
- end
399
-
400
- end
401
- end
402
- end
403
- end
404
-
405
- submit_refund(xml.target!)
406
- end
407
-
408
- def refund_transaction(amount, currency, transaction_id, card_holder = nil, details = nil)
409
- check_amount(amount)
410
- check_currency(currency)
411
-
412
- xml = Builder::XmlMarkup.new
413
- xml.hps :Transaction do
414
- xml.hps :CreditReturn do
415
- xml.hps :Block1 do
416
- xml.hps :AllowDup, "Y"
417
- xml.hps :Amt, amount
418
- xml.hps :GatewayTxnId, transaction_id
419
- xml << hydrate_cardholder_data(card_holder) if card_holder
420
- xml << hydrate_additional_txn_fields(details) if details
421
- end
422
- end
423
- end
424
-
425
- submit_refund(xml.target!)
426
- end
427
-
428
- def void(transaction_id)
429
- xml = Builder::XmlMarkup.new
430
- xml.hps :Transaction do
431
- xml.hps :CreditVoid do
432
- xml.hps :GatewayTxnId, transaction_id
433
- end
434
- end
435
-
436
- submit_void(xml.target!)
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
-
462
- private
463
-
464
- def check_amount(amount)
465
- raise @exception_mapper.map_sdk_exception(SdkCodes.invalid_amount) if amount.nil? or amount <= 0
466
- end
467
-
468
- def check_currency(currency)
469
- raise @exception_mapper.map_sdk_exception(SdkCodes.missing_currency) if currency.empty?
470
- raise @exception_mapper.map_sdk_exception(SdkCodes.invalid_currency) unless currency.downcase.eql? "usd"
471
- end
472
-
473
- def hydrate_cardholder_data(card_holder)
474
- xml = Builder::XmlMarkup.new
475
- xml.hps :CardHolderData do
476
- xml.hps :CardHolderFirstName, card_holder.first_name
477
- xml.hps :CardHolderLastName, card_holder.last_name
478
- xml.hps :CardHolderEmail, card_holder.email_address
479
- xml.hps :CardHolderPhone, card_holder.phone
480
- xml.hps :CardHolderAddr, card_holder.address.address
481
- xml.hps :CardHolderCity, card_holder.address.city
482
- xml.hps :CardHolderState, card_holder.address.state
483
- xml.hps :CardHolderZip, card_holder.address.zip
484
- end
485
- xml.target!
486
- end
487
-
488
- def hydrate_manual_entry(card)
489
- xml = Builder::XmlMarkup.new
490
- xml.hps :ManualEntry do
491
- xml.hps :CardNbr, card.number
492
- xml.hps :ExpMonth, card.exp_month
493
- xml.hps :ExpYear, card.exp_year
494
- xml.hps :CVV2, card.cvv
495
- xml.hps :CardPresent, card.card_present ? "Y" : "N"
496
- xml.hps :ReaderPresent, card.reader_present ? "Y" : "N"
497
- end
498
- xml.target!
499
- end
500
-
501
- def hydrate_card_track_data(track_data)
502
- xml = Builder::XmlMarkup.new
503
- xml.hps :TrackData, :method => track_data.method_obtained do
504
- xml << track_data.value
505
- end
506
- xml.target!
507
- end
508
-
509
- def hydrate_encryption_data(data)
510
- xml = Builder::XmlMarkup.new
511
- xml.hps :EncryptionData do
512
- xml.hps :EncryptedTrackNumber, data.encrypted_track_number if data.encrypted_track_number
513
- xml.hps :KSN, data.ksn if data.ksn
514
- xml.hps :KTB, data.ktb if data.ktb
515
- xml.hps :Version, data.version if data.version
516
- end
517
- xml.target!
518
- end
519
-
520
- def hydrate_direct_market_data(data)
521
- xml = Builder::XmlMarkup.new
522
- xml.hps :DirectMktData do
523
- xml.hps :DirectMktInvoideNbr, data.invoice_number
524
- xml.hps :DirectMktShipMonth, data.ship_month
525
- xml.hps :DirectMktShipDay, data.ship_day
526
- end
527
- xml.target!
528
- end
529
-
530
- def hydrate_additional_txn_fields(details)
531
- xml = Builder::XmlMarkup.new
532
- xml.hps :AdditionalTxnFields do
533
- xml.hps :Description, details.memo if details.memo
534
- xml.hps :InvoiceNbr, details.invoice_number if details.invoice_number
535
- xml.hps :CustomerID, details.customer_id if details.customer_id
536
- end
537
- xml.target!
538
- end
539
-
540
- def submit_charge(transaction, amount, currency)
541
-
542
- response = doTransaction(transaction)
543
-
544
- header = response["Header"]
545
- process_charge_gateway_response(header["GatewayRspCode"], header["GatewayRspMsg"], header["GatewayTxnId"], amount, currency)
546
-
547
- creditSaleRsp = response["Transaction"]["CreditSale"]
548
- process_charge_issuer_response(creditSaleRsp["RspCode"], creditSaleRsp["RspText"], header["GatewayTxnId"], amount, currency)
549
-
550
- result = HpsCharge.new(hydrate_transaction_header(header))
551
- result.transaction_id = header["GatewayTxnId"]
552
- result.authorized_amount = creditSaleRsp["AuthAmt"]
553
- result.authorization_code = creditSaleRsp["AuthCode"]
554
- result.avs_result_code = creditSaleRsp["AVSRsltCode"]
555
- result.avs_result_text = creditSaleRsp["AVSRsltText"]
556
- result.card_type = creditSaleRsp["CardType"]
557
- result.cpc_indicator = creditSaleRsp["CPCInd"]
558
- result.cvv_result_code = creditSaleRsp["CVVRsltCode"]
559
- result.cvv_result_text = creditSaleRsp["CVVRsltText"]
560
- result.reference_number = creditSaleRsp["RefNbr"]
561
- result.response_code = creditSaleRsp["RspCode"]
562
- result.response_text = creditSaleRsp["RspText"]
563
-
564
- unless header["TokenData"].nil?
565
- result.token_data = HpsTokenData.new()
566
- result.token_data.response_code = header["TokenData"]["TokenRspCode"];
567
- result.token_data.response_message = header["TokenData"]["TokenRspMsg"]
568
- result.token_data.token_value = header["TokenData"]["TokenValue"]
569
- end
570
-
571
- result
572
- end
573
-
574
- def submit_authorize(transaction, amount, currency)
575
-
576
- response = doTransaction(transaction)
577
- header = response["Header"]
578
- process_charge_gateway_response(header["GatewayRspCode"], header["GatewayRspMsg"], header["GatewayTxnId"], amount, currency)
579
-
580
- auth_response = response["Transaction"]["CreditAuth"]
581
- process_charge_issuer_response(auth_response["RspCode"], auth_response["RspText"], header["GatewayTxnId"], amount, currency)
582
-
583
- result = HpsAuthorization.new(hydrate_transaction_header(header))
584
- result.transaction_id = header["GatewayTxnId"]
585
- result.authorized_amount = auth_response["AuthAmt"]
586
- result.authorization_code = auth_response["AuthCode"]
587
- result.avs_result_code = auth_response["AVSRsltCode"]
588
- result.avs_result_text = auth_response["AVSRsltText"]
589
- result.card_type = auth_response["CardType"]
590
- result.cpc_indicator = auth_response["CPCInd"]
591
- result.cvv_result_code = auth_response["CVVRsltCode"]
592
- result.cvv_result_text = auth_response["CVVRsltText"]
593
- result.reference_number = auth_response["RefNbr"]
594
- result.response_code = auth_response["RspCode"]
595
- result.response_text = auth_response["RspText"]
596
-
597
- unless header["TokenData"].nil?
598
- result.token_data = HpsTokenData.new()
599
- result.token_data.response_code = header["TokenData"]["TokenRspCode"];
600
- result.token_data.response_message = header["TokenData"]["TokenRspMsg"]
601
- result.token_data.token_value = header["TokenData"]["TokenValue"]
602
- end
603
-
604
- result
605
- end
606
-
607
- def submit_refund(transaction)
608
-
609
- response = doTransaction(transaction)
610
- header = response["Header"]
611
-
612
- unless header["GatewayRspCode"].eql? "0"
613
- raise @exception_mapper.map_gateway_exception(header["GatewayTxnId"], header["GatewayRspCode"], header["GatewayRspMsg"])
614
- end
615
-
616
- result = HpsRefund.new(hydrate_transaction_header(header))
617
- result.transaction_id = header["GatewayTxnId"]
618
- result.response_code = "00"
619
- result.response_text = ""
620
-
621
- result
622
- end
623
-
624
- def submit_reverse(transaction)
625
-
626
- response = doTransaction(transaction)
627
- header = response["Header"]
628
-
629
- if !header["GatewayRspCode"].eql? "0"
630
- raise @exception_mapper.map_gateway_exception(header["GatewayTxnId"], header["GatewayRspCode"], header["GatewayRspMsg"])
631
- end
632
-
633
- reversal = response["Transaction"]["CreditReversal"]
634
- result = HpsReversal.new(hydrate_transaction_header(header))
635
- result.transaction_id = header["GatewayTxnId"]
636
- result.avs_result_code = reversal["AVSRsltCode"]
637
- result.avs_result_text = reversal["AVSRsltText"]
638
- result.cpc_indicator = reversal["CPCInd"]
639
- result.cvv_result_code = reversal["CVVRsltCode"]
640
- result.cvv_result_text = reversal["CVVRsltText"]
641
- result.reference_number = reversal["RefNbr"]
642
- result.response_code = reversal["RspCode"]
643
- result.response_text = reversal["RspText"]
644
- result
645
- end
646
-
647
- def submit_verify(transaction)
648
- response = doTransaction(transaction)
649
- header = response["Header"]
650
-
651
- if !header["GatewayRspCode"].eql? "0"
652
- raise @exception_mapper.map_gateway_exception(header["GatewayTxnId"], header["GatewayRspCode"], header["GatewayRspMsg"])
653
- end
654
-
655
- account_verify = response["Transaction"]["CreditAccountVerify"]
656
- result = HpsAccountVerify.new(hydrate_transaction_header(header))
657
- result.transaction_id = header["GatewayTxnId"]
658
- result.avs_result_code = account_verify["AVSRsltCode"]
659
- result.avs_result_text = account_verify["AVSRsltText"]
660
- result.reference_number = account_verify["RefNbr"]
661
- result.response_code = account_verify["RspCode"]
662
- result.response_text = account_verify["RspText"]
663
- result.card_type = account_verify["CardType"]
664
- result.cpc_indicator = account_verify["CPCInd"]
665
- result.cvv_result_code = account_verify["CVVRsltCode"]
666
- result.cvv_result_text = account_verify["CVVRsltText"]
667
- result.authorization_code = account_verify["AuthCode"]
668
- result.authorized_amount = account_verify["AuthAmt"]
669
-
670
- if [ "85", "00" ].include? result.response_code == false
671
- raise @exception_mapper.map_issuer_exception(result.transaction_id, result.response_code, result.response_text)
672
- end
673
-
674
- unless header["TokenData"].nil?
675
- result.token_data = HpsTokenData.new()
676
- result.token_data.response_code = header["TokenData"]["TokenRspCode"];
677
- result.token_data.response_message = header["TokenData"]["TokenRspMsg"]
678
- result.token_data.token_value = header["TokenData"]["TokenValue"]
679
- end
680
-
681
- result
682
- end
683
-
684
- def submit_void(transaction)
685
- response = doTransaction(transaction)
686
- header = response["Header"]
687
- unless header["GatewayRspCode"].eql? "0"
688
- raise @exception_mapper.map_gateway_exception(header["GatewayTxnId"], header["GatewayRspCode"], header["GatewayRspMsg"])
689
- end
690
-
691
- result = HpsVoid.new(hydrate_transaction_header(header))
692
- result.transaction_id = header["GatewayTxnId"]
693
- result.response_code = "00"
694
- result.response_text = ""
695
- result
696
- end
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
-
712
- def process_charge_gateway_response(response_code, response_text, transaction_id, amount, currency)
713
-
714
- if !response_code.eql? "0"
715
-
716
- if response_code.eql? "30"
717
-
718
- begin
719
-
720
- reverse_transaction(transaction_id, amount, currency)
721
-
722
- rescue => e
723
- exception = @exception_mapper.map_sdk_exception(SdkCodes.reversal_error_after_gateway_timeout, e)
724
- exception.response_code = response_code
725
- exception.response_text = response_text
726
- raise exception
727
- end
728
-
729
- end
730
-
731
- exception = @exception_mapper.map_gateway_exception(transaction_id, response_code, response_text)
732
- exception.response_code = response_code
733
- exception.response_text = response_text
734
- raise exception
735
-
736
- end
737
-
738
- end
739
-
740
- def process_charge_issuer_response(response_code, response_text, transaction_id, amount, currency)
741
-
742
- if response_code.eql? "91"
743
-
744
- begin
745
-
746
- reverse_transaction(transaction_id, amount, currency)
747
-
748
- rescue => e
749
- exception = @exception_mapper.map_sdk_exception(SdkCodes.reversal_error_after_issuer_timeout, e)
750
- exception.response_code = response_code
751
- exception.response_text = response_text
752
- raise exception
753
- end
754
-
755
- exception = @exception_mapper.map_sdk_exception(SdkCodes.processing_error)
756
- exception.response_code = response_code
757
- exception.response_text = response_text
758
- raise exception
759
-
760
- elsif !response_code.eql? "00" and !response_code.eql? "0"
761
-
762
- exception = @exception_mapper.map_issuer_exception(transaction_id, response_code, response_text)
763
- exception.response_code = response_code
764
- exception.response_text = response_text
765
- raise exception
766
-
767
- end
768
-
769
- end
770
-
771
- end
772
-
773
- end
1
+ module Hps
2
+ class HpsChargeService < HpsService
3
+
4
+ def get(transaction_id)
5
+
6
+ if transaction_id.nil? or transaction_id == 0
7
+ raise @exception_mapper.map_sdk_exception(SdkCodes.invalid_transaction_id)
8
+ end
9
+
10
+ xml = Builder::XmlMarkup.new
11
+ xml.hps :Transaction do
12
+ xml.hps :ReportTxnDetail do
13
+ xml.hps :TxnId, transaction_id
14
+ end
15
+ end
16
+
17
+ response = doTransaction(xml.target!)
18
+ detail = response["Transaction"]["ReportTxnDetail"]
19
+
20
+ header = hydrate_transaction_header(response["Header"])
21
+ result = HpsReportTransactionDetails.new(header)
22
+ result.transaction_id = detail["GatewayTxnId"]
23
+ result.original_transaction_id = detail["OriginalGatewayTxnId"]
24
+ result.authorized_amount = detail["Data"]["AuthAmt"]
25
+ result.authorization_code = detail["Data"]["AuthCode"]
26
+ result.avs_result_code = detail["Data"]["AVSRsltCode"]
27
+ result.avs_result_text = detail["Data"]["AVSRsltText"]
28
+ result.card_type = detail["Data"]["CardType"]
29
+ result.masked_card_number = detail["Data"]["MaskedCardNbr"]
30
+ result.transaction_type = Hps.service_name_to_transaction_type(detail["ServiceName"])
31
+ result.transaction_date = detail["RspUtcDT"]
32
+ result.cpc_indicator = detail["Data"]["CPCInd"]
33
+ result.cvv_result_code = detail["Data"]["CVVRsltCode"]
34
+ result.cvv_result_text = detail["Data"]["CVVRsltText"]
35
+ result.reference_number = detail["Data"]["RefNbr"]
36
+ result.response_code = detail["Data"]["RspCode"]
37
+ result.response_text = detail["Data"]["RspText"]
38
+
39
+ tokenization_message = detail["Data"]["TokenizationMsg"]
40
+
41
+ unless tokenization_message.nil?
42
+ result.token_data = HpsTokenData.new(tokenization_message)
43
+ end
44
+
45
+ header_response_code = response["Header"]["GatewayRspCode"]
46
+ data_response_code = detail["Data"]["RspCode"]
47
+
48
+ if header_response_code != "0" or data_response_code != "0" or data_response_code != "00"
49
+
50
+ exceptions = HpsChargeExceptions.new()
51
+
52
+ if header_response_code != "0"
53
+ message = response["Header"]["GatewayRspMsg"]
54
+ exceptions.hps_exception = @exception_mapper.map_gateway_exception(result.transaction_id, header_response_code, message)
55
+ end
56
+
57
+ if data_response_code != "0" || data_response_code != "00"
58
+ message = detail["Data"]["RspText"]
59
+ exceptions.card_exception = @exception_mapper.map_issuer_exception(transaction_id, data_response_code, message)
60
+ end
61
+
62
+ result.exceptions = exceptions
63
+
64
+ end
65
+
66
+ result
67
+
68
+ end
69
+
70
+ def list(start_date, end_date, filter_by = nil)
71
+
72
+ if start_date > DateTime.now
73
+ raise @exception_mapper.map_sdk_exception(SdkCodes.invalid_start_date)
74
+ elsif end_date > DateTime.now
75
+ raise @exception_mapper.map_sdk_exception(SdkCodes.invalid_end_date)
76
+ end
77
+
78
+ xml = Builder::XmlMarkup.new
79
+ xml.hps :Transaction do
80
+ xml.hps :ReportActivity do
81
+ xml.hps :RptStartUtcDT, start_date.utc.iso8601
82
+ xml.hps :RptEndUtcDT, end_date.utc.iso8601
83
+ end
84
+ end
85
+
86
+ response = doTransaction(xml.target!)
87
+
88
+ # Gateway exception
89
+ if response["Header"]["GatewayRspCode"] != "0"
90
+ transaction_id = response["Header"]["GatewayTxnId"]
91
+ response_code = response["Header"]["GatewayRspCode"]
92
+ response_message = response["Header"]["GatewayRspMsg"]
93
+ raise @exception_mapper.map_gateway_exception(transaction_id, response_code, response_message)
94
+ end
95
+
96
+ result = Array.new
97
+
98
+ if response["Transaction"]["ReportActivity"]["Header"]["TxnCnt"] == "0"
99
+ return result
100
+ end
101
+
102
+ response["Transaction"]["ReportActivity"]["Details"].each { |charge|
103
+
104
+ next if !filter_by.nil? and charge.serviceName != Hps.transaction_type_to_service_name(filter_by)
105
+
106
+ summary = HpsReportTransactionSummary.new()
107
+ summary.transaction_id = charge["GatewayTxnId"]
108
+ summary.original_transaction_id = charge["OriginalGatewayTxnId"]
109
+ summary.masked_card_number = charge["MaskedCardNbr"]
110
+ summary.response_code = charge["IssuerRspCode"]
111
+ summary.response_text = charge["IssuerRspText"]
112
+ summary.transaction_type = Hps.transaction_type_to_service_name(charge["ServiceName"]) if filter_by.nil? == false
113
+
114
+ gw_response_code = charge["GatewayRspCode"]
115
+ issuer_response_code = charge["IssuerRspCode"]
116
+
117
+ if gw_response_code != "0" or issuer_response_code != "0" or issuer_response_code != "00"
118
+
119
+ exceptions = HpsChargeExceptions.new()
120
+
121
+ if gw_response_code != "0"
122
+ message = charge["GatewayRspMsg"]
123
+ exceptions.hps_exception = @exception_mapper.map_gateway_exception(charge["GatewayTxnId"], gw_response_code, message)
124
+ end
125
+
126
+ if issuer_response_code != "0" || issuer_response_code != "00"
127
+ message = charge["IssuerRspText"]
128
+ exceptions.card_exception = @exception_mapper.map_issuer_exception(charge["GatewayTxnId"], issuer_response_code, message)
129
+ end
130
+
131
+ summary.exceptions = exceptions
132
+
133
+ end
134
+
135
+ result << summary
136
+ }
137
+
138
+ result
139
+ end
140
+
141
+ def charge(amount, currency, card, card_holder = nil, request_multi_use_token = false, details = nil, txn_descriptor = nil)
142
+ check_amount(amount)
143
+ check_currency(currency)
144
+
145
+ xml = Builder::XmlMarkup.new
146
+ xml.hps :Transaction do
147
+ xml.hps :CreditSale do
148
+ xml.hps :Block1 do
149
+ xml.hps :AllowDup, "Y"
150
+ xml.hps :Amt, amount
151
+ xml << hydrate_cardholder_data(card_holder) if card_holder
152
+ xml << hydrate_additional_txn_fields(details) if details
153
+ xml.hps :TxnDescriptor, txn_descriptor if txn_descriptor
154
+ xml.hps :CardData do
155
+
156
+ # NOTE: Process as Manual Entry if they gave us a Credit Card
157
+ if card.is_a? HpsCreditCard
158
+ xml << hydrate_manual_entry(card)
159
+ # Note: Otherwise, consider it a token
160
+ else
161
+ xml.hps :TokenData do
162
+ xml.hps :TokenValue, card
163
+ end
164
+ end
165
+
166
+ xml.hps :TokenRequest, request_multi_use_token ? "Y" : "N"
167
+
168
+ end
169
+ end
170
+ end
171
+ end
172
+
173
+ submit_charge(xml.target!, amount, currency)
174
+ end
175
+
176
+ def charge_swipe(amount, currency, track_data, encryption_data = nil, gratuity = 0, allow_partial_auth = false, txn_descriptor = nil, request_multi_use_token = false, direct_market_data = nil)
177
+ check_amount(amount)
178
+ check_currency(currency)
179
+
180
+ xml = Builder::XmlMarkup.new
181
+ xml.hps :Transaction do
182
+ xml.hps :CreditSale do
183
+ xml.hps :Block1 do
184
+ xml.hps :AllowDup, "Y"
185
+ xml.hps :Amt, amount
186
+ xml.hps :GratuityAmtInfo, gratuity if gratuity != 0
187
+ xml.hps :TxnDescriptor, txn_descriptor if txn_descriptor
188
+ xml.hps :AllowPartialAuth, allow_partial_auth ? "Y" : "N"
189
+ xml.hps :CardData do
190
+ xml << hydrate_card_track_data(track_data)
191
+ xml << hydrate_encryption_data(encryption_data) if encryption_data
192
+ xml.hps :TokenRequest, request_multi_use_token ? "Y" : "N"
193
+ end
194
+ xml << hydrate_direct_market_data(direct_market_data) if direct_market_data
195
+ end
196
+ end
197
+ end
198
+
199
+ submit_charge(xml.target!, amount, currency)
200
+ end
201
+
202
+ def verify(card, card_holder = nil, request_multi_use_token = false, client_txn_id = nil)
203
+
204
+ xml = Builder::XmlMarkup.new
205
+ xml.hps :Transaction do
206
+ xml.hps :CreditAccountVerify do
207
+ xml.hps :Block1 do
208
+ xml << hydrate_cardholder_data(card_holder) if card_holder
209
+ xml.hps :CardData do
210
+
211
+ # NOTE: Process as Manual Entry if they gave us a Credit Card
212
+ if card.is_a? HpsCreditCard
213
+ xml << hydrate_manual_entry(card)
214
+ # Note: Otherwise, consider it a token
215
+ else
216
+ xml.hps :TokenData do
217
+ xml.hps :TokenValue, card
218
+ end
219
+ end
220
+
221
+ xml.hps :TokenRequest, request_multi_use_token ? "Y" : "N"
222
+
223
+ end
224
+ end
225
+ end
226
+ end
227
+
228
+ submit_verify(xml.target!)
229
+ end
230
+
231
+ def verify_swipe(track_data, card_holder = nil, encryption_data = nil, request_multi_use_token = false, client_txn_id = nil)
232
+
233
+ xml = Builder::XmlMarkup.new
234
+ xml.hps :Transaction do
235
+ xml.hps :CreditAccountVerify do
236
+ xml.hps :Block1 do
237
+ xml << hydrate_cardholder_data(card_holder) if card_holder
238
+ xml.hps :CardData do
239
+ xml << hydrate_card_track_data(track_data)
240
+ xml << hydrate_encryption_data(encryption_data) if encryption_data
241
+
242
+ xml.hps :TokenRequest, request_multi_use_token ? "Y" : "N"
243
+ end
244
+ end
245
+ end
246
+ end
247
+
248
+ submit_verify(xml.target!)
249
+ end
250
+
251
+ def authorize(amount, currency, card, card_holder = nil, request_multi_use_token = false, details = nil, txn_descriptor = nil)
252
+
253
+ check_amount(amount)
254
+ check_currency(currency)
255
+
256
+ xml = Builder::XmlMarkup.new
257
+ xml.hps :Transaction do
258
+ xml.hps :CreditAuth do
259
+ xml.hps :Block1 do
260
+ xml.hps :AllowDup, "Y"
261
+ xml.hps :Amt, amount
262
+ xml << hydrate_cardholder_data(card_holder) if card_holder
263
+ xml << hydrate_additional_txn_fields(details) if details
264
+ xml.hps :TxnDescriptor, txn_descriptor if txn_descriptor
265
+ xml.hps :CardData do
266
+
267
+ # NOTE: Process as Manual Entry if they gave us a Credit Card
268
+ if card.is_a? HpsCreditCard
269
+ xml << hydrate_manual_entry(card)
270
+ # Note: Otherwise, consider it a token
271
+ else
272
+ xml.hps :TokenData do
273
+ xml.hps :TokenValue, card
274
+ end
275
+ end
276
+
277
+ xml.hps :TokenRequest, request_multi_use_token ? "Y" : "N"
278
+
279
+ end
280
+ end
281
+ end
282
+ end
283
+
284
+ submit_authorize(xml.target!, amount, currency)
285
+ end
286
+
287
+ def authorize_swipe(amount, currency, track_data, encryption_data = nil, gratuity = 0, allow_partial_auth = false, txn_descriptor = nil)
288
+ check_amount(amount)
289
+ check_currency(currency)
290
+
291
+ xml = Builder::XmlMarkup.new
292
+ xml.hps :Transaction do
293
+ xml.hps :CreditAuth do
294
+ xml.hps :Block1 do
295
+ xml.hps :AllowDup, "Y"
296
+ xml.hps :Amt, amount
297
+ xml.hps :TxnDescriptor, txn_descriptor if txn_descriptor
298
+ xml.hps :AllowPartialAuth, allow_partial_auth ? "Y" : "N"
299
+ xml.hps :CardData do
300
+ xml << hydrate_card_track_data(track_data)
301
+ xml << hydrate_encryption_data(encryption_data) if encryption_data
302
+ end
303
+ end
304
+ end
305
+ end
306
+
307
+ submit_authorize(xml.target!, amount, currency)
308
+ end
309
+
310
+ def capture(transaction_id, amount = nil)
311
+
312
+ xml = Builder::XmlMarkup.new
313
+ xml.hps :Transaction do
314
+ xml.hps :CreditAddToBatch do
315
+ xml.hps :GatewayTxnId, transaction_id
316
+ xml.hps :Amt, amount if amount
317
+ end
318
+ end
319
+
320
+ response = doTransaction(xml.target!)
321
+ header = response["Header"]
322
+
323
+ raise @exception_mapper.map_gateway_exception(transaction_id, header["GatewayRspCode"], header["GatewayRspMsg"]) unless header["GatewayRspCode"].eql? "0"
324
+
325
+ get(transaction_id)
326
+ end
327
+
328
+ def reverse(card, amount, currency, details = nil)
329
+ check_amount(amount)
330
+ check_currency(currency)
331
+
332
+ xml = Builder::XmlMarkup.new
333
+ xml.hps :Transaction do
334
+ xml.hps :CreditReversal do
335
+ xml.hps :Block1 do
336
+ xml.hps :Amt, amount
337
+ xml << hydrate_additional_txn_fields(details) if details
338
+ xml.hps :CardData do
339
+
340
+ # NOTE: Process as Manual Entry if they gave us a Credit Card
341
+ if card.is_a? HpsCreditCard
342
+ xml << hydrate_manual_entry(card)
343
+ # Note: Otherwise, consider it a token
344
+ else
345
+ xml.hps :TokenData do
346
+ xml.hps :TokenValue, card
347
+ end
348
+ end
349
+
350
+ end
351
+ end
352
+ end
353
+ end
354
+
355
+ submit_reverse(xml.target!)
356
+ end
357
+
358
+ def reverse_transaction(transaction_id, amount, currency, details = nil)
359
+ check_amount(amount)
360
+ check_currency(currency)
361
+
362
+ xml = Builder::XmlMarkup.new
363
+ xml.hps :Transaction do
364
+ xml.hps :CreditReversal do
365
+ xml.hps :Block1 do
366
+ xml.hps :Amt, amount
367
+ xml.hps :GatewayTxnId, transaction_id
368
+ xml << hydrate_additional_txn_fields(details) if details
369
+ end
370
+ end
371
+ end
372
+
373
+ submit_reverse(xml.target!)
374
+ end
375
+
376
+ def refund(amount, currency, card, card_holder = nil, details = nil)
377
+ check_amount(amount)
378
+ check_currency(currency)
379
+
380
+ xml = Builder::XmlMarkup.new
381
+ xml.hps :Transaction do
382
+ xml.hps :CreditReturn do
383
+ xml.hps :Block1 do
384
+ xml.hps :AllowDup, "Y"
385
+ xml.hps :Amt, amount
386
+ xml << hydrate_cardholder_data(card_holder) if card_holder
387
+ xml << hydrate_additional_txn_fields(details) if details
388
+ xml.hps :CardData do
389
+
390
+ # NOTE: Process as Manual Entry if they gave us a Credit Card
391
+ if card.is_a? HpsCreditCard
392
+ xml << hydrate_manual_entry(card)
393
+ # Note: Otherwise, consider it a token
394
+ else
395
+ xml.hps :TokenData do
396
+ xml.hps :TokenValue, card
397
+ end
398
+ end
399
+
400
+ end
401
+ end
402
+ end
403
+ end
404
+
405
+ submit_refund(xml.target!)
406
+ end
407
+
408
+ def refund_transaction(amount, currency, transaction_id, card_holder = nil, details = nil)
409
+ check_amount(amount)
410
+ check_currency(currency)
411
+
412
+ xml = Builder::XmlMarkup.new
413
+ xml.hps :Transaction do
414
+ xml.hps :CreditReturn do
415
+ xml.hps :Block1 do
416
+ xml.hps :AllowDup, "Y"
417
+ xml.hps :Amt, amount
418
+ xml.hps :GatewayTxnId, transaction_id
419
+ xml << hydrate_cardholder_data(card_holder) if card_holder
420
+ xml << hydrate_additional_txn_fields(details) if details
421
+ end
422
+ end
423
+ end
424
+
425
+ submit_refund(xml.target!)
426
+ end
427
+
428
+ def void(transaction_id)
429
+ xml = Builder::XmlMarkup.new
430
+ xml.hps :Transaction do
431
+ xml.hps :CreditVoid do
432
+ xml.hps :GatewayTxnId, transaction_id
433
+ end
434
+ end
435
+
436
+ submit_void(xml.target!)
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
+
462
+ private
463
+
464
+ def check_amount(amount)
465
+ raise @exception_mapper.map_sdk_exception(SdkCodes.invalid_amount) if amount.nil? or amount <= 0
466
+ end
467
+
468
+ def check_currency(currency)
469
+ raise @exception_mapper.map_sdk_exception(SdkCodes.missing_currency) if currency.empty?
470
+ raise @exception_mapper.map_sdk_exception(SdkCodes.invalid_currency) unless currency.downcase.eql? "usd"
471
+ end
472
+
473
+ def hydrate_cardholder_data(card_holder)
474
+ xml = Builder::XmlMarkup.new
475
+ xml.hps :CardHolderData do
476
+ xml.hps :CardHolderFirstName, card_holder.first_name
477
+ xml.hps :CardHolderLastName, card_holder.last_name
478
+ xml.hps :CardHolderEmail, card_holder.email_address
479
+ xml.hps :CardHolderPhone, card_holder.phone
480
+ xml.hps :CardHolderAddr, card_holder.address.address
481
+ xml.hps :CardHolderCity, card_holder.address.city
482
+ xml.hps :CardHolderState, card_holder.address.state
483
+ xml.hps :CardHolderZip, card_holder.address.zip
484
+ end
485
+ xml.target!
486
+ end
487
+
488
+ def hydrate_manual_entry(card)
489
+ xml = Builder::XmlMarkup.new
490
+ xml.hps :ManualEntry do
491
+ xml.hps :CardNbr, card.number
492
+ xml.hps :ExpMonth, card.exp_month
493
+ xml.hps :ExpYear, card.exp_year
494
+ xml.hps :CVV2, card.cvv
495
+ xml.hps :CardPresent, card.card_present ? "Y" : "N"
496
+ xml.hps :ReaderPresent, card.reader_present ? "Y" : "N"
497
+ end
498
+ xml.target!
499
+ end
500
+
501
+ def hydrate_card_track_data(track_data)
502
+ xml = Builder::XmlMarkup.new
503
+ xml.hps :TrackData, :method => track_data.method_obtained do
504
+ xml << track_data.value
505
+ end
506
+ xml.target!
507
+ end
508
+
509
+ def hydrate_encryption_data(data)
510
+ xml = Builder::XmlMarkup.new
511
+ xml.hps :EncryptionData do
512
+ xml.hps :EncryptedTrackNumber, data.encrypted_track_number if data.encrypted_track_number
513
+ xml.hps :KSN, data.ksn if data.ksn
514
+ xml.hps :KTB, data.ktb if data.ktb
515
+ xml.hps :Version, data.version if data.version
516
+ end
517
+ xml.target!
518
+ end
519
+
520
+ def hydrate_direct_market_data(data)
521
+ xml = Builder::XmlMarkup.new
522
+ xml.hps :DirectMktData do
523
+ xml.hps :DirectMktInvoideNbr, data.invoice_number
524
+ xml.hps :DirectMktShipMonth, data.ship_month
525
+ xml.hps :DirectMktShipDay, data.ship_day
526
+ end
527
+ xml.target!
528
+ end
529
+
530
+ def hydrate_additional_txn_fields(details)
531
+ xml = Builder::XmlMarkup.new
532
+ xml.hps :AdditionalTxnFields do
533
+ xml.hps :Description, details.memo if details.memo
534
+ xml.hps :InvoiceNbr, details.invoice_number if details.invoice_number
535
+ xml.hps :CustomerID, details.customer_id if details.customer_id
536
+ end
537
+ xml.target!
538
+ end
539
+
540
+ def submit_charge(transaction, amount, currency)
541
+
542
+ response = doTransaction(transaction)
543
+
544
+ header = response["Header"]
545
+ process_charge_gateway_response(header["GatewayRspCode"], header["GatewayRspMsg"], header["GatewayTxnId"], amount, currency)
546
+
547
+ creditSaleRsp = response["Transaction"]["CreditSale"]
548
+ process_charge_issuer_response(creditSaleRsp["RspCode"], creditSaleRsp["RspText"], header["GatewayTxnId"], amount, currency)
549
+
550
+ result = HpsCharge.new(hydrate_transaction_header(header))
551
+ result.transaction_id = header["GatewayTxnId"]
552
+ result.authorized_amount = creditSaleRsp["AuthAmt"]
553
+ result.authorization_code = creditSaleRsp["AuthCode"]
554
+ result.avs_result_code = creditSaleRsp["AVSRsltCode"]
555
+ result.avs_result_text = creditSaleRsp["AVSRsltText"]
556
+ result.card_type = creditSaleRsp["CardType"]
557
+ result.cpc_indicator = creditSaleRsp["CPCInd"]
558
+ result.cvv_result_code = creditSaleRsp["CVVRsltCode"]
559
+ result.cvv_result_text = creditSaleRsp["CVVRsltText"]
560
+ result.reference_number = creditSaleRsp["RefNbr"]
561
+ result.response_code = creditSaleRsp["RspCode"]
562
+ result.response_text = creditSaleRsp["RspText"]
563
+
564
+ unless header["TokenData"].nil?
565
+ result.token_data = HpsTokenData.new()
566
+ result.token_data.response_code = header["TokenData"]["TokenRspCode"];
567
+ result.token_data.response_message = header["TokenData"]["TokenRspMsg"]
568
+ result.token_data.token_value = header["TokenData"]["TokenValue"]
569
+ end
570
+
571
+ result
572
+ end
573
+
574
+ def submit_authorize(transaction, amount, currency)
575
+
576
+ response = doTransaction(transaction)
577
+ header = response["Header"]
578
+ process_charge_gateway_response(header["GatewayRspCode"], header["GatewayRspMsg"], header["GatewayTxnId"], amount, currency)
579
+
580
+ auth_response = response["Transaction"]["CreditAuth"]
581
+ process_charge_issuer_response(auth_response["RspCode"], auth_response["RspText"], header["GatewayTxnId"], amount, currency)
582
+
583
+ result = HpsAuthorization.new(hydrate_transaction_header(header))
584
+ result.transaction_id = header["GatewayTxnId"]
585
+ result.authorized_amount = auth_response["AuthAmt"]
586
+ result.authorization_code = auth_response["AuthCode"]
587
+ result.avs_result_code = auth_response["AVSRsltCode"]
588
+ result.avs_result_text = auth_response["AVSRsltText"]
589
+ result.card_type = auth_response["CardType"]
590
+ result.cpc_indicator = auth_response["CPCInd"]
591
+ result.cvv_result_code = auth_response["CVVRsltCode"]
592
+ result.cvv_result_text = auth_response["CVVRsltText"]
593
+ result.reference_number = auth_response["RefNbr"]
594
+ result.response_code = auth_response["RspCode"]
595
+ result.response_text = auth_response["RspText"]
596
+
597
+ unless header["TokenData"].nil?
598
+ result.token_data = HpsTokenData.new()
599
+ result.token_data.response_code = header["TokenData"]["TokenRspCode"];
600
+ result.token_data.response_message = header["TokenData"]["TokenRspMsg"]
601
+ result.token_data.token_value = header["TokenData"]["TokenValue"]
602
+ end
603
+
604
+ result
605
+ end
606
+
607
+ def submit_refund(transaction)
608
+
609
+ response = doTransaction(transaction)
610
+ header = response["Header"]
611
+
612
+ unless header["GatewayRspCode"].eql? "0"
613
+ raise @exception_mapper.map_gateway_exception(header["GatewayTxnId"], header["GatewayRspCode"], header["GatewayRspMsg"])
614
+ end
615
+
616
+ result = HpsRefund.new(hydrate_transaction_header(header))
617
+ result.transaction_id = header["GatewayTxnId"]
618
+ result.response_code = "00"
619
+ result.response_text = ""
620
+
621
+ result
622
+ end
623
+
624
+ def submit_reverse(transaction)
625
+
626
+ response = doTransaction(transaction)
627
+ header = response["Header"]
628
+
629
+ if !header["GatewayRspCode"].eql? "0"
630
+ raise @exception_mapper.map_gateway_exception(header["GatewayTxnId"], header["GatewayRspCode"], header["GatewayRspMsg"])
631
+ end
632
+
633
+ reversal = response["Transaction"]["CreditReversal"]
634
+ result = HpsReversal.new(hydrate_transaction_header(header))
635
+ result.transaction_id = header["GatewayTxnId"]
636
+ result.avs_result_code = reversal["AVSRsltCode"]
637
+ result.avs_result_text = reversal["AVSRsltText"]
638
+ result.cpc_indicator = reversal["CPCInd"]
639
+ result.cvv_result_code = reversal["CVVRsltCode"]
640
+ result.cvv_result_text = reversal["CVVRsltText"]
641
+ result.reference_number = reversal["RefNbr"]
642
+ result.response_code = reversal["RspCode"]
643
+ result.response_text = reversal["RspText"]
644
+ result
645
+ end
646
+
647
+ def submit_verify(transaction)
648
+ response = doTransaction(transaction)
649
+ header = response["Header"]
650
+
651
+ if !header["GatewayRspCode"].eql? "0"
652
+ raise @exception_mapper.map_gateway_exception(header["GatewayTxnId"], header["GatewayRspCode"], header["GatewayRspMsg"])
653
+ end
654
+
655
+ account_verify = response["Transaction"]["CreditAccountVerify"]
656
+ result = HpsAccountVerify.new(hydrate_transaction_header(header))
657
+ result.transaction_id = header["GatewayTxnId"]
658
+ result.avs_result_code = account_verify["AVSRsltCode"]
659
+ result.avs_result_text = account_verify["AVSRsltText"]
660
+ result.reference_number = account_verify["RefNbr"]
661
+ result.response_code = account_verify["RspCode"]
662
+ result.response_text = account_verify["RspText"]
663
+ result.card_type = account_verify["CardType"]
664
+ result.cpc_indicator = account_verify["CPCInd"]
665
+ result.cvv_result_code = account_verify["CVVRsltCode"]
666
+ result.cvv_result_text = account_verify["CVVRsltText"]
667
+ result.authorization_code = account_verify["AuthCode"]
668
+ result.authorized_amount = account_verify["AuthAmt"]
669
+
670
+ if [ "85", "00" ].include? result.response_code == false
671
+ raise @exception_mapper.map_issuer_exception(result.transaction_id, result.response_code, result.response_text)
672
+ end
673
+
674
+ unless header["TokenData"].nil?
675
+ result.token_data = HpsTokenData.new()
676
+ result.token_data.response_code = header["TokenData"]["TokenRspCode"];
677
+ result.token_data.response_message = header["TokenData"]["TokenRspMsg"]
678
+ result.token_data.token_value = header["TokenData"]["TokenValue"]
679
+ end
680
+
681
+ result
682
+ end
683
+
684
+ def submit_void(transaction)
685
+ response = doTransaction(transaction)
686
+ header = response["Header"]
687
+ unless header["GatewayRspCode"].eql? "0"
688
+ raise @exception_mapper.map_gateway_exception(header["GatewayTxnId"], header["GatewayRspCode"], header["GatewayRspMsg"])
689
+ end
690
+
691
+ result = HpsVoid.new(hydrate_transaction_header(header))
692
+ result.transaction_id = header["GatewayTxnId"]
693
+ result.response_code = "00"
694
+ result.response_text = ""
695
+ result
696
+ end
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
+
712
+ def process_charge_gateway_response(response_code, response_text, transaction_id, amount, currency)
713
+
714
+ if !response_code.eql? "0"
715
+
716
+ if response_code.eql? "30"
717
+
718
+ begin
719
+
720
+ reverse_transaction(transaction_id, amount, currency)
721
+
722
+ rescue => e
723
+ exception = @exception_mapper.map_sdk_exception(SdkCodes.reversal_error_after_gateway_timeout, e)
724
+ exception.response_code = response_code
725
+ exception.response_text = response_text
726
+ raise exception
727
+ end
728
+
729
+ end
730
+
731
+ exception = @exception_mapper.map_gateway_exception(transaction_id, response_code, response_text)
732
+ exception.response_code = response_code
733
+ exception.response_text = response_text
734
+ raise exception
735
+
736
+ end
737
+
738
+ end
739
+
740
+ def process_charge_issuer_response(response_code, response_text, transaction_id, amount, currency)
741
+
742
+ if response_code.eql? "91"
743
+
744
+ begin
745
+
746
+ reverse_transaction(transaction_id, amount, currency)
747
+
748
+ rescue => e
749
+ exception = @exception_mapper.map_sdk_exception(SdkCodes.reversal_error_after_issuer_timeout, e)
750
+ exception.response_code = response_code
751
+ exception.response_text = response_text
752
+ raise exception
753
+ end
754
+
755
+ exception = @exception_mapper.map_sdk_exception(SdkCodes.processing_error)
756
+ exception.response_code = response_code
757
+ exception.response_text = response_text
758
+ raise exception
759
+
760
+ elsif !response_code.eql? "00" and !response_code.eql? "0"
761
+
762
+ exception = @exception_mapper.map_issuer_exception(transaction_id, response_code, response_text)
763
+ exception.response_code = response_code
764
+ exception.response_text = response_text
765
+ raise exception
766
+
767
+ end
768
+
769
+ end
770
+
771
+ end
772
+
773
+ end