activemerchant 1.49.0 → 1.50.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +47 -0
  3. data/CONTRIBUTORS +4 -0
  4. data/README.md +5 -1
  5. data/lib/active_merchant/billing/credit_card.rb +9 -0
  6. data/lib/active_merchant/billing/gateways/allied_wallet.rb +203 -0
  7. data/lib/active_merchant/billing/gateways/authorize_net.rb +17 -6
  8. data/lib/active_merchant/billing/gateways/beanstream.rb +4 -0
  9. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +0 -4
  10. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +4 -0
  11. data/lib/active_merchant/billing/gateways/bpoint.rb +277 -0
  12. data/lib/active_merchant/billing/gateways/cashnet.rb +19 -8
  13. data/lib/active_merchant/billing/gateways/cenpos.rb +15 -29
  14. data/lib/active_merchant/billing/gateways/conekta.rb +3 -2
  15. data/lib/active_merchant/billing/gateways/dibs.rb +206 -0
  16. data/lib/active_merchant/billing/gateways/fat_zebra.rb +19 -12
  17. data/lib/active_merchant/billing/gateways/merchant_partners.rb +245 -0
  18. data/lib/active_merchant/billing/gateways/netbilling.rb +1 -0
  19. data/lib/active_merchant/billing/gateways/omise.rb +319 -0
  20. data/lib/active_merchant/billing/gateways/optimal_payment.rb +5 -4
  21. data/lib/active_merchant/billing/gateways/orbital.rb +7 -0
  22. data/lib/active_merchant/billing/gateways/payu_in.rb +243 -0
  23. data/lib/active_merchant/billing/gateways/quickpay.rb +11 -357
  24. data/lib/active_merchant/billing/gateways/quickpay/quickpay_common.rb +188 -0
  25. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +240 -0
  26. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v4to7.rb +227 -0
  27. data/lib/active_merchant/billing/gateways/s5.rb +226 -0
  28. data/lib/active_merchant/billing/gateways/sage_pay.rb +7 -1
  29. data/lib/active_merchant/billing/gateways/secure_net.rb +1 -1
  30. data/lib/active_merchant/billing/gateways/stripe.rb +8 -5
  31. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +2 -2
  32. data/lib/active_merchant/billing/gateways/vanco.rb +280 -0
  33. data/lib/active_merchant/connection.rb +3 -0
  34. data/lib/active_merchant/version.rb +1 -1
  35. metadata +15 -27
  36. checksums.yaml.gz.sig +0 -2
  37. data.tar.gz.sig +0 -0
  38. data/lib/active_merchant/billing/gateways/adyen.rb +0 -209
  39. metadata.gz.sig +0 -1
@@ -269,17 +269,19 @@ module ActiveMerchant #:nodoc:
269
269
  def build_billing_details(xml, opts)
270
270
  xml.tag! 'billingDetails' do
271
271
  xml.tag! 'cardPayMethod', 'WEB'
272
- build_address(xml, opts[:billing_address], opts[:email])
272
+ build_address(xml, opts[:billing_address]) if opts[:billing_address]
273
+ xml.tag! 'email', opts[:email] if opts[:email]
273
274
  end
274
275
  end
275
276
 
276
277
  def build_shipping_details(xml, opts)
277
278
  xml.tag! 'shippingDetails' do
278
- build_address(xml, opts[:shipping_address], opts[:email])
279
+ build_address(xml, opts[:shipping_address])
280
+ xml.tag! 'email', opts[:email] if opts[:email]
279
281
  end if opts[:shipping_address].present?
280
282
  end
281
283
 
282
- def build_address(xml, addr, email=nil)
284
+ def build_address(xml, addr)
283
285
  if addr[:name]
284
286
  xml.tag! 'firstName', addr[:name].split(' ').first
285
287
  xml.tag! 'lastName' , addr[:name].split(' ').last
@@ -294,7 +296,6 @@ module ActiveMerchant #:nodoc:
294
296
  xml.tag! 'country', addr[:country] if addr[:country].present?
295
297
  xml.tag! 'zip' , addr[:zip] if addr[:zip].present?
296
298
  xml.tag! 'phone' , addr[:phone] if addr[:phone].present?
297
- xml.tag! 'email', email if email
298
299
  end
299
300
 
300
301
  def card_type(key)
@@ -196,6 +196,13 @@ module ActiveMerchant #:nodoc:
196
196
  commit(order, :authorize, options[:trace_number])
197
197
  end
198
198
 
199
+ def verify(creditcard, options = {})
200
+ MultiResponse.run(:use_first_response) do |r|
201
+ r.process { authorize(100, creditcard, options) }
202
+ r.process(:ignore_result) { void(r.authorization) }
203
+ end
204
+ end
205
+
199
206
  # AC – Authorization and Capture
200
207
  def purchase(money, creditcard, options = {})
201
208
  order = build_new_order_xml(AUTH_AND_CAPTURE, money, options) do |xml|
@@ -0,0 +1,243 @@
1
+ # encoding: utf-8
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ class PayuInGateway < Gateway
6
+ self.test_url = "https://test.payu.in/_payment"
7
+ self.live_url = "https://secure.payu.in/_payment"
8
+
9
+ TEST_INFO_URL = "https://test.payu.in/merchant/postservice.php?form=2"
10
+ LIVE_INFO_URL = "https://info.payu.in/merchant/postservice.php?form=2"
11
+
12
+ self.supported_countries = ['IN']
13
+ self.default_currency = 'INR'
14
+ self.supported_cardtypes = [:visa, :master, :american_express, :diners_club]
15
+
16
+ self.homepage_url = 'https://www.payu.in/'
17
+ self.display_name = 'PayU India'
18
+
19
+ def initialize(options={})
20
+ requires!(options, :key, :salt)
21
+ super
22
+ end
23
+
24
+ def purchase(money, payment, options={})
25
+ requires!(options, :order_id)
26
+
27
+ post = {}
28
+ add_invoice(post, money, options)
29
+ add_payment(post, payment)
30
+ add_addresses(post, options)
31
+ add_customer_data(post, options)
32
+ add_auth(post)
33
+
34
+ MultiResponse.run do |r|
35
+ r.process{commit(url("purchase"), post)}
36
+ if(r.params["enrolled"].to_s == "0")
37
+ r.process{commit(r.params["post_uri"], r.params["form_post_vars"])}
38
+ else
39
+ r.process{handle_3dsecure(r)}
40
+ end
41
+ end
42
+ end
43
+
44
+ def refund(money, authorization, options={})
45
+ raise ArgumentError, "Amount is required" unless money
46
+
47
+ post = {}
48
+
49
+ post[:command] = "cancel_refund_transaction"
50
+ post[:var1] = authorization
51
+ post[:var2] = generate_unique_id
52
+ post[:var3] = amount(money)
53
+
54
+ add_auth(post, :command, :var1)
55
+
56
+ commit(url("refund"), post)
57
+ end
58
+
59
+ def supports_scrubbing?
60
+ true
61
+ end
62
+
63
+ def scrub(transcript)
64
+ transcript.
65
+ gsub(/(ccnum=)[^&\n"]*(&|\n|"|$)/, '\1[FILTERED]\2').
66
+ gsub(/(ccvv=)[^&\n"]*(&|\n|"|$)/, '\1[FILTERED]\2').
67
+ gsub(/(card_hash=)[^&\n"]*(&|\n|"|$)/, '\1[FILTERED]\2').
68
+ gsub(/(ccnum":")[^"]*(")/, '\1[FILTERED]\2').
69
+ gsub(/(ccvv":")[^"]*(")/, '\1[FILTERED]\2')
70
+ end
71
+
72
+ private
73
+
74
+ PAYMENT_DIGEST_KEYS = %w(
75
+ txnid amount productinfo firstname email
76
+ udf1 udf2 udf3 udf4 udf5
77
+ bogus bogus bogus bogus bogus
78
+ )
79
+ def add_auth(post, *digest_keys)
80
+ post[:key] = @options[:key]
81
+ post[:txn_s2s_flow] = 1
82
+
83
+ digest_keys = PAYMENT_DIGEST_KEYS if digest_keys.empty?
84
+ digest = Digest::SHA2.new(512)
85
+ digest << @options[:key] << "|"
86
+ digest_keys.each do |key|
87
+ digest << (post[key.to_sym] || "") << "|"
88
+ end
89
+ digest << @options[:salt]
90
+ post[:hash] = digest.hexdigest
91
+ end
92
+
93
+ def add_customer_data(post, options)
94
+ post[:email] = clean(options[:email] || "unknown@example.com", nil, 50)
95
+ post[:phone] = clean((options[:billing_address] && options[:billing_address][:phone]) || "11111111111", :numeric, 50)
96
+ end
97
+
98
+ def add_addresses(post, options)
99
+ if options[:billing_address]
100
+ post[:address1] = clean(options[:billing_address][:address1], :text, 100)
101
+ post[:address2] = clean(options[:billing_address][:address2], :text, 100)
102
+ post[:city] = clean(options[:billing_address][:city], :text, 50)
103
+ post[:state] = clean(options[:billing_address][:state], :text, 50)
104
+ post[:country] = clean(options[:billing_address][:country], :text, 50)
105
+ post[:zipcode] = clean(options[:billing_address][:zip], :numeric, 20)
106
+ end
107
+
108
+ if options[:shipping_address]
109
+ if options[:shipping_address][:name]
110
+ first, *rest = options[:shipping_address][:name].split(/\s+/)
111
+ post[:shipping_firstname] = clean(first, :name, 60)
112
+ post[:shipping_lastname] = clean(rest.join(" "), :name, 20)
113
+ end
114
+ post[:shipping_address1] = clean(options[:shipping_address][:address1], :text, 100)
115
+ post[:shipping_address2] = clean(options[:shipping_address][:address2], :text, 100)
116
+ post[:shipping_city] = clean(options[:shipping_address][:city], :text, 50)
117
+ post[:shipping_state] = clean(options[:shipping_address][:state], :text, 50)
118
+ post[:shipping_country] = clean(options[:shipping_address][:country], :text, 50)
119
+ post[:shipping_zipcode] = clean(options[:shipping_address][:zip], :numeric, 20)
120
+ post[:shipping_phone] = clean(options[:shipping_address][:phone], :numeric, 50)
121
+ end
122
+ end
123
+
124
+ def add_invoice(post, money, options)
125
+ post[:amount] = amount(money)
126
+
127
+ post[:txnid] = clean(options[:order_id], :alphanumeric, 25)
128
+ post[:productinfo] = clean(options[:description] || "Purchase", nil, 100)
129
+
130
+ post[:surl] = "http://example.com"
131
+ post[:furl] = "http://example.com"
132
+ end
133
+
134
+ BRAND_MAP = {
135
+ visa: "VISA",
136
+ master: "MAST",
137
+ american_express: "AMEX",
138
+ diners_club: "DINR"
139
+ }
140
+
141
+ def add_payment(post, payment)
142
+ post[:pg] = "CC"
143
+ post[:firstname] = clean(payment.first_name, :name, 60)
144
+ post[:lastname] = clean(payment.last_name, :name, 20)
145
+
146
+ post[:bankcode] = BRAND_MAP[payment.brand.to_sym]
147
+ post[:ccnum] = payment.number
148
+ post[:ccvv] = payment.verification_value
149
+ post[:ccname] = payment.name
150
+ post[:ccexpmon] = format(payment.month, :two_digits)
151
+ post[:ccexpyr] = format(payment.year, :four_digits)
152
+ end
153
+
154
+ def clean(value, format, maxlength)
155
+ value ||= ""
156
+ value = case format
157
+ when :alphanumeric
158
+ value.gsub(/[^A-Za-z0-9]/, "")
159
+ when :name
160
+ value.gsub(/[^A-Za-z ]/, "")
161
+ when :numeric
162
+ value.gsub(/[^0-9]/, "")
163
+ when :text
164
+ value.gsub(/[^A-Za-z0-9@\-_\/\. ]/, "")
165
+ when nil
166
+ value
167
+ else
168
+ raise "Unknown format #{format} for #{value}"
169
+ end
170
+ value[0...maxlength]
171
+ end
172
+
173
+ def parse(body)
174
+ top = JSON.parse(body)
175
+
176
+ if result = top.delete("result")
177
+ result.split("&").inject({}) do |hash, string|
178
+ key, value = string.split("=")
179
+ hash[CGI.unescape(key).downcase] = CGI.unescape(value || "")
180
+ hash
181
+ end.each do |key, value|
182
+ if top[key]
183
+ top["result_#{key}"] = value
184
+ else
185
+ top[key] = value
186
+ end
187
+ end
188
+ end
189
+
190
+ if response = top.delete("response")
191
+ top.merge!(response)
192
+ end
193
+
194
+ top
195
+ end
196
+
197
+ def commit(url, parameters)
198
+ response = parse(ssl_post(url, post_data(parameters), "Accept-Encoding" => "identity"))
199
+
200
+ Response.new(
201
+ success_from(response),
202
+ message_from(response),
203
+ response,
204
+ authorization: authorization_from(response),
205
+ test: test?
206
+ )
207
+ end
208
+
209
+ def url(action)
210
+ case action
211
+ when "purchase"
212
+ (test? ? test_url : live_url)
213
+ else
214
+ (test? ? TEST_INFO_URL : LIVE_INFO_URL)
215
+ end
216
+ end
217
+
218
+ def success_from(response)
219
+ if response["result_status"]
220
+ (response["status"] == "success" && response["result_status"] == "success")
221
+ else
222
+ (response["status"] == "success" || response["status"].to_s == "1")
223
+ end
224
+ end
225
+
226
+ def message_from(response)
227
+ (response["error_message"] || response["error"] || response["msg"])
228
+ end
229
+
230
+ def authorization_from(response)
231
+ response["mihpayid"]
232
+ end
233
+
234
+ def post_data(parameters = {})
235
+ PostData.new.merge!(parameters).to_post_data
236
+ end
237
+
238
+ def handle_3dsecure(response)
239
+ Response.new(false, "3D-secure enrolled cards are not supported.")
240
+ end
241
+ end
242
+ end
243
+ end
@@ -1,371 +1,25 @@
1
1
  require 'rexml/document'
2
2
  require 'digest/md5'
3
3
 
4
+ require 'active_merchant/billing/gateways/quickpay/quickpay_v10'
5
+ require 'active_merchant/billing/gateways/quickpay/quickpay_v4to7'
6
+
4
7
  module ActiveMerchant #:nodoc:
5
8
  module Billing #:nodoc:
6
9
  class QuickpayGateway < Gateway
7
- self.live_url = self.test_url = 'https://secure.quickpay.dk/api'
8
-
9
- self.default_currency = 'DKK'
10
- self.money_format = :cents
11
- self.supported_cardtypes = [:dankort, :forbrugsforeningen, :visa, :master, :american_express, :diners_club, :jcb, :maestro]
12
- self.supported_countries = ['DE', 'DK', 'ES', 'FI', 'FR', 'FO', 'GB', 'IS', 'NO', 'SE']
13
- self.homepage_url = 'http://quickpay.net/'
14
- self.display_name = 'QuickPay'
15
-
16
- MD5_CHECK_FIELDS = {
17
- 3 => {
18
- :authorize => %w(protocol msgtype merchant ordernumber amount
19
- currency autocapture cardnumber expirationdate
20
- cvd cardtypelock testmode),
21
-
22
- :capture => %w(protocol msgtype merchant amount finalize transaction),
23
-
24
- :cancel => %w(protocol msgtype merchant transaction),
25
-
26
- :refund => %w(protocol msgtype merchant amount transaction),
27
-
28
- :subscribe => %w(protocol msgtype merchant ordernumber cardnumber
29
- expirationdate cvd cardtypelock description testmode),
30
-
31
- :recurring => %w(protocol msgtype merchant ordernumber amount
32
- currency autocapture transaction),
33
-
34
- :status => %w(protocol msgtype merchant transaction),
35
-
36
- :chstatus => %w(protocol msgtype merchant)
37
- },
38
-
39
- 4 => {
40
- :authorize => %w(protocol msgtype merchant ordernumber amount
41
- currency autocapture cardnumber expirationdate cvd
42
- cardtypelock testmode fraud_remote_addr
43
- fraud_http_accept fraud_http_accept_language
44
- fraud_http_accept_encoding fraud_http_accept_charset
45
- fraud_http_referer fraud_http_user_agent apikey),
46
-
47
- :capture => %w(protocol msgtype merchant amount finalize transaction apikey),
48
-
49
- :cancel => %w(protocol msgtype merchant transaction apikey),
50
-
51
- :refund => %w(protocol msgtype merchant amount transaction apikey),
52
-
53
- :subscribe => %w(protocol msgtype merchant ordernumber cardnumber
54
- expirationdate cvd cardtypelock description testmode
55
- fraud_remote_addr fraud_http_accept fraud_http_accept_language
56
- fraud_http_accept_encoding fraud_http_accept_charset
57
- fraud_http_referer fraud_http_user_agent apikey),
58
-
59
- :recurring => %w(protocol msgtype merchant ordernumber amount currency
60
- autocapture transaction apikey),
61
-
62
- :status => %w(protocol msgtype merchant transaction apikey),
63
-
64
- :chstatus => %w(protocol msgtype merchant apikey)
65
- },
66
-
67
- 5 => {
68
- :authorize => %w(protocol msgtype merchant ordernumber amount
69
- currency autocapture cardnumber expirationdate cvd
70
- cardtypelock testmode fraud_remote_addr
71
- fraud_http_accept fraud_http_accept_language
72
- fraud_http_accept_encoding fraud_http_accept_charset
73
- fraud_http_referer fraud_http_user_agent apikey),
74
-
75
- :capture => %w(protocol msgtype merchant amount finalize transaction apikey),
76
-
77
- :cancel => %w(protocol msgtype merchant transaction apikey),
78
-
79
- :refund => %w(protocol msgtype merchant amount transaction apikey),
80
-
81
- :subscribe => %w(protocol msgtype merchant ordernumber cardnumber
82
- expirationdate cvd cardtypelock description testmode
83
- fraud_remote_addr fraud_http_accept fraud_http_accept_language
84
- fraud_http_accept_encoding fraud_http_accept_charset
85
- fraud_http_referer fraud_http_user_agent apikey),
86
-
87
- :recurring => %w(protocol msgtype merchant ordernumber amount currency
88
- autocapture transaction apikey),
89
-
90
- :status => %w(protocol msgtype merchant transaction apikey),
91
-
92
- :chstatus => %w(protocol msgtype merchant apikey)
93
- },
94
-
95
- 6 => {
96
- :authorize => %w(protocol msgtype merchant ordernumber amount
97
- currency autocapture cardnumber expirationdate cvd
98
- cardtypelock testmode fraud_remote_addr
99
- fraud_http_accept fraud_http_accept_language
100
- fraud_http_accept_encoding fraud_http_accept_charset
101
- fraud_http_referer fraud_http_user_agent apikey),
102
-
103
- :capture => %w(protocol msgtype merchant amount finalize transaction
104
- apikey),
105
-
106
- :cancel => %w(protocol msgtype merchant transaction apikey),
107
-
108
- :refund => %w(protocol msgtype merchant amount transaction apikey),
109
-
110
- :subscribe => %w(protocol msgtype merchant ordernumber cardnumber
111
- expirationdate cvd cardtypelock description testmode
112
- fraud_remote_addr fraud_http_accept fraud_http_accept_language
113
- fraud_http_accept_encoding fraud_http_accept_charset
114
- fraud_http_referer fraud_http_user_agent apikey),
115
-
116
- :recurring => %w(protocol msgtype merchant ordernumber amount currency
117
- autocapture transaction apikey),
118
-
119
- :status => %w(protocol msgtype merchant transaction apikey),
120
-
121
- :chstatus => %w(protocol msgtype merchant apikey)
122
- },
123
-
124
- 7 => {
125
- :authorize => %w(protocol msgtype merchant ordernumber amount
126
- currency autocapture cardnumber expirationdate cvd
127
- acquirers cardtypelock testmode fraud_remote_addr
128
- fraud_http_accept fraud_http_accept_language
129
- fraud_http_accept_encoding fraud_http_accept_charset
130
- fraud_http_referer fraud_http_user_agent apikey),
131
-
132
- :capture => %w(protocol msgtype merchant amount finalize transaction
133
- apikey),
134
-
135
- :cancel => %w(protocol msgtype merchant transaction apikey),
136
-
137
- :refund => %w(protocol msgtype merchant amount transaction apikey),
138
-
139
- :subscribe => %w(protocol msgtype merchant ordernumber amount currency
140
- cardnumber expirationdate cvd acquirers cardtypelock
141
- description testmode fraud_remote_addr fraud_http_accept
142
- fraud_http_accept_language fraud_http_accept_encoding
143
- fraud_http_accept_charset fraud_http_referer
144
- fraud_http_user_agent apikey),
145
-
146
- :recurring => %w(protocol msgtype merchant ordernumber amount currency
147
- autocapture transaction apikey),
148
-
149
- :status => %w(protocol msgtype merchant transaction apikey),
150
-
151
- :chstatus => %w(protocol msgtype merchant apikey)
152
- }
153
- }
154
-
155
- APPROVED = '000'
156
-
157
- # The login is the QuickpayId
158
- # The password is the md5checkword from the Quickpay manager
159
- # To use the API-key from the Quickpay manager, specify :api-key
160
- # Using the API-key, requires that you use version 4+. Specify :version => 4/5/6/7 in options.
161
- def initialize(options = {})
162
- requires!(options, :login, :password)
163
- @protocol = options.delete(:version) || 7 # default to protocol version 7
164
- super
165
- end
166
-
167
- def authorize(money, credit_card_or_reference, options = {})
168
- post = {}
169
-
170
- action = recurring_or_authorize(credit_card_or_reference)
171
-
172
- add_amount(post, money, options)
173
- add_invoice(post, options)
174
- add_creditcard_or_reference(post, credit_card_or_reference, options)
175
- add_autocapture(post, false)
176
- add_fraud_parameters(post, options) if action.eql?(:authorize)
177
- add_testmode(post)
178
-
179
- commit(action, post)
180
- end
181
-
182
- def purchase(money, credit_card_or_reference, options = {})
183
- post = {}
184
-
185
- action = recurring_or_authorize(credit_card_or_reference)
186
-
187
- add_amount(post, money, options)
188
- add_creditcard_or_reference(post, credit_card_or_reference, options)
189
- add_invoice(post, options)
190
- add_fraud_parameters(post, options) if action.eql?(:authorize)
191
- add_autocapture(post, true)
192
-
193
- commit(action, post)
194
- end
195
-
196
- def capture(money, authorization, options = {})
197
- post = {}
198
-
199
- add_finalize(post, options)
200
- add_reference(post, authorization)
201
- add_amount_without_currency(post, money)
202
- commit(:capture, post)
203
- end
204
-
205
- def void(identification, options = {})
206
- post = {}
207
-
208
- add_reference(post, identification)
10
+ self.abstract_class = true
209
11
 
210
- commit(:cancel, post)
211
- end
212
-
213
- def refund(money, identification, options = {})
214
- post = {}
215
-
216
- add_amount_without_currency(post, money)
217
- add_reference(post, identification)
218
-
219
- commit(:refund, post)
220
- end
221
-
222
- def credit(money, identification, options = {})
223
- ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
224
- refund(money, identification, options)
225
- end
226
-
227
- def store(creditcard, options = {})
228
- post = {}
229
-
230
- add_creditcard(post, creditcard, options)
231
- add_amount(post, 0, options) if @protocol >= 7
232
- add_invoice(post, options)
233
- add_description(post, options)
234
- add_fraud_parameters(post, options)
235
- add_testmode(post)
236
-
237
- commit(:subscribe, post)
238
- end
239
-
240
- private
241
-
242
- def add_amount(post, money, options = {})
243
- post[:amount] = amount(money)
244
- post[:currency] = options[:currency] || currency(money)
245
- end
246
-
247
- def add_amount_without_currency(post, money, options = {})
248
- post[:amount] = amount(money)
249
- end
250
-
251
- def add_invoice(post, options)
252
- post[:ordernumber] = format_order_number(options[:order_id])
253
- end
254
-
255
- def add_creditcard(post, credit_card, options)
256
- post[:cardnumber] = credit_card.number
257
- post[:cvd] = credit_card.verification_value
258
- post[:expirationdate] = expdate(credit_card)
259
- post[:cardtypelock] = options[:cardtypelock] unless options[:cardtypelock].blank?
260
- post[:acquirers] = options[:acquirers] unless options[:acquirers].blank?
261
- end
262
-
263
- def add_reference(post, identification)
264
- post[:transaction] = identification
265
- end
12
+ def self.new(options = {})
13
+ options.fetch(:login) rescue raise ArgumentError.new("Missing required parameter: login")
266
14
 
267
- def add_creditcard_or_reference(post, credit_card_or_reference, options)
268
- if credit_card_or_reference.is_a?(String)
269
- add_reference(post, credit_card_or_reference)
15
+ version = options[:login].to_i < 10000000 ? 10 : 7
16
+ if version <= 7
17
+ QuickpayV4to7Gateway.new(options)
270
18
  else
271
- add_creditcard(post, credit_card_or_reference, options)
272
- end
273
- end
274
-
275
- def add_autocapture(post, autocapture)
276
- post[:autocapture] = autocapture ? 1 : 0
277
- end
278
-
279
- def recurring_or_authorize(credit_card_or_reference)
280
- credit_card_or_reference.is_a?(String) ? :recurring : :authorize
281
- end
282
-
283
- def add_description(post, options)
284
- post[:description] = options[:description]
285
- end
286
-
287
- def add_testmode(post)
288
- return if post[:transaction].present?
289
- post[:testmode] = test? ? '1' : '0'
290
- end
291
-
292
- def add_fraud_parameters(post, options)
293
- if @protocol >= 4
294
- post[:fraud_remote_addr] = options[:ip] if options[:ip]
295
- post[:fraud_http_accept] = options[:fraud_http_accept] if options[:fraud_http_accept]
296
- post[:fraud_http_accept_language] = options[:fraud_http_accept_language] if options[:fraud_http_accept_language]
297
- post[:fraud_http_accept_encoding] = options[:fraud_http_accept_encoding] if options[:fraud_http_accept_encoding]
298
- post[:fraud_http_accept_charset] = options[:fraud_http_accept_charset] if options[:fraud_http_accept_charset]
299
- post[:fraud_http_referer] = options[:fraud_http_referer] if options[:fraud_http_referer]
300
- post[:fraud_http_user_agent] = options[:fraud_http_user_agent] if options[:fraud_http_user_agent]
301
- end
302
- end
303
-
304
- def add_finalize(post, options)
305
- post[:finalize] = options[:finalize] ? '1' : '0'
306
- end
307
-
308
- def commit(action, params)
309
- response = parse(ssl_post(self.live_url, post_data(action, params)))
310
-
311
- Response.new(successful?(response), message_from(response), response,
312
- :test => test?,
313
- :authorization => response[:transaction]
314
- )
315
- end
316
-
317
- def successful?(response)
318
- response[:qpstat] == APPROVED
319
- end
320
-
321
- def parse(data)
322
- response = {}
323
-
324
- doc = REXML::Document.new(data)
325
-
326
- doc.root.elements.each do |element|
327
- response[element.name.to_sym] = element.text
19
+ QuickpayV10Gateway.new(options)
328
20
  end
329
-
330
- response
331
- end
332
-
333
- def message_from(response)
334
- response[:qpstatmsg].to_s
335
- end
336
-
337
- def post_data(action, params = {})
338
- params[:protocol] = @protocol
339
- params[:msgtype] = action.to_s
340
- params[:merchant] = @options[:login]
341
- params[:apikey] = @options[:apikey] if @options[:apikey]
342
- params[:md5check] = generate_check_hash(action, params)
343
-
344
- params.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
345
- end
346
-
347
- def generate_check_hash(action, params)
348
- string = MD5_CHECK_FIELDS[@protocol][action].collect do |key|
349
- params[key.to_sym]
350
- end.join('')
351
-
352
- # Add the md5checkword
353
- string << @options[:password].to_s
354
-
355
- Digest::MD5.hexdigest(string)
356
- end
357
-
358
- def expdate(credit_card)
359
- year = format(credit_card.year, :two_digits)
360
- month = format(credit_card.month, :two_digits)
361
-
362
- "#{year}#{month}"
363
- end
364
-
365
- # Limited to 20 digits max
366
- def format_order_number(number)
367
- number.to_s.gsub(/[^\w]/, '').rjust(4, "0")[0...20]
368
21
  end
22
+
369
23
  end
370
24
  end
371
25
  end