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
@@ -28,14 +28,20 @@ module ActiveMerchant #:nodoc:
28
28
  maestro: '042',
29
29
  master: '002',
30
30
  unionpay: '062',
31
- visa: '001'
31
+ visa: '001',
32
+ carnet: '058'
32
33
  }
33
34
 
34
- PAYMENT_SOLUTION = {
35
+ WALLET_PAYMENT_SOLUTION = {
35
36
  apple_pay: '001',
36
37
  google_pay: '012'
37
38
  }
38
39
 
40
+ NT_PAYMENT_SOLUTION = {
41
+ 'master' => '014',
42
+ 'visa' => '015'
43
+ }
44
+
39
45
  def initialize(options = {})
40
46
  requires!(options, :merchant_id, :public_key, :private_key)
41
47
  super
@@ -93,6 +99,7 @@ module ActiveMerchant #:nodoc:
93
99
  gsub(/(\\?"number\\?":\\?")\d+/, '\1[FILTERED]').
94
100
  gsub(/(\\?"routingNumber\\?":\\?")\d+/, '\1[FILTERED]').
95
101
  gsub(/(\\?"securityCode\\?":\\?")\d+/, '\1[FILTERED]').
102
+ gsub(/(\\?"cryptogram\\?":\\?")[^<]+/, '\1[FILTERED]').
96
103
  gsub(/(signature=")[^"]*/, '\1[FILTERED]').
97
104
  gsub(/(keyid=")[^"]*/, '\1[FILTERED]').
98
105
  gsub(/(Digest: SHA-256=)[\w\/\+=]*/, '\1[FILTERED]')
@@ -100,6 +107,47 @@ module ActiveMerchant #:nodoc:
100
107
 
101
108
  private
102
109
 
110
+ def add_level_2_data(post, options)
111
+ return unless options[:purchase_order_number]
112
+
113
+ post[:orderInformation][:invoiceDetails] ||= {}
114
+ post[:orderInformation][:invoiceDetails][:purchaseOrderNumber] = options[:purchase_order_number]
115
+ end
116
+
117
+ def add_level_3_data(post, options)
118
+ return unless options[:line_items]
119
+
120
+ post[:orderInformation][:lineItems] = options[:line_items]
121
+ post[:processingInformation][:purchaseLevel] = '3'
122
+ post[:orderInformation][:shipping_details] = { shipFromPostalCode: options[:ships_from_postal_code] }
123
+ post[:orderInformation][:amountDetails] ||= {}
124
+ post[:orderInformation][:amountDetails][:discountAmount] = options[:discount_amount]
125
+ end
126
+
127
+ def add_three_ds(post, payment_method, options)
128
+ return unless three_d_secure = options[:three_d_secure]
129
+
130
+ post[:consumerAuthenticationInformation] ||= {}
131
+ if payment_method.brand == 'master'
132
+ post[:consumerAuthenticationInformation][:ucafAuthenticationData] = three_d_secure[:cavv]
133
+ post[:consumerAuthenticationInformation][:ucafCollectionIndicator] = '2'
134
+ else
135
+ post[:consumerAuthenticationInformation][:cavv] = three_d_secure[:cavv]
136
+ end
137
+ post[:consumerAuthenticationInformation][:cavvAlgorithm] = three_d_secure[:cavv_algorithm] if three_d_secure[:cavv_algorithm]
138
+ post[:consumerAuthenticationInformation][:paSpecificationVersion] = three_d_secure[:version] if three_d_secure[:version]
139
+ post[:consumerAuthenticationInformation][:directoryServerTransactionID] = three_d_secure[:ds_transaction_id] if three_d_secure[:ds_transaction_id]
140
+ post[:consumerAuthenticationInformation][:eciRaw] = three_d_secure[:eci] if three_d_secure[:eci]
141
+ if three_d_secure[:xid].present?
142
+ post[:consumerAuthenticationInformation][:xid] = three_d_secure[:xid]
143
+ else
144
+ post[:consumerAuthenticationInformation][:xid] = three_d_secure[:cavv]
145
+ end
146
+ post[:consumerAuthenticationInformation][:veresEnrolled] = three_d_secure[:enrolled] if three_d_secure[:enrolled]
147
+ post[:consumerAuthenticationInformation][:paresStatus] = three_d_secure[:authentication_response_status] if three_d_secure[:authentication_response_status]
148
+ post
149
+ end
150
+
103
151
  def build_void_request(amount = nil)
104
152
  { reversalInformation: { amountDetails: { totalAmount: nil } } }.tap do |post|
105
153
  add_reversal_amount(post, amount.to_i) if amount.present?
@@ -118,6 +166,9 @@ module ActiveMerchant #:nodoc:
118
166
  add_business_rules_data(post, payment, options)
119
167
  add_partner_solution_id(post)
120
168
  add_stored_credentials(post, payment, options)
169
+ add_three_ds(post, payment, options)
170
+ add_level_2_data(post, options)
171
+ add_level_3_data(post, options)
121
172
  end.compact
122
173
  end
123
174
 
@@ -191,25 +242,30 @@ module ActiveMerchant #:nodoc:
191
242
  end
192
243
 
193
244
  def add_network_tokenization_card(post, payment, options)
194
- post[:processingInformation][:paymentSolution] = PAYMENT_SOLUTION[payment.source]
195
- post[:processingInformation][:commerceIndicator] = 'internet' unless card_brand(payment) == 'jcb'
245
+ post[:processingInformation][:commerceIndicator] = 'internet' unless options[:stored_credential] || card_brand(payment) == 'jcb'
196
246
 
197
247
  post[:paymentInformation][:tokenizedCard] = {
198
248
  number: payment.number,
199
249
  expirationMonth: payment.month,
200
250
  expirationYear: payment.year,
201
251
  cryptogram: payment.payment_cryptogram,
202
- transactionType: '1',
203
- type: CREDIT_CARD_CODES[card_brand(payment).to_sym]
252
+ type: CREDIT_CARD_CODES[card_brand(payment).to_sym],
253
+ transactionType: payment.source == :network_token ? '3' : '1'
204
254
  }
205
255
 
206
- if card_brand(payment) == 'master'
207
- post[:consumerAuthenticationInformation] = {
208
- ucafAuthenticationData: payment.payment_cryptogram,
209
- ucafCollectionIndicator: '2'
210
- }
256
+ if payment.source == :network_token && NT_PAYMENT_SOLUTION[payment.brand]
257
+ post[:processingInformation][:paymentSolution] = NT_PAYMENT_SOLUTION[payment.brand]
211
258
  else
212
- post[:consumerAuthenticationInformation] = { cavv: payment.payment_cryptogram }
259
+ # Apple Pay / Google Pay
260
+ post[:processingInformation][:paymentSolution] = WALLET_PAYMENT_SOLUTION[payment.source]
261
+ if card_brand(payment) == 'master'
262
+ post[:consumerAuthenticationInformation] = {
263
+ ucafAuthenticationData: payment.payment_cryptogram,
264
+ ucafCollectionIndicator: '2'
265
+ }
266
+ else
267
+ post[:consumerAuthenticationInformation] = { cavv: payment.payment_cryptogram }
268
+ end
213
269
  end
214
270
  end
215
271
 
@@ -258,56 +314,43 @@ module ActiveMerchant #:nodoc:
258
314
  end
259
315
 
260
316
  def add_stored_credentials(post, payment, options)
261
- return unless stored_credential = options[:stored_credential]
317
+ return unless options[:stored_credential]
262
318
 
263
- options = stored_credential_options(stored_credential, options.fetch(:reason_code, ''))
264
- post[:processingInformation][:commerceIndicator] = options.fetch(:transaction_type, 'internet')
265
- stored_credential[:initial_transaction] ? initial_transaction(post, options) : subsequent_transaction(post, options)
319
+ post[:processingInformation][:commerceIndicator] = commerce_indicator(options.dig(:stored_credential, :reason_type))
320
+ add_authorization_options(post, payment, options)
266
321
  end
267
322
 
268
- def stored_credential_options(options, reason_code)
269
- transaction_type = options[:reason_type]
270
- transaction_type = 'install' if transaction_type == 'installment'
271
- initiator = options[:initiator] if options[:initiator]
272
- initiator = 'customer' if initiator == 'cardholder'
273
- stored_on_file = options[:reason_type] == 'recurring'
274
- options.merge({
275
- transaction_type: transaction_type,
276
- initiator: initiator,
277
- reason_code: reason_code,
278
- stored_on_file: stored_on_file
279
- })
323
+ def commerce_indicator(reason_type)
324
+ case reason_type
325
+ when 'recurring'
326
+ 'recurring'
327
+ when 'installment'
328
+ 'install'
329
+ else
330
+ 'internet'
331
+ end
280
332
  end
281
333
 
282
- def add_processing_information(initiator, merchant_initiated_transaction_hash = {})
283
- {
334
+ def add_authorization_options(post, payment, options)
335
+ initiator = options.dig(:stored_credential, :initiator) == 'cardholder' ? 'customer' : 'merchant'
336
+ authorization_options = {
284
337
  authorizationOptions: {
285
338
  initiator: {
286
- type: initiator,
287
- merchantInitiatedTransaction: merchant_initiated_transaction_hash,
288
- storedCredentialUsed: true
339
+ type: initiator
289
340
  }
290
341
  }
291
342
  }.compact
292
- end
293
-
294
- def initial_transaction(post, options)
295
- processing_information = add_processing_information(options[:initiator], {
296
- reason: options[:reason_code]
297
- })
298
343
 
299
- post[:processingInformation].merge!(processing_information)
300
- end
301
-
302
- def subsequent_transaction(post, options)
303
- network_transaction_id = options[:network_transaction_id] || options.dig(:stored_credential, :network_transaction_id) || ''
304
- processing_information = add_processing_information(options[:initiator], {
305
- originalAuthorizedAmount: post.dig(:orderInformation, :amountDetails, :totalAmount),
306
- previousTransactionID: network_transaction_id,
307
- reason: options[:reason_code],
308
- storedCredentialUsed: options[:stored_on_file]
309
- })
310
- post[:processingInformation].merge!(processing_information)
344
+ authorization_options[:authorizationOptions][:initiator][:storedCredentialUsed] = true if initiator == 'merchant'
345
+ authorization_options[:authorizationOptions][:initiator][:credentialStoredOnFile] = true if options.dig(:stored_credential, :initial_transaction)
346
+ authorization_options[:authorizationOptions][:initiator][:merchantInitiatedTransaction] ||= {}
347
+ unless options.dig(:stored_credential, :initial_transaction)
348
+ network_transaction_id = options[:network_transaction_id] || options.dig(:stored_credential, :network_transaction_id) || ''
349
+ authorization_options[:authorizationOptions][:initiator][:merchantInitiatedTransaction][:previousTransactionID] = network_transaction_id
350
+ authorization_options[:authorizationOptions][:initiator][:merchantInitiatedTransaction][:originalAuthorizedAmount] = post.dig(:orderInformation, :amountDetails, :totalAmount) if card_brand(payment) == 'discover'
351
+ end
352
+ authorization_options[:authorizationOptions][:initiator][:merchantInitiatedTransaction][:reason] = options[:reason_code] if options[:reason_code]
353
+ post[:processingInformation].merge!(authorization_options)
311
354
  end
312
355
 
313
356
  def network_transaction_id_from(response)
@@ -315,7 +358,7 @@ module ActiveMerchant #:nodoc:
315
358
  end
316
359
 
317
360
  def url(action)
318
- "#{(test? ? test_url : live_url)}/pts/v2/#{action}"
361
+ "#{test? ? test_url : live_url}/pts/v2/#{action}"
319
362
  end
320
363
 
321
364
  def host
@@ -330,7 +373,7 @@ module ActiveMerchant #:nodoc:
330
373
  add_reconciliation_id(post, options)
331
374
  add_sec_code(post, options)
332
375
  add_invoice_number(post, options)
333
- response = parse(ssl_post(url(action), post.to_json, auth_headers(action, post)))
376
+ response = parse(ssl_post(url(action), post.to_json, auth_headers(action, options, post)))
334
377
  Response.new(
335
378
  success_from(response),
336
379
  message_from(response),
@@ -378,7 +421,7 @@ module ActiveMerchant #:nodoc:
378
421
  string_to_sign = {
379
422
  host: host,
380
423
  date: gmtdatetime,
381
- "(request-target)": "#{http_method} /pts/v2/#{resource}",
424
+ "request-target": "#{http_method} /pts/v2/#{resource}",
382
425
  digest: digest,
383
426
  "v-c-merchant-id": @options[:merchant_id]
384
427
  }.map { |k, v| "#{k}: #{v}" }.join("\n").force_encoding(Encoding::UTF_8)
@@ -386,7 +429,7 @@ module ActiveMerchant #:nodoc:
386
429
  {
387
430
  keyid: @options[:public_key],
388
431
  algorithm: 'HmacSHA256',
389
- headers: "host date (request-target)#{digest.present? ? ' digest' : ''} v-c-merchant-id",
432
+ headers: "host date request-target#{digest.present? ? ' digest' : ''} v-c-merchant-id",
390
433
  signature: sign_payload(string_to_sign)
391
434
  }.map { |k, v| %{#{k}="#{v}"} }.join(', ')
392
435
  end
@@ -396,14 +439,14 @@ module ActiveMerchant #:nodoc:
396
439
  Base64.strict_encode64(OpenSSL::HMAC.digest('sha256', decoded_key, payload))
397
440
  end
398
441
 
399
- def auth_headers(action, post, http_method = 'post')
442
+ def auth_headers(action, options, post, http_method = 'post')
400
443
  digest = "SHA-256=#{Digest::SHA256.base64digest(post.to_json)}" if post.present?
401
444
  date = Time.now.httpdate
402
445
 
403
446
  {
404
447
  'Accept' => 'application/hal+json;charset=utf-8',
405
448
  'Content-Type' => 'application/json;charset=utf-8',
406
- 'V-C-Merchant-Id' => @options[:merchant_id],
449
+ 'V-C-Merchant-Id' => options[:merchant_id] || @options[:merchant_id],
407
450
  'Date' => date,
408
451
  'Host' => host,
409
452
  'Signature' => get_http_signature(action, digest, http_method, date),
@@ -441,7 +484,8 @@ module ActiveMerchant #:nodoc:
441
484
  def add_invoice_number(post, options)
442
485
  return unless options[:invoice_number].present?
443
486
 
444
- post[:orderInformation][:invoiceDetails] = { invoiceNumber: options[:invoice_number] }
487
+ post[:orderInformation][:invoiceDetails] ||= {}
488
+ post[:orderInformation][:invoiceDetails][:invoiceNumber] = options[:invoice_number]
445
489
  end
446
490
 
447
491
  def add_partner_solution_id(post)
@@ -118,16 +118,18 @@ module ActiveMerchant #:nodoc:
118
118
 
119
119
  def add_payer(post, card, options)
120
120
  address = options[:billing_address] || options[:address]
121
+ phone_number = address[:phone] || address[:phone_number] if address
122
+
121
123
  post[:payer] = {}
122
124
  post[:payer][:name] = card.name
123
125
  post[:payer][:email] = options[:email] if options[:email]
124
126
  post[:payer][:birth_date] = options[:birth_date] if options[:birth_date]
125
- post[:payer][:phone] = address[:phone] if address && address[:phone]
127
+ post[:payer][:phone] = phone_number if phone_number
126
128
  post[:payer][:document] = options[:document] if options[:document]
127
129
  post[:payer][:document2] = options[:document2] if options[:document2]
128
130
  post[:payer][:user_reference] = options[:user_reference] if options[:user_reference]
129
131
  post[:payer][:event_uuid] = options[:device_id] if options[:device_id]
130
- post[:payer][:onboarding_ip_address] = options[:ip] if options[:ip]
132
+ post[:payer][:ip] = options[:ip] if options[:ip]
131
133
  post[:payer][:address] = add_address(post, card, options)
132
134
  end
133
135
 
@@ -163,23 +165,19 @@ module ActiveMerchant #:nodoc:
163
165
  post[:card][:network_token] = card.number
164
166
  post[:card][:cryptogram] = card.payment_cryptogram
165
167
  post[:card][:eci] = card.eci
166
- # used case of Network Token: 'CARD_ON_FILE', 'SUBSCRIPTION', 'UNSCHEDULED_CARD_ON_FILE'
167
- if options.dig(:stored_credential, :reason_type) == 'unscheduled'
168
- if options.dig(:stored_credential, :initiator) == 'merchant'
169
- post[:card][:stored_credential_type] = 'UNSCHEDULED_CARD_ON_FILE'
170
- else
171
- post[:card][:stored_credential_type] = 'CARD_ON_FILE'
172
- end
173
- else
174
- post[:card][:stored_credential_type] = 'SUBSCRIPTION'
175
- end
176
- # required for MC debit recurrent in BR 'USED'(subsecuence Payments) . 'FIRST' an inital payment
177
- post[:card][:stored_credential_usage] = (options[:stored_credential][:initial_transaction] ? 'FIRST' : 'USED') if options[:stored_credential]
178
168
  else
179
169
  post[:card][:number] = card.number
180
170
  post[:card][:cvv] = card.verification_value
181
171
  end
182
172
 
173
+ if options[:stored_credential]
174
+ # required for MC debit recurrent in BR 'USED'(subsecuence Payments) . 'FIRST' an inital payment
175
+ post[:card][:stored_credential_usage] = (options[:stored_credential][:initial_transaction] ? 'FIRST' : 'USED')
176
+ post[:card][:network_payment_reference] = options[:stored_credential][:network_transaction_id] if options[:stored_credential][:network_transaction_id]
177
+ # used case of Network Token: 'CARD_ON_FILE', 'SUBSCRIPTION', 'UNSCHEDULED_CARD_ON_FILE'
178
+ post[:card][:stored_credential_type] = fetch_stored_credential_type(options[:stored_credential])
179
+ end
180
+
183
181
  post[:card][:holder_name] = card.name
184
182
  post[:card][:expiration_month] = card.month
185
183
  post[:card][:expiration_year] = card.year
@@ -191,6 +189,14 @@ module ActiveMerchant #:nodoc:
191
189
  post[:card][:save] = options[:save] if options[:save]
192
190
  end
193
191
 
192
+ def fetch_stored_credential_type(stored_credential)
193
+ if stored_credential[:reason_type] == 'unscheduled'
194
+ stored_credential[:initiator] == 'merchant' ? 'UNSCHEDULED_CARD_ON_FILE' : 'CARD_ON_FILE'
195
+ else
196
+ 'SUBSCRIPTION'
197
+ end
198
+ end
199
+
194
200
  def parse(body)
195
201
  JSON.parse(body)
196
202
  end
@@ -218,6 +224,7 @@ module ActiveMerchant #:nodoc:
218
224
  message_from(action, response),
219
225
  response,
220
226
  authorization: authorization_from(response),
227
+ network_transaction_id: network_transaction_id_from(response),
221
228
  avs_result: AVSResult.new(code: response['some_avs_response_key']),
222
229
  cvv_result: CVVResult.new(response['some_cvv_response_key']),
223
230
  test: test?,
@@ -242,6 +249,10 @@ module ActiveMerchant #:nodoc:
242
249
  response['id']
243
250
  end
244
251
 
252
+ def network_transaction_id_from(response)
253
+ response.dig('card', 'network_tx_reference')
254
+ end
255
+
245
256
  def error_code_from(action, response)
246
257
  return if success_from(action, response)
247
258
 
@@ -250,7 +261,7 @@ module ActiveMerchant #:nodoc:
250
261
  end
251
262
 
252
263
  def url(action, parameters, options = {})
253
- "#{(test? ? test_url : live_url)}/#{endpoint(action, parameters, options)}/"
264
+ "#{test? ? test_url : live_url}/#{endpoint(action, parameters, options)}/"
254
265
  end
255
266
 
256
267
  def endpoint(action, parameters, options)
@@ -235,23 +235,23 @@ module ActiveMerchant
235
235
  # a predefined one
236
236
  xml.tag! :ExtendedPolicy do
237
237
  xml.tag! :cv2_policy,
238
- notprovided: POLICY_REJECT,
239
- notchecked: POLICY_REJECT,
240
- matched: POLICY_ACCEPT,
241
- notmatched: POLICY_REJECT,
242
- partialmatch: POLICY_REJECT
238
+ notprovided: POLICY_REJECT,
239
+ notchecked: POLICY_REJECT,
240
+ matched: POLICY_ACCEPT,
241
+ notmatched: POLICY_REJECT,
242
+ partialmatch: POLICY_REJECT
243
243
  xml.tag! :postcode_policy,
244
- notprovided: POLICY_ACCEPT,
245
- notchecked: POLICY_ACCEPT,
246
- matched: POLICY_ACCEPT,
247
- notmatched: POLICY_REJECT,
248
- partialmatch: POLICY_ACCEPT
244
+ notprovided: POLICY_ACCEPT,
245
+ notchecked: POLICY_ACCEPT,
246
+ matched: POLICY_ACCEPT,
247
+ notmatched: POLICY_REJECT,
248
+ partialmatch: POLICY_ACCEPT
249
249
  xml.tag! :address_policy,
250
- notprovided: POLICY_ACCEPT,
251
- notchecked: POLICY_ACCEPT,
252
- matched: POLICY_ACCEPT,
253
- notmatched: POLICY_REJECT,
254
- partialmatch: POLICY_ACCEPT
250
+ notprovided: POLICY_ACCEPT,
251
+ notchecked: POLICY_ACCEPT,
252
+ matched: POLICY_ACCEPT,
253
+ notmatched: POLICY_REJECT,
254
+ partialmatch: POLICY_ACCEPT
255
255
  end
256
256
  end
257
257
  end
@@ -260,9 +260,13 @@ module ActiveMerchant
260
260
  def commit(request)
261
261
  response = parse(ssl_post(test? ? self.test_url : self.live_url, request))
262
262
 
263
- Response.new(response[:status] == '1', response[:reason], response,
263
+ Response.new(
264
+ response[:status] == '1',
265
+ response[:reason],
266
+ response,
264
267
  test: test?,
265
- authorization: "#{response[:datacash_reference]};#{response[:authcode]};#{response[:ca_reference]}")
268
+ authorization: "#{response[:datacash_reference]};#{response[:authcode]};#{response[:ca_reference]}"
269
+ )
266
270
  end
267
271
 
268
272
  def format_date(month, year)