activemerchant 1.133.0 → 1.137.0

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