activemerchant 1.49.0 → 1.50.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 (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