activemerchant 1.133.0 → 1.137.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 (183) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +240 -0
  3. data/lib/active_merchant/billing/check.rb +2 -2
  4. data/lib/active_merchant/billing/compatibility.rb +4 -4
  5. data/lib/active_merchant/billing/credit_card.rb +11 -8
  6. data/lib/active_merchant/billing/credit_card_formatting.rb +4 -0
  7. data/lib/active_merchant/billing/credit_card_methods.rb +59 -6
  8. data/lib/active_merchant/billing/gateway.rb +9 -0
  9. data/lib/active_merchant/billing/gateways/adyen.rb +162 -43
  10. data/lib/active_merchant/billing/gateways/airwallex.rb +26 -12
  11. data/lib/active_merchant/billing/gateways/alelo.rb +23 -5
  12. data/lib/active_merchant/billing/gateways/authorize_net.rb +43 -35
  13. data/lib/active_merchant/billing/gateways/authorize_net_arb.rb +10 -6
  14. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +1 -3
  15. data/lib/active_merchant/billing/gateways/axcessms.rb +6 -2
  16. data/lib/active_merchant/billing/gateways/banwire.rb +4 -2
  17. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +7 -3
  18. data/lib/active_merchant/billing/gateways/blue_pay.rb +13 -5
  19. data/lib/active_merchant/billing/gateways/blue_snap.rb +5 -5
  20. data/lib/active_merchant/billing/gateways/braintree/token_nonce.rb +65 -20
  21. data/lib/active_merchant/billing/gateways/braintree_blue.rb +226 -73
  22. data/lib/active_merchant/billing/gateways/braintree_orange.rb +1 -1
  23. data/lib/active_merchant/billing/gateways/card_connect.rb +5 -2
  24. data/lib/active_merchant/billing/gateways/card_stream.rb +4 -6
  25. data/lib/active_merchant/billing/gateways/cashnet.rb +1 -1
  26. data/lib/active_merchant/billing/gateways/cecabank/cecabank_common.rb +36 -0
  27. data/lib/active_merchant/billing/gateways/cecabank/cecabank_json.rb +316 -0
  28. data/lib/active_merchant/billing/gateways/cecabank/cecabank_xml.rb +220 -0
  29. data/lib/active_merchant/billing/gateways/cecabank.rb +7 -240
  30. data/lib/active_merchant/billing/gateways/checkout_v2.rb +238 -34
  31. data/lib/active_merchant/billing/gateways/commerce_hub.rb +63 -6
  32. data/lib/active_merchant/billing/gateways/credorax.rb +3 -5
  33. data/lib/active_merchant/billing/gateways/cyber_source.rb +185 -47
  34. data/lib/active_merchant/billing/gateways/cyber_source_rest.rb +102 -58
  35. data/lib/active_merchant/billing/gateways/d_local.rb +26 -15
  36. data/lib/active_merchant/billing/gateways/data_cash.rb +21 -17
  37. data/lib/active_merchant/billing/gateways/datatrans.rb +279 -0
  38. data/lib/active_merchant/billing/gateways/decidir.rb +53 -18
  39. data/lib/active_merchant/billing/gateways/decidir_plus.rb +4 -1
  40. data/lib/active_merchant/billing/gateways/deepstack.rb +382 -0
  41. data/lib/active_merchant/billing/gateways/ebanx.rb +40 -36
  42. data/lib/active_merchant/billing/gateways/efsnet.rb +6 -2
  43. data/lib/active_merchant/billing/gateways/elavon.rb +99 -33
  44. data/lib/active_merchant/billing/gateways/element.rb +36 -7
  45. data/lib/active_merchant/billing/gateways/epay.rb +6 -2
  46. data/lib/active_merchant/billing/gateways/evo_ca.rb +6 -2
  47. data/lib/active_merchant/billing/gateways/eway.rb +4 -2
  48. data/lib/active_merchant/billing/gateways/eway_managed.rb +6 -2
  49. data/lib/active_merchant/billing/gateways/exact.rb +6 -2
  50. data/lib/active_merchant/billing/gateways/fat_zebra.rb +31 -3
  51. data/lib/active_merchant/billing/gateways/federated_canada.rb +6 -2
  52. data/lib/active_merchant/billing/gateways/first_pay/first_pay_common.rb +15 -0
  53. data/lib/active_merchant/billing/gateways/first_pay/first_pay_json.rb +190 -0
  54. data/lib/active_merchant/billing/gateways/first_pay/first_pay_xml.rb +183 -0
  55. data/lib/active_merchant/billing/gateways/first_pay.rb +6 -172
  56. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +6 -2
  57. data/lib/active_merchant/billing/gateways/firstdata_e4_v27.rb +7 -3
  58. data/lib/active_merchant/billing/gateways/flex_charge.rb +347 -0
  59. data/lib/active_merchant/billing/gateways/garanti.rb +4 -2
  60. data/lib/active_merchant/billing/gateways/global_collect.rb +45 -37
  61. data/lib/active_merchant/billing/gateways/hi_pay.rb +286 -0
  62. data/lib/active_merchant/billing/gateways/hps.rb +1 -1
  63. data/lib/active_merchant/billing/gateways/iats_payments.rb +7 -2
  64. data/lib/active_merchant/billing/gateways/inspire.rb +6 -4
  65. data/lib/active_merchant/billing/gateways/instapay.rb +7 -4
  66. data/lib/active_merchant/billing/gateways/ipg.rb +9 -5
  67. data/lib/active_merchant/billing/gateways/iridium.rb +15 -5
  68. data/lib/active_merchant/billing/gateways/itransact.rb +6 -2
  69. data/lib/active_merchant/billing/gateways/iveri.rb +3 -3
  70. data/lib/active_merchant/billing/gateways/ixopay.rb +2 -2
  71. data/lib/active_merchant/billing/gateways/jetpay.rb +4 -2
  72. data/lib/active_merchant/billing/gateways/jetpay_v2.rb +4 -2
  73. data/lib/active_merchant/billing/gateways/kushki.rb +72 -12
  74. data/lib/active_merchant/billing/gateways/linkpoint.rb +6 -2
  75. data/lib/active_merchant/billing/gateways/litle.rb +33 -50
  76. data/lib/active_merchant/billing/gateways/mastercard.rb +4 -4
  77. data/lib/active_merchant/billing/gateways/maxipago.rb +2 -2
  78. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +8 -5
  79. data/lib/active_merchant/billing/gateways/merchant_ware.rb +11 -4
  80. data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +11 -4
  81. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +19 -3
  82. data/lib/active_merchant/billing/gateways/mercury.rb +6 -2
  83. data/lib/active_merchant/billing/gateways/metrics_global.rb +8 -6
  84. data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +1 -0
  85. data/lib/active_merchant/billing/gateways/migs.rb +6 -2
  86. data/lib/active_merchant/billing/gateways/mit.rb +8 -3
  87. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +18 -10
  88. data/lib/active_merchant/billing/gateways/monei.rb +1 -1
  89. data/lib/active_merchant/billing/gateways/moneris.rb +9 -3
  90. data/lib/active_merchant/billing/gateways/money_movers.rb +6 -2
  91. data/lib/active_merchant/billing/gateways/nab_transact.rb +12 -4
  92. data/lib/active_merchant/billing/gateways/net_registry.rb +6 -2
  93. data/lib/active_merchant/billing/gateways/netbanx.rb +1 -3
  94. data/lib/active_merchant/billing/gateways/netbilling.rb +6 -2
  95. data/lib/active_merchant/billing/gateways/network_merchants.rb +6 -2
  96. data/lib/active_merchant/billing/gateways/nmi.rb +18 -6
  97. data/lib/active_merchant/billing/gateways/ogone.rb +6 -2
  98. data/lib/active_merchant/billing/gateways/openpay.rb +4 -2
  99. data/lib/active_merchant/billing/gateways/opp.rb +1 -2
  100. data/lib/active_merchant/billing/gateways/optimal_payment.rb +6 -2
  101. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +1 -3
  102. data/lib/active_merchant/billing/gateways/orbital.rb +83 -24
  103. data/lib/active_merchant/billing/gateways/pac_net_raven.rb +7 -4
  104. data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +6 -2
  105. data/lib/active_merchant/billing/gateways/pay_hub.rb +4 -2
  106. data/lib/active_merchant/billing/gateways/pay_junction.rb +6 -2
  107. data/lib/active_merchant/billing/gateways/pay_secure.rb +6 -2
  108. data/lib/active_merchant/billing/gateways/pay_trace.rb +31 -18
  109. data/lib/active_merchant/billing/gateways/payeezy.rb +19 -8
  110. data/lib/active_merchant/billing/gateways/payex.rb +4 -2
  111. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +1 -1
  112. data/lib/active_merchant/billing/gateways/payflow.rb +1 -3
  113. data/lib/active_merchant/billing/gateways/payment_express.rb +8 -4
  114. data/lib/active_merchant/billing/gateways/paymentez.rb +23 -11
  115. data/lib/active_merchant/billing/gateways/paysafe.rb +12 -11
  116. data/lib/active_merchant/billing/gateways/payscout.rb +7 -4
  117. data/lib/active_merchant/billing/gateways/paystation.rb +7 -3
  118. data/lib/active_merchant/billing/gateways/payway.rb +6 -2
  119. data/lib/active_merchant/billing/gateways/payway_dot_com.rb +2 -2
  120. data/lib/active_merchant/billing/gateways/pin.rb +22 -4
  121. data/lib/active_merchant/billing/gateways/plexo.rb +49 -10
  122. data/lib/active_merchant/billing/gateways/plugnpay.rb +6 -2
  123. data/lib/active_merchant/billing/gateways/priority.rb +6 -5
  124. data/lib/active_merchant/billing/gateways/psigate.rb +6 -2
  125. data/lib/active_merchant/billing/gateways/psl_card.rb +6 -2
  126. data/lib/active_merchant/billing/gateways/qbms.rb +6 -2
  127. data/lib/active_merchant/billing/gateways/quantum.rb +6 -2
  128. data/lib/active_merchant/billing/gateways/quickbooks.rb +6 -5
  129. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +7 -4
  130. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v4to7.rb +6 -2
  131. data/lib/active_merchant/billing/gateways/rapyd.rb +148 -46
  132. data/lib/active_merchant/billing/gateways/reach.rb +11 -4
  133. data/lib/active_merchant/billing/gateways/redsys.rb +2 -10
  134. data/lib/active_merchant/billing/gateways/redsys_rest.rb +507 -0
  135. data/lib/active_merchant/billing/gateways/s5.rb +3 -3
  136. data/lib/active_merchant/billing/gateways/safe_charge.rb +36 -16
  137. data/lib/active_merchant/billing/gateways/sage.rb +12 -4
  138. data/lib/active_merchant/billing/gateways/sage_pay.rb +79 -5
  139. data/lib/active_merchant/billing/gateways/sallie_mae.rb +6 -2
  140. data/lib/active_merchant/billing/gateways/secure_net.rb +6 -2
  141. data/lib/active_merchant/billing/gateways/secure_pay.rb +8 -6
  142. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +12 -4
  143. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +6 -2
  144. data/lib/active_merchant/billing/gateways/securion_pay.rb +24 -10
  145. data/lib/active_merchant/billing/gateways/shift4.rb +17 -20
  146. data/lib/active_merchant/billing/gateways/shift4_v2.rb +117 -0
  147. data/lib/active_merchant/billing/gateways/simetrik.rb +17 -11
  148. data/lib/active_merchant/billing/gateways/skip_jack.rb +6 -2
  149. data/lib/active_merchant/billing/gateways/smart_ps.rb +7 -4
  150. data/lib/active_merchant/billing/gateways/so_easy_pay.rb +4 -2
  151. data/lib/active_merchant/billing/gateways/spreedly_core.rb +2 -4
  152. data/lib/active_merchant/billing/gateways/stripe.rb +53 -21
  153. data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +199 -50
  154. data/lib/active_merchant/billing/gateways/sum_up.rb +223 -0
  155. data/lib/active_merchant/billing/gateways/swipe_checkout.rb +4 -2
  156. data/lib/active_merchant/billing/gateways/telr.rb +3 -4
  157. data/lib/active_merchant/billing/gateways/trans_first.rb +1 -2
  158. data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +8 -16
  159. data/lib/active_merchant/billing/gateways/transact_pro.rb +1 -1
  160. data/lib/active_merchant/billing/gateways/trust_commerce.rb +6 -2
  161. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +9 -8
  162. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +6 -2
  163. data/lib/active_merchant/billing/gateways/vanco.rb +2 -4
  164. data/lib/active_merchant/billing/gateways/vantiv_express.rb +587 -0
  165. data/lib/active_merchant/billing/gateways/verifi.rb +6 -2
  166. data/lib/active_merchant/billing/gateways/viaklix.rb +6 -2
  167. data/lib/active_merchant/billing/gateways/visanet_peru.rb +2 -2
  168. data/lib/active_merchant/billing/gateways/vpos.rb +3 -3
  169. data/lib/active_merchant/billing/gateways/wirecard.rb +7 -3
  170. data/lib/active_merchant/billing/gateways/wompi.rb +5 -0
  171. data/lib/active_merchant/billing/gateways/worldpay.rb +140 -73
  172. data/lib/active_merchant/billing/gateways/worldpay_online_payments.rb +13 -10
  173. data/lib/active_merchant/billing/gateways/xpay.rb +242 -0
  174. data/lib/active_merchant/billing/network_tokenization_credit_card.rb +1 -1
  175. data/lib/active_merchant/billing/response.rb +2 -2
  176. data/lib/active_merchant/connection.rb +3 -17
  177. data/lib/active_merchant/country.rb +1 -0
  178. data/lib/active_merchant/errors.rb +10 -0
  179. data/lib/active_merchant/version.rb +1 -1
  180. data/lib/support/gateway_support.rb +2 -2
  181. data/lib/support/ssl_verify.rb +4 -4
  182. data/lib/support/ssl_version.rb +6 -6
  183. metadata +30 -9
@@ -0,0 +1,279 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class DatatransGateway < Gateway
4
+ self.test_url = 'https://api.sandbox.datatrans.com/v1/'
5
+ self.live_url = 'https://api.datatrans.com/v1/'
6
+
7
+ self.supported_countries = %w(CH GR US) # to confirm the countries supported.
8
+ self.default_currency = 'CHF'
9
+ self.currencies_without_fractions = %w(CHF EUR USD)
10
+ self.currencies_with_three_decimal_places = %w()
11
+ self.supported_cardtypes = %i[master visa american_express unionpay diners_club discover jcb maestro dankort]
12
+
13
+ self.money_format = :cents
14
+
15
+ self.homepage_url = 'https://www.datatrans.ch/'
16
+ self.display_name = 'Datatrans'
17
+
18
+ CREDIT_CARD_SOURCE = {
19
+ visa: 'VISA',
20
+ master: 'MASTERCARD'
21
+ }.with_indifferent_access
22
+
23
+ DEVICE_SOURCE = {
24
+ apple_pay: 'APPLE_PAY',
25
+ google_pay: 'GOOGLE_PAY'
26
+ }.with_indifferent_access
27
+
28
+ def initialize(options = {})
29
+ requires!(options, :merchant_id, :password)
30
+ @merchant_id, @password = options.values_at(:merchant_id, :password)
31
+ super
32
+ end
33
+
34
+ def purchase(money, payment, options = {})
35
+ authorize(money, payment, options.merge(auto_settle: true))
36
+ end
37
+
38
+ def verify(payment, options = {})
39
+ MultiResponse.run(:use_first_response) do |r|
40
+ r.process { authorize(100, payment, options) }
41
+ r.process(:ignore_result) { void(r.authorization, options) }
42
+ end
43
+ end
44
+
45
+ def authorize(money, payment, options = {})
46
+ post = { refno: options.fetch(:order_id, '') }
47
+ add_payment_method(post, payment)
48
+ add_3ds_data(post, payment, options)
49
+ add_currency_amount(post, money, options)
50
+ add_billing_address(post, options)
51
+ post[:autoSettle] = options[:auto_settle] if options[:auto_settle]
52
+ commit('authorize', post)
53
+ end
54
+
55
+ def capture(money, authorization, options = {})
56
+ post = { refno: options.fetch(:order_id, '') }
57
+ transaction_id = authorization.split('|').first
58
+ add_currency_amount(post, money, options)
59
+ commit('settle', post, { transaction_id: transaction_id })
60
+ end
61
+
62
+ def refund(money, authorization, options = {})
63
+ post = { refno: options.fetch(:order_id, '') }
64
+ transaction_id = authorization.split('|').first
65
+ add_currency_amount(post, money, options)
66
+ commit('credit', post, { transaction_id: transaction_id })
67
+ end
68
+
69
+ def void(authorization, options = {})
70
+ post = {}
71
+ transaction_id = authorization.split('|').first
72
+ commit('cancel', post, { transaction_id: transaction_id })
73
+ end
74
+
75
+ def store(payment_method, options = {})
76
+ exp_year = format(payment_method.year, :two_digits)
77
+ exp_month = format(payment_method.month, :two_digits)
78
+
79
+ post = {
80
+ requests: [
81
+ {
82
+ type: 'CARD',
83
+ pan: payment_method.number,
84
+ expiryMonth: exp_month,
85
+ expiryYear: exp_year
86
+ }
87
+ ]
88
+ }
89
+ commit('tokenize', post, { expiry_month: exp_month, expiry_year: exp_year })
90
+ end
91
+
92
+ def unstore(authorization, options = {})
93
+ data_alias = authorization.split('|')[2]
94
+ commit('delete_alias', {}, { alias_id: data_alias }, :delete)
95
+ end
96
+
97
+ def supports_scrubbing?
98
+ true
99
+ end
100
+
101
+ def scrub(transcript)
102
+ transcript.
103
+ gsub(%r((Authorization: Basic )[\w =]+), '\1[FILTERED]').
104
+ gsub(%r((\"number\\":\\")\d+), '\1[FILTERED]\2').
105
+ gsub(%r((\"cvv\\":\\")\d+), '\1[FILTERED]\2')
106
+ end
107
+
108
+ private
109
+
110
+ def add_payment_method(post, payment_method)
111
+ case payment_method
112
+ when String
113
+ token, exp_month, exp_year = payment_method.split('|')[2..4]
114
+ card = {
115
+ type: 'ALIAS',
116
+ alias: token,
117
+ expiryMonth: exp_month,
118
+ expiryYear: exp_year
119
+ }
120
+ when NetworkTokenizationCreditCard
121
+ card = {
122
+ type: DEVICE_SOURCE[payment_method.source] ? 'DEVICE_TOKEN' : 'NETWORK_TOKEN',
123
+ tokenType: DEVICE_SOURCE[payment_method.source] || CREDIT_CARD_SOURCE[card_brand(payment_method)],
124
+ token: payment_method.number,
125
+ cryptogram: payment_method.payment_cryptogram,
126
+ expiryMonth: format(payment_method.month, :two_digits),
127
+ expiryYear: format(payment_method.year, :two_digits)
128
+ }
129
+ when CreditCard
130
+ card = {
131
+ number: payment_method.number,
132
+ cvv: payment_method.verification_value.to_s,
133
+ expiryMonth: format(payment_method.month, :two_digits),
134
+ expiryYear: format(payment_method.year, :two_digits)
135
+ }
136
+ end
137
+ post[:card] = card
138
+ end
139
+
140
+ def add_3ds_data(post, payment_method, options)
141
+ return unless three_d_secure = options[:three_d_secure]
142
+
143
+ three_ds =
144
+ {
145
+ "3D":
146
+ {
147
+ eci: three_d_secure[:eci],
148
+ xid: three_d_secure[:xid],
149
+ threeDSTransactionId: three_d_secure[:ds_transaction_id],
150
+ cavv: three_d_secure[:cavv],
151
+ threeDSVersion: three_d_secure[:version],
152
+ cavvAlgorithm: three_d_secure[:cavv_algorithm],
153
+ directoryResponse: three_d_secure[:directory_response_status],
154
+ authenticationResponse: three_d_secure[:authentication_response_status],
155
+ transStatusReason: three_d_secure[:trans_status_reason]
156
+ }.compact
157
+ }
158
+
159
+ post[:card].merge!(three_ds)
160
+ end
161
+
162
+ def country_code(country)
163
+ Country.find(country).code(:alpha3).value if country
164
+ rescue InvalidCountryCodeError
165
+ nil
166
+ end
167
+
168
+ def add_billing_address(post, options)
169
+ return unless billing_address = options[:billing_address]
170
+
171
+ post[:billing] = {
172
+ name: billing_address[:name],
173
+ street: billing_address[:address1],
174
+ street2: billing_address[:address2],
175
+ city: billing_address[:city],
176
+ country: country_code(billing_address[:country]),
177
+ phoneNumber: billing_address[:phone],
178
+ zipCode: billing_address[:zip],
179
+ email: options[:email]
180
+ }.compact
181
+ end
182
+
183
+ def add_currency_amount(post, money, options)
184
+ post[:currency] = (options[:currency] || currency(money))
185
+ post[:amount] = amount(money)
186
+ end
187
+
188
+ def commit(action, post, options = {}, method = :post)
189
+ response = parse(ssl_request(method, url(action, options), post.to_json, headers))
190
+ succeeded = success_from(action, response)
191
+
192
+ Response.new(
193
+ succeeded,
194
+ message_from(succeeded, response),
195
+ response,
196
+ authorization: authorization_from(response, action, options),
197
+ test: test?,
198
+ error_code: error_code_from(response)
199
+ )
200
+ rescue ResponseError => e
201
+ response = parse(e.response.body)
202
+ Response.new(false, message_from(false, response), response, test: test?, error_code: error_code_from(response))
203
+ end
204
+
205
+ def parse(response)
206
+ JSON.parse response
207
+ rescue JSON::ParserError
208
+ msg = 'Invalid JSON response received from Datatrans. Please contact them for support if you continue to receive this message.'
209
+ msg += " (The raw response returned by the API was #{response.inspect})"
210
+ {
211
+ 'successful' => false,
212
+ 'response' => {},
213
+ 'errors' => [msg]
214
+ }
215
+ end
216
+
217
+ def headers
218
+ {
219
+ 'Content-Type' => 'application/json; charset=UTF-8',
220
+ 'Authorization' => "Basic #{Base64.strict_encode64("#{@merchant_id}:#{@password}")}"
221
+ }
222
+ end
223
+
224
+ def url(endpoint, options = {})
225
+ case endpoint
226
+ when 'settle', 'credit', 'cancel'
227
+ "#{test? ? test_url : live_url}transactions/#{options[:transaction_id]}/#{endpoint}"
228
+ when 'tokenize'
229
+ "#{test? ? test_url : live_url}aliases/#{endpoint}"
230
+ when 'delete_alias'
231
+ "#{test? ? test_url : live_url}aliases/#{options[:alias_id]}"
232
+ else
233
+ "#{test? ? test_url : live_url}transactions/#{endpoint}"
234
+ end
235
+ end
236
+
237
+ def success_from(action, response)
238
+ case action
239
+ when 'authorize', 'credit'
240
+ response.include?('transactionId') && response.include?('acquirerAuthorizationCode')
241
+ when 'settle', 'cancel'
242
+ response.dig('response_code') == 204
243
+ when 'tokenize'
244
+ response.dig('responses', 0, 'alias') && response.dig('overview', 'failed') == 0
245
+ when 'delete_alias'
246
+ response.dig('response_code') == 204
247
+ else
248
+ false
249
+ end
250
+ end
251
+
252
+ def authorization_from(response, action, options)
253
+ token_array = [response.dig('responses', 0, 'alias'), options[:expiry_month], options[:expiry_year]].join('|') if action == 'tokenize'
254
+
255
+ auth = [response['transactionId'], response['acquirerAuthorizationCode'], token_array].join('|')
256
+ return auth unless auth == '||'
257
+ end
258
+
259
+ def message_from(succeeded, response)
260
+ return if succeeded
261
+
262
+ response.dig('error', 'message')
263
+ end
264
+
265
+ def error_code_from(response)
266
+ response.dig('error', 'code')
267
+ end
268
+
269
+ def handle_response(response)
270
+ case response.code.to_i
271
+ when 200...300
272
+ response.body || { response_code: response.code.to_i }.to_json
273
+ else
274
+ raise ResponseError.new(response)
275
+ end
276
+ end
277
+ end
278
+ end
279
+ end
@@ -7,7 +7,7 @@ module ActiveMerchant #:nodoc:
7
7
  self.supported_countries = ['AR']
8
8
  self.money_format = :cents
9
9
  self.default_currency = 'ARS'
10
- self.supported_cardtypes = %i[visa master american_express diners_club naranja cabal]
10
+ self.supported_cardtypes = %i[visa master american_express diners_club naranja cabal tuya]
11
11
 
12
12
  self.homepage_url = 'http://www.decidir.com'
13
13
  self.display_name = 'Decidir'
@@ -127,6 +127,7 @@ module ActiveMerchant #:nodoc:
127
127
  add_payment(post, credit_card, options)
128
128
  add_aggregate_data(post, options) if options[:aggregate_data]
129
129
  add_sub_payments(post, options)
130
+ add_customer_data(post, options)
130
131
  end
131
132
 
132
133
  def add_payment_method_id(credit_card, options)
@@ -167,29 +168,55 @@ module ActiveMerchant #:nodoc:
167
168
  post[:amount] = localized_amount(money, currency).to_i
168
169
  end
169
170
 
170
- def add_payment(post, credit_card, options)
171
- card_data = {}
171
+ def add_payment(post, payment_method, options)
172
+ add_common_payment_data(post, payment_method, options)
173
+
174
+ case payment_method
175
+ when NetworkTokenizationCreditCard
176
+ add_network_token(post, payment_method, options)
177
+ else
178
+ add_credit_card(post, payment_method, options)
179
+ end
180
+ end
181
+
182
+ def add_common_payment_data(post, payment_method, options)
183
+ post[:card_data] = {}
184
+
185
+ data = post[:card_data]
186
+ data[:card_holder_identification] = {}
187
+ data[:card_holder_identification][:type] = options[:card_holder_identification_type] if options[:card_holder_identification_type]
188
+ data[:card_holder_identification][:number] = options[:card_holder_identification_number] if options[:card_holder_identification_number]
189
+ data[:card_holder_name] = payment_method.name if payment_method.name
190
+
191
+ # additional data used for Visa transactions
192
+ data[:card_holder_door_number] = options[:card_holder_door_number].to_i if options[:card_holder_door_number]
193
+ data[:card_holder_birthday] = options[:card_holder_birthday] if options[:card_holder_birthday]
194
+ end
195
+
196
+ def add_network_token(post, payment_method, options)
197
+ post[:is_tokenized_payment] = true
198
+ post[:fraud_detection] ||= {}
199
+ post[:fraud_detection][:sent_to_cs] = false
200
+ post[:card_data][:last_four_digits] = options[:last_4]
201
+
202
+ post[:token_card_data] = {
203
+ token: payment_method.number,
204
+ eci: payment_method.eci,
205
+ cryptogram: payment_method.payment_cryptogram
206
+ }
207
+ end
208
+
209
+ def add_credit_card(post, credit_card, options)
210
+ card_data = post[:card_data]
172
211
  card_data[:card_number] = credit_card.number
173
212
  card_data[:card_expiration_month] = format(credit_card.month, :two_digits)
174
213
  card_data[:card_expiration_year] = format(credit_card.year, :two_digits)
175
214
  card_data[:security_code] = credit_card.verification_value if credit_card.verification_value?
176
- card_data[:card_holder_name] = credit_card.name if credit_card.name
177
215
 
178
216
  # the device_unique_id has to be sent in via the card data (as device_unique_identifier) no other fraud detection fields require this
179
- if options[:fraud_detection].present?
180
- card_data[:fraud_detection] = {} if (options[:fraud_detection][:device_unique_id]).present?
181
- card_data[:fraud_detection][:device_unique_identifier] = (options[:fraud_detection][:device_unique_id]) if (options[:fraud_detection][:device_unique_id]).present?
217
+ if (device_id = options.dig(:fraud_detection, :device_unique_id))
218
+ card_data[:fraud_detection] = { device_unique_identifier: device_id }
182
219
  end
183
-
184
- # additional data used for Visa transactions
185
- card_data[:card_holder_door_number] = options[:card_holder_door_number].to_i if options[:card_holder_door_number]
186
- card_data[:card_holder_birthday] = options[:card_holder_birthday] if options[:card_holder_birthday]
187
-
188
- card_data[:card_holder_identification] = {}
189
- card_data[:card_holder_identification][:type] = options[:card_holder_identification_type] if options[:card_holder_identification_type]
190
- card_data[:card_holder_identification][:number] = options[:card_holder_identification_number] if options[:card_holder_identification_number]
191
-
192
- post[:card_data] = card_data
193
220
  end
194
221
 
195
222
  def add_aggregate_data(post, options)
@@ -215,6 +242,14 @@ module ActiveMerchant #:nodoc:
215
242
  post[:aggregate_data] = aggregate_data
216
243
  end
217
244
 
245
+ def add_customer_data(post, options = {})
246
+ return unless options[:customer_email] || options[:customer_id]
247
+
248
+ post[:customer] = {}
249
+ post[:customer][:id] = options[:customer_id] if options[:customer_id]
250
+ post[:customer][:email] = options[:customer_email] if options[:customer_email]
251
+ end
252
+
218
253
  def add_sub_payments(post, options)
219
254
  # sub_payments field is required for purchase transactions, even if empty
220
255
  post[:sub_payments] = []
@@ -262,7 +297,7 @@ module ActiveMerchant #:nodoc:
262
297
  end
263
298
 
264
299
  def commit(method, endpoint, parameters, options = {})
265
- url = "#{(test? ? test_url : live_url)}/#{endpoint}"
300
+ url = "#{test? ? test_url : live_url}/#{endpoint}"
266
301
 
267
302
  begin
268
303
  raw_response = ssl_request(method, url, post_data(parameters), headers(options))
@@ -321,8 +321,11 @@ module ActiveMerchant #:nodoc:
321
321
  return error_code_from(response) unless validation_errors = response.dig('validation_errors')
322
322
 
323
323
  validation_errors = validation_errors[0]
324
+ message = "#{validation_errors&.dig('code')}: #{validation_errors&.dig('param')}"
325
+ return message unless message == ': '
324
326
 
325
- "#{validation_errors.dig('code')}: #{validation_errors.dig('param')}"
327
+ errors = response['validation_errors'].map { |k, v| "#{k}: #{v}" }.join(', ')
328
+ "#{response['error_type']} - #{errors}"
326
329
  end
327
330
 
328
331
  def rejected?(response)