activemerchant 1.116.0 → 1.121.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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +148 -1
  3. data/README.md +4 -2
  4. data/lib/active_merchant/billing/check.rb +10 -0
  5. data/lib/active_merchant/billing/credit_card.rb +3 -0
  6. data/lib/active_merchant/billing/credit_card_methods.rb +80 -15
  7. data/lib/active_merchant/billing/gateways/adyen.rb +29 -8
  8. data/lib/active_merchant/billing/gateways/authorize_net.rb +37 -1
  9. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +4 -0
  10. data/lib/active_merchant/billing/gateways/blue_snap.rb +3 -1
  11. data/lib/active_merchant/billing/gateways/braintree_blue.rb +54 -7
  12. data/lib/active_merchant/billing/gateways/cashnet.rb +7 -2
  13. data/lib/active_merchant/billing/gateways/checkout_v2.rb +33 -2
  14. data/lib/active_merchant/billing/gateways/credorax.rb +30 -14
  15. data/lib/active_merchant/billing/gateways/cyber_source.rb +51 -8
  16. data/lib/active_merchant/billing/gateways/d_local.rb +1 -1
  17. data/lib/active_merchant/billing/gateways/decidir.rb +22 -2
  18. data/lib/active_merchant/billing/gateways/elavon.rb +54 -2
  19. data/lib/active_merchant/billing/gateways/eway_rapid.rb +13 -0
  20. data/lib/active_merchant/billing/gateways/firstdata_e4_v27.rb +17 -6
  21. data/lib/active_merchant/billing/gateways/forte.rb +12 -0
  22. data/lib/active_merchant/billing/gateways/global_collect.rb +25 -6
  23. data/lib/active_merchant/billing/gateways/hps.rb +65 -2
  24. data/lib/active_merchant/billing/gateways/litle.rb +21 -5
  25. data/lib/active_merchant/billing/gateways/mercado_pago.rb +2 -2
  26. data/lib/active_merchant/billing/gateways/netbanx.rb +37 -2
  27. data/lib/active_merchant/billing/gateways/orbital.rb +178 -45
  28. data/lib/active_merchant/billing/gateways/payeezy.rb +53 -11
  29. data/lib/active_merchant/billing/gateways/payment_express.rb +10 -5
  30. data/lib/active_merchant/billing/gateways/paymentez.rb +21 -1
  31. data/lib/active_merchant/billing/gateways/paypal.rb +10 -2
  32. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +1 -0
  33. data/lib/active_merchant/billing/gateways/paypal_express.rb +1 -0
  34. data/lib/active_merchant/billing/gateways/payway_dot_com.rb +253 -0
  35. data/lib/active_merchant/billing/gateways/pin.rb +11 -0
  36. data/lib/active_merchant/billing/gateways/qvalent.rb +23 -9
  37. data/lib/active_merchant/billing/gateways/redsys.rb +101 -5
  38. data/lib/active_merchant/billing/gateways/safe_charge.rb +39 -6
  39. data/lib/active_merchant/billing/gateways/stripe.rb +9 -9
  40. data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +82 -25
  41. data/lib/active_merchant/billing/gateways/vpos.rb +177 -0
  42. data/lib/active_merchant/billing/gateways/worldpay.rb +31 -14
  43. data/lib/active_merchant/billing/response.rb +2 -1
  44. data/lib/active_merchant/version.rb +1 -1
  45. data/lib/certs/cacert.pem +1582 -2431
  46. metadata +5 -3
@@ -39,6 +39,7 @@ module ActiveMerchant
39
39
  add_address(params, options)
40
40
  add_amount(params, amount, options)
41
41
  add_soft_descriptors(params, options)
42
+ add_level2_data(params, options)
42
43
  add_stored_credentials(params, options)
43
44
 
44
45
  commit(params, options)
@@ -53,6 +54,7 @@ module ActiveMerchant
53
54
  add_address(params, options)
54
55
  add_amount(params, amount, options)
55
56
  add_soft_descriptors(params, options)
57
+ add_level2_data(params, options)
56
58
  add_stored_credentials(params, options)
57
59
 
58
60
  commit(params, options)
@@ -77,6 +79,14 @@ module ActiveMerchant
77
79
  commit(params, options)
78
80
  end
79
81
 
82
+ def credit(amount, payment_method, options = {})
83
+ params = { transaction_type: 'refund' }
84
+
85
+ add_amount(params, amount, options)
86
+ add_payment_method(params, payment_method, options)
87
+ commit(params, options)
88
+ end
89
+
80
90
  def store(payment_method, options = {})
81
91
  params = { transaction_type: 'store' }
82
92
 
@@ -246,17 +256,42 @@ module ActiveMerchant
246
256
  params[:soft_descriptors] = options[:soft_descriptors] if options[:soft_descriptors]
247
257
  end
248
258
 
259
+ def add_level2_data(params, options)
260
+ return unless level2_data = options[:level2]
261
+
262
+ params[:level2] = {}
263
+ params[:level2][:customer_ref] = level2_data[:customer_ref]
264
+ end
265
+
249
266
  def add_stored_credentials(params, options)
250
- if options[:sequence]
267
+ if options[:sequence] || options[:stored_credential]
251
268
  params[:stored_credentials] = {}
252
- params[:stored_credentials][:cardbrand_original_transaction_id] = options[:cardbrand_original_transaction_id] if options[:cardbrand_original_transaction_id]
253
- params[:stored_credentials][:sequence] = options[:sequence]
254
- params[:stored_credentials][:initiator] = options[:initiator] if options[:initiator]
255
- params[:stored_credentials][:is_scheduled] = options[:is_scheduled]
269
+ params[:stored_credentials][:cardbrand_original_transaction_id] = original_transaction_id(options) if original_transaction_id(options)
270
+ params[:stored_credentials][:initiator] = initiator(options) if initiator(options)
271
+ params[:stored_credentials][:sequence] = options[:sequence] || sequence(options[:stored_credential][:initial_transaction])
272
+ params[:stored_credentials][:is_scheduled] = options[:is_scheduled] || is_scheduled(options[:stored_credential][:reason_type])
256
273
  params[:stored_credentials][:auth_type_override] = options[:auth_type_override] if options[:auth_type_override]
257
274
  end
258
275
  end
259
276
 
277
+ def original_transaction_id(options)
278
+ return options[:cardbrand_original_transaction_id] if options[:cardbrand_original_transaction_id]
279
+ return options[:stored_credential][:network_transaction_id] if options.dig(:stored_credential, :network_transaction_id)
280
+ end
281
+
282
+ def initiator(options)
283
+ return options[:initiator] if options[:initiator]
284
+ return options[:stored_credential][:initiator].upcase if options.dig(:stored_credential, :initiator)
285
+ end
286
+
287
+ def sequence(initial_transaction)
288
+ initial_transaction ? 'FIRST' : 'SUBSEQUENT'
289
+ end
290
+
291
+ def is_scheduled(reason_type)
292
+ reason_type == 'recurring' ? 'true' : 'false'
293
+ end
294
+
260
295
  def commit(params, options)
261
296
  url = base_url(options) + endpoint(params)
262
297
 
@@ -272,15 +307,16 @@ module ActiveMerchant
272
307
  response = json_error(e.response.body)
273
308
  end
274
309
 
310
+ success = success_from(response)
275
311
  Response.new(
276
- success_from(response),
277
- handle_message(response, success_from(response)),
312
+ success,
313
+ handle_message(response, success),
278
314
  response,
279
315
  test: test?,
280
316
  authorization: authorization_from(params, response),
281
317
  avs_result: { code: response['avs'] },
282
318
  cvv_result: response['cvv2'],
283
- error_code: error_code(response, success_from(response))
319
+ error_code: success ? nil : error_code_from(response)
284
320
  )
285
321
  end
286
322
 
@@ -334,10 +370,16 @@ module ActiveMerchant
334
370
  }
335
371
  end
336
372
 
337
- def error_code(response, success)
338
- return if success
373
+ def error_code_from(response)
374
+ error_code = nil
375
+ if response['bank_resp_code'] == '100'
376
+ return
377
+ elsif response['bank_resp_code']
378
+ error_code = response['bank_resp_code']
379
+ elsif error_code = response['Error'].to_h['messages'].to_a.map { |e| e['code'] }.join(', ')
380
+ end
339
381
 
340
- response['Error'].to_h['messages'].to_a.map { |e| e['code'] }.join(', ')
382
+ error_code
341
383
  end
342
384
 
343
385
  def success_from(response)
@@ -86,6 +86,11 @@ module ActiveMerchant #:nodoc:
86
86
  refund(money, identification, options)
87
87
  end
88
88
 
89
+ def verify(money, payment_source, options = {})
90
+ request = build_purchase_or_authorization_request(money, payment_source, options)
91
+ commit(:validate, request)
92
+ end
93
+
89
94
  # Token Based Billing
90
95
  #
91
96
  # Instead of storing the credit card details locally, you can store them inside the
@@ -149,7 +154,7 @@ module ActiveMerchant #:nodoc:
149
154
  add_credit_card(result, payment_source)
150
155
  end
151
156
 
152
- add_amount(result, money, options)
157
+ add_amount(result, money, options) if money
153
158
  add_invoice(result, options)
154
159
  add_address_verification_data(result, options)
155
160
  add_optional_elements(result, options)
@@ -229,8 +234,8 @@ module ActiveMerchant #:nodoc:
229
234
  address = options[:billing_address] || options[:address]
230
235
  return if address.nil?
231
236
 
232
- xml.add_element('EnableAvsData').text = 1
233
- xml.add_element('AvsAction').text = 1
237
+ xml.add_element('EnableAvsData').text = options[:enable_avs_data] || 1
238
+ xml.add_element('AvsAction').text = options[:avs_action] || 1
234
239
 
235
240
  xml.add_element('AvsStreetAddress').text = address[:address1]
236
241
  xml.add_element('AvsPostCode').text = address[:zip]
@@ -334,7 +339,7 @@ module ActiveMerchant #:nodoc:
334
339
  def authorization_from(action, response)
335
340
  case action
336
341
  when :validate
337
- (response[:billing_id] || response[:dps_billing_id])
342
+ (response[:billing_id] || response[:dps_billing_id] || response[:dps_txn_ref])
338
343
  else
339
344
  response[:dps_txn_ref]
340
345
  end
@@ -361,7 +366,7 @@ module ActiveMerchant #:nodoc:
361
366
  # add a method to response so we can easily get the token
362
367
  # for Validate transactions
363
368
  def token
364
- @params['billing_id'] || @params['dps_billing_id']
369
+ @params['billing_id'] || @params['dps_billing_id'] || @params['dps_txn_ref']
365
370
  end
366
371
  end
367
372
  end
@@ -9,7 +9,7 @@ module ActiveMerchant #:nodoc:
9
9
 
10
10
  self.supported_countries = %w[MX EC CO BR CL PE]
11
11
  self.default_currency = 'USD'
12
- self.supported_cardtypes = %i[visa master american_express diners_club elo alia]
12
+ self.supported_cardtypes = %i[visa master american_express diners_club elo alia olimpica]
13
13
 
14
14
  self.homepage_url = 'https://secure.paymentez.com/'
15
15
  self.display_name = 'Paymentez'
@@ -175,9 +175,29 @@ module ActiveMerchant #:nodoc:
175
175
  extra_params = {}
176
176
  extra_params.merge!(options[:extra_params]) if options[:extra_params]
177
177
 
178
+ add_external_mpi_fields(extra_params, options)
179
+
178
180
  post['extra_params'] = extra_params unless extra_params.empty?
179
181
  end
180
182
 
183
+ def add_external_mpi_fields(extra_params, options)
184
+ three_d_secure_options = options[:three_d_secure]
185
+ return unless three_d_secure_options
186
+
187
+ auth_data = {
188
+ cavv: three_d_secure_options[:cavv],
189
+ xid: three_d_secure_options[:xid],
190
+ eci: three_d_secure_options[:eci],
191
+ version: three_d_secure_options[:version],
192
+ reference_id: three_d_secure_options[:three_ds_server_trans_id],
193
+ status: three_d_secure_options[:authentication_response_status] || three_d_secure_options[:directory_response_status]
194
+ }.compact
195
+
196
+ return if auth_data.empty?
197
+
198
+ extra_params[:auth_data] = auth_data
199
+ end
200
+
181
201
  def parse(body)
182
202
  JSON.parse(body)
183
203
  end
@@ -58,7 +58,7 @@ module ActiveMerchant #:nodoc:
58
58
  xml = Builder::XmlMarkup.new indent: 2
59
59
  xml.tag! transaction_type + 'Req', 'xmlns' => PAYPAL_NAMESPACE do
60
60
  xml.tag! transaction_type + 'Request', 'xmlns:n2' => EBAY_NAMESPACE do
61
- xml.tag! 'n2:Version', API_VERSION
61
+ xml.tag! 'n2:Version', api_version(options)
62
62
  xml.tag! 'n2:' + transaction_type + 'RequestDetails' do
63
63
  xml.tag! 'n2:ReferenceID', reference_id if transaction_type == 'DoReferenceTransaction'
64
64
  xml.tag! 'n2:PaymentAction', action
@@ -73,6 +73,12 @@ module ActiveMerchant #:nodoc:
73
73
  xml.target!
74
74
  end
75
75
 
76
+ def api_version(options)
77
+ return API_VERSION_3DS2 if options.dig(:three_d_secure, :version) =~ /^2/
78
+
79
+ API_VERSION
80
+ end
81
+
76
82
  def add_credit_card(xml, credit_card, address, options)
77
83
  xml.tag! 'n2:CreditCard' do
78
84
  xml.tag! 'n2:CreditCardType', credit_card_type(card_brand(credit_card))
@@ -104,10 +110,12 @@ module ActiveMerchant #:nodoc:
104
110
  three_d_secure = options[:three_d_secure]
105
111
  xml.tag! 'ThreeDSecureRequest' do
106
112
  xml.tag! 'MpiVendor3ds', 'Y'
107
- xml.tag! 'AuthStatus3ds', three_d_secure[:trans_status] unless three_d_secure[:trans_status].blank?
113
+ xml.tag! 'AuthStatus3ds', three_d_secure[:authentication_response_status] || three_d_secure[:trans_status] if three_d_secure[:authentication_response_status] || three_d_secure[:trans_status]
108
114
  xml.tag! 'Cavv', three_d_secure[:cavv] unless three_d_secure[:cavv].blank?
109
115
  xml.tag! 'Eci3ds', three_d_secure[:eci] unless three_d_secure[:eci].blank?
110
116
  xml.tag! 'Xid', three_d_secure[:xid] unless three_d_secure[:xid].blank?
117
+ xml.tag! 'ThreeDSVersion', three_d_secure[:version] unless three_d_secure[:version].blank?
118
+ xml.tag! 'DSTransactionId', three_d_secure[:ds_transaction_id] unless three_d_secure[:ds_transaction_id].blank?
111
119
  end
112
120
  end
113
121
 
@@ -5,6 +5,7 @@ module ActiveMerchant #:nodoc:
5
5
  include Empty
6
6
 
7
7
  API_VERSION = '124'
8
+ API_VERSION_3DS2 = '214.0'
8
9
 
9
10
  URLS = {
10
11
  :test => { :certificate => 'https://api.sandbox.paypal.com/2.0/',
@@ -250,6 +250,7 @@ module ActiveMerchant #:nodoc:
250
250
  xml.tag! 'n2:PaymentType', options[:payment_type] || 'Any'
251
251
  add_payment_details(xml, money, currency_code, options)
252
252
  xml.tag! 'n2:IPAddress', options[:ip]
253
+ xml.tag! 'n2:MerchantSessionId', options[:merchant_session_id] if options[:merchant_session_id].present?
253
254
  end
254
255
  end
255
256
  end
@@ -0,0 +1,253 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class PaywayDotComGateway < Gateway
4
+ self.test_url = 'https://devedgilpayway.net/PaywayWS/Payment/CreditCard'
5
+ self.live_url = 'https://edgilpayway.com/PaywayWS/Payment/CreditCard'
6
+
7
+ self.supported_countries = %w[US CA]
8
+ self.default_currency = 'USD'
9
+ self.supported_cardtypes = %i[visa master american_express discover]
10
+
11
+ self.money_format = :cents
12
+
13
+ self.homepage_url = 'http://www.payway.com'
14
+ self.display_name = 'Payway Gateway'
15
+
16
+ STANDARD_ERROR_CODE_MAPPING = {
17
+ '5012' => STANDARD_ERROR_CODE[:card_declined],
18
+ '5035' => STANDARD_ERROR_CODE[:invalid_number],
19
+ '5037' => STANDARD_ERROR_CODE[:invalid_expiry_date],
20
+ '5045' => STANDARD_ERROR_CODE[:incorrect_zip]
21
+ }
22
+
23
+ # Payway to standard AVSResult codes.
24
+ AVS_MAPPING = {
25
+ 'N1' => 'I', # No address given with order
26
+ 'N2' => 'I', # Bill-to address did not pass
27
+ '““' => 'R', # AVS not performed (Blanks returned)
28
+ 'IU' => 'G', # AVS not performed by Issuer
29
+ 'ID' => 'S', # Issuer does not participate in AVS
30
+ 'IE' => 'E', # Edit Error - AVS data is invalid
31
+ 'IS' => 'R', # System unavailable or time-out
32
+ 'IB' => 'B', # Street address match. Postal code not verified due to incompatible formats (both were sent).
33
+ 'IC' => 'C', # Street address and postal code not verified due to incompatible format (both were sent).
34
+ 'IP' => 'P', # Postal code match. Street address not verified due to incompatible formats (both were sent).
35
+ 'A1' => 'K', # Accountholder name matches
36
+ 'A3' => 'V', # Accountholder name, billing address and postal code.
37
+ 'A4' => 'L', # Accountholder name and billing postal code match
38
+ 'A7' => 'O', # Accountholder name and billing address match
39
+ 'B3' => 'H', # Accountholder name incorrect, billing address and postal code match
40
+ 'B4' => 'F', # Accountholder name incorrect, billing postal code matches
41
+ 'B7' => 'T', # Accountholder name incorrect, billing address matches
42
+ 'B8' => 'N', # Accountholder name, billing address and postal code are all incorrect
43
+ '??' => 'R', # A double question mark symbol indicates an unrecognized response from association
44
+ 'I1' => 'X', # Zip code +4 and Address Match
45
+ 'I2' => 'W', # Zip code +4 Match
46
+ 'I3' => 'Y', # Zip code and Address Match
47
+ 'I4' => 'Z', # Zip code Match
48
+ 'I5' => 'M', # +4 and Address Match
49
+ 'I6' => 'W', # +4 Match
50
+ 'I7' => 'A', # Address Match
51
+ 'I8' => 'C', # No Match
52
+ }
53
+
54
+ PAYWAY_WS_SUCCESS = '5000'
55
+
56
+ SCRUB_PATTERNS = [
57
+ %r(("password\\?":\\?")[^\\]+),
58
+ %r(("fsv\\?":\\?")\d+),
59
+ %r(("fsv\\?": \\?")\d+),
60
+ %r(("accountNumber\\?":\\?")\d+),
61
+ %r(("accountNumber\\?": \\?")[^\\]+),
62
+ %r(("Invalid account number: )\d+)
63
+ ].freeze
64
+
65
+ SCRUB_REPLACEMENT = '\1[FILTERED]'
66
+
67
+ def initialize(options = {})
68
+ requires!(options, :login, :password, :company_id, :source_id)
69
+ super
70
+ end
71
+
72
+ def purchase(money, payment, options = {})
73
+ post = {}
74
+ add_common(post, options)
75
+ add_card_payment(post, payment, options)
76
+ add_card_transaction_details(post, money, options)
77
+ add_address(post, payment, options)
78
+
79
+ commit('sale', post)
80
+ end
81
+
82
+ def authorize(money, payment, options = {})
83
+ post = {}
84
+ add_common(post, options)
85
+ add_card_payment(post, payment, options)
86
+ add_card_transaction_details(post, money, options)
87
+ add_address(post, payment, options)
88
+
89
+ commit('authorize', post)
90
+ end
91
+
92
+ def capture(money, authorization, options = {})
93
+ post = {}
94
+ add_common(post, options)
95
+ add_card_transaction_name(post, authorization, options)
96
+
97
+ commit('capture', post)
98
+ end
99
+
100
+ def credit(money, payment, options = {})
101
+ post = {}
102
+ add_common(post, options)
103
+ add_card_payment(post, payment, options)
104
+ add_card_transaction_details(post, money, options)
105
+ add_address(post, payment, options)
106
+
107
+ commit('credit', post)
108
+ end
109
+
110
+ def void(authorization, options = {})
111
+ post = {}
112
+ add_common(post, options)
113
+ add_card_transaction_name(post, authorization, options)
114
+
115
+ commit('void', post)
116
+ end
117
+
118
+ def supports_scrubbing?
119
+ true
120
+ end
121
+
122
+ def scrub(transcript)
123
+ SCRUB_PATTERNS.inject(transcript) do |text, pattern|
124
+ text.gsub(pattern, SCRUB_REPLACEMENT)
125
+ end
126
+ end
127
+
128
+ private
129
+
130
+ def add_common(post, options)
131
+ post[:userName] = @options[:login]
132
+ post[:password] = @options[:password]
133
+ post[:companyId] = @options[:company_id]
134
+ post[:cardTransaction] = {}
135
+ post[:cardTransaction][:sourceId] = @options[:source_id]
136
+ end
137
+
138
+ def add_address(post, payment, options)
139
+ post[:cardAccount] ||= {}
140
+ address = options[:billing_address] || options[:address] || {}
141
+ first_name, last_name = split_names(address[:name])
142
+ full_address = "#{address[:address1]} #{address[:address2]}".strip
143
+ phone = address[:phone] || address[:phone_number]
144
+
145
+ post[:cardAccount][:firstName] = first_name if first_name
146
+ post[:cardAccount][:lastName] = last_name if last_name
147
+ post[:cardAccount][:address] = full_address if full_address
148
+ post[:cardAccount][:city] = address[:city] if address[:city]
149
+ post[:cardAccount][:state] = address[:state] if address[:state]
150
+ post[:cardAccount][:zip] = address[:zip] if address[:zip]
151
+ post[:cardAccount][:phone] = phone if phone
152
+ end
153
+
154
+ def add_card_transaction_details(post, money, options)
155
+ post[:cardTransaction][:amount] = amount(money)
156
+ eci_type = options[:eci_type].nil? ? '1' : options[:eci_type]
157
+ post[:cardTransaction][:eciType] = eci_type
158
+ post[:cardTransaction][:processorSoftDescriptor] = options[:processor_soft_descriptor] if options[:processor_soft_descriptor]
159
+ post[:cardTransaction][:tax] = options[:tax] if options[:tax]
160
+ end
161
+
162
+ def add_card_transaction_name(post, identifier, options)
163
+ post[:cardTransaction][:name] = identifier
164
+ end
165
+
166
+ def add_card_payment(post, payment, options)
167
+ # credit_card
168
+ post[:accountInputMode] = 'primaryAccountNumber'
169
+
170
+ post[:cardAccount] ||= {}
171
+ post[:cardAccount][:accountNumber] = payment.number
172
+ post[:cardAccount][:fsv] = payment.verification_value
173
+ post[:cardAccount][:expirationDate] = expdate(payment)
174
+ post[:cardAccount][:email] = options[:email] if options[:email]
175
+ end
176
+
177
+ def expdate(credit_card)
178
+ year = format(credit_card.year, :four_digits)
179
+ month = format(credit_card.month, :two_digits)
180
+
181
+ month + year
182
+ end
183
+
184
+ def parse(body)
185
+ body.blank? ? {} : JSON.parse(body)
186
+ end
187
+
188
+ def commit(action, parameters)
189
+ parameters[:request] = action
190
+
191
+ url = (test? ? test_url : live_url)
192
+ payload = parameters.to_json unless parameters.nil?
193
+
194
+ response =
195
+ begin
196
+ parse(ssl_request(:post, url, payload, headers))
197
+ rescue ResponseError => e
198
+ return Response.new(false, 'Invalid Login') if e.response.code == '401'
199
+
200
+ parse(e.response.body)
201
+ end
202
+
203
+ success = success_from(response)
204
+ avs_result_code = response['cardTransaction'].nil? || response['cardTransaction']['addressVerificationResults'].nil? ? '' : response['cardTransaction']['addressVerificationResults']
205
+ avs_result = AVSResult.new(code: AVS_MAPPING[avs_result_code])
206
+ cvv_result = CVVResult.new(response['cardTransaction']['fraudSecurityResults']) if response['cardTransaction'] && response['cardTransaction']['fraudSecurityResults']
207
+
208
+ Response.new(
209
+ success,
210
+ message_from(success, response),
211
+ response,
212
+ test: test?,
213
+ error_code: error_code_from(response),
214
+ authorization: authorization_from(response),
215
+ avs_result: avs_result,
216
+ cvv_result: cvv_result
217
+ )
218
+ end
219
+
220
+ def success_from(response)
221
+ response['paywayCode'] == PAYWAY_WS_SUCCESS
222
+ end
223
+
224
+ def error_code_from(response)
225
+ return '' if success_from(response)
226
+
227
+ error = !STANDARD_ERROR_CODE_MAPPING[response['paywayCode']].nil? ? STANDARD_ERROR_CODE_MAPPING[response['paywayCode']] : STANDARD_ERROR_CODE[:processing_error]
228
+ return error
229
+ end
230
+
231
+ def message_from(success, response)
232
+ return '' if response['paywayCode'].nil?
233
+
234
+ return response['paywayCode'] + '-' + 'success' if success
235
+
236
+ response['paywayCode'] + '-' + response['paywayMessage']
237
+ end
238
+
239
+ def authorization_from(response)
240
+ return '' if !success_from(response) || response['cardTransaction'].nil?
241
+
242
+ response['cardTransaction']['name']
243
+ end
244
+
245
+ def headers
246
+ {
247
+ 'Accept' => 'application/json',
248
+ 'Content-type' => 'application/json'
249
+ }
250
+ end
251
+ end
252
+ end
253
+ end