activemerchant 1.62.0 → 1.79.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +420 -2
  3. data/README.md +1 -2
  4. data/lib/active_merchant/billing/credit_card.rb +13 -14
  5. data/lib/active_merchant/billing/credit_card_methods.rb +3 -1
  6. data/lib/active_merchant/billing/gateway.rb +25 -9
  7. data/lib/active_merchant/billing/gateways/adyen.rb +299 -0
  8. data/lib/active_merchant/billing/gateways/authorize_net.rb +168 -56
  9. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +4 -2
  10. data/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb +65 -22
  11. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +87 -7
  12. data/lib/active_merchant/billing/gateways/beanstream.rb +2 -0
  13. data/lib/active_merchant/billing/gateways/blue_snap.rb +3 -8
  14. data/lib/active_merchant/billing/gateways/borgun.rb +10 -10
  15. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +1 -0
  16. data/lib/active_merchant/billing/gateways/braintree_blue.rb +49 -15
  17. data/lib/active_merchant/billing/gateways/card_connect.rb +286 -0
  18. data/lib/active_merchant/billing/gateways/card_stream.rb +97 -2
  19. data/lib/active_merchant/billing/gateways/cardprocess.rb +254 -0
  20. data/lib/active_merchant/billing/gateways/cashnet.rb +14 -2
  21. data/lib/active_merchant/billing/gateways/cenpos.rb +1 -1
  22. data/lib/active_merchant/billing/gateways/checkout.rb +1 -1
  23. data/lib/active_merchant/billing/gateways/checkout_v2.rb +44 -14
  24. data/lib/active_merchant/billing/gateways/citrus_pay.rb +0 -1
  25. data/lib/active_merchant/billing/gateways/clearhaus.rb +0 -2
  26. data/lib/active_merchant/billing/gateways/conekta.rb +4 -4
  27. data/lib/active_merchant/billing/gateways/creditcall.rb +71 -9
  28. data/lib/active_merchant/billing/gateways/credorax.rb +117 -5
  29. data/lib/active_merchant/billing/gateways/culqi.rb +279 -0
  30. data/lib/active_merchant/billing/gateways/cyber_source.rb +54 -15
  31. data/lib/active_merchant/billing/gateways/data_cash.rb +12 -0
  32. data/lib/active_merchant/billing/gateways/dibs.rb +0 -1
  33. data/lib/active_merchant/billing/gateways/digitzs.rb +292 -0
  34. data/lib/active_merchant/billing/gateways/ebanx.rb +296 -0
  35. data/lib/active_merchant/billing/gateways/elavon.rb +37 -95
  36. data/lib/active_merchant/billing/gateways/element.rb +11 -1
  37. data/lib/active_merchant/billing/gateways/fat_zebra.rb +3 -29
  38. data/lib/active_merchant/billing/gateways/first_pay.rb +12 -10
  39. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +37 -20
  40. data/lib/active_merchant/billing/gateways/forte.rb +0 -1
  41. data/lib/active_merchant/billing/gateways/global_collect.rb +55 -16
  42. data/lib/active_merchant/billing/gateways/global_transport.rb +16 -2
  43. data/lib/active_merchant/billing/gateways/hps.rb +12 -1
  44. data/lib/active_merchant/billing/gateways/iats_payments.rb +2 -2
  45. data/lib/active_merchant/billing/gateways/iveri.rb +251 -0
  46. data/lib/active_merchant/billing/gateways/jetpay.rb +12 -9
  47. data/lib/active_merchant/billing/gateways/jetpay_v2.rb +437 -0
  48. data/lib/active_merchant/billing/gateways/kushki.rb +227 -0
  49. data/lib/active_merchant/billing/gateways/linkpoint.rb +2 -2
  50. data/lib/active_merchant/billing/gateways/litle.rb +107 -30
  51. data/lib/active_merchant/billing/gateways/mercado_pago.rb +262 -0
  52. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +11 -0
  53. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +16 -4
  54. data/lib/active_merchant/billing/gateways/mercury.rb +14 -1
  55. data/lib/active_merchant/billing/gateways/migs.rb +28 -6
  56. data/lib/active_merchant/billing/gateways/moneris.rb +20 -12
  57. data/lib/active_merchant/billing/gateways/moneris_us.rb +11 -0
  58. data/lib/active_merchant/billing/gateways/mundipagg.rb +292 -0
  59. data/lib/active_merchant/billing/gateways/nab_transact.rb +4 -4
  60. data/lib/active_merchant/billing/gateways/netbanx.rb +60 -16
  61. data/lib/active_merchant/billing/gateways/netbilling.rb +0 -1
  62. data/lib/active_merchant/billing/gateways/nmi.rb +12 -1
  63. data/lib/active_merchant/billing/gateways/ogone.rb +1 -1
  64. data/lib/active_merchant/billing/gateways/omise.rb +9 -5
  65. data/lib/active_merchant/billing/gateways/openpay.rb +13 -0
  66. data/lib/active_merchant/billing/gateways/opp.rb +124 -114
  67. data/lib/active_merchant/billing/gateways/optimal_payment.rb +14 -1
  68. data/lib/active_merchant/billing/gateways/orbital.rb +83 -14
  69. data/lib/active_merchant/billing/gateways/pay_hub.rb +2 -2
  70. data/lib/active_merchant/billing/gateways/payeezy.rb +152 -46
  71. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +12 -2
  72. data/lib/active_merchant/billing/gateways/payflow.rb +24 -2
  73. data/lib/active_merchant/billing/gateways/payment_express.rb +3 -2
  74. data/lib/active_merchant/billing/gateways/paymentez.rb +276 -0
  75. data/lib/active_merchant/billing/gateways/paymill.rb +18 -10
  76. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +14 -0
  77. data/lib/active_merchant/billing/gateways/paypal.rb +0 -12
  78. data/lib/active_merchant/billing/gateways/paystation.rb +14 -1
  79. data/lib/active_merchant/billing/gateways/payu_latam.rb +102 -62
  80. data/lib/active_merchant/billing/gateways/pin.rb +5 -0
  81. data/lib/active_merchant/billing/gateways/pro_pay.rb +326 -0
  82. data/lib/active_merchant/billing/gateways/psigate.rb +12 -1
  83. data/lib/active_merchant/billing/gateways/qbms.rb +11 -0
  84. data/lib/active_merchant/billing/gateways/quickbooks.rb +10 -0
  85. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +21 -17
  86. data/lib/active_merchant/billing/gateways/quickpay.rb +3 -3
  87. data/lib/active_merchant/billing/gateways/qvalent.rb +60 -3
  88. data/lib/active_merchant/billing/gateways/realex.rb +16 -6
  89. data/lib/active_merchant/billing/gateways/redsys.rb +8 -2
  90. data/lib/active_merchant/billing/gateways/safe_charge.rb +262 -0
  91. data/lib/active_merchant/billing/gateways/sage.rb +8 -3
  92. data/lib/active_merchant/billing/gateways/sage_pay.rb +29 -13
  93. data/lib/active_merchant/billing/gateways/secure_net.rb +11 -1
  94. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +12 -0
  95. data/lib/active_merchant/billing/gateways/smart_ps.rb +1 -1
  96. data/lib/active_merchant/billing/gateways/spreedly_core.rb +53 -7
  97. data/lib/active_merchant/billing/gateways/stripe.rb +84 -26
  98. data/lib/active_merchant/billing/gateways/tns.rb +0 -1
  99. data/lib/active_merchant/billing/gateways/trans_first.rb +3 -2
  100. data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +61 -26
  101. data/lib/active_merchant/billing/gateways/trexle.rb +217 -0
  102. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +114 -9
  103. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +45 -22
  104. data/lib/active_merchant/billing/gateways/vanco.rb +1 -1
  105. data/lib/active_merchant/billing/gateways/wepay.rb +79 -46
  106. data/lib/active_merchant/billing/gateways/wirecard.rb +5 -4
  107. data/lib/active_merchant/billing/gateways/worldpay.rb +85 -20
  108. data/lib/active_merchant/billing/gateways/worldpay_us.rb +27 -8
  109. data/lib/active_merchant/billing/network_tokenization_credit_card.rb +1 -1
  110. data/lib/active_merchant/connection.rb +48 -12
  111. data/lib/active_merchant/net_http_ssl_connection.rb +9 -0
  112. data/lib/active_merchant/network_connection_retries.rb +6 -4
  113. data/lib/active_merchant/posts_data.rb +11 -1
  114. data/lib/active_merchant/version.rb +1 -1
  115. data/lib/active_merchant.rb +2 -5
  116. data/lib/certs/cacert.pem +85 -0
  117. data/lib/support/ssl_version.rb +87 -0
  118. metadata +25 -9
  119. data/lib/active_merchant/billing/gateways/barclays_epdq.rb +0 -314
@@ -29,7 +29,7 @@ module ActiveMerchant #:nodoc:
29
29
  }
30
30
 
31
31
  def initialize(options={})
32
- requires!(options, :merchant_id, :account_id, :api_login, :api_key)
32
+ requires!(options, :merchant_id, :account_id, :api_login, :api_key, :payment_country)
33
33
  super
34
34
  end
35
35
 
@@ -45,11 +45,11 @@ module ActiveMerchant #:nodoc:
45
45
  commit('auth', post)
46
46
  end
47
47
 
48
- def capture(authorization, options={})
48
+ def capture(amount, authorization, options={})
49
49
  post = {}
50
50
 
51
- add_credentials(post, 'SUBMIT_TRANSACTION')
52
- add_transaction_type(post, 'CAPTURE')
51
+ add_credentials(post, 'SUBMIT_TRANSACTION', options)
52
+ add_transaction_elements(post, 'CAPTURE', options)
53
53
  add_reference(post, authorization)
54
54
 
55
55
  commit('capture', post)
@@ -58,18 +58,18 @@ module ActiveMerchant #:nodoc:
58
58
  def void(authorization, options={})
59
59
  post = {}
60
60
 
61
- add_credentials(post, 'SUBMIT_TRANSACTION')
62
- add_transaction_type(post, 'VOID')
61
+ add_credentials(post, 'SUBMIT_TRANSACTION', options)
62
+ add_transaction_elements(post, 'VOID', options)
63
63
  add_reference(post, authorization)
64
64
 
65
65
  commit('void', post)
66
66
  end
67
67
 
68
- def refund(authorization, options={})
68
+ def refund(amount, authorization, options={})
69
69
  post = {}
70
70
 
71
- add_credentials(post, 'SUBMIT_TRANSACTION')
72
- add_transaction_type(post, 'REFUND')
71
+ add_credentials(post, 'SUBMIT_TRANSACTION', options)
72
+ add_transaction_elements(post, 'REFUND', options)
73
73
  add_reference(post, authorization)
74
74
 
75
75
  commit('refund', post)
@@ -77,7 +77,7 @@ module ActiveMerchant #:nodoc:
77
77
 
78
78
  def verify(credit_card, options={})
79
79
  minimum = MINIMUMS[options[:currency].upcase] if options[:currency]
80
- amount = minimum || 100
80
+ amount = options[:verify_amount] || minimum || 100
81
81
 
82
82
  MultiResponse.run(:use_first_response) do |r|
83
83
  r.process { authorize(amount, credit_card, options) }
@@ -115,20 +115,20 @@ module ActiveMerchant #:nodoc:
115
115
  private
116
116
 
117
117
  def auth_or_sale(post, transaction_type, amount, payment_method, options)
118
- add_credentials(post, 'SUBMIT_TRANSACTION')
119
- add_transaction_type(post, transaction_type)
118
+ add_credentials(post, 'SUBMIT_TRANSACTION', options)
119
+ add_transaction_elements(post, transaction_type, options)
120
120
  add_order(post, options)
121
- add_buyer(post, options)
121
+ add_buyer(post, payment_method, options)
122
122
  add_invoice(post, amount, options)
123
123
  add_signature(post)
124
124
  add_payment_method(post, payment_method, options)
125
- add_payer(post, options)
125
+ add_payer(post, payment_method, options)
126
126
  add_extra_parameters(post, options)
127
127
  end
128
128
 
129
- def add_credentials(post, command)
129
+ def add_credentials(post, command, options={})
130
130
  post[:test] = test? unless command == 'CREATE_TOKEN'
131
- post[:language] = 'en'
131
+ post[:language] = options[:language] || 'en'
132
132
  post[:command] = command
133
133
  merchant = {}
134
134
  merchant[:apiLogin] = @options[:api_login]
@@ -136,36 +136,87 @@ module ActiveMerchant #:nodoc:
136
136
  post[:merchant] = merchant
137
137
  end
138
138
 
139
- def add_transaction_type(post, type)
139
+ def add_transaction_elements(post, type, options)
140
140
  transaction = {}
141
+ transaction[:paymentCountry] = @options[:payment_country]
141
142
  transaction[:type] = type
143
+ transaction[:ipAddress] = options[:ip] || ''
144
+ transaction[:userAgent] = options[:user_agent] if options[:user_agent]
145
+ transaction[:cookie] = options[:cookie] if options[:cookie]
146
+ transaction[:deviceSessionId] = options[:device_session_id] if options[:device_session_id]
142
147
  post[:transaction] = transaction
143
148
  end
144
149
 
145
150
  def add_order(post, options)
146
151
  order = {}
147
152
  order[:accountId] = @options[:account_id]
153
+ order[:partnerId] = options[:partner_id] if options[:partner_id]
148
154
  order[:referenceCode] = options[:order_id] || generate_unique_id
149
- order[:description] = options[:description] || 'unspecified'
150
- order[:language] = 'en'
155
+ order[:description] = options[:description] || 'Compra en ' + @options[:merchant_id]
156
+ order[:language] = options[:language] || 'en'
157
+ order[:shippingAddress] = shipping_address_fields(options) if options[:shipping_address]
151
158
  post[:transaction][:order] = order
152
159
  end
153
160
 
154
- def add_buyer(post, options)
155
- if address = options[:shipping_address]
156
- buyer = {}
157
- buyer[:fullName] = address[:name]
158
- shipping_address = {}
159
- shipping_address[:street1] = address[:address1]
160
- shipping_address[:street2] = address[:address2]
161
- shipping_address[:city] = address[:city]
162
- shipping_address[:state] = address[:state]
163
- shipping_address[:country] = address[:country]
164
- shipping_address[:postalCode] = address[:zip]
165
- shipping_address[:phone] = address[:phone]
166
- buyer[:shippingAddress] = shipping_address
167
- post[:transaction][:order][:buyer] = buyer
161
+ def add_payer(post, payment_method, options)
162
+ address = options[:billing_address]
163
+ payer = {}
164
+ payer[:fullName] = payment_method.name.strip
165
+ payer[:contactPhone] = address[:phone] if (address && address[:phone])
166
+ payer[:dniNumber] = options[:dni_number] if options[:dni_number]
167
+ payer[:dniType] = options[:dni_type] if options[:dni_type]
168
+ payer[:emailAddress] = options[:email] if options[:email]
169
+ payer[:birthdate] = options[:birth_date] if options[:birth_date] && @options[:payment_country] == 'MX'
170
+ payer[:billingAddress] = billing_address_fields(options)
171
+ post[:transaction][:payer] = payer
172
+ end
173
+
174
+ def billing_address_fields(options)
175
+ return unless address = options[:billing_address]
176
+ billing_address = {}
177
+ billing_address[:street1] = address[:address1]
178
+ billing_address[:street2] = address[:address2]
179
+ billing_address[:city] = address[:city]
180
+ billing_address[:state] = address[:state]
181
+ billing_address[:country] = address[:country]
182
+ billing_address[:postalCode] = address[:zip] if @options[:payment_country] == 'MX'
183
+ billing_address[:phone] = address[:phone]
184
+ billing_address
185
+ end
186
+
187
+ def add_buyer(post, payment_method, options)
188
+ buyer = {}
189
+ if buyer_hash = options[:buyer]
190
+ buyer[:fullName] = buyer_hash[:name]
191
+ buyer[:dniNumber] = buyer_hash[:dni_number]
192
+ buyer[:dniType] = buyer_hash[:dni_type]
193
+ buyer[:cnpj] = buyer_hash[:cnpj] if @options[:payment_country] == 'BR'
194
+ buyer[:emailAddress] = buyer_hash[:email]
195
+ buyer[:contactPhone] = (options[:billing_address][:phone] if options[:billing_address]) || (options[:shipping_address][:phone] if options[:shipping_address]) || ''
196
+ buyer[:shippingAddress] = shipping_address_fields(options) if options[:shipping_address]
197
+ else
198
+ buyer[:fullName] = payment_method.name.strip
199
+ buyer[:dniNumber] = options[:dni_number]
200
+ buyer[:dniType] = options[:dni_type]
201
+ buyer[:cnpj] = options[:cnpj] if @options[:payment_country] == 'BR'
202
+ buyer[:emailAddress] = options[:email]
203
+ buyer[:contactPhone] = (options[:billing_address][:phone] if options[:billing_address]) || (options[:shipping_address][:phone] if options[:shipping_address]) || ''
204
+ buyer[:shippingAddress] = shipping_address_fields(options) if options[:shipping_address]
168
205
  end
206
+ post[:transaction][:order][:buyer] = buyer
207
+ end
208
+
209
+ def shipping_address_fields(options)
210
+ return unless address = options[:shipping_address]
211
+ shipping_address = {}
212
+ shipping_address[:street1] = address[:address1]
213
+ shipping_address[:street2] = address[:address2]
214
+ shipping_address[:city] = address[:city]
215
+ shipping_address[:state] = address[:state]
216
+ shipping_address[:country] = address[:country]
217
+ shipping_address[:postalCode] = address[:zip]
218
+ shipping_address[:phone] = address[:phone]
219
+ shipping_address
169
220
  end
170
221
 
171
222
  def add_invoice(post, money, options)
@@ -173,8 +224,18 @@ module ActiveMerchant #:nodoc:
173
224
  tx_value[:value] = amount(money)
174
225
  tx_value[:currency] = options[:currency] || currency(money)
175
226
 
227
+ tx_tax = {}
228
+ tx_tax[:value] = options[:tax] || '0'
229
+ tx_tax[:currency] = options[:currency] || currency(money)
230
+
231
+ tx_tax_return_base = {}
232
+ tx_tax_return_base[:value] = options[:tax_return_base] || '0'
233
+ tx_tax_return_base[:currency] = options[:currency] || currency(money)
234
+
176
235
  additional_values = {}
177
236
  additional_values[:TX_VALUE] = tx_value
237
+ additional_values[:TX_TAX] = tx_tax if @options[:payment_country] == 'CO'
238
+ additional_values[:TX_TAX_RETURN_BASE] = tx_tax_return_base if @options[:payment_country] == 'CO'
178
239
 
179
240
  post[:transaction][:order][:additionalValues] = additional_values
180
241
  end
@@ -207,7 +268,7 @@ module ActiveMerchant #:nodoc:
207
268
  else
208
269
  credit_card = {}
209
270
  credit_card[:number] = payment_method.number
210
- credit_card[:securityCode] = add_security_code(payment_method, options)
271
+ credit_card[:securityCode] = payment_method.verification_value || options[:cvv]
211
272
  credit_card[:expirationDate] = format(payment_method.year, :four_digits).to_s + '/' + format(payment_method.month, :two_digits).to_s
212
273
  credit_card[:name] = payment_method.name.strip
213
274
  credit_card[:processWithoutCvv2] = true if add_process_without_cvv2(payment_method, options)
@@ -216,37 +277,11 @@ module ActiveMerchant #:nodoc:
216
277
  end
217
278
  end
218
279
 
219
- def add_security_code(payment_method, options)
220
- return payment_method.verification_value unless payment_method.verification_value.blank?
221
- return options[:cvv] unless options[:cvv].blank?
222
- return "0000" if BRAND_MAP[payment_method.brand.to_s] == "AMEX"
223
- "000"
224
- end
225
-
226
280
  def add_process_without_cvv2(payment_method, options)
227
281
  return true if payment_method.verification_value.blank? && options[:cvv].blank?
228
282
  false
229
283
  end
230
284
 
231
- def add_payer(post, options)
232
- if address = options[:billing_address]
233
- payer = {}
234
- post[:transaction][:paymentCountry] = address[:country]
235
- payer[:fullName] = address[:name]
236
- payer[:contactPhone] = address[:phone]
237
- billing_address = {}
238
- billing_address[:street1] = address[:address1]
239
- billing_address[:street2] = address[:address2]
240
- billing_address[:city] = address[:city]
241
- billing_address[:state] = address[:state]
242
- billing_address[:country] = address[:country]
243
- billing_address[:postalCode] = address[:zip]
244
- billing_address[:phone] = address[:phone]
245
- payer[:billingAddress] = billing_address
246
- post[:transaction][:payer] = payer
247
- end
248
- end
249
-
250
285
  def add_extra_parameters(post, options)
251
286
  extra_parameters = {}
252
287
  extra_parameters[:INSTALLMENTS_NUMBER] = options[:installments_number] || 1
@@ -304,6 +339,7 @@ module ActiveMerchant #:nodoc:
304
339
  end
305
340
 
306
341
  def post_data(params)
342
+ params.merge(test: test?)
307
343
  params.to_json
308
344
  end
309
345
 
@@ -321,6 +357,8 @@ module ActiveMerchant #:nodoc:
321
357
  response["code"] == "SUCCESS" && response["creditCardToken"] && response["creditCardToken"]["creditCardTokenId"].present?
322
358
  when 'verify_credentials'
323
359
  response["code"] == "SUCCESS"
360
+ when 'refund', 'void'
361
+ response["code"] == "SUCCESS" && response["transactionResponse"] && (response["transactionResponse"]["state"] == "PENDING" || response["transactionResponse"]["state"] == "APPROVED")
324
362
  else
325
363
  response["code"] == "SUCCESS" && response["transactionResponse"] && (response["transactionResponse"]["state"] == "APPROVED")
326
364
  end
@@ -336,8 +374,10 @@ module ActiveMerchant #:nodoc:
336
374
  return "VERIFIED" if success
337
375
  "FAILED"
338
376
  else
339
- response_message = response["transactionResponse"]["responseMessage"] if response["transactionResponse"]
340
- response_code = response["transactionResponse"]["responseCode"] if response["transactionResponse"]
377
+ if response["transactionResponse"]
378
+ response_message = response["transactionResponse"]["responseMessage"]
379
+ response_code = response["transactionResponse"]["responseCode"] || response["transactionResponse"]["pendingReason"]
380
+ end
341
381
  return response_code if success
342
382
  response["error"] || response_message || response_code || "FAILED"
343
383
  end
@@ -29,6 +29,7 @@ module ActiveMerchant #:nodoc:
29
29
  add_creditcard(post, creditcard)
30
30
  add_address(post, creditcard, options)
31
31
  add_capture(post, options)
32
+ add_metadata(post, options)
32
33
 
33
34
  commit(:post, 'charges', post, options)
34
35
  end
@@ -141,6 +142,10 @@ module ActiveMerchant #:nodoc:
141
142
  end
142
143
  end
143
144
 
145
+ def add_metadata(post, options)
146
+ post[:metadata] = options[:metadata] if options[:metadata]
147
+ end
148
+
144
149
  def headers(params = {})
145
150
  result = {
146
151
  "Content-Type" => "application/json",
@@ -0,0 +1,326 @@
1
+ require 'nokogiri'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ class ProPayGateway < Gateway
6
+ self.test_url = 'https://xmltest.propay.com/API/PropayAPI.aspx'
7
+ self.live_url = 'https://epay.propay.com/api/propayapi.aspx'
8
+
9
+ self.supported_countries = ['US', 'CA']
10
+ self.default_currency = 'USD'
11
+ self.money_format = :cents
12
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover]
13
+
14
+ self.homepage_url = 'https://www.propay.com/'
15
+ self.display_name = 'ProPay'
16
+
17
+ STATUS_RESPONSE_CODES = {
18
+ "00" => "Success",
19
+ "20" => "Invalid username",
20
+ "21" => "Invalid transType",
21
+ "22" => "Invalid Currency Code",
22
+ "23" => "Invalid accountType",
23
+ "24" => "Invalid sourceEmail",
24
+ "25" => "Invalid firstName",
25
+ "26" => "Invalid mInitial",
26
+ "27" => "Invalid lastName",
27
+ "28" => "Invalid billAddr",
28
+ "29" => "Invalid aptNum",
29
+ "30" => "Invalid city",
30
+ "31" => "Invalid state",
31
+ "32" => "Invalid billZip",
32
+ "33" => "Invalid mailAddr",
33
+ "34" => "Invalid mailApt",
34
+ "35" => "Invalid mailCity",
35
+ "36" => "Invalid mailState",
36
+ "37" => "Invalid mailZip",
37
+ "38" => "Invalid dayPhone",
38
+ "39" => "Invalid evenPhone",
39
+ "40" => "Invalid ssn",
40
+ "41" => "Invalid dob",
41
+ "42" => "Invalid recEmail",
42
+ "43" => "Invalid knownAccount",
43
+ "44" => "Invalid amount",
44
+ "45" => "Invalid invNum",
45
+ "46" => "Invalid rtNum",
46
+ "47" => "Invalid accntNum",
47
+ "48" => "Invalid ccNum",
48
+ "49" => "Invalid expDate",
49
+ "50" => "Invalid cvv2",
50
+ "51" => "Invalid transNum and/or Unable to act perform actions on transNum due to funding",
51
+ "52" => "Invalid splitNum",
52
+ "53" => "A ProPay account with this email address already exists AND/OR User has no account number",
53
+ "54" => "A ProPay account with this social security number already exists",
54
+ "55" => "The email address provided does not correspond to a ProPay account.",
55
+ "56" => "Recipient’s email address shouldn’t have a ProPay account and does",
56
+ "57" => "Cannot settle transaction because it already expired",
57
+ "58" => "Credit card declined",
58
+ "59" => "Invalid Credential or IP address not allowed",
59
+ "60" => "Credit card authorization timed out; retry at a later time",
60
+ "61" => "Amount exceeds single transaction limit",
61
+ "62" => "Amount exceeds monthly volume limit",
62
+ "63" => "Insufficient funds in account",
63
+ "64" => "Over credit card use limit",
64
+ "65" => "Miscellaneous error",
65
+ "66" => "Denied a ProPay account",
66
+ "67" => "Unauthorized service requested",
67
+ "68" => "Account not affiliated",
68
+ "69" => "Duplicate invoice number (The same card was charged for the same amount with the same invoice number (including blank invoices) in a 1 minute period. Details about the original transaction are included whenever a 69 response is returned. These details include a repeat of the auth code, the original AVS response, and the original CVV response.)",
69
+ "70" => "Duplicate external ID",
70
+ "71" => "Account previously set up, but problem affiliating it with partner",
71
+ "72" => "The ProPay Account has already been upgraded to a Premium Account",
72
+ "73" => "Invalid Destination Account",
73
+ "74" => "Account or Trans Error",
74
+ "75" => "Money already pulled",
75
+ "76" => "Not Premium (used only for push/pull transactions)",
76
+ "77" => "Empty results",
77
+ "78" => "Invalid Authentication",
78
+ "79" => "Generic account status error",
79
+ "80" => "Invalid Password",
80
+ "81" => "Account Expired",
81
+ "82" => "InvalidUserID",
82
+ "83" => "BatchTransCountError",
83
+ "84" => "InvalidBeginDate",
84
+ "85" => "InvalidEndDate",
85
+ "86" => "InvalidExternalID",
86
+ "87" => "DuplicateUserID",
87
+ "88" => "Invalid track 1",
88
+ "89" => "Invalid track 2",
89
+ "90" => "Transaction already refunded",
90
+ "91" => "Duplicate Batch ID"
91
+ }
92
+
93
+ TRANSACTION_RESPONSE_CODES = {
94
+ "00" => "Success",
95
+ "1" => "Transaction blocked by issuer",
96
+ "4" => "Pick up card and deny transaction",
97
+ "5" => "Problem with the account",
98
+ "6" => "Customer requested stop to recurring payment",
99
+ "7" => "Customer requested stop to all recurring payments",
100
+ "8" => "Honor with ID only",
101
+ "9" => "Unpaid items on customer account",
102
+ "12" => "Invalid transaction",
103
+ "13" => "Amount Error",
104
+ "14" => "Invalid card number",
105
+ "15" => "No such issuer. Could not route transaction",
106
+ "16" => "Refund error",
107
+ "17" => "Over limit",
108
+ "19" => "Reenter transaction or the merchant account may be boarded incorrectly",
109
+ "25" => "Invalid terminal 41 Lost card",
110
+ "43" => "Stolen card",
111
+ "51" => "Insufficient funds",
112
+ "52" => "No such account",
113
+ "54" => "Expired card",
114
+ "55" => "Incorrect PIN",
115
+ "57" => "Bank does not allow this type of purchase",
116
+ "58" => "Credit card network does not allow this type of purchase for your merchant account.",
117
+ "61" => "Exceeds issuer withdrawal limit",
118
+ "62" => "Issuer does not allow this card to be charged for your business.",
119
+ "63" => "Security Violation",
120
+ "65" => "Activity limit exceeded",
121
+ "75" => "PIN tries exceeded",
122
+ "76" => "Unable to locate account",
123
+ "78" => "Account not recognized",
124
+ "80" => "Invalid Date",
125
+ "82" => "Invalid CVV2",
126
+ "83" => "Cannot verify the PIN",
127
+ "85" => "Service not supported for this card",
128
+ "93" => "Cannot complete transaction. Customer should call 800 number.",
129
+ "95" => "Misc Error Transaction failure",
130
+ "96" => "Issuer system malfunction or timeout.",
131
+ "97" => "Approved for a lesser amount. ProPay will not settle and consider this a decline.",
132
+ "98" => "Failure HV",
133
+ "99" => "Generic decline or unable to parse issuer response code"
134
+ }
135
+
136
+ def initialize(options={})
137
+ requires!(options, :cert_str)
138
+ super
139
+ end
140
+
141
+ def purchase(money, payment, options={})
142
+ request = build_xml_request do |xml|
143
+ add_invoice(xml, money, options)
144
+ add_payment(xml, payment, options)
145
+ add_address(xml, options)
146
+ add_account(xml, options)
147
+ add_recurring(xml, options)
148
+ xml.transType "04"
149
+ end
150
+
151
+ commit(request)
152
+ end
153
+
154
+ def authorize(money, payment, options={})
155
+ request = build_xml_request do |xml|
156
+ add_invoice(xml, money, options)
157
+ add_payment(xml, payment, options)
158
+ add_address(xml, options)
159
+ add_account(xml, options)
160
+ add_recurring(xml, options)
161
+ xml.transType "05"
162
+ end
163
+
164
+ commit(request)
165
+ end
166
+
167
+ def capture(money, authorization, options={})
168
+ request = build_xml_request do |xml|
169
+ add_invoice(xml, money, options)
170
+ add_account(xml, options)
171
+ xml.transNum authorization
172
+ xml.transType "06"
173
+ end
174
+
175
+ commit(request)
176
+ end
177
+
178
+ def refund(money, authorization, options={})
179
+ request = build_xml_request do |xml|
180
+ add_invoice(xml, money, options)
181
+ add_account(xml, options)
182
+ xml.transNum authorization
183
+ xml.transType "07"
184
+ end
185
+
186
+ commit(request)
187
+ end
188
+
189
+ def void(authorization, options={})
190
+ refund(nil, authorization, options)
191
+ end
192
+
193
+ def credit(money, payment, options={})
194
+ request = build_xml_request do |xml|
195
+ add_invoice(xml, money, options)
196
+ add_payment(xml, payment, options)
197
+ add_account(xml, options)
198
+ xml.transType "35"
199
+ end
200
+
201
+ commit(request)
202
+ end
203
+
204
+ def verify(credit_card, options={})
205
+ MultiResponse.run(:use_first_response) do |r|
206
+ r.process { authorize(100, credit_card, options) }
207
+ r.process(:ignore_result) { void(r.authorization, options) }
208
+ end
209
+ end
210
+
211
+ def supports_scrubbing?
212
+ true
213
+ end
214
+
215
+ def scrub(transcript)
216
+ transcript.
217
+ gsub(%r((<certStr>).+(</certStr>)), '\1[FILTERED]\2').
218
+ gsub(%r((<ccNum>).+(</ccNum>)), '\1[FILTERED]\2').
219
+ gsub(%r((<CVV2>).+(</CVV2>)), '\1[FILTERED]\2')
220
+ end
221
+
222
+ private
223
+
224
+ def add_payment(xml, payment, options)
225
+ xml.ccNum payment.number
226
+ xml.expDate "#{format(payment.month, :two_digits)}#{format(payment.year, :two_digits)}"
227
+ xml.CVV2 payment.verification_value
228
+ xml.cardholderName payment.name
229
+ end
230
+
231
+ def add_address(xml, options)
232
+ if address = options[:billing_address] || options[:address]
233
+ xml.addr address[:address1]
234
+ xml.aptNum address[:address2]
235
+ xml.city address[:city]
236
+ xml.state address[:state]
237
+ xml.zip address[:zip]
238
+ end
239
+ end
240
+
241
+ def add_account(xml, options)
242
+ xml.accountNum options[:account_num]
243
+ end
244
+
245
+ def add_invoice(xml, money, options)
246
+ xml.amount amount(money)
247
+ xml.currencyCode options[:currency] || currency(money)
248
+ xml.invNum options[:order_id] || SecureRandom.hex(25)
249
+ end
250
+
251
+ def add_recurring(xml, options)
252
+ xml.recurringPayment options[:recurring_payment]
253
+ end
254
+
255
+ def parse(body)
256
+ results = {}
257
+ xml = Nokogiri::XML(body)
258
+ resp = xml.xpath("//XMLResponse/XMLTrans")
259
+ resp.children.each do |element|
260
+ results[element.name.underscore.downcase.to_sym] = element.text
261
+ end
262
+ results
263
+ end
264
+
265
+ def commit(parameters)
266
+ url = (test? ? test_url : live_url)
267
+ response = parse(ssl_post(url, parameters))
268
+
269
+ Response.new(
270
+ success_from(response),
271
+ message_from(response),
272
+ response,
273
+ authorization: authorization_from(response),
274
+ avs_result: AVSResult.new(code: response[:avs]),
275
+ cvv_result: CVVResult.new(response[:cvv2_resp]),
276
+ test: test?,
277
+ error_code: error_code_from(response)
278
+ )
279
+ end
280
+
281
+ def success_from(response)
282
+ response[:status] == "00"
283
+ end
284
+
285
+ def message_from(response)
286
+ return "Success" if success_from(response)
287
+ message = STATUS_RESPONSE_CODES[response[:status]]
288
+ message += " - #{TRANSACTION_RESPONSE_CODES[response[:response_code]]}" if response[:response_code]
289
+
290
+ message
291
+ end
292
+
293
+ def authorization_from(response)
294
+ response[:trans_num]
295
+ end
296
+
297
+ def error_code_from(response)
298
+ unless success_from(response)
299
+ response[:status]
300
+ end
301
+ end
302
+
303
+ def build_xml_request
304
+ builder = Nokogiri::XML::Builder.new do |xml|
305
+ xml.XMLRequest do
306
+ xml.certStr @options[:cert_str]
307
+ xml.class_ "partner"
308
+ xml.XMLTrans do
309
+ yield(xml)
310
+ end
311
+ end
312
+ end
313
+
314
+ builder.to_xml
315
+ end
316
+ end
317
+
318
+ def underscore(camel_cased_word)
319
+ camel_cased_word.to_s.gsub(/::/, '/').
320
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
321
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
322
+ tr("-", "_").
323
+ downcase
324
+ end
325
+ end
326
+ end
@@ -35,7 +35,7 @@ module ActiveMerchant #:nodoc:
35
35
  # :email => 'jack@yahoo.com'
36
36
  # )
37
37
  class PsigateGateway < Gateway
38
- self.test_url = 'https://dev.psigate.com:7989/Messenger/XMLMessenger'
38
+ self.test_url = 'https://staging.psigate.com:17989/Messenger/XMLMessenger'
39
39
  self.live_url = 'https://secure.psigate.com:17934/Messenger/XMLMessenger'
40
40
 
41
41
  self.supported_cardtypes = [:visa, :master, :american_express]
@@ -86,6 +86,17 @@ module ActiveMerchant #:nodoc:
86
86
  commit(nil, nil, options)
87
87
  end
88
88
 
89
+ def supports_scrubbing?
90
+ true
91
+ end
92
+
93
+ def scrub(transcript)
94
+ transcript.
95
+ gsub(%r((<Passphrase>)[^<]*(</Passphrase>))i, '\1[FILTERED]\2').
96
+ gsub(%r((<CardNumber>)[^<]*(</CardNumber>))i, '\1[FILTERED]\2').
97
+ gsub(%r((<CardIDNumber>)[^<]*(</CardIDNumber>))i, '\1[FILTERED]\2')
98
+ end
99
+
89
100
  private
90
101
 
91
102
  def commit(money, creditcard, options = {})
@@ -113,6 +113,17 @@ module ActiveMerchant #:nodoc:
113
113
  commit(:query, nil, {})
114
114
  end
115
115
 
116
+ def supports_scrubbing?
117
+ true
118
+ end
119
+
120
+ def scrub(transcript)
121
+ transcript.
122
+ gsub(%r((<ConnectionTicket>)[^<]*(</ConnectionTicket>))i, '\1[FILTERED]\2').
123
+ gsub(%r((<CreditCardNumber>)[^<]*(</CreditCardNumber>))i, '\1[FILTERED]\2').
124
+ gsub(%r((<CardSecurityCode>)[^<]*(</CardSecurityCode>))i, '\1[FILTERED]\2')
125
+ end
126
+
116
127
  private
117
128
 
118
129
  def hosted?