activemerchant 1.99.0 → 1.100.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cbb76da56e87639a3f9129d70297b78a0edabe9faf2300e682e06e872e019419
4
- data.tar.gz: 94cb0693e867b03071fe55a7e71b3cfbaf53a7c340d480f24108948822e9e1e7
3
+ metadata.gz: 823ed7b22c50e7910c846fe99b621d38589cc4ae2b01825219a344d08dee0024
4
+ data.tar.gz: 8cc6c8294cb70df4df71e805b7d9b336237540ada7e4867388eba7677ba37641
5
5
  SHA512:
6
- metadata.gz: aa96ed1337c57fa00d0405ff07a70b9423bac6a26ec69fde450d73bc9cabfc0ae27b75a46faddcdf3e79f2198db8214e8e6c5926468f0acb999bef43fc220a73
7
- data.tar.gz: f672640992309d545629a41e4f89d505732d0bb88559648a96935ef01293bcff737de41c8a7b8992993dafdfdb71d29bcbf8b85133c3d9ae5311f7b720b7c9c7
6
+ metadata.gz: 85b8024522112e07fd028f1331574ce47c4a7e343d8a92906d043f2448f4c656723151202f53de0f49627a4d5815fbda5d7ab81274268dd1cd2decf61b8b69bf
7
+ data.tar.gz: ce6135c3bd5c0c6985b60083abde4eef4a8bec4fb75c857ddb49a1a10d60608821ccca6337a7928d649b5fef7f847a191658db62004ec225c36b48e7ed9719c7
data/CHANGELOG CHANGED
@@ -1,6 +1,25 @@
1
1
  = ActiveMerchant CHANGELOG
2
2
 
3
3
  == HEAD
4
+ == Version 1.100.0 (Oct 16, 2019)
5
+ * Stripe: Restore non-auto capture behaviour for card present transactions [PatrickFang] #3258
6
+ * Revert "Revert "Worldpay: Switch to Nokogiri"" [curiousepic] #3373
7
+ * Adyen: Fix `authorise3d` message for refusals [jeremywrowe] #3374
8
+ * Redsys: Set authorization field for 3DS transactions [britth] #3377
9
+ * Adyen: Add capture_delay_hours GSF [therufs] #3376
10
+ * Credorax: Add support for stored credentials [chinhle23] #3375
11
+ * BlueSnap: Add remote tests for Cabal and Naranja [leila-alderman] #3382
12
+ * WorldPay: Add Cabal and Naranja remote tests [leila-alderman] #3378
13
+ * Rubocop: Indentions [nfarve] #3383
14
+ * Worldpay: Handle parse errors gracefully [curiousepic] #3380
15
+ * BluePay: Add ability to pass doc_type in refunds and credits [britth] #3386
16
+ * Stripe Payment Intents: Fix fallback for Store [waaux] #3343
17
+ * Update Securionpay supported countries [hossamhossny] #2472
18
+ * Visanet Peru: Add amount argument to Capture [curiousepic] #3389
19
+ * Rubocop: Layout/MultilineHashBraceLayout [nfarve] #3385
20
+ * CardConnect: Always include additional_data in purchase [therufs] #3387
21
+ * CardConnect: Add user_fields GSF [therufs] #3388
22
+
4
23
  == Version 1.99.0 (Sep 26, 2019)
5
24
  * Adyen: Add functionality to set 3DS exemptions via API [britth] #3331
6
25
  * Adyen: Send "NA" instead of "N/A" [leila-alderman] #3339
data/README.md CHANGED
@@ -215,7 +215,7 @@ The [ActiveMerchant Wiki](https://github.com/activemerchant/active_merchant/wiki
215
215
  * [SecureNet](http://www.securenet.com/) - US
216
216
  * [SecurePay](http://www.securepay.com/) - US, CA, GB, AU
217
217
  * [SecurePayTech](http://www.securepaytech.com/) - NZ
218
- * [SecurionPay](https://securionpay.com/) - AD, AE, AF, AG, AI, AL, AM, AO, AR, AS, AT, AU, AW, AX, AZ, BA, BB, BD, BE, BF, BG, BH, BI, BJ, BL, BM, BN, BO, BR, BS, BT, BV, BW, BY, BZ, CA, CC, CD, CF, CG, CH, CI, CK, CL, CM, CN, CO, CR, CU, CV, CW, CX, CY, CZ, DE, DJ, DK, DM, DO, DZ, EC, EE, EG, EH, ER, ES, ET, FI, FJ, FK, FM, FO, FR, GA, GB, GD, GE, GF, GG, GH, GI, GL, GM, GN, GP, GQ, GR, GS, GT, GU, GW, GY, HK, HM, HN, HR, HT, HU, ID, IE, IL, IM, IN, IO, IQ, IR, IS, IT, JE, JM, JO, JP, KE, KG, KH, KI, KM, KN, KP, KR, KW, KY, KZ, LA, LB, LC, LI, LK, LR, LS, LT, LU, LV, LY, MA, MC, MD, ME, MF, MG, MH, MK, ML, MM, MN, MO, MP, MQ, MR, MS, MT, MU, MV, MW, MX, MY, MZ, NA, NC, NE, NF, NG, NI, NL, NO, NP, NR, NU, NZ, OM, PA, PE, PF, PG, PH, PK, PL, PM, PN, PR, PS, PT, PW, PY, QA, RE, RO, RS, RU, RW, SA, SB, SC, SD, SE, SG, SH, SI, SJ, SK, SL, SM, SN, SO, SR, ST, SV, SY, SZ, TC, TD, TF, TG, TH, TJ, TK, TL, TM, TN, TO, TR, TT, TV, TW, TZ, UA, UG, UM, US, UY, UZ, VA, VC, VE, VG, VI, VN, VU, WF, WS, YE, YT, ZA, ZM, ZW
218
+ * [SecurionPay](https://securionpay.com/) - AD, BE, BG, CH, CY, CZ, DE, DK, EE, ES, FI, FO, FR, GI, GL, GR, GS, GT, HR, HU, IE, IS, IT, LI, LR, LT, LU, LV, MC, MT, MU, MV, MW, NL, NO, PL, RO, SE, SI
219
219
  * [SkipJack](http://www.skipjack.com/) - US, CA
220
220
  * [SoEasyPay](http://www.soeasypay.com/) - US, CA, AT, BE, BG, HR, CY, CZ, DK, EE, FI, FR, DE, GR, HU, IE, IT, LV, LT, LU, MT, NL, PL, PT, RO, SK, SI, ES, SE, GB, IS, NO, CH
221
221
  * [Spreedly](https://spreedly.com) - AD, AE, AT, AU, BD, BE, BG, BN, CA, CH, CY, CZ, DE, DK, EE, EG, ES, FI, FR, GB, GI, GR, HK, HU, ID, IE, IL, IM, IN, IS, IT, JO, KW, LB, LI, LK, LT, LU, LV, MC, MT, MU, MV, MX, MY, NL, NO, NZ, OM, PH, PL, PT, QA, RO, SA, SE, SG, SI, SK, SM, TR, TT, UM, US, VA, VN, ZA
@@ -225,6 +225,7 @@ The [ActiveMerchant Wiki](https://github.com/activemerchant/active_merchant/wiki
225
225
  * [Transact Pro](https://www.transactpro.lv/business/online-payments-acceptance) - US
226
226
  * [TransFirst](http://www.transfirst.com/) - US
227
227
  * [Transnational](http://www.tnbci.com/) - US
228
+ * [Trexle](https://trexle.com) - AD, AE, AT, AU, BD, BE, BG, BN, CA, CH, CY, CZ, DE, DK, EE, EG, ES, FI, FR, GB, GI, GR, HK, HU, ID, IE, IL, IM, IN, IS, IT, JO, KW, LB, LI, LK, LT, LU, LV, MC, MT, MU, MV, MX, MY, NL, NO, NZ, OM, PH, PL, PT, QA, RO, SA, SE, SG, SI, SK, SM, TR, TT, UM, US, VA, VN, ZA
228
229
  * [TrustCommerce](http://www.trustcommerce.com/) - US
229
230
  * [USA ePay](http://www.usaepay.com/) - US
230
231
  * [Vanco Payment Solutions](http://vancopayments.com/) - US
@@ -88,8 +88,7 @@ module ActiveMerchant
88
88
  { 'code' => code,
89
89
  'message' => message,
90
90
  'street_match' => street_match,
91
- 'postal_match' => postal_match
92
- }
91
+ 'postal_match' => postal_match}
93
92
  end
94
93
  end
95
94
  end
@@ -186,6 +186,7 @@ module ActiveMerchant #:nodoc:
186
186
  post[:selectedBrand] ||= NETWORK_TOKENIZATION_CARD_SOURCE[payment.source.to_s] if payment.is_a?(NetworkTokenizationCreditCard)
187
187
  post[:deliveryDate] = options[:delivery_date] if options[:delivery_date]
188
188
  post[:merchantOrderReference] = options[:merchant_order_reference] if options[:merchant_order_reference]
189
+ post[:captureDelayHours] = options[:capture_delay_hours] if options[:capture_delay_hours]
189
190
  post[:additionalData] ||= {}
190
191
  post[:additionalData][:overwriteBrand] = normalize(options[:overwrite_brand]) if options[:overwrite_brand]
191
192
  post[:additionalData][:customRoutingFlag] = options[:custom_routing_flag] if options[:custom_routing_flag]
@@ -464,7 +465,7 @@ module ActiveMerchant #:nodoc:
464
465
  end
465
466
 
466
467
  def message_from(action, response)
467
- return authorize_message_from(response) if action.to_s == 'authorise'
468
+ return authorize_message_from(response) if action.to_s == 'authorise' || action.to_s == 'authorise3d'
468
469
  response['response'] || response['message']
469
470
  end
470
471
 
@@ -164,6 +164,7 @@ module ActiveMerchant #:nodoc:
164
164
  post[:PAYMENT_ACCOUNT] = ''
165
165
  post[:MASTER_ID] = identification
166
166
  post[:TRANS_TYPE] = 'REFUND'
167
+ post[:DOC_TYPE] = options[:doc_type] if options[:doc_type]
167
168
  post[:NAME1] = options[:first_name] || ''
168
169
  post[:NAME2] = options[:last_name] if options[:last_name]
169
170
  post[:ZIP] = options[:zip] if options[:zip]
@@ -183,6 +184,7 @@ module ActiveMerchant #:nodoc:
183
184
  post[:PAYMENT_ACCOUNT] = ''
184
185
  add_payment_method(post, payment_object)
185
186
  post[:TRANS_TYPE] = 'CREDIT'
187
+ post[:DOC_TYPE] = options[:doc_type] if options[:doc_type]
186
188
 
187
189
  post[:NAME1] = options[:first_name] || ''
188
190
  post[:NAME2] = options[:last_name] if options[:last_name]
@@ -88,6 +88,7 @@ module ActiveMerchant #:nodoc:
88
88
  add_address(post, options)
89
89
  add_customer_data(post, options)
90
90
  add_3DS(post, options)
91
+ add_additional_data(post, options)
91
92
  post[:capture] = 'Y'
92
93
  commit('auth', post)
93
94
  end
@@ -102,6 +103,7 @@ module ActiveMerchant #:nodoc:
102
103
  add_address(post, options)
103
104
  add_customer_data(post, options)
104
105
  add_3DS(post, options)
106
+ add_additional_data(post, options)
105
107
  commit('auth', post)
106
108
  end
107
109
 
@@ -236,6 +238,7 @@ module ActiveMerchant #:nodoc:
236
238
  updated
237
239
  end
238
240
  end
241
+ post[:userfields] = options[:user_fields] if options[:user_fields]
239
242
  end
240
243
 
241
244
  def add_3DS(post, options)
@@ -134,7 +134,7 @@ module ActiveMerchant #:nodoc:
134
134
  add_3d_secure(post, options)
135
135
  add_echo(post, options)
136
136
  add_submerchant_id(post, options)
137
- add_transaction_type(post, options)
137
+ add_stored_credential(post, options)
138
138
  add_processor(post, options)
139
139
 
140
140
  commit(:purchase, post)
@@ -149,7 +149,7 @@ module ActiveMerchant #:nodoc:
149
149
  add_3d_secure(post, options)
150
150
  add_echo(post, options)
151
151
  add_submerchant_id(post, options)
152
- add_transaction_type(post, options)
152
+ add_stored_credential(post, options)
153
153
  add_processor(post, options)
154
154
 
155
155
  commit(:authorize, post)
@@ -249,6 +249,22 @@ module ActiveMerchant #:nodoc:
249
249
  post[:b3] = format(payment_method.month, :two_digits)
250
250
  end
251
251
 
252
+ def add_stored_credential(post, options)
253
+ add_transaction_type(post, options)
254
+ # if :transaction_type option is not passed, then check for :stored_credential options
255
+ return unless (stored_credential = options[:stored_credential]) && options.dig(:transaction_type).nil?
256
+ if stored_credential[:initiator] == 'merchant'
257
+ case stored_credential[:reason_type]
258
+ when 'recurring'
259
+ stored_credential[:initial_transaction] ? post[:a9] = '1' : post[:a9] = '2'
260
+ when 'installment', 'unscheduled'
261
+ post[:a9] = '8'
262
+ end
263
+ else
264
+ post[:a9] = '9'
265
+ end
266
+ end
267
+
252
268
  def add_customer_data(post, options)
253
269
  post[:d1] = options[:ip] || '127.0.0.1'
254
270
  if (billing_address = options[:billing_address])
@@ -281,7 +297,7 @@ module ActiveMerchant #:nodoc:
281
297
  browser_info = three_ds_2_options[:browser_info]
282
298
  post[:'3ds_initiate'] = options[:three_ds_initiate] || '01'
283
299
  post[:'3ds_purchasedate'] = Time.now.utc.strftime('%Y%m%d%I%M%S')
284
- post[:'3ds_channel'] = '02'
300
+ options.dig(:stored_credential, :initiator) == 'merchant' ? post[:'3ds_channel'] = '03' : post[:'3ds_channel'] = '02'
285
301
  post[:'3ds_redirect_url'] = three_ds_2_options[:notification_url]
286
302
  post[:'3ds_challengewindowsize'] = options[:three_ds_challenge_window_size] || '03'
287
303
  post[:'3ds_version'] = options[:three_ds_version] if options[:three_ds_version]
@@ -15,20 +15,16 @@ module ActiveMerchant #:nodoc:
15
15
 
16
16
  ENVELOPE_NAMESPACES = { 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
17
17
  'xmlns:env' => 'http://schemas.xmlsoap.org/soap/envelope/',
18
- 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
19
- }
18
+ 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'}
20
19
 
21
20
  SEND_AND_COMMIT_ATTRIBUTES = { 'xmlns:n1' => 'http://secure2.e-xact.com/vplug-in/transaction/rpc-enc/Request',
22
- 'env:encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/'
23
- }
21
+ 'env:encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/'}
24
22
 
25
23
  SEND_AND_COMMIT_SOURCE_ATTRIBUTES = { 'xmlns:n2' => 'http://secure2.e-xact.com/vplug-in/transaction/rpc-enc/encodedTypes',
26
- 'xsi:type' => 'n2:Transaction'
27
- }
24
+ 'xsi:type' => 'n2:Transaction'}
28
25
 
29
26
  POST_HEADERS = { 'soapAction' => 'http://secure2.e-xact.com/vplug-in/transaction/rpc-enc/SendAndCommit',
30
- 'Content-Type' => 'text/xml'
31
- }
27
+ 'Content-Type' => 'text/xml'}
32
28
 
33
29
  SUCCESS = 'true'
34
30
 
@@ -268,7 +268,7 @@ POST
268
268
  #{content_type}
269
269
  #{date}
270
270
  #{uri(action, authorization)}
271
- EOS
271
+ EOS
272
272
  digest = OpenSSL::Digest.new('sha256')
273
273
  key = @options[:secret_api_key]
274
274
  "GCS v1HMAC:#{@options[:api_key_id]}:#{Base64.strict_encode64(OpenSSL::HMAC.digest(digest, key, data))}"
@@ -214,7 +214,8 @@ module ActiveMerchant #:nodoc:
214
214
  xml.instruct!(:xml, encoding: 'UTF-8')
215
215
  xml.SOAP :Envelope, {
216
216
  'xmlns:SOAP' => 'http://schemas.xmlsoap.org/soap/envelope/',
217
- 'xmlns:hps' => 'http://Hps.Exchange.PosGateway' } do
217
+ 'xmlns:hps' => 'http://Hps.Exchange.PosGateway'
218
+ } do
218
219
  xml.SOAP :Body do
219
220
  xml.hps :PosRequest do
220
221
  xml.hps 'Ver1.0'.to_sym do
@@ -13,12 +13,10 @@ module ActiveMerchant #:nodoc:
13
13
 
14
14
  ENV_NAMESPACES = { 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
15
15
  'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
16
- 'xmlns:env' => 'http://schemas.xmlsoap.org/soap/envelope/'
17
- }
16
+ 'xmlns:env' => 'http://schemas.xmlsoap.org/soap/envelope/'}
18
17
  ENV_NAMESPACES_V4 = { 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
19
18
  'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
20
- 'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/'
21
- }
19
+ 'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/'}
22
20
 
23
21
  TX_NAMESPACE = 'http://merchantwarehouse.com/MerchantWARE/Client/TransactionRetail'
24
22
  TX_NAMESPACE_V4 = 'http://schemas.merchantwarehouse.com/merchantware/40/Credit/'
@@ -136,8 +136,7 @@ module ActiveMerchant #:nodoc:
136
136
  requires!(options, :card_number)
137
137
 
138
138
  post = { :trans_id => identification,
139
- :card_num => options[:card_number]
140
- }
139
+ :card_num => options[:card_number]}
141
140
 
142
141
  post[:first_name] = options[:first_name] if options[:first_name]
143
142
  post[:last_name] = options[:last_name] if options[:last_name]
@@ -50,7 +50,7 @@ module ActiveMerchant #:nodoc:
50
50
  post[:order_id] = options[:order_id]
51
51
  post[:address] = options[:billing_address] || options[:address]
52
52
  post[:crypt_type] = options[:crypt_type] || @options[:crypt_type]
53
- add_cof(post, options)
53
+ add_stored_credential(post, options)
54
54
  action = if post[:cavv]
55
55
  'cavv_preauth'
56
56
  elsif post[:data_key].blank?
@@ -73,7 +73,7 @@ module ActiveMerchant #:nodoc:
73
73
  post[:order_id] = options[:order_id]
74
74
  post[:address] = options[:billing_address] || options[:address]
75
75
  post[:crypt_type] = options[:crypt_type] || @options[:crypt_type]
76
- add_cof(post, options)
76
+ add_stored_credential(post, options)
77
77
  action = if post[:cavv]
78
78
  'cavv_purchase'
79
79
  elsif post[:data_key].blank?
@@ -208,6 +208,48 @@ module ActiveMerchant #:nodoc:
208
208
  post[:payment_information] = options[:payment_information] if options[:payment_information]
209
209
  end
210
210
 
211
+ def add_stored_credential(post, options)
212
+ add_cof(post, options)
213
+ # if any of :issuer_id, :payment_information, or :payment_indicator is not passed,
214
+ # then check for :stored credential options
215
+ return unless (stored_credential = options[:stored_credential]) && !cof_details_present?(options)
216
+ if stored_credential[:initial_transaction]
217
+ add_stored_credential_initial(post, options)
218
+ else
219
+ add_stored_credential_used(post, options)
220
+ end
221
+ end
222
+
223
+ def add_stored_credential_initial(post, options)
224
+ post[:payment_information] ||= '0'
225
+ post[:issuer_id] ||= ''
226
+ if options[:stored_credential][:initiator] == 'merchant'
227
+ case options[:stored_credential][:reason_type]
228
+ when 'recurring', 'installment'
229
+ post[:payment_indicator] ||= 'R'
230
+ when 'unscheduled'
231
+ post[:payment_indicator] ||= 'C'
232
+ end
233
+ else
234
+ post[:payment_indicator] ||= 'C'
235
+ end
236
+ end
237
+
238
+ def add_stored_credential_used(post, options)
239
+ post[:payment_information] ||= '2'
240
+ post[:issuer_id] = options[:stored_credential][:network_transaction_id] if options[:issuer_id].blank?
241
+ if options[:stored_credential][:initiator] == 'merchant'
242
+ case options[:stored_credential][:reason_type]
243
+ when 'recurring', 'installment'
244
+ post[:payment_indicator] ||= 'R'
245
+ when '', 'unscheduled'
246
+ post[:payment_indicator] ||= 'U'
247
+ end
248
+ else
249
+ post[:payment_indicator] ||= 'Z'
250
+ end
251
+ end
252
+
211
253
  # Common params used amongst the +credit+, +void+ and +capture+ methods
212
254
  def crediting_params(authorization, options = {})
213
255
  {
@@ -254,8 +254,7 @@ module ActiveMerchant #:nodoc:
254
254
  def schema
255
255
  { 'xmlns' => 'http://www.optimalpayments.com/creditcard/xmlschema/v1',
256
256
  'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
257
- 'xsi:schemaLocation' => 'http://www.optimalpayments.com/creditcard/xmlschema/v1'
258
- }
257
+ 'xsi:schemaLocation' => 'http://www.optimalpayments.com/creditcard/xmlschema/v1'}
259
258
  end
260
259
 
261
260
  def build_merchant_account(xml)
@@ -323,8 +322,7 @@ module ActiveMerchant #:nodoc:
323
322
  'master' => 'MC',
324
323
  'american_express'=> 'AM',
325
324
  'discover' => 'DI',
326
- 'diners_club' => 'DC',
327
- }[key]
325
+ 'diners_club' => 'DC', }[key]
328
326
  end
329
327
 
330
328
  end
@@ -35,8 +35,7 @@ module ActiveMerchant #:nodoc:
35
35
  'state' => @params['state'],
36
36
  'country' => @params['country'],
37
37
  'zip' => @params['zip'],
38
- 'phone' => phone,
39
- }
38
+ 'phone' => phone, }
40
39
  end
41
40
  end
42
41
  end
@@ -473,6 +473,7 @@ module ActiveMerchant #:nodoc:
473
473
  params[element.name.downcase.to_sym] = element.text
474
474
  end
475
475
  message = response_text_3ds(xml, params)
476
+ options[:authorization] = build_authorization(params)
476
477
  success = params.size > 0 && is_success_response?(params[:ds_response])
477
478
  elsif code == '0'
478
479
  op = xml.xpath('//RETORNOXML/OPERACION')
@@ -4,8 +4,8 @@ module ActiveMerchant #:nodoc:
4
4
  self.test_url = 'https://api.securionpay.com/'
5
5
  self.live_url = 'https://api.securionpay.com/'
6
6
 
7
- self.supported_countries = %w(AL AD AT BY BE BG HR CY CZ RE DK EE IS FI FR DE GI GR HU IS IE IT IL LV LI LT LU
8
- MK MT MD MC NL NO PL PT RO RU MA RS SK SI ES SE CH UA GB KI CI ME)
7
+ self.supported_countries = %w(AD BE BG CH CY CZ DE DK EE ES FI FO FR GI GL GR GS GT HR HU IE IS IT LI LR LT
8
+ LU LV MC MT MU MV MW NL NO PL RO SE SI)
9
9
 
10
10
  self.default_currency = 'USD'
11
11
  self.money_format = :cents
@@ -177,7 +177,8 @@ module ActiveMerchant #:nodoc:
177
177
  'xmlns:soapenc' => 'http://schemas.xmlsoap.org/soap/encoding/',
178
178
  'xmlns:tns' => 'urn:Interface',
179
179
  'xmlns:types' => 'urn:Interface/encodedTypes',
180
- 'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/'}) do
180
+ 'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/'
181
+ }) do
181
182
  retval.tag!('soap:Body', {'soap:encodingStyle'=>'http://schemas.xmlsoap.org/soap/encoding/'}) do
182
183
  retval.tag!("tns:#{request}") do
183
184
  retval.tag!("#{request}Request", {'xsi:type'=>"tns:#{request}Request"}) do
@@ -87,11 +87,8 @@ module ActiveMerchant #:nodoc:
87
87
  end
88
88
  r.process do
89
89
  post = create_post_for_auth_or_purchase(money, payment, options)
90
- if emv_payment?(payment)
91
- add_application_fee(post, options)
92
- else
93
- post[:capture] = 'false'
94
- end
90
+ add_application_fee(post, options) if emv_payment?(payment)
91
+ post[:capture] = 'false'
95
92
  commit(:post, 'charges', post, options)
96
93
  end
97
94
  end.responses.last
@@ -127,14 +124,17 @@ module ActiveMerchant #:nodoc:
127
124
  post = {}
128
125
 
129
126
  if emv_tc_response = options.delete(:icc_data)
130
- post[:card] = { emv_approval_data: emv_tc_response }
131
- commit(:post, "charges/#{CGI.escape(authorization)}", post, options)
127
+ # update the charge with emv data if card present
128
+ update = {}
129
+ update[:card] = { emv_approval_data: emv_tc_response }
130
+ commit(:post, "charges/#{CGI.escape(authorization)}", update, options)
132
131
  else
133
132
  add_application_fee(post, options)
134
133
  add_amount(post, money, options)
135
134
  add_exchange_rate(post, options)
136
- commit(:post, "charges/#{CGI.escape(authorization)}/capture", post, options)
137
135
  end
136
+
137
+ commit(:post, "charges/#{CGI.escape(authorization)}/capture", post, options)
138
138
  end
139
139
 
140
140
  def void(identification, options = {})
@@ -134,7 +134,7 @@ module ActiveMerchant #:nodoc:
134
134
  end
135
135
  commit(:post, "payment_methods/#{params[:payment_method]}/attach", { customer: customer_id }, options)
136
136
  else
137
- super(payment, options)
137
+ super(payment_method, options)
138
138
  end
139
139
  end
140
140
 
@@ -21,7 +21,7 @@ module ActiveMerchant #:nodoc:
21
21
  def purchase(amount, payment_method, options={})
22
22
  MultiResponse.run() do |r|
23
23
  r.process { authorize(amount, payment_method, options) }
24
- r.process { capture(r.authorization, options) }
24
+ r.process { capture(amount, r.authorization, options) }
25
25
  end
26
26
  end
27
27
 
@@ -37,7 +37,7 @@ module ActiveMerchant #:nodoc:
37
37
  commit('authorize', params, options)
38
38
  end
39
39
 
40
- def capture(authorization, options={})
40
+ def capture(amount, authorization, options={})
41
41
  params = {}
42
42
  options[:id_unico] = split_authorization(authorization)[1]
43
43
  add_auth_order_id(params, authorization, options)
@@ -1,3 +1,5 @@
1
+ require 'nokogiri'
2
+
1
3
  module ActiveMerchant #:nodoc:
2
4
  module Billing #:nodoc:
3
5
  class WorldpayGateway < Gateway
@@ -455,23 +457,28 @@ module ActiveMerchant #:nodoc:
455
457
  end
456
458
 
457
459
  def parse(action, xml)
458
- parse_element({:action => action}, REXML::Document.new(xml))
460
+ xml = xml.strip.gsub(/\&/, '&amp;')
461
+ doc = Nokogiri::XML(xml, &:strict)
462
+ doc.remove_namespaces!
463
+ resp_params = {:action => action}
464
+
465
+ parse_elements(doc.root, resp_params)
466
+ resp_params
459
467
  end
460
468
 
461
- def parse_element(raw, node)
469
+ def parse_elements(node, response)
462
470
  node_name = node.name.underscore
463
471
  node.attributes.each do |k, v|
464
- raw["#{node_name}_#{k.underscore}".to_sym] = v
472
+ response["#{node_name}_#{k.underscore}".to_sym] = v.value
465
473
  end
466
- if node.has_elements?
467
- raw[node_name.to_sym] = true unless node.name.blank?
468
- node.elements.each { |e| parse_element(raw, e) }
469
- elsif node.children.count > 1
470
- raw[node_name.to_sym] = node.children.join(' ').strip
474
+ if node.elements.empty?
475
+ response[node_name.to_sym] = node.text unless node.text.blank?
471
476
  else
472
- raw[node_name.to_sym] = node.text unless node.text.nil?
477
+ response[node_name.to_sym] = true unless node.name.blank?
478
+ node.elements.each do |childnode|
479
+ parse_elements(childnode, response)
480
+ end
473
481
  end
474
- raw
475
482
  end
476
483
 
477
484
  def headers(options)
@@ -506,6 +513,8 @@ module ActiveMerchant #:nodoc:
506
513
  :avs_result => AVSResult.new(code: AVS_CODE_MAP[raw[:avs_result_code_description]]),
507
514
  :cvv_result => CVVResult.new(CVC_CODE_MAP[raw[:cvc_result_code_description]])
508
515
  )
516
+ rescue Nokogiri::SyntaxError
517
+ unparsable_response(xml)
509
518
  rescue ActiveMerchant::ResponseError => e
510
519
  if e.response.code.to_s == '401'
511
520
  return Response.new(false, 'Invalid credentials', {}, :test => test?)
@@ -518,6 +527,12 @@ module ActiveMerchant #:nodoc:
518
527
  test? ? self.test_url : self.live_url
519
528
  end
520
529
 
530
+ def unparsable_response(raw_response)
531
+ message = 'Unparsable response received from Worldpay. Please contact Worldpay if you continue to receive this message.'
532
+ message += " (The raw response returned by the API was: #{raw_response.inspect})"
533
+ return Response.new(false, message)
534
+ end
535
+
521
536
  # Override the regular handle response so we can access the headers
522
537
  # Set-Cookie value is needed for 3DS transactions
523
538
  def handle_response(response)
@@ -1,3 +1,3 @@
1
1
  module ActiveMerchant
2
- VERSION = '1.99.0'
2
+ VERSION = '1.100.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activemerchant
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.99.0
4
+ version: 1.100.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Luetke
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-27 00:00:00.000000000 Z
11
+ date: 2019-10-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport