activemerchant 1.131.0 → 1.137.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (184) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +262 -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 +13 -8
  6. data/lib/active_merchant/billing/credit_card_formatting.rb +4 -0
  7. data/lib/active_merchant/billing/credit_card_methods.rb +64 -7
  8. data/lib/active_merchant/billing/gateway.rb +9 -0
  9. data/lib/active_merchant/billing/gateways/adyen.rb +240 -41
  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/borgun.rb +6 -4
  21. data/lib/active_merchant/billing/gateways/braintree/token_nonce.rb +65 -20
  22. data/lib/active_merchant/billing/gateways/braintree_blue.rb +226 -73
  23. data/lib/active_merchant/billing/gateways/braintree_orange.rb +1 -1
  24. data/lib/active_merchant/billing/gateways/card_connect.rb +5 -2
  25. data/lib/active_merchant/billing/gateways/card_stream.rb +4 -6
  26. data/lib/active_merchant/billing/gateways/cashnet.rb +1 -1
  27. data/lib/active_merchant/billing/gateways/cecabank/cecabank_common.rb +36 -0
  28. data/lib/active_merchant/billing/gateways/cecabank/cecabank_json.rb +316 -0
  29. data/lib/active_merchant/billing/gateways/cecabank/cecabank_xml.rb +220 -0
  30. data/lib/active_merchant/billing/gateways/cecabank.rb +7 -240
  31. data/lib/active_merchant/billing/gateways/checkout_v2.rb +242 -41
  32. data/lib/active_merchant/billing/gateways/commerce_hub.rb +69 -8
  33. data/lib/active_merchant/billing/gateways/credorax.rb +3 -5
  34. data/lib/active_merchant/billing/gateways/cyber_source.rb +192 -41
  35. data/lib/active_merchant/billing/gateways/cyber_source_rest.rb +102 -58
  36. data/lib/active_merchant/billing/gateways/d_local.rb +26 -15
  37. data/lib/active_merchant/billing/gateways/data_cash.rb +21 -17
  38. data/lib/active_merchant/billing/gateways/datatrans.rb +279 -0
  39. data/lib/active_merchant/billing/gateways/decidir.rb +53 -18
  40. data/lib/active_merchant/billing/gateways/decidir_plus.rb +4 -1
  41. data/lib/active_merchant/billing/gateways/deepstack.rb +382 -0
  42. data/lib/active_merchant/billing/gateways/ebanx.rb +40 -36
  43. data/lib/active_merchant/billing/gateways/efsnet.rb +6 -2
  44. data/lib/active_merchant/billing/gateways/elavon.rb +99 -33
  45. data/lib/active_merchant/billing/gateways/element.rb +36 -7
  46. data/lib/active_merchant/billing/gateways/epay.rb +6 -2
  47. data/lib/active_merchant/billing/gateways/evo_ca.rb +6 -2
  48. data/lib/active_merchant/billing/gateways/eway.rb +4 -2
  49. data/lib/active_merchant/billing/gateways/eway_managed.rb +6 -2
  50. data/lib/active_merchant/billing/gateways/exact.rb +6 -2
  51. data/lib/active_merchant/billing/gateways/fat_zebra.rb +31 -3
  52. data/lib/active_merchant/billing/gateways/federated_canada.rb +6 -2
  53. data/lib/active_merchant/billing/gateways/first_pay/first_pay_common.rb +15 -0
  54. data/lib/active_merchant/billing/gateways/first_pay/first_pay_json.rb +190 -0
  55. data/lib/active_merchant/billing/gateways/first_pay/first_pay_xml.rb +183 -0
  56. data/lib/active_merchant/billing/gateways/first_pay.rb +6 -172
  57. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +6 -2
  58. data/lib/active_merchant/billing/gateways/firstdata_e4_v27.rb +7 -3
  59. data/lib/active_merchant/billing/gateways/flex_charge.rb +347 -0
  60. data/lib/active_merchant/billing/gateways/garanti.rb +4 -2
  61. data/lib/active_merchant/billing/gateways/global_collect.rb +45 -37
  62. data/lib/active_merchant/billing/gateways/hi_pay.rb +286 -0
  63. data/lib/active_merchant/billing/gateways/hps.rb +1 -1
  64. data/lib/active_merchant/billing/gateways/iats_payments.rb +7 -2
  65. data/lib/active_merchant/billing/gateways/inspire.rb +6 -4
  66. data/lib/active_merchant/billing/gateways/instapay.rb +7 -4
  67. data/lib/active_merchant/billing/gateways/ipg.rb +10 -6
  68. data/lib/active_merchant/billing/gateways/iridium.rb +15 -5
  69. data/lib/active_merchant/billing/gateways/itransact.rb +6 -2
  70. data/lib/active_merchant/billing/gateways/iveri.rb +3 -3
  71. data/lib/active_merchant/billing/gateways/ixopay.rb +2 -2
  72. data/lib/active_merchant/billing/gateways/jetpay.rb +4 -2
  73. data/lib/active_merchant/billing/gateways/jetpay_v2.rb +4 -2
  74. data/lib/active_merchant/billing/gateways/kushki.rb +73 -13
  75. data/lib/active_merchant/billing/gateways/linkpoint.rb +6 -2
  76. data/lib/active_merchant/billing/gateways/litle.rb +33 -50
  77. data/lib/active_merchant/billing/gateways/mastercard.rb +4 -4
  78. data/lib/active_merchant/billing/gateways/maxipago.rb +2 -2
  79. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +8 -5
  80. data/lib/active_merchant/billing/gateways/merchant_ware.rb +11 -4
  81. data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +11 -4
  82. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +19 -3
  83. data/lib/active_merchant/billing/gateways/mercury.rb +6 -2
  84. data/lib/active_merchant/billing/gateways/metrics_global.rb +8 -6
  85. data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +1 -0
  86. data/lib/active_merchant/billing/gateways/migs.rb +6 -2
  87. data/lib/active_merchant/billing/gateways/mit.rb +25 -20
  88. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +18 -10
  89. data/lib/active_merchant/billing/gateways/monei.rb +1 -1
  90. data/lib/active_merchant/billing/gateways/moneris.rb +9 -3
  91. data/lib/active_merchant/billing/gateways/money_movers.rb +6 -2
  92. data/lib/active_merchant/billing/gateways/nab_transact.rb +12 -4
  93. data/lib/active_merchant/billing/gateways/net_registry.rb +6 -2
  94. data/lib/active_merchant/billing/gateways/netbanx.rb +1 -3
  95. data/lib/active_merchant/billing/gateways/netbilling.rb +6 -2
  96. data/lib/active_merchant/billing/gateways/network_merchants.rb +6 -2
  97. data/lib/active_merchant/billing/gateways/nmi.rb +23 -6
  98. data/lib/active_merchant/billing/gateways/ogone.rb +6 -2
  99. data/lib/active_merchant/billing/gateways/openpay.rb +4 -2
  100. data/lib/active_merchant/billing/gateways/opp.rb +1 -2
  101. data/lib/active_merchant/billing/gateways/optimal_payment.rb +6 -2
  102. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +1 -3
  103. data/lib/active_merchant/billing/gateways/orbital.rb +83 -24
  104. data/lib/active_merchant/billing/gateways/pac_net_raven.rb +7 -4
  105. data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +6 -2
  106. data/lib/active_merchant/billing/gateways/pay_hub.rb +4 -2
  107. data/lib/active_merchant/billing/gateways/pay_junction.rb +6 -2
  108. data/lib/active_merchant/billing/gateways/pay_secure.rb +6 -2
  109. data/lib/active_merchant/billing/gateways/pay_trace.rb +31 -18
  110. data/lib/active_merchant/billing/gateways/payeezy.rb +19 -8
  111. data/lib/active_merchant/billing/gateways/payex.rb +4 -2
  112. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +1 -1
  113. data/lib/active_merchant/billing/gateways/payflow.rb +1 -3
  114. data/lib/active_merchant/billing/gateways/payment_express.rb +8 -4
  115. data/lib/active_merchant/billing/gateways/paymentez.rb +23 -11
  116. data/lib/active_merchant/billing/gateways/paysafe.rb +12 -11
  117. data/lib/active_merchant/billing/gateways/payscout.rb +7 -4
  118. data/lib/active_merchant/billing/gateways/paystation.rb +7 -3
  119. data/lib/active_merchant/billing/gateways/payway.rb +6 -2
  120. data/lib/active_merchant/billing/gateways/payway_dot_com.rb +3 -3
  121. data/lib/active_merchant/billing/gateways/pin.rb +22 -4
  122. data/lib/active_merchant/billing/gateways/plexo.rb +49 -10
  123. data/lib/active_merchant/billing/gateways/plugnpay.rb +6 -2
  124. data/lib/active_merchant/billing/gateways/priority.rb +6 -5
  125. data/lib/active_merchant/billing/gateways/psigate.rb +6 -2
  126. data/lib/active_merchant/billing/gateways/psl_card.rb +6 -2
  127. data/lib/active_merchant/billing/gateways/qbms.rb +6 -2
  128. data/lib/active_merchant/billing/gateways/quantum.rb +6 -2
  129. data/lib/active_merchant/billing/gateways/quickbooks.rb +6 -5
  130. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +7 -4
  131. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v4to7.rb +6 -2
  132. data/lib/active_merchant/billing/gateways/rapyd.rb +148 -46
  133. data/lib/active_merchant/billing/gateways/reach.rb +11 -4
  134. data/lib/active_merchant/billing/gateways/redsys.rb +2 -10
  135. data/lib/active_merchant/billing/gateways/redsys_rest.rb +507 -0
  136. data/lib/active_merchant/billing/gateways/s5.rb +3 -3
  137. data/lib/active_merchant/billing/gateways/safe_charge.rb +38 -17
  138. data/lib/active_merchant/billing/gateways/sage.rb +12 -4
  139. data/lib/active_merchant/billing/gateways/sage_pay.rb +79 -5
  140. data/lib/active_merchant/billing/gateways/sallie_mae.rb +6 -2
  141. data/lib/active_merchant/billing/gateways/secure_net.rb +6 -2
  142. data/lib/active_merchant/billing/gateways/secure_pay.rb +8 -6
  143. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +12 -4
  144. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +6 -2
  145. data/lib/active_merchant/billing/gateways/securion_pay.rb +24 -10
  146. data/lib/active_merchant/billing/gateways/shift4.rb +17 -20
  147. data/lib/active_merchant/billing/gateways/shift4_v2.rb +117 -0
  148. data/lib/active_merchant/billing/gateways/simetrik.rb +17 -11
  149. data/lib/active_merchant/billing/gateways/skip_jack.rb +6 -2
  150. data/lib/active_merchant/billing/gateways/smart_ps.rb +7 -4
  151. data/lib/active_merchant/billing/gateways/so_easy_pay.rb +4 -2
  152. data/lib/active_merchant/billing/gateways/spreedly_core.rb +2 -4
  153. data/lib/active_merchant/billing/gateways/stripe.rb +63 -19
  154. data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +280 -88
  155. data/lib/active_merchant/billing/gateways/sum_up.rb +223 -0
  156. data/lib/active_merchant/billing/gateways/swipe_checkout.rb +4 -2
  157. data/lib/active_merchant/billing/gateways/telr.rb +3 -4
  158. data/lib/active_merchant/billing/gateways/trans_first.rb +1 -2
  159. data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +8 -16
  160. data/lib/active_merchant/billing/gateways/transact_pro.rb +1 -1
  161. data/lib/active_merchant/billing/gateways/trust_commerce.rb +6 -2
  162. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +9 -8
  163. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +6 -2
  164. data/lib/active_merchant/billing/gateways/vanco.rb +2 -4
  165. data/lib/active_merchant/billing/gateways/vantiv_express.rb +587 -0
  166. data/lib/active_merchant/billing/gateways/verifi.rb +6 -2
  167. data/lib/active_merchant/billing/gateways/viaklix.rb +6 -2
  168. data/lib/active_merchant/billing/gateways/visanet_peru.rb +2 -2
  169. data/lib/active_merchant/billing/gateways/vpos.rb +4 -4
  170. data/lib/active_merchant/billing/gateways/wirecard.rb +7 -3
  171. data/lib/active_merchant/billing/gateways/wompi.rb +5 -0
  172. data/lib/active_merchant/billing/gateways/worldpay.rb +141 -93
  173. data/lib/active_merchant/billing/gateways/worldpay_online_payments.rb +13 -10
  174. data/lib/active_merchant/billing/gateways/xpay.rb +242 -0
  175. data/lib/active_merchant/billing/network_tokenization_credit_card.rb +1 -1
  176. data/lib/active_merchant/billing/response.rb +2 -2
  177. data/lib/active_merchant/connection.rb +3 -17
  178. data/lib/active_merchant/country.rb +1 -0
  179. data/lib/active_merchant/errors.rb +10 -0
  180. data/lib/active_merchant/version.rb +1 -1
  181. data/lib/support/gateway_support.rb +2 -2
  182. data/lib/support/ssl_verify.rb +4 -4
  183. data/lib/support/ssl_version.rb +6 -6
  184. metadata +30 -9
@@ -1,12 +1,17 @@
1
1
  module ActiveMerchant #:nodoc:
2
2
  module Billing #:nodoc:
3
3
  class RapydGateway < Gateway
4
+ class_attribute :payment_redirect_test, :payment_redirect_live
5
+
4
6
  self.test_url = 'https://sandboxapi.rapyd.net/v1/'
5
7
  self.live_url = 'https://api.rapyd.net/v1/'
6
8
 
9
+ self.payment_redirect_test = 'https://sandboxpayment-redirect.rapyd.net/v1/'
10
+ self.payment_redirect_live = 'https://payment-redirect.rapyd.net/v1/'
11
+
7
12
  self.supported_countries = %w(CA CL CO DO SV PE PT VI AU HK IN ID JP MY NZ PH SG KR TW TH VN AD AT BE BA BG HR CY CZ DK EE FI FR GE DE GI GR GL HU IS IE IL IT LV LI LT LU MK MT MD MC ME NL GB NO PL RO RU SM SK SI ZA ES SE CH TR VA)
8
13
  self.default_currency = 'USD'
9
- self.supported_cardtypes = %i[visa master american_express discover]
14
+ self.supported_cardtypes = %i[visa master american_express discover verve]
10
15
 
11
16
  self.homepage_url = 'https://www.rapyd.net/'
12
17
  self.display_name = 'Rapyd Gateway'
@@ -63,11 +68,11 @@ module ActiveMerchant #:nodoc:
63
68
  def store(payment, options = {})
64
69
  post = {}
65
70
  add_payment(post, payment, options)
66
- add_customer_object(post, payment, options)
71
+ add_customer_data(post, payment, options, 'store')
67
72
  add_metadata(post, options)
68
73
  add_ewallet(post, options)
69
74
  add_payment_fields(post, options)
70
- add_payment_urls(post, options)
75
+ add_payment_urls(post, options, 'store')
71
76
  add_address(post, payment, options)
72
77
  commit(:post, 'customers', post)
73
78
  end
@@ -100,14 +105,18 @@ module ActiveMerchant #:nodoc:
100
105
  def add_auth_purchase(post, money, payment, options)
101
106
  add_invoice(post, money, options)
102
107
  add_payment(post, payment, options)
103
- add_customer_object(post, payment, options)
108
+ add_customer_data(post, payment, options)
104
109
  add_3ds(post, payment, options)
105
110
  add_address(post, payment, options)
106
111
  add_metadata(post, options)
107
112
  add_ewallet(post, options)
108
113
  add_payment_fields(post, options)
109
114
  add_payment_urls(post, options)
110
- add_customer_id(post, options)
115
+ add_idempotency(options)
116
+ end
117
+
118
+ def add_idempotency(options)
119
+ @options[:idempotency] = options[:idempotency_key] if options[:idempotency_key]
111
120
  end
112
121
 
113
122
  def add_address(post, creditcard, options)
@@ -128,6 +137,10 @@ module ActiveMerchant #:nodoc:
128
137
  def add_invoice(post, money, options)
129
138
  post[:amount] = money.zero? ? 0 : amount(money).to_f.to_s
130
139
  post[:currency] = (options[:currency] || currency(money))
140
+ post[:merchant_reference_id] = options[:merchant_reference_id] || options[:order_id]
141
+ post[:requested_currency] = options[:requested_currency] if options[:requested_currency].present?
142
+ post[:fixed_side] = options[:fixed_side] if options[:fixed_side].present?
143
+ post[:expiration] = (options[:expiration_days] || 7).to_i.days.from_now.to_i if options[:fixed_side].present?
131
144
  end
132
145
 
133
146
  def add_payment(post, payment, options)
@@ -136,15 +149,27 @@ module ActiveMerchant #:nodoc:
136
149
  elsif payment.is_a?(Check)
137
150
  add_ach(post, payment, options)
138
151
  else
139
- add_token(post, payment, options)
152
+ add_tokens(post, payment, options)
140
153
  end
141
154
  end
142
155
 
143
156
  def add_stored_credential(post, options)
144
- return unless stored_credential = options[:stored_credential]
157
+ add_network_reference_id(post, options)
158
+ add_initiation_type(post, options)
159
+ end
160
+
161
+ def add_network_reference_id(post, options)
162
+ return unless (options[:stored_credential] && options[:stored_credential][:reason_type] == 'recurring') || options[:network_transaction_id]
163
+
164
+ network_transaction_id = options[:network_transaction_id] || options[:stored_credential][:network_transaction_id]
165
+ post[:payment_method][:fields][:network_reference_id] = network_transaction_id unless network_transaction_id&.empty?
166
+ end
167
+
168
+ def add_initiation_type(post, options)
169
+ return unless options[:stored_credential] || options[:initiation_type]
145
170
 
146
- post[:payment_method][:fields][:network_reference_id] = stored_credential[:network_transaction_id] if stored_credential[:network_transaction_id]
147
- post[:initiation_type] = stored_credential[:reason_type] if stored_credential[:reason_type]
171
+ initiation_type = options[:initiation_type] || options[:stored_credential][:reason_type]
172
+ post[:initiation_type] = initiation_type if initiation_type
148
173
  end
149
174
 
150
175
  def add_creditcard(post, payment, options)
@@ -154,14 +179,23 @@ module ActiveMerchant #:nodoc:
154
179
 
155
180
  post[:payment_method][:type] = options[:pm_type]
156
181
  pm_fields[:number] = payment.number
157
- pm_fields[:expiration_month] = payment.month.to_s
158
- pm_fields[:expiration_year] = payment.year.to_s
182
+ pm_fields[:expiration_month] = format(payment.month, :two_digits).to_s
183
+ pm_fields[:expiration_year] = format(payment.year, :two_digits).to_s
159
184
  pm_fields[:name] = "#{payment.first_name} #{payment.last_name}"
160
- pm_fields[:cvv] = payment.verification_value.to_s
161
-
185
+ pm_fields[:cvv] = payment.verification_value.to_s unless valid_network_transaction_id?(options) || payment.verification_value.blank?
186
+ pm_fields[:recurrence_type] = options[:recurrence_type] if options[:recurrence_type]
162
187
  add_stored_credential(post, options)
163
188
  end
164
189
 
190
+ def send_customer_object?(options)
191
+ options[:stored_credential] && options[:stored_credential][:reason_type] == 'recurring'
192
+ end
193
+
194
+ def valid_network_transaction_id?(options)
195
+ network_transaction_id = options[:network_tansaction_id] || options.dig(:stored_credential_options, :network_transaction_id) || options.dig(:stored_credential, :network_transaction_id)
196
+ return network_transaction_id.present?
197
+ end
198
+
165
199
  def add_ach(post, payment, options)
166
200
  post[:payment_method] = {}
167
201
  post[:payment_method][:fields] = {}
@@ -175,22 +209,27 @@ module ActiveMerchant #:nodoc:
175
209
  post[:payment_method][:fields][:payment_purpose] = options[:payment_purpose] if options[:payment_purpose]
176
210
  end
177
211
 
178
- def add_token(post, payment, options)
179
- return unless token = payment.split('|')[1]
212
+ def add_tokens(post, payment, options)
213
+ return unless payment.respond_to?(:split)
180
214
 
181
- post[:payment_method] = token
215
+ customer_id, card_id = payment.split('|')
216
+
217
+ post[:customer] = customer_id unless send_customer_object?(options)
218
+ post[:payment_method] = card_id
182
219
  end
183
220
 
184
221
  def add_3ds(post, payment, options)
185
- return unless three_d_secure = options[:three_d_secure]
186
-
187
- post[:payment_method_options] = {}
188
- post[:payment_method_options]['3d_required'] = three_d_secure[:required]
189
- post[:payment_method_options]['3d_version'] = three_d_secure[:version]
190
- post[:payment_method_options][:cavv] = three_d_secure[:cavv]
191
- post[:payment_method_options][:eci] = three_d_secure[:eci]
192
- post[:payment_method_options][:xid] = three_d_secure[:xid]
193
- post[:payment_method_options][:ds_trans_id] = three_d_secure[:ds_transaction_id]
222
+ if options[:execute_threed] == true
223
+ post[:payment_method_options] = { '3d_required' => true } if options[:force_3d_secure].to_s == 'true'
224
+ elsif three_d_secure = options[:three_d_secure]
225
+ post[:payment_method_options] = {}
226
+ post[:payment_method_options]['3d_required'] = three_d_secure[:required]
227
+ post[:payment_method_options]['3d_version'] = three_d_secure[:version]
228
+ post[:payment_method_options][:cavv] = three_d_secure[:cavv]
229
+ post[:payment_method_options][:eci] = three_d_secure[:eci]
230
+ post[:payment_method_options][:xid] = three_d_secure[:xid]
231
+ post[:payment_method_options][:ds_trans_id] = three_d_secure[:ds_transaction_id]
232
+ end
194
233
  end
195
234
 
196
235
  def add_metadata(post, options)
@@ -198,27 +237,67 @@ module ActiveMerchant #:nodoc:
198
237
  end
199
238
 
200
239
  def add_ewallet(post, options)
201
- post[:ewallet_id] = options[:ewallet_id] if options[:ewallet_id]
240
+ post[:ewallet] = options[:ewallet_id] if options[:ewallet_id]
202
241
  end
203
242
 
204
243
  def add_payment_fields(post, options)
205
- post[:payment] = {}
244
+ post[:description] = options[:description] if options[:description]
245
+ post[:statement_descriptor] = options[:statement_descriptor] if options[:statement_descriptor]
246
+ post[:save_payment_method] = options[:save_payment_method] if options[:save_payment_method]
247
+ end
248
+
249
+ def add_payment_urls(post, options, action = '')
250
+ if action == 'store'
251
+ url_location = post[:payment_method]
252
+ else
253
+ url_location = post
254
+ end
255
+
256
+ url_location[:complete_payment_url] = options[:complete_payment_url] if options[:complete_payment_url]
257
+ url_location[:error_payment_url] = options[:error_payment_url] if options[:error_payment_url]
258
+ end
259
+
260
+ def add_customer_data(post, payment, options, action = '')
261
+ phone_number = options.dig(:billing_address, :phone) || options.dig(:billing_address, :phone_number)
262
+ post[:phone_number] = phone_number.gsub(/\D/, '') unless phone_number.nil?
263
+ post[:receipt_email] = options[:email] if payment.is_a?(String) && options[:customer_id].present? && !send_customer_object?(options)
206
264
 
207
- post[:payment][:description] = options[:description] if options[:description]
208
- post[:payment][:statement_descriptor] = options[:statement_descriptor] if options[:statement_descriptor]
265
+ return if payment.is_a?(String)
266
+ return add_customer_id(post, options) if options[:customer_id]
267
+
268
+ if action == 'store'
269
+ post.merge!(customer_fields(payment, options))
270
+ else
271
+ post[:customer] = customer_fields(payment, options) unless send_customer_object?(options)
272
+ end
209
273
  end
210
274
 
211
- def add_payment_urls(post, options)
212
- post[:complete_payment_url] = options[:complete_payment_url] if options[:complete_payment_url]
213
- post[:error_payment_url] = options[:error_payment_url] if options[:error_payment_url]
275
+ def customer_fields(payment, options)
276
+ return if options[:customer_id]
277
+
278
+ customer_address = address(options)
279
+ customer_data = {}
280
+ customer_data[:name] = "#{payment.first_name} #{payment.last_name}" unless payment.is_a?(String)
281
+ customer_data[:email] = options[:email] unless payment.is_a?(String) && options[:customer_id].blank?
282
+ customer_data[:addresses] = [customer_address] if customer_address
283
+ customer_data
214
284
  end
215
285
 
216
- def add_customer_object(post, payment, options)
217
- post[:name] = "#{payment.first_name} #{payment.last_name}" unless payment.is_a?(String)
218
- phone = options.dig(:billing_address, :phone) .gsub(/\D/, '') unless options[:billing_address].nil?
219
- post[:phone_number] = phone || options.dig(:customer, :phone_number)
220
- post[:email] = options[:email] || options.dig(:customer, :email)
221
- post[:addresses] = options.dig(:customer, :addresses) if USA_PAYMENT_METHODS.include?(options[:pm_type])
286
+ def address(options)
287
+ return unless address = options[:billing_address]
288
+
289
+ formatted_address = {}
290
+
291
+ formatted_address[:name] = address[:name] if address[:name]
292
+ formatted_address[:line_1] = address[:address1] if address[:address1]
293
+ formatted_address[:line_2] = address[:address2] if address[:address2]
294
+ formatted_address[:city] = address[:city] if address[:city]
295
+ formatted_address[:state] = address[:state] if address[:state]
296
+ formatted_address[:country] = address[:country] if address[:country]
297
+ formatted_address[:zip] = address[:zip] if address[:zip]
298
+ formatted_address[:phone_number] = address[:phone].gsub(/\D/, '') if address[:phone]
299
+
300
+ formatted_address
222
301
  end
223
302
 
224
303
  def add_customer_id(post, options)
@@ -228,13 +307,21 @@ module ActiveMerchant #:nodoc:
228
307
  def parse(body)
229
308
  return {} if body.empty? || body.nil?
230
309
 
231
- JSON.parse(body)
310
+ parsed = JSON.parse(body)
311
+ parsed.is_a?(Hash) ? parsed : { 'status' => { 'status' => parsed } }
312
+ end
313
+
314
+ def url(action, url_override = nil)
315
+ if url_override.to_s == 'payment_redirect' && action == 'payments'
316
+ (self.test? ? self.payment_redirect_test : self.payment_redirect_live) + action.to_s
317
+ else
318
+ (self.test? ? self.test_url : self.live_url) + action.to_s
319
+ end
232
320
  end
233
321
 
234
322
  def commit(method, action, parameters)
235
- url = (test? ? test_url : live_url) + action.to_s
236
323
  rel_path = "#{method}/v1/#{action}"
237
- response = api_request(method, url, rel_path, parameters)
324
+ response = api_request(method, url(action, @options[:url_override]), rel_path, parameters)
238
325
 
239
326
  Response.new(
240
327
  success_from(response),
@@ -246,10 +333,25 @@ module ActiveMerchant #:nodoc:
246
333
  test: test?,
247
334
  error_code: error_code_from(response)
248
335
  )
336
+ rescue ActiveMerchant::ResponseError => e
337
+ response = e.response.body.present? ? parse(e.response.body) : { 'status' => { 'response_code' => e.response.msg } }
338
+ message = response['status'].slice('message', 'response_code').values.select(&:present?).first || ''
339
+ Response.new(false, message, response, test: test?, error_code: error_code_from(response))
340
+ end
341
+
342
+ # We need to revert the work of ActiveSupport JSON encoder to prevent discrepancies
343
+ # Between the signature and the actual request body
344
+ def revert_json_html_encoding!(string)
345
+ {
346
+ '\\u003e' => '>',
347
+ '\\u003c' => '<',
348
+ '\\u0026' => '&'
349
+ }.each { |k, v| string.gsub! k, v }
249
350
  end
250
351
 
251
352
  def api_request(method, url, rel_path, params)
252
353
  params == {} ? body = '' : body = params.to_json
354
+ revert_json_html_encoding!(body) if defined?(ActiveSupport::JSON::Encoding) && ActiveSupport::JSON::Encoding.escape_html_entities_in_json
253
355
  parse(ssl_request(method, url, body, headers(rel_path, body)))
254
356
  end
255
357
 
@@ -261,14 +363,14 @@ module ActiveMerchant #:nodoc:
261
363
  'access_key' => @options[:access_key],
262
364
  'salt' => salt,
263
365
  'timestamp' => timestamp,
264
- 'signature' => generate_hmac(rel_path, salt, timestamp, payload)
265
- }
366
+ 'signature' => generate_hmac(rel_path, salt, timestamp, payload),
367
+ 'idempotency' => @options[:idempotency]
368
+ }.delete_if { |_, value| value.nil? }
266
369
  end
267
370
 
268
371
  def generate_hmac(rel_path, salt, timestamp, payload)
269
372
  signature = "#{rel_path}#{salt}#{timestamp}#{@options[:access_key]}#{@options[:secret_key]}#{payload}"
270
- hash = Base64.urlsafe_encode64(OpenSSL::HMAC.hexdigest('sha256', @options[:secret_key], signature))
271
- hash
373
+ Base64.urlsafe_encode64(OpenSSL::HMAC.hexdigest('sha256', @options[:secret_key], signature))
272
374
  end
273
375
 
274
376
  def avs_result(response)
@@ -303,7 +405,7 @@ module ActiveMerchant #:nodoc:
303
405
  end
304
406
 
305
407
  def error_code_from(response)
306
- response.dig('status', 'error_code') unless success_from(response)
408
+ response.dig('status', 'error_code') || response.dig('status', 'response_code') || ''
307
409
  end
308
410
 
309
411
  def handle_response(response)
@@ -4,7 +4,14 @@ module ActiveMerchant #:nodoc:
4
4
  self.test_url = 'https://checkout.rch.how/'
5
5
  self.live_url = 'https://checkout.rch.io/'
6
6
 
7
- self.supported_countries = ['US']
7
+ self.supported_countries = %w(AE AG AL AM AT AU AW AZ BA BB BD BE BF BG BH BJ BM BN BO BR BS BW BZ CA CD CF
8
+ CH CI CL CM CN CO CR CU CV CY CZ DE DJ DK DM DO DZ EE EG ES ET FI FJ FK FR GA
9
+ GB GD GE GG GH GI GN GR GT GU GW GY HK HN HR HU ID IE IL IM IN IS IT JE JM JO
10
+ JP KE KG KH KM KN KR KW KY KZ LA LC LK LR LT LU LV LY MA MD MK ML MN MO MR MS
11
+ MT MU MV MW MX MY MZ NA NC NE NG NI NL NO NP NZ OM PA PE PF PG PH PK PL PT PY
12
+ QA RO RS RW SA SB SC SE SG SH SI SK SL SN SO SR ST SV SY SZ TD TG TH TN TO TR
13
+ TT TV TW TZ UG US UY UZ VC VN VU WF WS YE ZM)
14
+
8
15
  self.default_currency = 'USD'
9
16
  self.supported_cardtypes = %i[visa diners_club american_express jcb master discover maestro]
10
17
 
@@ -71,10 +78,10 @@ module ActiveMerchant #:nodoc:
71
78
 
72
79
  def scrub(transcript)
73
80
  transcript.
74
- gsub(%r(((MerchantId)[% \w]+[%]\d{2})[\w -]+), '\1[FILTERED]').
81
+ gsub(%r(((MerchantId)[% \w]+%\d{2})[\w -]+), '\1[FILTERED]').
75
82
  gsub(%r((signature=)[\w%]+), '\1[FILTERED]\2').
76
- gsub(%r((Number%22%3A%22)[\d]+), '\1[FILTERED]\2').
77
- gsub(%r((VerificationCode%22%3A)[\d]+), '\1[FILTERED]\2')
83
+ gsub(%r((Number%22%3A%22)\d+), '\1[FILTERED]\2').
84
+ gsub(%r((VerificationCode%22%3A)\d+), '\1[FILTERED]\2')
78
85
  end
79
86
 
80
87
  def refund(amount, authorization, options = {})
@@ -266,14 +266,7 @@ module ActiveMerchant #:nodoc:
266
266
  end
267
267
 
268
268
  def verify(creditcard, options = {})
269
- if options[:sca_exemption_behavior_override] == 'endpoint_and_ntid'
270
- purchase(0, creditcard, options)
271
- else
272
- MultiResponse.run(:use_first_response) do |r|
273
- r.process { authorize(100, creditcard, options) }
274
- r.process(:ignore_result) { void(r.authorization, options) }
275
- end
276
- end
269
+ purchase(0, creditcard, options)
277
270
  end
278
271
 
279
272
  def supports_scrubbing
@@ -696,8 +689,7 @@ module ActiveMerchant #:nodoc:
696
689
 
697
690
  order_id += "\0" until order_id.bytesize % block_length == 0 # Pad with zeros
698
691
 
699
- output = cipher.update(order_id) + cipher.final
700
- output
692
+ cipher.update(order_id) + cipher.final
701
693
  end
702
694
 
703
695
  def mac256(key, data)