activemerchant 1.99.0 → 1.100.0

Sign up to get free protection for your applications and to get access to all the features.
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