CnpOnline 11.4.0 → 12.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +4 -164
  3. data/CHANGELOG~ +0 -0
  4. data/CONTRIBUTORS +0 -2
  5. data/DESCRIPTION +1 -1
  6. data/LICENSE +0 -0
  7. data/README.md +13 -15
  8. data/Rakefile +3 -2
  9. data/Rakefile~ +4 -3
  10. data/SETUP.md +13 -10
  11. data/bin/Setup.rb +26 -22
  12. data/bin/sample_batch_driver.rb +15 -15
  13. data/bin/sample_driver.rb +5 -5
  14. data/lib/{LitleBatchRequest.rb → CnpBatchRequest.rb} +68 -66
  15. data/lib/{LitleListeners.rb → CnpListeners.rb} +48 -40
  16. data/lib/{LitleOnline.rb → CnpOnline.rb} +8 -7
  17. data/lib/{LitleOnlineRequest.rb → CnpOnlineRequest.rb} +53 -53
  18. data/lib/{LitleRequest.rb → CnpRequest.rb} +186 -192
  19. data/lib/{LitleTransaction.rb → CnpTransaction.rb} +53 -52
  20. data/lib/{LitleXmlMapper.rb → CnpXmlMapper.rb} +7 -7
  21. data/lib/Communications.rb +8 -7
  22. data/lib/Configuration.rb +7 -6
  23. data/lib/EnvironmentVariables.rb +2 -2
  24. data/lib/XMLFields.rb +98 -108
  25. data/lib/cacert.pem +0 -0
  26. data/samples/Auth/CnpAuthReversalTransaction.rb +15 -0
  27. data/samples/Auth/{LitleAuthorizationTransaction.rb → CnpAuthorizationTransaction.rb} +4 -4
  28. data/samples/Auth/{LitlePaymentFullLifeCycle.rb → CnpPaymentFullLifeCycle.rb} +11 -11
  29. data/samples/Batch/AccountUpdate.rb +11 -11
  30. data/samples/Batch/SampleBatchDriver.rb +16 -16
  31. data/samples/Capture/{LitleCaptureGivenAuthTransaction.rb → CnpCaptureGivenAuthTransaction.rb} +4 -4
  32. data/samples/Capture/CnpCaptureTransaction.rb +14 -0
  33. data/samples/Capture/{LitleForceCaptureTransaction.rb → CnpForceCaptureTransaction.rb} +5 -5
  34. data/samples/Capture/CnpPartialCapture.rb +16 -0
  35. data/samples/Credit/CnpCreditTransaction.rb +16 -0
  36. data/samples/Credit/{LitleRefundTransaction.rb → CnpRefundTransaction.rb} +4 -4
  37. data/samples/Other/{LitleAvsTransaction.rb → CnpAvsTransaction.rb} +4 -4
  38. data/samples/Other/CnpVoidTransaction.rb +19 -0
  39. data/samples/Paypage/FullPaypageLifeCycle.rb +16 -16
  40. data/samples/Run_all.rb +12 -12
  41. data/samples/Sale/{LitleSaleTransaction.rb → CnpSaleTransaction.rb} +4 -4
  42. data/samples/Sale/SampleSaleTransaction.rb +5 -5
  43. data/test/certification/certTest1_base.rb +104 -103
  44. data/test/certification/certTest2_authenhanced.rb +90 -88
  45. data/test/certification/certTest3_authreversal.rb +29 -28
  46. data/test/certification/certTest4_echeck.rb +22 -20
  47. data/test/certification/certTest5_token.rb +51 -49
  48. data/test/certification/certTest_batchAll.rb +60 -60
  49. data/test/certification/ts_all.rb +1 -1
  50. data/test/functional/test_activate.rb +9 -8
  51. data/test/functional/test_activateReversal.rb +5 -5
  52. data/test/functional/test_auth.rb +31 -30
  53. data/test/functional/test_authReversal.rb +8 -8
  54. data/test/functional/test_balanceInquiry.rb +6 -6
  55. data/test/functional/test_batch.rb +32 -32
  56. data/test/functional/test_batchStream.rb +14 -14
  57. data/test/functional/test_cancelSubscription.rb +4 -4
  58. data/test/functional/test_capture.rb +14 -14
  59. data/test/functional/test_captureGivenAuth.rb +16 -16
  60. data/test/functional/test_configuration.rb +26 -26
  61. data/test/functional/test_createPlan.rb +5 -5
  62. data/test/functional/test_credit.rb +13 -33
  63. data/test/functional/test_deactivate.rb +6 -6
  64. data/test/functional/test_deactivateReversal.rb +5 -5
  65. data/test/functional/test_depositReversal.rb +5 -5
  66. data/test/functional/test_echeckCredit.rb +20 -20
  67. data/test/functional/test_echeckRedeposit.rb +16 -16
  68. data/test/functional/test_echeckSale.rb +35 -35
  69. data/test/functional/test_echeckVerification.rb +17 -17
  70. data/test/functional/test_echeckVoid.rb +4 -4
  71. data/test/functional/test_forceCapture.rb +21 -21
  72. data/test/functional/test_fraudCheck.rb +6 -5
  73. data/test/functional/test_giftCardAuthReversal.rb +5 -5
  74. data/test/functional/test_giftCardCapture.rb +5 -5
  75. data/test/functional/test_giftCardCredit.rb +5 -5
  76. data/test/functional/test_litle_requests.rb +101 -99
  77. data/test/functional/test_load.rb +6 -6
  78. data/test/functional/test_loadReversal.rb +5 -5
  79. data/test/functional/test_override.rb +9 -9
  80. data/test/functional/{test_pgp_litle_requests.rb → test_pgp_cnp_requests.rb} +61 -60
  81. data/test/functional/test_queryTransaction.rb +10 -10
  82. data/test/functional/test_refundReversal.rb +5 -5
  83. data/test/functional/test_sale.rb +36 -36
  84. data/test/functional/test_token.rb +10 -10
  85. data/test/functional/test_unload.rb +6 -6
  86. data/test/functional/test_unloadReversal.rb +5 -5
  87. data/test/functional/test_updateCardValidationNumOnToken.rb +4 -4
  88. data/test/functional/test_updatePlan.rb +4 -4
  89. data/test/functional/test_updateSubscription.rb +5 -5
  90. data/test/functional/test_wallet.rb +5 -5
  91. data/test/functional/test_xmlfields.rb +29 -69
  92. data/test/functional/ts_all.rb +2 -2
  93. data/test/unit/test_LitleAUBatch.rb +15 -15
  94. data/test/unit/test_LitleBatchRequest.rb +42 -76
  95. data/test/unit/test_LitleOnlineRequest.rb +38 -38
  96. data/test/unit/test_LitleRequest.rb +47 -47
  97. data/test/unit/test_LitleTransaction.rb +34 -34
  98. data/test/unit/test_LitleXmlMapper.rb +27 -27
  99. data/test/unit/test_activate.rb +8 -8
  100. data/test/unit/test_activateReversal.rb +5 -5
  101. data/test/unit/test_auth.rb +43 -43
  102. data/test/unit/test_authReversal.rb +14 -14
  103. data/test/unit/test_balanceInquiry.rb +4 -4
  104. data/test/unit/test_cancelSubscription.rb +4 -4
  105. data/test/unit/test_capture.rb +20 -20
  106. data/test/unit/test_captureGivenAuth.rb +22 -22
  107. data/test/unit/test_createPlan.rb +4 -4
  108. data/test/unit/test_credit.rb +43 -43
  109. data/test/unit/test_deactivate.rb +6 -6
  110. data/test/unit/test_deactivateReversal.rb +5 -5
  111. data/test/unit/test_depositReversal.rb +5 -5
  112. data/test/unit/test_echeckCredit.rb +16 -16
  113. data/test/unit/test_echeckRedeposit.rb +19 -19
  114. data/test/unit/test_echeckSale.rb +16 -16
  115. data/test/unit/test_echeckVerification.rb +11 -11
  116. data/test/unit/test_echeckVoid.rb +8 -8
  117. data/test/unit/test_forceCapture.rb +19 -19
  118. data/test/unit/test_fraudCheck.rb +4 -4
  119. data/test/unit/test_giftCardAuthReversal.rb +5 -5
  120. data/test/unit/test_giftCardCapture.rb +5 -5
  121. data/test/unit/test_giftCardCredit.rb +5 -5
  122. data/test/unit/test_load.rb +4 -4
  123. data/test/unit/test_loadReversal.rb +5 -5
  124. data/test/unit/{test_pgp_LitleRequest → test_pgp_CnpRequest.rb} +32 -32
  125. data/test/unit/test_queryTransaction.rb +8 -8
  126. data/test/unit/test_refundReversal.rb +5 -5
  127. data/test/unit/test_sale.rb +64 -64
  128. data/test/unit/test_token.rb +13 -13
  129. data/test/unit/test_unload.rb +4 -4
  130. data/test/unit/test_unloadReversal.rb +5 -5
  131. data/test/unit/test_updateCardValidationNumOnToken.rb +16 -16
  132. data/test/unit/test_updatePlan.rb +4 -4
  133. data/test/unit/test_updateSubscription.rb +11 -11
  134. data/test/unit/test_wallet.rb +13 -13
  135. data/test/unit/test_xmlfields.rb +119 -119
  136. data/test/unit/ts_unit.rb +6 -6
  137. metadata +35 -26
  138. data/samples/Auth/LitleAuthReversalTransaction.rb +0 -15
  139. data/samples/Capture/LitleCaptureTransaction.rb +0 -14
  140. data/samples/Capture/LitlePartialCapture.rb +0 -16
  141. data/samples/Credit/LitleCreditTransaction.rb +0 -16
  142. data/samples/Other/LitleVoidTransaction.rb +0 -19
@@ -29,10 +29,9 @@ require 'open3'
29
29
 
30
30
  include Socket::Constants
31
31
  #
32
- # This class handles sending the Litle Request (which is actually a series of batches!)
32
+ # This class handles sending the Cnp Request (which is actually a series of batches!)
33
33
  #
34
34
 
35
-
36
35
  SFTP_USERNAME_CONFIG_NAME = :sftp_username
37
36
  SFTP_PASSWORD_CONFIG_NAME = :sftp_password
38
37
  SFTP_URL_CONFIG_NAME = :sftp_url
@@ -50,9 +49,9 @@ SENT_FILE_SUFFIX = '.sent'
50
49
  RECEIVED_FILE_SUFFIX = '.received'
51
50
  COMPLETE_FILE_SUFFIX = '.complete'
52
51
 
53
- module LitleOnline
54
- class LitleRequest
55
- #include XML::Mapping
52
+ module CnpOnline
53
+ class CnpRequest
54
+ include XML::Mapping
56
55
  def initialize(options = {})
57
56
  #load configuration data
58
57
  @config_hash = Configuration.new.config
@@ -64,23 +63,23 @@ module LitleOnline
64
63
  @options = options
65
64
  # current time out set to 2 mins
66
65
  # this value is in seconds
67
- @RESPONSE_TIME_OUT = 520
66
+ @RESPONSE_TIME_OUT = 5200
68
67
  @POLL_DELAY = 0
69
68
  @responses_expected = 0
70
69
  end
71
70
 
72
- # Creates the necessary files for the LitleRequest at the path specified. path/request_(TIMESTAMP) will be
71
+ # Creates the necessary files for the CnpRequest at the path specified. path/request_(TIMESTAMP) will be
73
72
  # the final XML markup and path/request_(TIMESTAMP) will hold intermediary XML markup
74
73
  # Params:
75
74
  # +path+:: A +String+ containing the path to the folder on disc to write the files to
76
- def create_new_litle_request(path)
75
+ def create_new_cnp_request(path)
77
76
  ts = Time::now.to_i.to_s
78
77
  begin
79
78
  ts += Time::now.nsec.to_s
80
79
  rescue NoMethodError # ruby 1.8.7 fix
81
80
  ts += Time::now.usec.to_s
82
- end
83
-
81
+ end
82
+
84
83
  if(File.file?(path)) then
85
84
  raise RuntimeError, "Entered a file not a path."
86
85
  end
@@ -92,13 +91,12 @@ module LitleOnline
92
91
  if !File.directory?(path) then
93
92
  Dir.mkdir(path)
94
93
  end
95
-
94
+
96
95
  @path_to_request = path + REQUEST_FILE_PREFIX + ts
97
96
  @path_to_batches = @path_to_request + '_batches'
98
97
 
99
98
  if File.file?(@path_to_request) or File.file?(@path_to_batches) then
100
- create_new_litle_request(path)
101
-
99
+ create_new_cnp_request(path)
102
100
  return
103
101
  end
104
102
 
@@ -110,30 +108,30 @@ module LitleOnline
110
108
  end
111
109
  end
112
110
 
113
- # Adds a batch to the LitleRequest. If the batch is open when passed, it will be closed prior to being added.
111
+ # Adds a batch to the CnpRequest. If the batch is open when passed, it will be closed prior to being added.
114
112
  # Params:
115
- # +arg+:: a +LitleBatchRequest+ containing the transactions you wish to send or a +String+ specifying the
113
+ # +arg+:: a +CnpBatchRequest+ containing the transactions you wish to send or a +String+ specifying the
116
114
  # path to the batch file
117
115
  def commit_batch(arg)
118
116
  path_to_batch = ""
119
117
  #they passed a batch
120
- if arg.kind_of?(LitleBatchRequest) then
118
+ if arg.kind_of?(CnpBatchRequest) then
121
119
  path_to_batch = arg.get_batch_name
122
- if((au = arg.get_au_batch) != nil) then
120
+ if((au = arg.get_au_batch) != nil) then
123
121
  # also commit the account updater batch
124
122
  commit_batch(au)
125
123
  end
126
- elsif arg.kind_of?(LitleAUBatch) then
124
+ elsif arg.kind_of?(CnpAUBatch) then
127
125
  path_to_batch = arg.get_batch_name
128
126
  elsif arg.kind_of?(String) then
129
127
  path_to_batch = arg
130
128
  else
131
- raise RuntimeError, "You entered neither a path nor a batch."
129
+ raise RuntimeError, "You entered neither a path nor a batch. Game over :("
132
130
  end
133
131
  #the batch isn't closed. let's help a brother out
134
132
  if (ind = path_to_batch.index(/\.closed/)) == nil then
135
133
  if arg.kind_of?(String) then
136
- new_batch = LitleBatchRequest.new
134
+ new_batch = CnpBatchRequest.new
137
135
  new_batch.open_existing_batch(path_to_batch)
138
136
  new_batch.close_batch()
139
137
  path_to_batch = new_batch.get_batch_name
@@ -142,79 +140,79 @@ module LitleOnline
142
140
  if(new_batch.get_au_batch != nil) then
143
141
  File.remove(path_to_batch)
144
142
  path_to_batch = new_batch.get_au_batch.get_batch_name
145
- end
146
- elsif arg.kind_of?(LitleBatchRequest) then
143
+ end
144
+ elsif arg.kind_of?(CnpBatchRequest) then
147
145
  arg.close_batch()
148
146
  path_to_batch = arg.get_batch_name
149
- elsif arg.kind_of?(LitleAUBatch) then
147
+ elsif arg.kind_of?(CnpAUBatch) then
150
148
  arg.close_batch()
151
- path_to_batch = arg.get_batch_name
149
+ path_to_batch = arg.get_batch_name
152
150
  end
153
151
  ind = path_to_batch.index(/\.closed/)
154
152
  end
155
153
  transactions_in_batch = path_to_batch[ind+8..path_to_batch.length].to_i
156
154
 
157
- # if the litle request would be too big, let's make another!
155
+ # if the cnp request would be too big, let's make another!
158
156
  if (@num_total_transactions + transactions_in_batch) > @MAX_NUM_TRANSACTIONS then
159
157
  finish_request
160
158
  initialize(@options)
161
- create_new_litle_request #(path_to_batch)
159
+ create_new_cnp_request
162
160
  else #otherwise, let's add it line by line to the request doc
163
- # @num_batch_requests += 1
161
+ # @num_batch_requests += 1
164
162
  #how long we wnat to wait around for the FTP server to get us a response
165
163
  @RESPONSE_TIME_OUT += 90 + (transactions_in_batch * 0.25)
166
164
  #don't start looking until there could possibly be a response
167
165
  @POLL_DELAY += 30 +(transactions_in_batch * 0.02)
168
166
  @num_total_transactions += transactions_in_batch
169
- # Don't add empty batches
170
- @num_batch_requests += 1 unless transactions_in_batch.eql?(0)
167
+ # Don't add empty batches
168
+ @num_batch_requests += 1 unless transactions_in_batch.eql?(0)
171
169
  File.open(@path_to_batches, 'a+') do |fo|
172
170
  File.foreach(path_to_batch) do |li|
173
171
  fo.puts li
174
172
  end
175
173
  end
176
-
174
+
177
175
  File.delete(path_to_batch)
178
176
  end
179
177
  end
180
178
 
181
- # Adds an RFRRequest to the LitleRequest.
182
- # params:
183
- # +options+:: a required +Hash+ containing configuration info for the RFRRequest. If the RFRRequest is for a batch, then the
184
- # litleSessionId is required as a key/val pair. If the RFRRequest is for account updater, then merchantId and postDay are required
179
+ # Adds an RFRRequest to the CnpRequest.
180
+ # params:
181
+ # +options+:: a required +Hash+ containing configuration info for the RFRRequest. If the RFRRequest is for a batch, then the
182
+ # cnpSessionId is required as a key/val pair. If the RFRRequest is for account updater, then merchantId and postDay are required
185
183
  # as key/val pairs.
186
- # +path+:: optional path to save the new litle request containing the RFRRequest at
184
+ # +path+:: optional path to save the new cnp request containing the RFRRequest at
187
185
  def add_rfr_request(options, path = (File.dirname(@path_to_batches)))
188
-
189
- rfrrequest = LitleRFRRequest.new
190
- if(options['litleSessionId']) then
191
- rfrrequest.litleSessionId = options['litleSessionId']
186
+
187
+ rfrrequest = CnpRFRRequest.new
188
+ if(options['cnpSessionId']) then
189
+ rfrrequest.cnpSessionId = options['cnpSessionId']
192
190
  elsif(options['merchantId'] and options['postDay']) then
193
191
  accountUpdate = AccountUpdateFileRequestData.new
194
192
  accountUpdate.merchantId = options['merchantId']
195
193
  accountUpdate.postDay = options['postDay']
196
194
  rfrrequest.accountUpdateFileRequestData = accountUpdate
197
195
  else
198
- raise ArgumentError, "For an RFR Request, you must specify either a litleSessionId for an RFRRequest for batch or a merchantId
196
+ raise ArgumentError, "For an RFR Request, you must specify either a cnpSessionId for an RFRRequest for batch or a merchantId
199
197
  and a postDay for an RFRRequest for account updater."
200
- end
201
-
202
- litleRequest = LitleRequestForRFR.new
203
- litleRequest.rfrRequest = rfrrequest
204
-
198
+ end
199
+
200
+ cnpRequest = CnpRequestForRFR.new
201
+ cnpRequest.rfrRequest = rfrrequest
202
+
205
203
  authentication = Authentication.new
206
204
  authentication.user = get_config(:user, options)
207
205
  authentication.password = get_config(:password, options)
208
206
 
209
- litleRequest.authentication = authentication
210
- litleRequest.numBatchRequests = "0"
211
-
212
- litleRequest.version = '11.4'
213
- litleRequest.xmlns = "http://www.litle.com/schema"
214
-
215
-
216
- xml = litleRequest.save_to_xml.to_s
207
+ cnpRequest.authentication = authentication
208
+ cnpRequest.numBatchRequests = "0"
209
+
210
+ cnpRequest.version = '12.1'
211
+ cnpRequest.xmlns = "http://www.vantivcnp.com/schema"
217
212
 
213
+
214
+ xml = cnpRequest.save_to_xml.to_s
215
+
218
216
  ts = Time::now.to_i.to_s
219
217
  begin
220
218
  ts += Time::now.nsec.to_s
@@ -232,24 +230,24 @@ module LitleOnline
232
230
  if !File.directory?(path) then
233
231
  Dir.mkdir(path)
234
232
  end
235
-
233
+
236
234
  path_to_request = path + REQUEST_FILE_PREFIX + ts
237
235
 
238
236
  File.open(path_to_request, 'a+') do |file|
239
237
  file.write xml
240
238
  end
241
239
  File.rename(path_to_request, path_to_request + COMPLETE_FILE_SUFFIX)
242
- @RESPONSE_TIME_OUT += 90
240
+ @RESPONSE_TIME_OUT += 90
243
241
  end
244
242
 
245
- # FTPs all previously unsent LitleRequests located in the folder denoted by path to the server
243
+ # FTPs all previously unsent CnpRequests located in the folder denoted by path to the server
246
244
  # Params:
247
- # +path+:: A +String+ containing the path to the folder on disc where LitleRequests are located.
248
- # This should be the same location where the LitleRequests were written to. If no path is explicitly
245
+ # +path+:: A +String+ containing the path to the folder on disc where CnpRequests are located.
246
+ # This should be the same location where the CnpRequests were written to. If no path is explicitly
249
247
  # provided, then we use the directory where the current working batches file is stored.
250
- # +options+:: An (option) +Hash+ containing the username, password, useEncryption and URL to attempt to sFTP to.
248
+ # +options+:: An (option) +Hash+ containing the username, password, and URL to attempt to sFTP to.
251
249
  # If not provided, the values will be populated from the configuration file.
252
- def send_to_litle(path = (File.dirname(@path_to_batches)), options = {})
250
+ def send_to_cnp(path = (File.dirname(@path_to_batches)), options = {})
253
251
  use_encryption = get_config(SFTP_USE_ENCRYPTION_CONFIG_NAME, options)
254
252
  username = get_config(SFTP_USERNAME_CONFIG_NAME, options)
255
253
  password = get_config(SFTP_PASSWORD_CONFIG_NAME, options)
@@ -275,65 +273,64 @@ module LitleOnline
275
273
  end
276
274
  end
277
275
  end
278
-
279
-
280
- # Sends all previously unsent LitleRequests in the specified directory to the Litle server
276
+
277
+ # Sends all previously unsent CnpRequests in the specified directory to the Cnp server
281
278
  # by use of fast batch. All results will be written to disk as we get them. Note that use
282
279
  # of fastbatch is strongly discouraged!
283
- def send_to_litle_stream(options = {}, path = (File.dirname(@path_to_batches)))
280
+ def send_to_cnp_stream(options = {}, path = (File.dirname(@path_to_batches)))
284
281
  url = get_config(:fast_url, options)
285
282
  port = get_config(:fast_port, options)
286
-
287
-
283
+
284
+
288
285
  if(url == nil or url == "") then
289
286
  raise ArgumentError, "A URL for fastbatch was not specified in the config file or passed options. Reconfigure and try again."
290
- end
291
-
287
+ end
288
+
292
289
  if(port == "" or port == nil) then
293
290
  raise ArgumentError, "A port number for fastbatch was not specified in the config file or passed options. Reconfigure and try again."
294
- end
295
-
291
+ end
292
+
296
293
  if(path[-1,1] != '/' && path[-1,1] != '\\') then
297
294
  path = path + File::SEPARATOR
298
295
  end
299
-
296
+
300
297
  if (!File.directory?(path + RESPONSE_PATH_DIR)) then
301
298
  Dir.mkdir(path + RESPONSE_PATH_DIR)
302
299
  end
303
-
300
+
304
301
  Dir.foreach(path) do |filename|
305
302
  if((filename =~ /#{REQUEST_FILE_PREFIX}\d+#{COMPLETE_FILE_SUFFIX}\z/) != nil) then
306
- begin
303
+ begin
307
304
  socket = TCPSocket.open(url,port.to_i)
308
305
  ssl_context = OpenSSL::SSL::SSLContext.new()
309
306
  ssl_context.ssl_version = :SSLv23
310
307
  ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, ssl_context)
311
308
  ssl_socket.sync_close = true
312
309
  ssl_socket.connect
313
-
314
- rescue => e
310
+
311
+ rescue => e
315
312
  raise "A connection couldn't be established. Are you sure you have the correct credentials? Exception: " + e.message
316
313
  end
317
-
318
- File.foreach(path + filename) do |li|
319
- ssl_socket.puts li
320
-
321
- end
322
- File.rename(path + filename, path + filename + SENT_FILE_SUFFIX)
323
- File.open(path + RESPONSE_PATH_DIR + (filename + '.asc' + RECEIVED_FILE_SUFFIX).gsub("request", "response"), 'a+') do |fo|
314
+
315
+ File.foreach(path + filename) do |li|
316
+ ssl_socket.puts li
317
+
318
+ end
319
+ File.rename(path + filename, path + filename + SENT_FILE_SUFFIX)
320
+ File.open(path + RESPONSE_PATH_DIR + (filename + '.asc' + RECEIVED_FILE_SUFFIX).gsub("request", "response"), 'a+') do |fo|
324
321
  while line = ssl_socket.gets
325
- fo.puts(line)
322
+ fo.puts(line)
326
323
  end
327
- end
328
-
324
+ end
329
325
  end
330
- end
326
+ end
331
327
  end
332
-
333
- # Grabs response files over SFTP from Litle.
328
+
329
+
330
+ # Grabs response files over SFTP from Cnp.
334
331
  # Params:
335
332
  # +args+:: An (optional) +Hash+ containing values for the number of responses expected, the
336
- # path to the folder on disk to write the responses from the Litle server to, the username and
333
+ # path to the folder on disk to write the responses from the Cnp server to, the username and
337
334
  # password with which to connect ot the sFTP server, and the URL to connect over sFTP. Values not
338
335
  # provided in the hash will be populate automatically based on our best guess
339
336
  def get_responses_from_server(args = {})
@@ -361,84 +358,80 @@ module LitleOnline
361
358
 
362
359
  # Params:
363
360
  # +args+:: A +Hash+ containing arguments for the processing process. This hash MUST contain an entry
364
- # for a transaction listener (see +DefaultLitleListener+). It may also include a batch listener and a
361
+ # for a transaction listener (see +DefaultCnpListener+). It may also include a batch listener and a
365
362
  # custom path where response files from the server are located (if it is not provided, we'll guess the position)
366
363
  def process_responses(args)
367
364
  #the transaction listener is required
368
365
  if(!args.has_key?(:transaction_listener)) then
369
366
  raise ArgumentError, "The arguments hash must contain an entry for transaction listener!"
370
367
  end
371
-
368
+
372
369
  transaction_listener = args[:transaction_listener]
373
370
  batch_listener = args[:batch_listener] ||= nil
374
371
  path_to_responses = args[:path_to_responses] ||= (File.dirname(@path_to_batches) + '/' + RESPONSE_PATH_DIR)
375
372
  delete_batch_files = args[:deleteBatchFiles] ||= get_config(:deleteBatchFiles, args)
376
-
377
- if(path_to_responses[-1,1] != '/' && path_to_responses[-1,1] != '\\') then
378
- path_to_responses = path_to_responses + File::SEPARATOR
379
- end
380
-
373
+ #deleteBatchFiles = get_config(:deleteBatchFiles, args)
374
+
381
375
  Dir.foreach(path_to_responses) do |filename|
382
376
  if ((filename =~ /#{RESPONSE_FILE_PREFIX}\d+#{COMPLETE_FILE_SUFFIX}.asc#{RECEIVED_FILE_SUFFIX}\z/) != nil) then
383
377
  process_response(path_to_responses + filename, transaction_listener, batch_listener)
384
378
  File.rename(path_to_responses + filename, path_to_responses + filename + '.processed')
385
- end
379
+ end
386
380
  end
387
381
 
388
382
  if delete_batch_files
389
383
  delete_files_in_path(path_to_responses, /#{RESPONSE_FILE_PREFIX}\d+#{COMPLETE_FILE_SUFFIX}.asc#{RECEIVED_FILE_SUFFIX}.processed\z/)
390
384
  end
391
385
  end
392
-
386
+
393
387
  # Params:
394
388
  # +path_to_response+:: The path to a specific .asc file to process
395
- # +transaction_listener+:: A listener to be applied to the hash of each transaction
396
- # (see +DefaultLitleListener+)
397
- # +batch_listener+:: An (optional) listener to be applied to the hash of each batch.
398
- # Note that this will om-nom-nom quite a bit of memory
389
+ # +transaction_listener+:: A listener to be applied to the hash of each transaction
390
+ # (see +DefaultCnpListener+)
391
+ # +batch_listener+:: An (optional) listener to be applied to the hash of each batch.
392
+ # Note that this will om-nom-nom quite a bit of memory
399
393
  def process_response(path_to_response, transaction_listener, batch_listener = nil)
400
394
  reader = LibXML::XML::Reader.file(path_to_response)
401
395
  reader.read # read into the root node
402
396
  #if the response attribute is nil, we're dealing with an RFR and everything is a-okay
403
397
  if reader.get_attribute('response') != "0" and reader.get_attribute('response') != nil then
404
- raise RuntimeError, "Error parsing Litle Request: " + reader.get_attribute("message")
398
+ raise RuntimeError, "Error parsing Cnp Request: " + reader.get_attribute("message")
405
399
  end
406
-
400
+
407
401
  reader.read
408
402
  count = 0
409
403
  while true and count < 500001 do
410
-
404
+
411
405
  count += 1
412
406
  if(reader.node == nil) then
413
407
  return false
414
- end
415
-
408
+ end
409
+
416
410
  case reader.node.name.to_s
417
- when "batchResponse"
418
- reader.read
419
- when "litleResponse"
420
- return false
421
- when "text"
422
- reader.read
423
- else
424
- xml = reader.read_outer_xml
425
- duck = Crack::XML.parse(xml)
426
- duck[duck.keys[0]]["type"] = duck.keys[0]
427
- duck = duck[duck.keys[0]]
428
- transaction_listener.apply(duck)
429
- reader.next
411
+ when "batchResponse"
412
+ reader.read
413
+ when "cnpResponse"
414
+ return false
415
+ when "text"
416
+ reader.read
417
+ else
418
+ xml = reader.read_outer_xml
419
+ duck = Crack::XML.parse(xml)
420
+ duck[duck.keys[0]]["type"] = duck.keys[0]
421
+ duck = duck[duck.keys[0]]
422
+ transaction_listener.apply(duck)
423
+ reader.next
430
424
  end
431
425
  end
432
426
  end
433
-
427
+
434
428
  def get_path_to_batches
435
429
  return @path_to_batches
436
430
  end
437
431
 
438
432
  # Called when you wish to finish adding batches to your request, this method rewrites the aggregate
439
- # batch file to the final LitleRequest xml doc with the appropos LitleRequest tags.
433
+ # batch file to the final CnpRequest xml doc with the appropos CnpRequest tags.
440
434
  def finish_request
441
-
442
435
  File.open(@path_to_request, 'w') do |f|
443
436
  #jam dat header in there
444
437
  f.puts(build_request_header())
@@ -447,7 +440,7 @@ module LitleOnline
447
440
  f.puts li
448
441
  end
449
442
  #finally, let's poot in a header, for old time's sake
450
- f.puts '</litleRequest>'
443
+ f.puts '</cnpRequest>'
451
444
  end
452
445
 
453
446
  #rename the requests file
@@ -459,33 +452,34 @@ module LitleOnline
459
452
  private
460
453
 
461
454
  def build_request_header(options = @options)
462
- litle_request = self
455
+ cnp_request = self
463
456
 
464
457
  authentication = Authentication.new
465
458
  authentication.user = get_config(:user, options)
466
459
  authentication.password = get_config(:password, options)
467
460
 
468
- litle_request.authentication = authentication
469
- litle_request.version = '11.4'
470
- litle_request.xmlns = "http://www.litle.com/schema"
471
- # litle_request.id = options['sessionId'] #grab from options; okay if nil
472
- litle_request.numBatchRequests = @num_batch_requests
461
+ cnp_request.authentication = authentication
462
+ cnp_request.version = '12.1'
463
+ cnp_request.xmlns = "http://www.vantivcnp.com/schema"
464
+ # cnp_request.id = options['sessionId'] #grab from options; okay if nil
465
+ cnp_request.numBatchRequests = @num_batch_requests
473
466
 
474
- xml = litle_request.save_to_xml.to_s
475
- xml[/<\/litleRequest>/]=''
467
+ xml = cnp_request.save_to_xml.to_s
468
+ xml[/<\/cnpRequest>/]=''
476
469
  return xml
477
470
  end
478
471
 
479
472
  def get_config(field, options)
480
473
  if options[field.to_s] == nil and options[field] == nil then
481
474
  return @config_hash[field.to_s]
482
- elsif options[field.to_s] != nil then
475
+ elsif options[field.to_s] != nil then
483
476
  return options[field.to_s]
484
- else
477
+ else
485
478
  return options[field]
486
479
  end
487
480
  end
488
481
 
482
+
489
483
  def delete_files_in_path(path, pattern)
490
484
  Dir.foreach(path) do |filename|
491
485
  if((filename =~ pattern)) != nil then
@@ -539,69 +533,69 @@ module LitleOnline
539
533
 
540
534
 
541
535
  def upload_to_sftp(path_to_requests, url, username, password, use_encryption)
542
- begin
543
- responses_expected = 0
544
- Net::SFTP.start(url, username, :password => password) do |sftp|
545
- Dir.foreach(path_to_requests) do |filename|
546
- if (filename =~ /#{REQUEST_FILE_PREFIX}\d+#{COMPLETE_FILE_SUFFIX}((#{ENCRYPTED_FILE_SUFFIX})?)\z/) != nil
547
- new_filename = filename + '.prg'
548
- File.rename(path_to_requests + filename, path_to_requests + new_filename)
549
- # upload the file
550
- sftp.upload!(path_to_requests + new_filename, '/inbound/' + new_filename)
551
- responses_expected += 1
552
- # rename now that we're done
553
- sftp.rename!('/inbound/'+ new_filename, '/inbound/' + new_filename.gsub('prg', 'asc'))
554
- File.rename(path_to_requests + new_filename, path_to_requests + new_filename.gsub('prg','sent'))
555
- if use_encryption
556
- # rename the plain text file too
557
- text_filename = (path_to_requests + filename).gsub(ENCRYPTED_PATH_DIR, '').gsub(ENCRYPTED_FILE_SUFFIX, '')
558
- File.rename(text_filename, text_filename + SENT_FILE_SUFFIX)
559
- end
536
+ begin
537
+ responses_expected = 0
538
+ Net::SFTP.start(url, username, :password => password) do |sftp|
539
+ Dir.foreach(path_to_requests) do |filename|
540
+ if (filename =~ /#{REQUEST_FILE_PREFIX}\d+#{COMPLETE_FILE_SUFFIX}((#{ENCRYPTED_FILE_SUFFIX})?)\z/) != nil
541
+ new_filename = filename + '.prg'
542
+ File.rename(path_to_requests + filename, path_to_requests + new_filename)
543
+ # upload the file
544
+ sftp.upload!(path_to_requests + new_filename, '/inbound/' + new_filename)
545
+ responses_expected += 1
546
+ # rename now that we're done
547
+ sftp.rename!('/inbound/'+ new_filename, '/inbound/' + new_filename.gsub('prg', 'asc'))
548
+ File.rename(path_to_requests + new_filename, path_to_requests + new_filename.gsub('prg','sent'))
549
+ if use_encryption
550
+ # rename the plain text file too
551
+ text_filename = (path_to_requests + filename).gsub(ENCRYPTED_PATH_DIR, '').gsub(ENCRYPTED_FILE_SUFFIX, '')
552
+ File.rename(text_filename, text_filename + SENT_FILE_SUFFIX)
560
553
  end
561
554
  end
562
555
  end
563
- return responses_expected
564
- rescue Net::SSH::AuthenticationFailed
565
- raise ArgumentError, "The sFTP credentials provided were incorrect. Try again!"
566
556
  end
557
+ return responses_expected
558
+ rescue Net::SSH::AuthenticationFailed
559
+ raise ArgumentError, "The sFTP credentials provided were incorrect. Try again!"
567
560
  end
561
+ end
568
562
 
569
-
570
- def download_from_sftp(response_path, url, username, password)
571
- responses_grabbed = 0
572
- begin
573
- #wait until a response has a possibility of being there
574
- sleep(@POLL_DELAY)
575
- time_begin = Time.now
576
- Net::SFTP.start(url, username, :password => password) do |sftp|
577
- while((Time.now - time_begin) < @RESPONSE_TIME_OUT && responses_grabbed < @responses_expected)
578
- #sleep for 60 seconds, ¿no es bueno?
579
- sleep(60)
580
- sftp.dir.foreach('/outbound/') do |entry|
581
- if (entry.name =~ /#{REQUEST_FILE_PREFIX}\d+#{COMPLETE_FILE_SUFFIX}((#{ENCRYPTED_FILE_SUFFIX})?).asc\z/) != nil then
582
- response_filename = response_path + entry.name.gsub(REQUEST_FILE_PREFIX, RESPONSE_FILE_PREFIX) + RECEIVED_FILE_SUFFIX
583
- sftp.download!('/outbound/' + entry.name, response_filename)
584
- responses_grabbed += 1
585
- 3.times{
586
- begin
587
- sftp.remove!('/outbound/' + entry.name)
588
- break
589
- rescue Net::SFTP::StatusException
590
- #try, try, try again
591
- puts "We couldn't remove it! Try again"
592
- end
593
- }
594
- end
563
+ def download_from_sftp(response_path, url, username, password)
564
+ responses_grabbed = 0
565
+ begin
566
+ #wait until a response has a possibility of being there?
567
+ sleep(@POLL_DELAY)
568
+ time_begin = Time.now
569
+ Net::SFTP.start(url, username, :password => password) do |sftp|
570
+ while((Time.now - time_begin) < @RESPONSE_TIME_OUT && responses_grabbed < @responses_expected)
571
+ #sleep for 60 seconds, ¿no es bueno?
572
+ sleep(60)
573
+ sftp.dir.foreach('/outbound/') do |entry|
574
+ if (entry.name =~ /#{REQUEST_FILE_PREFIX}\d+#{COMPLETE_FILE_SUFFIX}((#{ENCRYPTED_FILE_SUFFIX})?).asc\z/) != nil then
575
+ response_filename = response_path + entry.name.gsub(REQUEST_FILE_PREFIX, RESPONSE_FILE_PREFIX) + RECEIVED_FILE_SUFFIX
576
+ sftp.download!('/outbound/' + entry.name, response_filename)
577
+ responses_grabbed += 1
578
+ 3.times{
579
+ begin
580
+ sftp.remove!('/outbound/' + entry.name)
581
+ break
582
+ rescue Net::SFTP::StatusException
583
+ #try, try, try again
584
+ puts "We couldn't remove it! Try again"
585
+ end
586
+ }
595
587
  end
596
588
  end
597
- if responses_grabbed < @responses_expected then
598
- raise RuntimeError, "We timed out in waiting for a response from the server. :("
599
- end
600
589
  end
601
- rescue Net::SSH::AuthenticationFailed
602
- raise ArgumentError, "The sFTP credentials provided were incorrect. Try again!"
590
+ if responses_grabbed < @responses_expected then
591
+ raise RuntimeError, "We timed out in waiting for a response from the server. :("
592
+ end
603
593
  end
594
+ rescue Net::SSH::AuthenticationFailed
595
+ raise ArgumentError, "The sFTP credentials provided were incorrect. Try again!"
604
596
  end
597
+ end
598
+
605
599
 
606
600
  # Encrypt the request file for a PGP enabled account
607
601
  # +cipher_filename+:: Name of File that would contain encrypted batch
@@ -625,9 +619,10 @@ module LitleOnline
625
619
 
626
620
  rescue IOStreams::Pgp::Failure => e
627
621
  raise ArgumentError, "Please check if you have entered correct vantivePublicKeyID to config and that " +
628
- "vantiv's public key is added to your gpg keyring and is trusted. #{e.message}"
622
+ "vantiv's public key is added to your gpg keyring and is trusted. #{e.message}"
629
623
  end
630
624
 
625
+
631
626
  # Decrypt the encrypted batch response file
632
627
  # +response_filename+:: Filename of encrypted batch response file
633
628
  # The decrypted response would be placed in +response_filename+.gsub("encrypted", "")
@@ -635,11 +630,10 @@ module LitleOnline
635
630
  # If not provided, the values will be populated from the configuration file.
636
631
  def decrypt_batch_file_response(response_filename, args)
637
632
  passphrase = get_config(:passphrase, args)
638
- delete_batch_files = get_config(:deleteBatchFiles, args)
639
633
  if passphrase == ""
640
634
  raise RuntimeError, "The passphrase to decrypt the batch file responses is missing from the config"
641
635
  end
642
- decrypted_response_filename = response_filename.gsub('/encrypted', '').gsub(".encrypted", "")
636
+ decrypted_response_filename = response_filename.gsub(ENCRYPTED_PATH_DIR, '').gsub(ENCRYPTED_FILE_SUFFIX, "")
643
637
 
644
638
  decrypted_file = File.open(decrypted_response_filename, "w")
645
639
  IOStreams::Pgp::Reader.open(
@@ -647,14 +641,14 @@ module LitleOnline
647
641
  passphrase: passphrase
648
642
  ) do |stream|
649
643
  while !stream.eof?
650
- decrypted_file.puts(stream.readline())
644
+ decrypted_file.puts(stream.readline)
651
645
  #puts stream.readline()
652
646
  end
653
647
  end
654
- decrypted_file.close()
648
+ decrypted_file.close
655
649
  rescue IOStreams::Pgp::Failure => e
656
650
  raise ArgumentError, "Please check if you have entered correct passphrase to config and that your " +
657
- "merchant private key is added to your gpg keyring and is trusted. #{e.message}"
651
+ "merchant private key is added to your gpg keyring and is trusted. #{e.message}"
658
652
  end
659
653
  end
660
654
  end