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,587 @@
1
+ require 'nokogiri'
2
+ require 'securerandom'
3
+
4
+ module ActiveMerchant #:nodoc:
5
+ module Billing #:nodoc:
6
+ class VantivExpressGateway < Gateway
7
+ self.test_url = 'https://certtransaction.elementexpress.com'
8
+ self.live_url = 'https://transaction.elementexpress.com'
9
+
10
+ self.supported_countries = ['US']
11
+ self.default_currency = 'USD'
12
+ self.supported_cardtypes = %i[visa master american_express discover diners_club jcb]
13
+
14
+ self.homepage_url = 'http://www.elementps.com'
15
+ self.display_name = 'Element'
16
+
17
+ SERVICE_TEST_URL = 'https://certservices.elementexpress.com'
18
+ SERVICE_LIVE_URL = 'https://services.elementexpress.com'
19
+
20
+ NETWORK_TOKEN_TYPE = {
21
+ apple_pay: 2,
22
+ google_pay: 1
23
+ }
24
+
25
+ CARD_PRESENT_CODE = {
26
+ 'Unknown' => 1,
27
+ 'Present' => 2,
28
+ 'NotPresent' => 3
29
+ }
30
+
31
+ MARKET_CODE = {
32
+ 'AutoRental' => 1,
33
+ 'DirectMarketing' => 2,
34
+ 'ECommerce' => 3,
35
+ 'FoodRestaurant' => 4,
36
+ 'HotelLodging' => 5,
37
+ 'Petroleum' => 6,
38
+ 'Retail' => 7,
39
+ 'QSR' => 8,
40
+ 'Grocery' => 9
41
+ }
42
+
43
+ PAYMENT_TYPE = {
44
+ 'NotUsed' => 0,
45
+ 'Recurring' => 1,
46
+ 'Installment' => 2,
47
+ 'CardHolderInitiated' => 3,
48
+ 'CredentialOnFile' => 4
49
+ }
50
+
51
+ REVERSAL_TYPE = {
52
+ 'System' => 0,
53
+ 'Full' => 1,
54
+ 'Partial' => 2
55
+ }
56
+
57
+ SUBMISSION_TYPE = {
58
+ 'NotUsed' => 0,
59
+ 'Initial' => 1,
60
+ 'Subsequent' => 2,
61
+ 'Resubmission' => 3,
62
+ 'ReAuthorization' => 4,
63
+ 'DelayedCharges' => 5,
64
+ 'NoShow' => 6
65
+ }
66
+
67
+ LODGING_PPC = {
68
+ 'NonParticipant' => 0,
69
+ 'DollarLimit500' => 1,
70
+ 'DollarLimit1000' => 2,
71
+ 'DollarLimit1500' => 3
72
+ }
73
+
74
+ LODGING_SPC = {
75
+ 'Default' => 0,
76
+ 'Sale' => 1,
77
+ 'NoShow' => 2,
78
+ 'AdvanceDeposit' => 3
79
+ }
80
+
81
+ LODGING_CHARGE_TYPE = {
82
+ 'Default' => 0,
83
+ 'Restaurant' => 1,
84
+ 'GiftShop' => 2
85
+ }
86
+
87
+ TERMINAL_TYPE = {
88
+ 'Unknown' => 0,
89
+ 'PointOfSale' => 1,
90
+ 'ECommerce' => 2,
91
+ 'MOTO' => 3,
92
+ 'FuelPump' => 4,
93
+ 'ATM' => 5,
94
+ 'Voice' => 6,
95
+ 'Mobile' => 7,
96
+ 'WebSiteGiftCard' => 8
97
+ }
98
+
99
+ CARD_HOLDER_PRESENT_CODE = {
100
+ 'Default' => 0,
101
+ 'Unknown' => 1,
102
+ 'Present' => 2,
103
+ 'NotPresent' => 3,
104
+ 'MailOrder' => 4,
105
+ 'PhoneOrder' => 5,
106
+ 'StandingAuth' => 6,
107
+ 'ECommerce' => 7
108
+ }
109
+
110
+ CARD_INPUT_CODE = {
111
+ 'Default' => 0,
112
+ 'Unknown' => 1,
113
+ 'MagstripeRead' => 2,
114
+ 'ContactlessMagstripeRead' => 3,
115
+ 'ManualKeyed' => 4,
116
+ 'ManualKeyedMagstripeFailure' => 5,
117
+ 'ChipRead' => 6,
118
+ 'ContactlessChipRead' => 7,
119
+ 'ManualKeyedChipReadFailure' => 8,
120
+ 'MagstripeReadChipReadFailure' => 9,
121
+ 'MagstripeReadNonTechnicalFallback' => 10
122
+ }
123
+
124
+ CVV_PRESENCE_CODE = {
125
+ 'UseDefault' => 0,
126
+ 'NotProvided' => 1,
127
+ 'Provided' => 2,
128
+ 'Illegible' => 3,
129
+ 'CustomerIllegible' => 4
130
+ }
131
+
132
+ TERMINAL_CAPABILITY_CODE = {
133
+ 'Default' => 0,
134
+ 'Unknown' => 1,
135
+ 'NoTerminal' => 2,
136
+ 'MagstripeReader' => 3,
137
+ 'ContactlessMagstripeReader' => 4,
138
+ 'KeyEntered' => 5,
139
+ 'ChipReader' => 6,
140
+ 'ContactlessChipReader' => 7
141
+ }
142
+
143
+ TERMINAL_ENVIRONMENT_CODE = {
144
+ 'Default' => 0,
145
+ 'NoTerminal' => 1,
146
+ 'LocalAttended' => 2,
147
+ 'LocalUnattended' => 3,
148
+ 'RemoteAttended' => 4,
149
+ 'RemoteUnattended' => 5,
150
+ 'ECommerce' => 6
151
+ }
152
+
153
+ def initialize(options = {})
154
+ requires!(options, :account_id, :account_token, :application_id, :acceptor_id, :application_name, :application_version)
155
+ super
156
+ end
157
+
158
+ def purchase(money, payment, options = {})
159
+ action = payment.is_a?(Check) ? 'CheckSale' : 'CreditCardSale'
160
+ eci = parse_eci(payment)
161
+
162
+ request = build_xml_request do |xml|
163
+ xml.send(action, xmlns: live_url) do
164
+ add_credentials(xml)
165
+ add_payment_method(xml, payment)
166
+ add_transaction(xml, money, options, eci)
167
+ add_terminal(xml, options, eci)
168
+ add_address(xml, options)
169
+ add_lodging(xml, options)
170
+ end
171
+ end
172
+
173
+ commit(request, money, payment)
174
+ end
175
+
176
+ def authorize(money, payment, options = {})
177
+ eci = parse_eci(payment)
178
+
179
+ request = build_xml_request do |xml|
180
+ xml.CreditCardAuthorization(xmlns: live_url) do
181
+ add_credentials(xml)
182
+ add_payment_method(xml, payment)
183
+ add_transaction(xml, money, options, eci)
184
+ add_terminal(xml, options, eci)
185
+ add_address(xml, options)
186
+ add_lodging(xml, options)
187
+ end
188
+ end
189
+
190
+ commit(request, money, payment)
191
+ end
192
+
193
+ def capture(money, authorization, options = {})
194
+ trans_id, _, eci = authorization.split('|')
195
+ options[:trans_id] = trans_id
196
+
197
+ request = build_xml_request do |xml|
198
+ xml.CreditCardAuthorizationCompletion(xmlns: live_url) do
199
+ add_credentials(xml)
200
+ add_transaction(xml, money, options, eci)
201
+ add_terminal(xml, options, eci)
202
+ end
203
+ end
204
+
205
+ commit(request, money)
206
+ end
207
+
208
+ def refund(money, authorization, options = {})
209
+ trans_id, _, eci = authorization.split('|')
210
+ options[:trans_id] = trans_id
211
+
212
+ request = build_xml_request do |xml|
213
+ xml.CreditCardReturn(xmlns: live_url) do
214
+ add_credentials(xml)
215
+ add_transaction(xml, money, options, eci)
216
+ add_terminal(xml, options, eci)
217
+ end
218
+ end
219
+
220
+ commit(request, money)
221
+ end
222
+
223
+ def credit(money, payment, options = {})
224
+ eci = parse_eci(payment)
225
+
226
+ request = build_xml_request do |xml|
227
+ xml.CreditCardCredit(xmlns: live_url) do
228
+ add_credentials(xml)
229
+ add_payment_method(xml, payment)
230
+ add_transaction(xml, money, options, eci)
231
+ add_terminal(xml, options, eci)
232
+ end
233
+ end
234
+
235
+ commit(request, money, payment)
236
+ end
237
+
238
+ def void(authorization, options = {})
239
+ trans_id, trans_amount, eci = authorization.split('|')
240
+ options.merge!({ trans_id: trans_id, trans_amount: trans_amount, reversal_type: 1 })
241
+
242
+ request = build_xml_request do |xml|
243
+ xml.CreditCardReversal(xmlns: live_url) do
244
+ add_credentials(xml)
245
+ add_transaction(xml, trans_amount, options, eci)
246
+ add_terminal(xml, options, eci)
247
+ end
248
+ end
249
+
250
+ commit(request, trans_amount)
251
+ end
252
+
253
+ def store(payment, options = {})
254
+ request = build_xml_request do |xml|
255
+ xml.PaymentAccountCreate(xmlns: SERVICE_LIVE_URL) do
256
+ add_credentials(xml)
257
+ add_payment_method(xml, payment)
258
+ add_payment_account(xml, payment, options[:payment_account_reference_number] || SecureRandom.hex(20))
259
+ add_address(xml, options)
260
+ end
261
+ end
262
+
263
+ commit(request, payment, nil, :store)
264
+ end
265
+
266
+ def verify(payment, options = {})
267
+ eci = parse_eci(payment)
268
+
269
+ request = build_xml_request do |xml|
270
+ xml.CreditCardAVSOnly(xmlns: live_url) do
271
+ add_credentials(xml)
272
+ add_payment_method(xml, payment)
273
+ add_transaction(xml, 0, options, eci)
274
+ add_terminal(xml, options, eci)
275
+ add_address(xml, options)
276
+ end
277
+ end
278
+
279
+ commit(request)
280
+ end
281
+
282
+ def supports_scrubbing?
283
+ true
284
+ end
285
+
286
+ def scrub(transcript)
287
+ transcript.
288
+ gsub(%r((<AccountToken>).+?(</AccountToken>))i, '\1[FILTERED]\2').
289
+ gsub(%r((<CardNumber>).+?(</CardNumber>))i, '\1[FILTERED]\2').
290
+ gsub(%r((<CVV>).+?(</CVV>))i, '\1[FILTERED]\2').
291
+ gsub(%r((<AccountNumber>).+?(</AccountNumber>))i, '\1[FILTERED]\2').
292
+ gsub(%r((<RoutingNumber>).+?(</RoutingNumber>))i, '\1[FILTERED]\2')
293
+ end
294
+
295
+ private
296
+
297
+ def add_credentials(xml)
298
+ xml.Credentials do
299
+ xml.AccountID @options[:account_id]
300
+ xml.AccountToken @options[:account_token]
301
+ xml.AcceptorID @options[:acceptor_id]
302
+ end
303
+ xml.Application do
304
+ xml.ApplicationID @options[:application_id]
305
+ xml.ApplicationName @options[:application_name]
306
+ xml.ApplicationVersion @options[:application_version]
307
+ end
308
+ end
309
+
310
+ def add_payment_method(xml, payment)
311
+ if payment.is_a?(String)
312
+ add_payment_account_id(xml, payment)
313
+ elsif payment.is_a?(Check)
314
+ add_echeck(xml, payment)
315
+ elsif payment.is_a?(NetworkTokenizationCreditCard)
316
+ add_network_tokenization_card(xml, payment)
317
+ else
318
+ add_credit_card(xml, payment)
319
+ end
320
+ end
321
+
322
+ def add_payment_account(xml, payment, payment_account_reference_number)
323
+ xml.PaymentAccount do
324
+ xml.PaymentAccountType payment_account_type(payment)
325
+ xml.PaymentAccountReferenceNumber payment_account_reference_number
326
+ end
327
+ end
328
+
329
+ def add_payment_account_id(xml, payment)
330
+ xml.PaymentAccount do
331
+ xml.PaymentAccountID payment
332
+ end
333
+ end
334
+
335
+ def add_transaction(xml, money, options = {}, network_token_eci = nil)
336
+ xml.Transaction do
337
+ xml.ReversalType REVERSAL_TYPE[options[:reversal_type]] || options[:reversal_type] if options[:reversal_type]
338
+ xml.TransactionID options[:trans_id] if options[:trans_id]
339
+ xml.TransactionAmount amount(money.to_i) if money
340
+ xml.MarketCode market_code(money, options, network_token_eci) if options[:market_code] || money
341
+ xml.ReferenceNumber options[:order_id].present? ? options[:order_id][0, 50] : SecureRandom.hex(20)
342
+ xml.TicketNumber options[:ticket_number] || rand(1..999999)
343
+ xml.MerchantSuppliedTransactionID options[:merchant_supplied_transaction_id] if options[:merchant_supplied_transaction_id]
344
+ xml.PaymentType PAYMENT_TYPE[options[:payment_type]] || options[:payment_type] if options[:payment_type]
345
+ xml.SubmissionType SUBMISSION_TYPE[options[:submission_type]] || options[:submission_type] if options[:submission_type]
346
+ xml.DuplicateCheckDisableFlag 1 if options[:duplicate_check_disable_flag].to_s == 'true' || options[:duplicate_override_flag].to_s == 'true'
347
+ end
348
+ end
349
+
350
+ def parse_eci(payment)
351
+ return nil unless payment.is_a?(NetworkTokenizationCreditCard)
352
+
353
+ if (eci = payment.eci)
354
+ eci = eci[0] == '0' ? eci.sub!(/^0/, '') : eci
355
+ return eci
356
+ else
357
+ payment.brand == 'american_express' ? '9' : '6'
358
+ end
359
+ end
360
+
361
+ def market_code(money, options, network_token_eci)
362
+ return 3 if network_token_eci
363
+
364
+ MARKET_CODE[options[:market_code]] || options[:market_code] || 0
365
+ end
366
+
367
+ def add_lodging(xml, options)
368
+ if options[:lodging]
369
+ lodging = parse_lodging(options[:lodging])
370
+ xml.ExtendedParameters do
371
+ xml.Lodging do
372
+ xml.LodgingAgreementNumber lodging[:agreement_number] if lodging[:agreement_number]
373
+ xml.LodgingCheckInDate lodging[:check_in_date] if lodging[:check_in_date]
374
+ xml.LodgingCheckOutDate lodging[:check_out_date] if lodging[:check_out_date]
375
+ xml.LodgingRoomAmount lodging[:room_amount] if lodging[:room_amount]
376
+ xml.LodgingRoomTax lodging[:room_tax] if lodging[:room_tax]
377
+ xml.LodgingNoShowIndicator lodging[:no_show_indicator] if lodging[:no_show_indicator]
378
+ xml.LodgingDuration lodging[:duration] if lodging[:duration]
379
+ xml.LodgingCustomerName lodging[:customer_name] if lodging[:customer_name]
380
+ xml.LodgingClientCode lodging[:client_code] if lodging[:client_code]
381
+ xml.LodgingExtraChargesDetail lodging[:extra_charges_detail] if lodging[:extra_charges_detail]
382
+ xml.LodgingExtraChargesAmounts lodging[:extra_charges_amounts] if lodging[:extra_charges_amounts]
383
+ xml.LodgingPrestigiousPropertyCode lodging[:prestigious_property_code] if lodging[:prestigious_property_code]
384
+ xml.LodgingSpecialProgramCode lodging[:special_program_code] if lodging[:special_program_code]
385
+ xml.LodgingChargeType lodging[:charge_type] if lodging[:charge_type]
386
+ end
387
+ end
388
+ end
389
+ end
390
+
391
+ def add_terminal(xml, options, network_token_eci = nil)
392
+ options = parse_terminal(options)
393
+
394
+ xml.Terminal do
395
+ xml.TerminalID options[:terminal_id] || '01'
396
+ xml.TerminalType options[:terminal_type] if options[:terminal_type]
397
+ xml.CardPresentCode options[:card_present_code] || 0
398
+ xml.CardholderPresentCode options[:card_holder_present_code] || 0
399
+ xml.CardInputCode options[:card_input_code] || 0
400
+ xml.CVVPresenceCode options[:cvv_presence_code] || 0
401
+ xml.TerminalCapabilityCode options[:terminal_capability_code] || 0
402
+ xml.TerminalEnvironmentCode options[:terminal_environment_code] || 0
403
+ xml.MotoECICode network_token_eci || 7
404
+ xml.PartialApprovedFlag options[:partial_approved_flag] if options[:partial_approved_flag]
405
+ end
406
+ end
407
+
408
+ def add_credit_card(xml, payment)
409
+ xml.Card do
410
+ xml.CardNumber payment.number
411
+ xml.ExpirationMonth format(payment.month, :two_digits)
412
+ xml.ExpirationYear format(payment.year, :two_digits)
413
+ xml.CardholderName "#{payment.first_name} #{payment.last_name}"
414
+ xml.CVV payment.verification_value
415
+ end
416
+ end
417
+
418
+ def add_echeck(xml, payment)
419
+ xml.DemandDepositAccount do
420
+ xml.AccountNumber payment.account_number
421
+ xml.RoutingNumber payment.routing_number
422
+ xml.DDAAccountType payment.account_type == 'checking' ? 0 : 1
423
+ end
424
+ end
425
+
426
+ def add_network_tokenization_card(xml, payment)
427
+ xml.Card do
428
+ xml.CardNumber payment.number
429
+ xml.ExpirationMonth format(payment.month, :two_digits)
430
+ xml.ExpirationYear format(payment.year, :two_digits)
431
+ xml.CardholderName "#{payment.first_name} #{payment.last_name}"
432
+ xml.Cryptogram payment.payment_cryptogram
433
+ xml.WalletType NETWORK_TOKEN_TYPE[payment.source]
434
+ end
435
+ end
436
+
437
+ def add_address(xml, options)
438
+ address = address = options[:billing_address] || options[:address]
439
+ shipping_address = options[:shipping_address]
440
+
441
+ if address || shipping_address
442
+ xml.Address do
443
+ if address
444
+ address[:email] ||= options[:email]
445
+
446
+ xml.BillingAddress1 address[:address1] if address[:address1]
447
+ xml.BillingAddress2 address[:address2] if address[:address2]
448
+ xml.BillingCity address[:city] if address[:city]
449
+ xml.BillingState address[:state] if address[:state]
450
+ xml.BillingZipcode address[:zip] if address[:zip]
451
+ xml.BillingEmail address[:email] if address[:email]
452
+ xml.BillingPhone address[:phone_number] if address[:phone_number]
453
+ end
454
+
455
+ if shipping_address
456
+ xml.ShippingAddress1 shipping_address[:address1] if shipping_address[:address1]
457
+ xml.ShippingAddress2 shipping_address[:address2] if shipping_address[:address2]
458
+ xml.ShippingCity shipping_address[:city] if shipping_address[:city]
459
+ xml.ShippingState shipping_address[:state] if shipping_address[:state]
460
+ xml.ShippingZipcode shipping_address[:zip] if shipping_address[:zip]
461
+ xml.ShippingEmail shipping_address[:email] if shipping_address[:email]
462
+ xml.ShippingPhone shipping_address[:phone_number] if shipping_address[:phone_number]
463
+ end
464
+ end
465
+ end
466
+ end
467
+
468
+ def parse(xml)
469
+ response = {}
470
+
471
+ doc = Nokogiri::XML(xml)
472
+ doc.remove_namespaces!
473
+ root = doc.root.xpath('//response/*')
474
+
475
+ root = doc.root.xpath('//Response/*') if root.empty?
476
+
477
+ root.each do |node|
478
+ if node.elements.empty?
479
+ response[node.name.downcase] = node.text
480
+ else
481
+ node_name = node.name.downcase
482
+ response[node_name] = {}
483
+
484
+ node.elements.each do |childnode|
485
+ response[node_name][childnode.name.downcase] = childnode.text
486
+ end
487
+ end
488
+ end
489
+
490
+ response
491
+ end
492
+
493
+ def parse_lodging(lodging)
494
+ lodging[:prestigious_property_code] = LODGING_PPC[lodging[:prestigious_property_code]] || lodging[:prestigious_property_code] if lodging[:prestigious_property_code]
495
+ lodging[:special_program_code] = LODGING_SPC[lodging[:special_program_code]] || lodging[:special_program_code] if lodging[:special_program_code]
496
+ lodging[:charge_type] = LODGING_CHARGE_TYPE[lodging[:charge_type]] || lodging[:charge_type] if lodging[:charge_type]
497
+
498
+ lodging
499
+ end
500
+
501
+ def parse_terminal(options)
502
+ options[:terminal_type] = TERMINAL_TYPE[options[:terminal_type]] || options[:terminal_type]
503
+ options[:card_present_code] = CARD_PRESENT_CODE[options[:card_present_code]] || options[:card_present_code]
504
+ options[:card_holder_present_code] = CARD_HOLDER_PRESENT_CODE[options[:card_holder_present_code]] || options[:card_holder_present_code]
505
+ options[:card_input_code] = CARD_INPUT_CODE[options[:card_input_code]] || options[:card_input_code]
506
+ options[:cvv_presence_code] = CVV_PRESENCE_CODE[options[:cvv_presence_code]] || options[:cvv_presence_code]
507
+ options[:terminal_capability_code] = TERMINAL_CAPABILITY_CODE[options[:terminal_capability_code]] || options[:terminal_capability_code]
508
+ options[:terminal_environment_code] = TERMINAL_ENVIRONMENT_CODE[options[:terminal_environment_code]] || options[:terminal_environment_code]
509
+
510
+ options
511
+ end
512
+
513
+ def commit(xml, amount = nil, payment = nil, action = nil)
514
+ response = parse(ssl_post(url(action), xml, headers))
515
+ success = success_from(response)
516
+
517
+ Response.new(
518
+ success,
519
+ message_from(response),
520
+ response,
521
+ authorization: authorization_from(action, response, amount, payment),
522
+ avs_result: success ? avs_from(response) : nil,
523
+ cvv_result: success ? cvv_from(response) : nil,
524
+ test: test?
525
+ )
526
+ end
527
+
528
+ def authorization_from(action, response, amount, payment)
529
+ return response.dig('paymentaccount', 'paymentaccountid') if action == :store
530
+
531
+ if response['transaction']
532
+ authorization = "#{response.dig('transaction', 'transactionid')}|#{amount}"
533
+ authorization << "|#{parse_eci(payment)}" if parse_eci(payment)
534
+ authorization
535
+ end
536
+ end
537
+
538
+ def success_from(response)
539
+ response['expressresponsecode'] == '0'
540
+ end
541
+
542
+ def message_from(response)
543
+ response['expressresponsemessage']
544
+ end
545
+
546
+ def avs_from(response)
547
+ AVSResult.new(code: response['card']['avsresponsecode']) if response['card']
548
+ end
549
+
550
+ def cvv_from(response)
551
+ CVVResult.new(response['card']['cvvresponsecode']) if response['card']
552
+ end
553
+
554
+ def build_xml_request(&block)
555
+ builder = Nokogiri::XML::Builder.new(encoding: 'UTF-8', &block)
556
+
557
+ builder.to_xml
558
+ end
559
+
560
+ def payment_account_type(payment)
561
+ return 0 unless payment.is_a?(Check)
562
+
563
+ if payment.account_type == 'checking'
564
+ 1
565
+ elsif payment.account_type == 'savings'
566
+ 2
567
+ else
568
+ 3
569
+ end
570
+ end
571
+
572
+ def url(action)
573
+ if action == :store
574
+ test? ? SERVICE_TEST_URL : SERVICE_LIVE_URL
575
+ else
576
+ test? ? test_url : live_url
577
+ end
578
+ end
579
+
580
+ def headers
581
+ {
582
+ 'Content-Type' => 'text/xml'
583
+ }
584
+ end
585
+ end
586
+ end
587
+ end
@@ -194,11 +194,15 @@ module ActiveMerchant #:nodoc:
194
194
 
195
195
  response = parse(ssl_post(self.live_url, post_data(trx_type, post)))
196
196
 
197
- Response.new(response[:response].to_i == SUCCESS, message_from(response), response,
197
+ Response.new(
198
+ response[:response].to_i == SUCCESS,
199
+ message_from(response),
200
+ response,
198
201
  test: test?,
199
202
  authorization: response[:transactionid],
200
203
  avs_result: { code: response[:avsresponse] },
201
- cvv_result: response[:cvvresponse])
204
+ cvv_result: response[:cvvresponse]
205
+ )
202
206
  end
203
207
 
204
208
  def message_from(response)
@@ -136,11 +136,15 @@ module ActiveMerchant #:nodoc:
136
136
 
137
137
  response = parse(ssl_post(test? ? self.test_url : self.live_url, post_data(parameters)))
138
138
 
139
- Response.new(response['result'] == APPROVED, message_from(response), response,
139
+ Response.new(
140
+ response['result'] == APPROVED,
141
+ message_from(response),
142
+ response,
140
143
  test: @options[:test] || test?,
141
144
  authorization: authorization_from(response),
142
145
  avs_result: { code: response['avs_response'] },
143
- cvv_result: response['cvv2_response'])
146
+ cvv_result: response['cvv2_response']
147
+ )
144
148
  end
145
149
 
146
150
  def authorization_from(response)
@@ -143,12 +143,12 @@ module ActiveMerchant #:nodoc:
143
143
  end
144
144
 
145
145
  def generate_purchase_number_stamp
146
- Time.now.to_f.to_s.delete('.')[1..10] + rand(99).to_s
146
+ rand(('9' * 12).to_i).to_s.center(12, rand(9).to_s)
147
147
  end
148
148
 
149
149
  def commit(action, params, options = {})
150
150
  raw_response = ssl_request(method(action), url(action, params, options), params.to_json, headers)
151
- response = parse(raw_response)
151
+ response = parse(raw_response).merge('purchaseNumber' => params[:purchaseNumber])
152
152
  rescue ResponseError => e
153
153
  raw_response = e.response.body
154
154
  response_error(raw_response, options, action)
@@ -137,7 +137,7 @@ module ActiveMerchant #:nodoc:
137
137
  card_number = payment.number
138
138
  cvv = payment.verification_value
139
139
 
140
- payload = { card_number: card_number, 'cvv': cvv }.to_json
140
+ payload = { card_number: card_number, cvv: cvv }.to_json
141
141
 
142
142
  encryption_key = @encryption_key || OpenSSL::PKey::RSA.new(one_time_public_key)
143
143
 
@@ -158,10 +158,10 @@ module ActiveMerchant #:nodoc:
158
158
  url = build_request_url(action)
159
159
  begin
160
160
  response = parse(ssl_post(url, post_data(parameters)))
161
- rescue ResponseError => response
161
+ rescue ResponseError => e
162
162
  # Errors are returned with helpful data,
163
163
  # but get filtered out by `ssl_post` because of their HTTP status.
164
- response = parse(response.response.body)
164
+ response = parse(e.response.body)
165
165
  end
166
166
 
167
167
  Response.new(
@@ -179,11 +179,15 @@ module ActiveMerchant #:nodoc:
179
179
  message = response[:Message]
180
180
  authorization = response[:GuWID]
181
181
 
182
- Response.new(success, message, response,
182
+ Response.new(
183
+ success,
184
+ message,
185
+ response,
183
186
  test: test?,
184
187
  authorization: authorization,
185
188
  avs_result: { code: avs_code(response, options) },
186
- cvv_result: response[:CVCResponseCode])
189
+ cvv_result: response[:CVCResponseCode]
190
+ )
187
191
  rescue ResponseError => e
188
192
  if e.response.code == '401'
189
193
  return Response.new(false, 'Invalid Login')
@@ -405,7 +409,7 @@ module ActiveMerchant #:nodoc:
405
409
  'N' => 'I', # CSC Match
406
410
  'U' => 'U', # Data Not Checked
407
411
  'Y' => 'D', # All Data Matched
408
- 'Z' => 'P', # CSC and Postcode Matched
412
+ 'Z' => 'P' # CSC and Postcode Matched
409
413
  }
410
414
 
411
415
  # Amex have different AVS response codes to visa etc