activemerchant 1.5.1 → 1.6.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 (29) hide show
  1. data/CHANGELOG +14 -0
  2. data/CONTRIBUTORS +4 -0
  3. data/lib/active_merchant.rb +1 -9
  4. data/lib/active_merchant/billing/credit_card_methods.rb +2 -2
  5. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +2 -2
  6. data/lib/active_merchant/billing/gateways/bogus.rb +12 -8
  7. data/lib/active_merchant/billing/gateways/garanti.rb +222 -0
  8. data/lib/active_merchant/billing/gateways/linkpoint.rb +1 -1
  9. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +1 -1
  10. data/lib/active_merchant/billing/gateways/paypal_express.rb +5 -0
  11. data/lib/active_merchant/billing/gateways/sage.rb +2 -2
  12. data/lib/active_merchant/billing/integrations/chronopay/helper.rb +3 -3
  13. data/lib/active_merchant/common.rb +14 -0
  14. data/lib/active_merchant/{lib → common}/connection.rb +2 -0
  15. data/lib/active_merchant/{lib → common}/country.rb +1 -1
  16. data/lib/active_merchant/common/error.rb +26 -0
  17. data/lib/active_merchant/common/post_data.rb +24 -0
  18. data/lib/active_merchant/{lib → common}/posts_data.rb +0 -0
  19. data/lib/active_merchant/{lib → common}/requires_parameters.rb +0 -0
  20. data/lib/active_merchant/{lib → common}/utils.rb +0 -0
  21. data/lib/active_merchant/{lib → common}/validateable.rb +0 -0
  22. data/lib/activemerchant.rb +1 -0
  23. data/lib/support/outbound_hosts.rb +25 -0
  24. metadata +50 -44
  25. data.tar.gz.sig +0 -0
  26. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb.orig +0 -736
  27. data/lib/active_merchant/lib/error.rb +0 -4
  28. data/lib/active_merchant/lib/post_data.rb +0 -22
  29. metadata.gz.sig +0 -3
data/CHANGELOG CHANGED
@@ -1,5 +1,19 @@
1
1
  = ActiveMerchant CHANGELOG
2
2
 
3
+ * Add a task rake gateways:hosts to get a list of all outbound hosts and ports [cody]
4
+ * Fix test failure in chronopay helper in Ruby 1.9.1 [cody]
5
+ * Fix timezone issue in credit card test. [cody]
6
+ * Fix failing unit test for Garanti gateway [cody]
7
+ * Fix failing CyberSource remote test [Patrick Joyce]
8
+ * Support for Garanti Sanal Pos: Turkish bank and billing gateway [Selem Delul]
9
+ * Add deprecation note for Money objects to Bogus gateway [Soleone]
10
+ * Updated test URL for Merchant eSolutions and added valid remote test credentials [Soleone]
11
+ * Add new error class for SSL certificate problems in connection class [Soleone]
12
+ * Update valid_month and valid_expiry_year to coerce string arguments to integers [cody]
13
+ * Add support for displaying credit cards with PayPal Express. Use the :allow_guest_checkout => true option when setting up the transaction [Edward Ocampo-Gooding]
14
+ * Use card_brand method for checking for checks in Sage and Beanstream [cody]
15
+ * Add JCB and Diners Club to LinkPoint [Soleone]
16
+
3
17
  == Version 1.5.1 (February 14, 2010)
4
18
 
5
19
  * Cleanup Rakefile, add gemspec and prepare for 1.5.1 release [cody]
@@ -132,3 +132,7 @@ JetPay (September 29, 2009)
132
132
  SallieMae (October 2, 2009)
133
133
 
134
134
  * iamjwc
135
+
136
+ Garanti (May 05, 2010)
137
+
138
+ * Selem Delul (moon@mac.home)
@@ -28,15 +28,7 @@ require 'builder'
28
28
  require 'cgi'
29
29
  require 'rexml/document'
30
30
 
31
- require 'active_merchant/lib/utils'
32
- require 'active_merchant/lib/error'
33
- require 'active_merchant/lib/validateable'
34
- require 'active_merchant/lib/connection'
35
- require 'active_merchant/lib/posts_data'
36
- require 'active_merchant/lib/post_data'
37
- require 'active_merchant/lib/requires_parameters'
38
- require 'active_merchant/lib/country'
39
-
31
+ require 'active_merchant/common'
40
32
  require 'active_merchant/billing'
41
33
 
42
34
  module ActiveMerchant #:nodoc:
@@ -22,11 +22,11 @@ module ActiveMerchant #:nodoc:
22
22
  end
23
23
 
24
24
  def valid_month?(month)
25
- (1..12).include?(month)
25
+ (1..12).include?(month.to_i)
26
26
  end
27
27
 
28
28
  def valid_expiry_year?(year)
29
- (Time.now.year..Time.now.year + 20).include?(year)
29
+ (Time.now.year..Time.now.year + 20).include?(year.to_i)
30
30
  end
31
31
 
32
32
  def valid_start_year?(year)
@@ -78,7 +78,7 @@ module ActiveMerchant #:nodoc:
78
78
 
79
79
  private
80
80
  def purchase_action(source)
81
- source.type.to_s == "check" ? :check_purchase : :purchase
81
+ card_brand(source) == "check" ? :check_purchase : :purchase
82
82
  end
83
83
 
84
84
  def void_action(original_transaction_type)
@@ -221,7 +221,7 @@ module ActiveMerchant #:nodoc:
221
221
  end
222
222
 
223
223
  def add_source(post, source)
224
- source.type == "check" ? add_check(post, source) : add_credit_card(post, source)
224
+ card_brand(source) == "check" ? add_check(post, source) : add_credit_card(post, source)
225
225
  end
226
226
 
227
227
  def add_transaction_type(post, action)
@@ -18,46 +18,50 @@ module ActiveMerchant #:nodoc:
18
18
  self.display_name = 'Bogus'
19
19
 
20
20
  def authorize(money, creditcard, options = {})
21
+ money = amount(money)
21
22
  case creditcard.number
22
23
  when '1'
23
- Response.new(true, SUCCESS_MESSAGE, {:authorized_amount => money.to_s}, :test => true, :authorization => AUTHORIZATION )
24
+ Response.new(true, SUCCESS_MESSAGE, {:authorized_amount => money}, :test => true, :authorization => AUTHORIZATION )
24
25
  when '2'
25
- Response.new(false, FAILURE_MESSAGE, {:authorized_amount => money.to_s, :error => FAILURE_MESSAGE }, :test => true)
26
+ Response.new(false, FAILURE_MESSAGE, {:authorized_amount => money, :error => FAILURE_MESSAGE }, :test => true)
26
27
  else
27
28
  raise Error, ERROR_MESSAGE
28
29
  end
29
30
  end
30
31
 
31
32
  def purchase(money, creditcard, options = {})
33
+ money = amount(money)
32
34
  case creditcard.number
33
35
  when '1'
34
- Response.new(true, SUCCESS_MESSAGE, {:paid_amount => money.to_s}, :test => true)
36
+ Response.new(true, SUCCESS_MESSAGE, {:paid_amount => money}, :test => true)
35
37
  when '2'
36
- Response.new(false, FAILURE_MESSAGE, {:paid_amount => money.to_s, :error => FAILURE_MESSAGE },:test => true)
38
+ Response.new(false, FAILURE_MESSAGE, {:paid_amount => money, :error => FAILURE_MESSAGE },:test => true)
37
39
  else
38
40
  raise Error, ERROR_MESSAGE
39
41
  end
40
42
  end
41
43
 
42
44
  def credit(money, ident, options = {})
45
+ money = amount(money)
43
46
  case ident
44
47
  when '1'
45
48
  raise Error, CREDIT_ERROR_MESSAGE
46
49
  when '2'
47
- Response.new(false, FAILURE_MESSAGE, {:paid_amount => money.to_s, :error => FAILURE_MESSAGE }, :test => true)
50
+ Response.new(false, FAILURE_MESSAGE, {:paid_amount => money, :error => FAILURE_MESSAGE }, :test => true)
48
51
  else
49
- Response.new(true, SUCCESS_MESSAGE, {:paid_amount => money.to_s}, :test => true)
52
+ Response.new(true, SUCCESS_MESSAGE, {:paid_amount => money}, :test => true)
50
53
  end
51
54
  end
52
55
 
53
56
  def capture(money, ident, options = {})
57
+ money = amount(money)
54
58
  case ident
55
59
  when '1'
56
60
  raise Error, CAPTURE_ERROR_MESSAGE
57
61
  when '2'
58
- Response.new(false, FAILURE_MESSAGE, {:paid_amount => money.to_s, :error => FAILURE_MESSAGE }, :test => true)
62
+ Response.new(false, FAILURE_MESSAGE, {:paid_amount => money, :error => FAILURE_MESSAGE }, :test => true)
59
63
  else
60
- Response.new(true, SUCCESS_MESSAGE, {:paid_amount => money.to_s}, :test => true)
64
+ Response.new(true, SUCCESS_MESSAGE, {:paid_amount => money}, :test => true)
61
65
  end
62
66
  end
63
67
 
@@ -0,0 +1,222 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class GarantiGateway < Gateway
4
+ URL = 'https://ccpos.garanti.com.tr/servlet/cc5ApiServer'
5
+
6
+ # The countries the gateway supports merchants from as 2 digit ISO country codes
7
+ self.supported_countries = ['US','TR']
8
+
9
+ # The card types supported by the payment gateway
10
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover]
11
+
12
+ # The homepage URL of the gateway
13
+ self.homepage_url = 'https://ccpos.garanti.com.tr/ccRaporlar/garanti/ccReports'
14
+
15
+ # The name of the gateway
16
+ self.display_name = 'Garanti Sanal POS'
17
+
18
+ self.default_currency = 'TRL'
19
+
20
+ CURRENCY_CODES = {
21
+ 'YTL' => 949,
22
+ 'TRL' => 949,
23
+ 'USD' => 840,
24
+ 'EUR' => 978
25
+ }
26
+
27
+
28
+ def initialize(options = {})
29
+ requires!(options, :login, :password, :client_id)
30
+ @options = options
31
+ super
32
+ end
33
+
34
+ def purchase(money, credit_card, options = {})
35
+ commit(money, build_sale_request(money, credit_card, options))
36
+ end
37
+
38
+ def authorize(money, credit_card, options = {})
39
+ commit(money, build_authorize_request(money, credit_card, options))
40
+ end
41
+
42
+ def capture(money, reference, options = {})
43
+ commit(money, build_capture_request(money,reference,options))
44
+ end
45
+
46
+ private
47
+
48
+ def build_xml_request(transaction_type,&block)
49
+ xml = Builder::XmlMarkup.new
50
+ xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
51
+
52
+ xml.tag! 'CC5Request' do
53
+ xml.tag! 'Name', @options[:login]
54
+ xml.tag! 'Password', @options[:password]
55
+ xml.tag! 'ClientId', @options[:client_id]
56
+ xml.tag! 'Mode', if test? then 'R' else 'P' end
57
+ xml.tag! 'Type', transaction_type
58
+
59
+ if block_given?
60
+ yield xml
61
+ else
62
+ xml.target!
63
+ end
64
+ end
65
+ end
66
+
67
+ def build_sale_request(money, credit_card, options)
68
+ build_xml_request('Auth') do |xml|
69
+ add_customer_data(xml,options)
70
+ add_order_data(xml,options)
71
+ add_credit_card(xml, credit_card)
72
+ add_addresses(xml, options)
73
+
74
+ xml.tag! 'Total', amount(money)
75
+ xml.tag! 'Currency', currency_code(options[:currency])
76
+
77
+ xml.target!
78
+ end
79
+ end
80
+
81
+ def build_authorize_request(money, credit_card, options)
82
+ build_xml_request('PreAuth') do |xml|
83
+ add_customer_data(xml,options)
84
+ add_order_data(xml,options)
85
+ add_credit_card(xml, credit_card)
86
+ add_addresses(xml, options)
87
+
88
+ xml.tag! 'Total', amount(money)
89
+ xml.tag! 'Currency', currency_code(options[:currency])
90
+
91
+ xml.target!
92
+
93
+ end
94
+ end
95
+
96
+ def build_capture_request(money, reference, options = {})
97
+ build_xml_request('PostAuth') do |xml|
98
+ add_customer_data(xml,options)
99
+ xml.tag! 'OrderId', reference
100
+ xml.tag! 'Total', amount(money)
101
+ xml.tag! 'Currency', currency_code(options[:currency])
102
+
103
+ xml.target!
104
+ end
105
+ end
106
+
107
+ def build_void_request(reference, options = {})
108
+ build_xml_request('Void') do |xml|
109
+ add_customer_data(xml,options)
110
+ xml.tag! 'OrderId', reference
111
+ xml.tag! 'Total', amount(money)
112
+ xml.tag! 'Currency', currency_code(options[:currency])
113
+
114
+ xml.target!
115
+ end
116
+ end
117
+
118
+ def build_credit_request(money, reference, options = {})
119
+ build_xml_request('Credit') do |xml|
120
+ add_customer_data(xml,options)
121
+ xml.tag! 'OrderId', reference
122
+ xml.tag! 'Total', amount(money)
123
+ xml.tag! 'Currency', currency_code(options[:currency])
124
+
125
+ xml.target!
126
+ end
127
+ end
128
+
129
+ def add_customer_data(xml, options)
130
+ xml.tag! 'IPAddress', options[:ip_]
131
+ xml.tag! 'Email', options[:email]
132
+ end
133
+
134
+ def add_order_data(xml,options)
135
+ xml.tag! 'OrderId', options[:order_id]
136
+ xml.tag! 'GroupId', nil
137
+ xml.tag! 'TransId', nil
138
+ end
139
+
140
+ def add_credit_card(xml, credit_card)
141
+ xml.tag! 'Number', credit_card.number
142
+ xml.tag! 'Expires', [format_exp(credit_card.month),format_exp(credit_card.year)].join('/')
143
+ xml.tag! 'Cvv2Val', credit_card.verification_value
144
+ end
145
+
146
+ def format_exp(value)
147
+ format(value, :two_digits)
148
+ end
149
+
150
+ def add_addresses(xml,options)
151
+ if billing_address = options[:billing_address] || options[:address]
152
+ xml.tag! 'BillTo' do
153
+ xml.tag! 'Name', billing_address[:name]
154
+ xml.tag! 'Street1', billing_address[:address1]
155
+ xml.tag! 'Street2', billing_address[:address2]
156
+ xml.tag! 'City', billing_address[:city]
157
+ xml.tag! 'StateProv', billing_address[:state]
158
+ xml.tag! 'PostalCode', billing_address[:zip]
159
+ xml.tag! 'Country', billing_address[:country]
160
+ xml.tag! 'Company', billing_address[:company]
161
+ xml.tag! 'TelVoice', billing_address[:phone]
162
+ end
163
+ end
164
+
165
+ if shipping_address = options[:shipping_address]
166
+ xml.tag! 'ShipTo' do
167
+ xml.tag! 'Name', shipping_address[:name]
168
+ xml.tag! 'Street1', shipping_address[:address1]
169
+ xml.tag! 'Street2', shipping_address[:address2]
170
+ xml.tag! 'City', shipping_address[:city]
171
+ xml.tag! 'StateProv',shipping_address[:state]
172
+ xml.tag! 'PostalCode',shipping_address[:zip]
173
+ xml.tag! 'Country', shipping_address[:country]
174
+ xml.tag! 'Company', shipping_address[:company]
175
+ xml.tag! 'TelVoice', shipping_address[:phone]
176
+ end
177
+ end
178
+ end
179
+
180
+ def currency_code(currency)
181
+ CURRENCY_CODES[currency] || CURRENCY_CODES[default_currency]
182
+ end
183
+
184
+ def commit(money,request)
185
+ raw_response = ssl_post(URL,"DATA=" + request)
186
+ response = parse(raw_response)
187
+
188
+ success = success?(response)
189
+
190
+ Response.new(success,
191
+ success ? 'Approved' : 'Declined',
192
+ response,
193
+ :test => test?,
194
+ :authorization => response[:order_id])
195
+ end
196
+
197
+ def parse(body)
198
+ xml = REXML::Document.new(body)
199
+
200
+ response = {}
201
+ xml.root.elements.to_a.each do |node|
202
+ parse_element(response, node)
203
+ end
204
+ response
205
+ end
206
+
207
+ def parse_element(response, node)
208
+ if node.has_elements?
209
+ node.elements.each{|element| parse_element(response, element) }
210
+ else
211
+ response[node.name.underscore.to_sym] = node.text
212
+ end
213
+ end
214
+
215
+ def success?(response)
216
+ response[:response] == "Approved"
217
+ end
218
+
219
+ end
220
+ end
221
+ end
222
+
@@ -134,7 +134,7 @@ module ActiveMerchant #:nodoc:
134
134
  self.ssl_strict = false
135
135
 
136
136
  self.supported_countries = ['US']
137
- self.supported_cardtypes = [:visa, :master, :american_express, :discover]
137
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club]
138
138
  self.homepage_url = 'http://www.linkpoint.com/'
139
139
  self.display_name = 'LinkPoint'
140
140
 
@@ -2,7 +2,7 @@ module ActiveMerchant #:nodoc:
2
2
  module Billing #:nodoc:
3
3
  class MerchantESolutionsGateway < Gateway
4
4
 
5
- TEST_URL = 'https://test.merchante-solutions.com/mes-api/tridentApi'
5
+ TEST_URL = 'https://cert.merchante-solutions.com/mes-api/tridentApi'
6
6
  LIVE_URL = 'https://api.merchante-solutions.com/mes-api/tridentApi'
7
7
 
8
8
  # The countries the gateway supports merchants from as 2 digit ISO country codes
@@ -114,6 +114,11 @@ module ActiveMerchant #:nodoc:
114
114
  xml.tag! 'n2:cpp-header-border-color', options[:header_border_color] unless options[:header_border_color].blank?
115
115
  xml.tag! 'n2:cpp-payflow-color', options[:background_color] unless options[:background_color].blank?
116
116
 
117
+ if options[:allow_guest_checkout]
118
+ xml.tag! 'n2:SolutionType', 'Sole'
119
+ xml.tag! 'n2:LandingPage', 'Billing'
120
+ end
121
+
117
122
  xml.tag! 'n2:LocaleCode', options[:locale] unless options[:locale].blank?
118
123
  end
119
124
  end
@@ -88,7 +88,7 @@ module ActiveMerchant #:nodoc:
88
88
  # * <tt>:drivers_license_number</tt> - The customer's drivers license number.
89
89
  # * <tt>:date_of_birth</tt> - The customer's date of birth as a Time or Date object or a string in the format <tt>mm/dd/yyyy</tt>.
90
90
  def purchase(money, source, options = {})
91
- if source.type == "check"
91
+ if card_brand(source) == "check"
92
92
  virtual_check.purchase(money, source, options)
93
93
  else
94
94
  bankcard.purchase(money, source, options)
@@ -125,7 +125,7 @@ module ActiveMerchant #:nodoc:
125
125
  # * <tt>money</tt> - The amount to be authorized as an integer value in cents.
126
126
  # * <tt>source</tt> - The CreditCard or Check object to be used as the target for the credit.
127
127
  def credit(money, source, options = {})
128
- if source.type == "check"
128
+ if card_brand(source) == "check"
129
129
  virtual_check.credit(money, source, options)
130
130
  else
131
131
  bankcard.credit(money, source, options)
@@ -18,9 +18,9 @@ module ActiveMerchant #:nodoc:
18
18
  'DE' => %w( DE AT CH LI ),
19
19
  'PT' => %w( AO BR CV GW MZ PT ST TL),
20
20
  'RU' => %w( BY KG KZ RU ),
21
- 'LV' => 'LV',
22
- 'CN1' => 'CN',
23
- 'NL' => 'NL'
21
+ 'LV' => %w( LV ),
22
+ 'CN1' => %w( CN ),
23
+ 'NL' => %w( NL )
24
24
  }
25
25
 
26
26
  LANG_FOR_COUNTRY = COUNTRIES_FOR_LANG.inject(Hash.new("EN")) do |memo, (lang, countries)|
@@ -0,0 +1,14 @@
1
+ module ActiveMerchant
2
+ autoload :Connection, 'active_merchant/common/connection'
3
+ autoload :Country, 'active_merchant/common/country'
4
+ autoload :ActiveMerchantError, 'active_merchant/common/error'
5
+ autoload :ConnectionError, 'active_merchant/common/error'
6
+ autoload :RetriableConnectionError, 'active_merchant/common/error'
7
+ autoload :ResponseError, 'active_merchant/common/error'
8
+ autoload :ClientCertificateError, 'active_merchant/common/error'
9
+ autoload :PostData, 'active_merchant/common/post_data'
10
+ autoload :PostsData, 'active_merchant/common/posts_data'
11
+ autoload :RequiresParameters, 'active_merchant/common/requires_parameters'
12
+ autoload :Utils, 'active_merchant/common/utils'
13
+ autoload :Validateable, 'active_merchant/common/validateable'
14
+ end
@@ -80,6 +80,8 @@ module ActiveMerchant
80
80
  raise ConnectionError, "The remote server reset the connection"
81
81
  rescue Errno::ECONNREFUSED => e
82
82
  raise RetriableConnectionError, "The remote server refused the connection"
83
+ rescue OpenSSL::X509::CertificateError => e
84
+ raise ClientCertificateError, "The remote server did not accept the provided SSL certificate"
83
85
  rescue Timeout::Error, Errno::ETIMEDOUT => e
84
86
  raise ConnectionError, "The connection to the remote server timed out"
85
87
  end