activemerchant 1.4.1 → 1.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG +28 -0
  3. data/Rakefile +2 -4
  4. data/lib/active_merchant/billing/credit_card.rb +2 -0
  5. data/lib/active_merchant/billing/gateways/authorize_net.rb +13 -0
  6. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +1 -1
  7. data/lib/active_merchant/billing/gateways/bogus.rb +13 -1
  8. data/lib/active_merchant/billing/gateways/braintree.rb +13 -5
  9. data/lib/active_merchant/billing/gateways/card_stream.rb +1 -5
  10. data/lib/active_merchant/billing/gateways/moneris.rb +1 -1
  11. data/lib/active_merchant/billing/gateways/pay_junction.rb +9 -3
  12. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +2 -8
  13. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +1 -1
  14. data/lib/active_merchant/billing/gateways/psl_card.rb +7 -3
  15. data/lib/active_merchant/billing/gateways/quickpay.rb +84 -54
  16. data/lib/active_merchant/billing/gateways/sage.rb +1 -0
  17. data/lib/active_merchant/billing/gateways/trust_commerce.rb +5 -1
  18. data/lib/active_merchant/billing/gateways/wirecard.rb +20 -19
  19. data/lib/active_merchant/billing/integrations.rb +1 -0
  20. data/lib/active_merchant/billing/integrations/quickpay.rb +18 -0
  21. data/lib/active_merchant/billing/integrations/quickpay/helper.rb +72 -0
  22. data/lib/active_merchant/billing/integrations/quickpay/notification.rb +74 -0
  23. data/lib/active_merchant/lib/country.rb +21 -3
  24. data/lib/active_merchant/lib/posts_data.rb +54 -34
  25. data/lib/active_merchant/lib/requires_parameters.rb +1 -1
  26. data/test/fixtures.yml +19 -3
  27. data/test/remote/gateways/remote_braintree_test.rb +11 -4
  28. data/test/remote/gateways/remote_card_stream_test.rb +20 -20
  29. data/test/remote/gateways/remote_psl_card_test.rb +23 -4
  30. data/test/remote/gateways/remote_quickpay_test.rb +17 -9
  31. data/test/remote/gateways/remote_wirecard_test.rb +3 -2
  32. data/test/test_helper.rb +3 -2
  33. data/test/unit/credit_card_test.rb +7 -0
  34. data/test/unit/gateways/authorize_net_cim_test.rb +2 -5
  35. data/test/unit/gateways/authorize_net_test.rb +16 -6
  36. data/test/unit/gateways/bogus_test.rb +4 -0
  37. data/test/unit/gateways/moneris_test.rb +1 -1
  38. data/test/unit/gateways/payflow_test.rb +6 -2
  39. data/test/unit/gateways/quickpay_test.rb +8 -8
  40. data/test/unit/gateways/trust_commerce_test.rb +12 -0
  41. data/test/unit/integrations/helpers/quickpay_helper_test.rb +40 -0
  42. data/test/unit/integrations/notifications/quickpay_notification_test.rb +69 -0
  43. data/test/unit/integrations/quickpay_module_test.rb +9 -0
  44. metadata +10 -5
  45. metadata.gz.sig +0 -0
  46. data/lib/tasks/cia.rb +0 -90
@@ -4,6 +4,7 @@ require File.dirname(__FILE__) + '/sage/sage_virtual_check'
4
4
  module ActiveMerchant #:nodoc:
5
5
  module Billing #:nodoc:
6
6
  class SageGateway < Gateway
7
+ self.supported_countries = SageBankcardGateway.supported_countries
7
8
  self.supported_cardtypes = SageBankcardGateway.supported_cardtypes
8
9
 
9
10
  # Creates a new SageGateway
@@ -101,6 +101,9 @@ module ActiveMerchant #:nodoc:
101
101
  "failtoprocess" => "The bank servers are offline and unable to authorize transactions"
102
102
  }
103
103
 
104
+ TEST_LOGIN = 'TestMerchant'
105
+ TEST_PASSWORD = 'password'
106
+
104
107
  self.money_format = :cents
105
108
  self.supported_cardtypes = [:visa, :master, :discover, :american_express, :diners_club, :jcb]
106
109
  self.supported_countries = ['US']
@@ -137,7 +140,8 @@ module ActiveMerchant #:nodoc:
137
140
  end
138
141
 
139
142
  def test?
140
- @options[:test] || super
143
+ @options[:login] == TEST_LOGIN &&
144
+ @options[:password] == TEST_PASSWORD || @options[:test] || super
141
145
  end
142
146
 
143
147
  # authorize() is the first half of the preauth(authorize)/postauth(capture) model. The TC API docs call this
@@ -220,7 +220,7 @@ module ActiveMerchant #:nodoc:
220
220
  xml = REXML::Document.new(xml)
221
221
  if root = REXML::XPath.first(xml, "#{basepath}/W_JOB")
222
222
  parse_response(response, root)
223
- elsif root = REXML::XPath.first(xml, "/#{basepath}/ERROR")
223
+ elsif root = REXML::XPath.first(xml, "//ERROR")
224
224
  parse_error(response, root)
225
225
  else
226
226
  response[:Message] = "No valid XML response message received. \
@@ -239,36 +239,37 @@ module ActiveMerchant #:nodoc:
239
239
  status = REXML::XPath.first(node, "CC_TRANSACTION/PROCESSING_STATUS")
240
240
  end
241
241
  end
242
- # Get message
243
- message = ''
244
- if info = status.elements['Info']
245
- message << info.text
242
+ message = ""
243
+ if status
244
+ if info = status.elements['Info']
245
+ message << info.text
246
+ end
247
+ # Get basic response information
248
+ status.elements.to_a.each do |node|
249
+ response[node.name.to_sym] = (node.text || '').strip
250
+ end
246
251
  end
252
+ parse_error(root, message)
253
+ response[:Message] = message
254
+ end
255
+
256
+ # Parse a generic error response from the gateway
257
+ def parse_error(root, message = "")
247
258
  # Get errors if available and append them to the message
248
- errors = errors_to_string(status)
259
+ errors = errors_to_string(root)
249
260
  unless errors.strip.blank?
250
261
  message << ' - ' unless message.strip.blank?
251
262
  message << errors
252
263
  end
253
- response[:Message] = message
254
-
255
- # Get basic response information
256
- status.elements.to_a.each do |node|
257
- response[node.name.to_sym] = (node.text || '').strip
258
- end
259
- end
260
-
261
- # Parse a generic error response from the gateway
262
- def parse_error(response, root)
263
- # TODO: Implement parsing of more generic error messages
264
+ message
264
265
  end
265
266
 
266
267
  # Parses all <ERROR> elements in the response and converts the information
267
268
  # to a single string
268
- def errors_to_string(status)
269
+ def errors_to_string(root)
269
270
  # Get context error messages (can be 0..*)
270
271
  errors = []
271
- REXML::XPath.each(status, "ERROR") do |error_elem|
272
+ REXML::XPath.each(root, "//ERROR") do |error_elem|
272
273
  error = {}
273
274
  error[:Advice] = []
274
275
  error[:Message] = error_elem.elements['Message'].text
@@ -8,6 +8,7 @@ require 'active_merchant/billing/integrations/nochex'
8
8
  require 'active_merchant/billing/integrations/gestpay'
9
9
  require 'active_merchant/billing/integrations/two_checkout'
10
10
  require 'active_merchant/billing/integrations/hi_trust'
11
+ require 'active_merchant/billing/integrations/quickpay'
11
12
 
12
13
  # make the bogus gateway be classified correctly by the inflector
13
14
  if defined?(ActiveSupport::Inflector)
@@ -0,0 +1,18 @@
1
+ require File.dirname(__FILE__) + '/quickpay/helper.rb'
2
+ require File.dirname(__FILE__) + '/quickpay/notification.rb'
3
+
4
+ module ActiveMerchant #:nodoc:
5
+ module Billing #:nodoc:
6
+ module Integrations #:nodoc:
7
+ module Quickpay
8
+
9
+ mattr_accessor :service_url
10
+ self.service_url = 'https://secure.quickpay.dk/form/'
11
+
12
+ def self.notification(post)
13
+ Notification.new(post)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,72 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Integrations #:nodoc:
4
+ module Quickpay
5
+ class Helper < ActiveMerchant::Billing::Integrations::Helper
6
+
7
+ def initialize(order, account, options = {})
8
+ super
9
+ add_field('protocol', '3')
10
+ add_field('msgtype', 'authorize')
11
+ add_field('language', 'da')
12
+ add_field('autocapture', 0)
13
+ add_field('testmode', 0)
14
+ add_field('ordernumber', format_order_number(order))
15
+ end
16
+
17
+ def md5secret(value)
18
+ @md5secret = value
19
+ end
20
+
21
+ def form_fields
22
+ @fields.merge('md5check' => generate_md5check)
23
+ end
24
+
25
+ def generate_md5string
26
+ MD5_CHECK_FIELDS.map {|key| @fields[key.to_s]} * "" + @md5secret
27
+ end
28
+
29
+ def generate_md5check
30
+ Digest::MD5.hexdigest(generate_md5string)
31
+ end
32
+
33
+ # Limited to 20 digits max
34
+ def format_order_number(number)
35
+ number.to_s.gsub(/[^\w_]/, '').rjust(4, "0")[0...20]
36
+ end
37
+
38
+ MD5_CHECK_FIELDS = [
39
+ :protocol, :msgtype, :merchant, :language, :ordernumber,
40
+ :amount, :currency, :continueurl, :cancelurl, :callbackurl,
41
+ :autocapture, :cardtypelock, :description, :ipaddress, :testmode
42
+ ]
43
+
44
+ mapping :protocol, 'protocol'
45
+ mapping :msgtype, 'msgtype'
46
+ mapping :account, 'merchant'
47
+ mapping :language, 'language'
48
+ mapping :amount, 'amount'
49
+ mapping :currency, 'currency'
50
+
51
+ mapping :return_url, 'continueurl'
52
+ mapping :cancel_return_url, 'cancelurl'
53
+ mapping :notify_url, 'callbackurl'
54
+
55
+ mapping :autocapture, 'autocapture'
56
+ mapping :cardtypelock, 'cardtypelock'
57
+
58
+ mapping :description, 'description'
59
+ mapping :ipaddress, 'ipaddress'
60
+ mapping :testmode, 'testmode'
61
+
62
+ mapping :md5secret, 'md5secret'
63
+
64
+ mapping :customer, ''
65
+ mapping :billing_address, ''
66
+ mapping :tax, ''
67
+ mapping :shipping, ''
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,74 @@
1
+ require 'net/http'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ module Integrations #:nodoc:
6
+ module Quickpay
7
+ class Notification < ActiveMerchant::Billing::Integrations::Notification
8
+ def complete?
9
+ status == '000'
10
+ end
11
+
12
+ def item_id
13
+ params['ordernumber']
14
+ end
15
+
16
+ def transaction_id
17
+ params['transaction']
18
+ end
19
+
20
+ def received_at
21
+ Time.local(*params['time'].scan(/../))
22
+ end
23
+
24
+ def gross
25
+ "%.2f" % (gross_cents / 100.0)
26
+ end
27
+
28
+ def gross_cents
29
+ params['amount'].to_i
30
+ end
31
+
32
+ def test?
33
+ params['testmode'] == 'Yes'
34
+ end
35
+
36
+ def status
37
+ params['qpstat']
38
+ end
39
+
40
+ def currency
41
+ params['currency']
42
+ end
43
+
44
+ # Provide access to raw fields from quickpay
45
+ %w(msgtype ordernumber state chstat chstatmsg qpstat qpstatmsg merchant merchantemail cardtype cardnumber).each do |attr|
46
+ define_method(attr) do
47
+ params[attr]
48
+ end
49
+ end
50
+
51
+ MD5_CHECK_FIELDS = [
52
+ :msgtype, :ordernumber, :amount, :currency, :time, :state,
53
+ :chstat, :chstatmsg, :qpstat, :qpstatmsg, :merchant, :merchantemail,
54
+ :transaction, :cardtype, :cardnumber, :testmode
55
+ ]
56
+
57
+ def generate_md5string
58
+ MD5_CHECK_FIELDS.map { |key| params[key.to_s] } * "" + @options[:md5secret]
59
+ end
60
+
61
+ def generate_md5check
62
+ Digest::MD5.hexdigest(generate_md5string)
63
+ end
64
+
65
+ # Quickpay doesn't do acknowledgements of callback notifications
66
+ # Instead it uses and MD5 hash of all parameters
67
+ def acknowledge
68
+ generate_md5check == params['md5check']
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -79,8 +79,10 @@ module ActiveMerchant #:nodoc:
79
79
  { :alpha2 => 'BO', :name => 'Bolivia', :alpha3 => 'BOL', :numeric => '068' },
80
80
  { :alpha2 => 'BA', :name => 'Bosnia and Herzegovina', :alpha3 => 'BIH', :numeric => '070' },
81
81
  { :alpha2 => 'BW', :name => 'Botswana', :alpha3 => 'BWA', :numeric => '072' },
82
+ { :alpha2 => 'BV', :name => 'Bouvet Island', :alpha3 => 'BVD', :numeric => '074' },
82
83
  { :alpha2 => 'BR', :name => 'Brazil', :alpha3 => 'BRA', :numeric => '076' },
83
- { :alpha2 => 'BN', :name => 'Brunei Darussalam', :alpha3 => 'BRN', :numeric => '096' },
84
+ { :alpha2 => 'BN', :name => 'Brunei Darussalam', :alpha3 => 'BRN', :numeric => '096' },
85
+ { :alpha2 => 'IO', :name => 'British Indian Ocean Territory', :alpha3 => 'IOT', :numeric => '086' },
84
86
  { :alpha2 => 'BG', :name => 'Bulgaria', :alpha3 => 'BGR', :numeric => '100' },
85
87
  { :alpha2 => 'BF', :name => 'Burkina Faso', :alpha3 => 'BFA', :numeric => '854' },
86
88
  { :alpha2 => 'BI', :name => 'Burundi', :alpha3 => 'BDI', :numeric => '108' },
@@ -93,6 +95,8 @@ module ActiveMerchant #:nodoc:
93
95
  { :alpha2 => 'TD', :name => 'Chad', :alpha3 => 'TCD', :numeric => '148' },
94
96
  { :alpha2 => 'CL', :name => 'Chile', :alpha3 => 'CHL', :numeric => '152' },
95
97
  { :alpha2 => 'CN', :name => 'China', :alpha3 => 'CHN', :numeric => '156' },
98
+ { :alpha2 => 'CX', :name => 'Christmas Island', :alpha3 => 'CXR', :numeric => '162' },
99
+ { :alpha2 => 'CC', :name => 'Cocos (Keeling) Islands', :alpha3 => 'CCK', :numeric => '166' },
96
100
  { :alpha2 => 'CO', :name => 'Colombia', :alpha3 => 'COL', :numeric => '170' },
97
101
  { :alpha2 => 'KM', :name => 'Comoros', :alpha3 => 'COM', :numeric => '174' },
98
102
  { :alpha2 => 'CG', :name => 'Congo', :alpha3 => 'COG', :numeric => '178' },
@@ -122,6 +126,7 @@ module ActiveMerchant #:nodoc:
122
126
  { :alpha2 => 'FR', :name => 'France', :alpha3 => 'FRA', :numeric => '250' },
123
127
  { :alpha2 => 'GF', :name => 'French Guiana', :alpha3 => 'GUF', :numeric => '254' },
124
128
  { :alpha2 => 'PF', :name => 'French Polynesia', :alpha3 => 'PYF', :numeric => '258' },
129
+ { :alpha2 => 'TF', :name => 'French Southern Territories', :alpha3 => 'ATF', :numeric => '260' },
125
130
  { :alpha2 => 'GA', :name => 'Gabon', :alpha3 => 'GAB', :numeric => '266' },
126
131
  { :alpha2 => 'GM', :name => 'Gambia', :alpha3 => 'GMB', :numeric => '270' },
127
132
  { :alpha2 => 'GE', :name => 'Georgia', :alpha3 => 'GEO', :numeric => '268' },
@@ -136,22 +141,26 @@ module ActiveMerchant #:nodoc:
136
141
  { :alpha2 => 'GT', :name => 'Guatemala', :alpha3 => 'GTM', :numeric => '320' },
137
142
  { :alpha2 => 'GN', :name => 'Guinea', :alpha3 => 'GIN', :numeric => '324' },
138
143
  { :alpha2 => 'GW', :name => 'Guinea-Bissau', :alpha3 => 'GNB', :numeric => '624' },
139
- { :alpha2 => 'GY', :name => 'Guyana', :alpha3 => 'GUY', :numeric => '328' },
144
+ { :alpha2 => 'GY', :name => 'Guyana', :alpha3 => 'GUY', :numeric => '328' },
145
+ { :alpha2 => 'GG', :name => 'Guernsey', :alpha3 => 'GGY', :numeric => '831' },
140
146
  { :alpha2 => 'HT', :name => 'Haiti', :alpha3 => 'HTI', :numeric => '332' },
141
147
  { :alpha2 => 'VA', :name => 'Holy See (Vatican City State)', :alpha3 => 'VAT', :numeric => '336' },
142
148
  { :alpha2 => 'HN', :name => 'Honduras', :alpha3 => 'HND', :numeric => '340' },
143
149
  { :alpha2 => 'HK', :name => 'Hong Kong', :alpha3 => 'HKG', :numeric => '344' },
150
+ { :alpha2 => 'HM', :name => 'Heard Island And Mcdonald Islands', :alpha3 => 'HMD', :numeric => '334' },
144
151
  { :alpha2 => 'HU', :name => 'Hungary', :alpha3 => 'HUN', :numeric => '348' },
145
152
  { :alpha2 => 'IS', :name => 'Iceland', :alpha3 => 'ISL', :numeric => '352' },
146
153
  { :alpha2 => 'IN', :name => 'India', :alpha3 => 'IND', :numeric => '356' },
147
154
  { :alpha2 => 'ID', :name => 'Indonesia', :alpha3 => 'IDN', :numeric => '360' },
148
155
  { :alpha2 => 'IR', :name => 'Iran, Islamic Republic of', :alpha3 => 'IRN', :numeric => '364' },
149
156
  { :alpha2 => 'IQ', :name => 'Iraq', :alpha3 => 'IRQ', :numeric => '368' },
150
- { :alpha2 => 'IE', :name => 'Ireland', :alpha3 => 'IRL', :numeric => '372' },
157
+ { :alpha2 => 'IE', :name => 'Ireland', :alpha3 => 'IRL', :numeric => '372' },
158
+ { :alpha2 => 'IM', :name => 'Isle Of Man', :alpha3 => 'IMN', :numeric => '833' },
151
159
  { :alpha2 => 'IL', :name => 'Israel', :alpha3 => 'ISR', :numeric => '376' },
152
160
  { :alpha2 => 'IT', :name => 'Italy', :alpha3 => 'ITA', :numeric => '380' },
153
161
  { :alpha2 => 'JM', :name => 'Jamaica', :alpha3 => 'JAM', :numeric => '388' },
154
162
  { :alpha2 => 'JP', :name => 'Japan', :alpha3 => 'JPN', :numeric => '392' },
163
+ { :alpha2 => 'JE', :name => 'Jersey', :alpha3 => 'JEY', :numeric => '832' },
155
164
  { :alpha2 => 'JO', :name => 'Jordan', :alpha3 => 'JOR', :numeric => '400' },
156
165
  { :alpha2 => 'KZ', :name => 'Kazakhstan', :alpha3 => 'KAZ', :numeric => '398' },
157
166
  { :alpha2 => 'KE', :name => 'Kenya', :alpha3 => 'KEN', :numeric => '404' },
@@ -181,11 +190,13 @@ module ActiveMerchant #:nodoc:
181
190
  { :alpha2 => 'MQ', :name => 'Martinique', :alpha3 => 'MTQ', :numeric => '474' },
182
191
  { :alpha2 => 'MR', :name => 'Mauritania', :alpha3 => 'MRT', :numeric => '478' },
183
192
  { :alpha2 => 'MU', :name => 'Mauritius', :alpha3 => 'MUS', :numeric => '480' },
193
+ { :alpha2 => 'YT', :name => 'Mayotte', :alpha3 => 'MYT', :numeric => '175' },
184
194
  { :alpha2 => 'MX', :name => 'Mexico', :alpha3 => 'MEX', :numeric => '484' },
185
195
  { :alpha2 => 'FM', :name => 'Micronesia, Federated States of', :alpha3 => 'FSM', :numeric => '583' },
186
196
  { :alpha2 => 'MD', :name => 'Moldova, Republic of', :alpha3 => 'MDA', :numeric => '498' },
187
197
  { :alpha2 => 'MC', :name => 'Monaco', :alpha3 => 'MCO', :numeric => '492' },
188
198
  { :alpha2 => 'MN', :name => 'Mongolia', :alpha3 => 'MNG', :numeric => '496' },
199
+ { :alpha2 => 'ME', :name => 'Montenegro', :alpha3 => 'MNE', :numeric => '499' },
189
200
  { :alpha2 => 'MS', :name => 'Montserrat', :alpha3 => 'MSR', :numeric => '500' },
190
201
  { :alpha2 => 'MA', :name => 'Morocco', :alpha3 => 'MAR', :numeric => '504' },
191
202
  { :alpha2 => 'MZ', :name => 'Mozambique', :alpha3 => 'MOZ', :numeric => '508' },
@@ -207,6 +218,7 @@ module ActiveMerchant #:nodoc:
207
218
  { :alpha2 => 'OM', :name => 'Oman', :alpha3 => 'OMN', :numeric => '512' },
208
219
  { :alpha2 => 'PK', :name => 'Pakistan', :alpha3 => 'PAK', :numeric => '586' },
209
220
  { :alpha2 => 'PW', :name => 'Palau', :alpha3 => 'PLW', :numeric => '585' },
221
+ { :alpha2 => 'PS', :name => 'Palestinian Territory, Occupied', :alpha3 => 'PSE', :numeric => '275' },
210
222
  { :alpha2 => 'PA', :name => 'Panama', :alpha3 => 'PAN', :numeric => '591' },
211
223
  { :alpha2 => 'PG', :name => 'Papua New Guinea', :alpha3 => 'PNG', :numeric => '598' },
212
224
  { :alpha2 => 'PY', :name => 'Paraguay', :alpha3 => 'PRY', :numeric => '600' },
@@ -221,9 +233,11 @@ module ActiveMerchant #:nodoc:
221
233
  { :alpha2 => 'RO', :name => 'Romania', :alpha3 => 'ROM', :numeric => '642' },
222
234
  { :alpha2 => 'RU', :name => 'Russian Federation', :alpha3 => 'RUS', :numeric => '643' },
223
235
  { :alpha2 => 'RW', :name => 'Rwanda', :alpha3 => 'RWA', :numeric => '646' },
236
+ { :alpha2 => 'BL', :name => 'Saint Barthélemy', :alpha3 => 'BLM', :numeric => '652' },
224
237
  { :alpha2 => 'SH', :name => 'Saint Helena', :alpha3 => 'SHN', :numeric => '654' },
225
238
  { :alpha2 => 'KN', :name => 'Saint Kitts and Nevis', :alpha3 => 'KNA', :numeric => '659' },
226
239
  { :alpha2 => 'LC', :name => 'Saint Lucia', :alpha3 => 'LCA', :numeric => '662' },
240
+ { :alpha2 => 'MF', :name => 'Saint Martin (French part)', :alpha3 => 'MAF', :numeric => '663' },
227
241
  { :alpha2 => 'PM', :name => 'Saint Pierre and Miquelon', :alpha3 => 'SPM', :numeric => '666' },
228
242
  { :alpha2 => 'VC', :name => 'Saint Vincent and the Grenadines', :alpha3 => 'VCT', :numeric => '670' },
229
243
  { :alpha2 => 'WS', :name => 'Samoa', :alpha3 => 'WSM', :numeric => '882' },
@@ -231,6 +245,7 @@ module ActiveMerchant #:nodoc:
231
245
  { :alpha2 => 'ST', :name => 'Sao Tome and Principe', :alpha3 => 'STP', :numeric => '678' },
232
246
  { :alpha2 => 'SA', :name => 'Saudi Arabia', :alpha3 => 'SAU', :numeric => '682' },
233
247
  { :alpha2 => 'SN', :name => 'Senegal', :alpha3 => 'SEN', :numeric => '686' },
248
+ { :alpha2 => 'RS', :name => 'Serbia', :alpha3 => 'SRB', :numeric => '688' },
234
249
  { :alpha2 => 'SC', :name => 'Seychelles', :alpha3 => 'SYC', :numeric => '690' },
235
250
  { :alpha2 => 'SL', :name => 'Sierra Leone', :alpha3 => 'SLE', :numeric => '694' },
236
251
  { :alpha2 => 'SG', :name => 'Singapore', :alpha3 => 'SGP', :numeric => '702' },
@@ -239,6 +254,7 @@ module ActiveMerchant #:nodoc:
239
254
  { :alpha2 => 'SB', :name => 'Solomon Islands', :alpha3 => 'SLB', :numeric => '090' },
240
255
  { :alpha2 => 'SO', :name => 'Somalia', :alpha3 => 'SOM', :numeric => '706' },
241
256
  { :alpha2 => 'ZA', :name => 'South Africa', :alpha3 => 'ZAF', :numeric => '710' },
257
+ { :alpha2 => 'GS', :name => 'South Georgia and the South Sandwich Islands', :alpha3 => 'SGS', :numeric => '239' },
242
258
  { :alpha2 => 'ES', :name => 'Spain', :alpha3 => 'ESP', :numeric => '724' },
243
259
  { :alpha2 => 'LK', :name => 'Sri Lanka', :alpha3 => 'LKA', :numeric => '144' },
244
260
  { :alpha2 => 'SD', :name => 'Sudan', :alpha3 => 'SDN', :numeric => '736' },
@@ -252,6 +268,7 @@ module ActiveMerchant #:nodoc:
252
268
  { :alpha2 => 'TJ', :name => 'Tajikistan', :alpha3 => 'TJK', :numeric => '762' },
253
269
  { :alpha2 => 'TZ', :name => 'Tanzania, United Republic of', :alpha3 => 'TZA', :numeric => '834' },
254
270
  { :alpha2 => 'TH', :name => 'Thailand', :alpha3 => 'THA', :numeric => '764' },
271
+ { :alpha2 => 'TL', :name => 'Timor Leste', :alpha3 => 'TLS', :numeric => '626' },
255
272
  { :alpha2 => 'TG', :name => 'Togo', :alpha3 => 'TGO', :numeric => '768' },
256
273
  { :alpha2 => 'TK', :name => 'Tokelau', :alpha3 => 'TKL', :numeric => '772' },
257
274
  { :alpha2 => 'TO', :name => 'Tonga', :alpha3 => 'TON', :numeric => '776' },
@@ -266,6 +283,7 @@ module ActiveMerchant #:nodoc:
266
283
  { :alpha2 => 'AE', :name => 'United Arab Emirates', :alpha3 => 'ARE', :numeric => '784' },
267
284
  { :alpha2 => 'GB', :name => 'United Kingdom', :alpha3 => 'GBR', :numeric => '826' },
268
285
  { :alpha2 => 'US', :name => 'United States', :alpha3 => 'USA', :numeric => '840' },
286
+ { :alpha2 => 'UM', :name => 'United States Minor Outlying Islands', :alpha3 => 'UMI', :numeric => '581' },
269
287
  { :alpha2 => 'UY', :name => 'Uruguay', :alpha3 => 'URY', :numeric => '858' },
270
288
  { :alpha2 => 'UZ', :name => 'Uzbekistan', :alpha3 => 'UZB', :numeric => '860' },
271
289
  { :alpha2 => 'VU', :name => 'Vanuatu', :alpha3 => 'VUT', :numeric => '548' },
@@ -27,38 +27,72 @@ module ActiveMerchant #:nodoc:
27
27
  base.read_timeout = READ_TIMEOUT
28
28
  end
29
29
 
30
+ def ssl_get(url, headers={})
31
+ ssl_request(:get, url, nil, headers)
32
+ end
33
+
30
34
  def ssl_post(url, data, headers = {})
31
- # Ruby 1.8.4 doesn't automatically set this header
32
- headers['Content-Type'] ||= "application/x-www-form-urlencoded"
35
+ ssl_request(:post, url, data, headers)
36
+ end
37
+
38
+ private
39
+ def retry_exceptions
40
+ retries = MAX_RETRIES
41
+ begin
42
+ yield
43
+ rescue RetriableConnectionError => e
44
+ retries -= 1
45
+ retry unless retries.zero?
46
+ raise ConnectionError, e.message
47
+ rescue ConnectionError
48
+ retries -= 1
49
+ retry if retry_safe && !retries.zero?
50
+ raise
51
+ end
52
+ end
53
+
54
+ def ssl_request(method, url, data, headers = {})
55
+ if method == :post
56
+ # Ruby 1.8.4 doesn't automatically set this header
57
+ headers['Content-Type'] ||= "application/x-www-form-urlencoded"
58
+ end
33
59
 
34
60
  uri = URI.parse(url)
35
61
 
36
- http = Net::HTTP.new(uri.host, uri.port)
62
+ http = Net::HTTP.new(uri.host, uri.port)
37
63
  http.open_timeout = self.class.open_timeout
38
64
  http.read_timeout = self.class.read_timeout
39
- http.use_ssl = true
40
65
 
41
- if ssl_strict
42
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
43
- http.ca_file = File.dirname(__FILE__) + '/../../certs/cacert.pem'
44
- else
45
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
46
- end
47
-
48
- if @options && !@options[:pem].blank?
49
- http.cert = OpenSSL::X509::Certificate.new(@options[:pem])
66
+ if uri.scheme == "https"
67
+ http.use_ssl = true
50
68
 
51
- if pem_password
52
- raise ArgumentError, "The private key requires a password" if @options[:pem_password].blank?
53
- http.key = OpenSSL::PKey::RSA.new(@options[:pem], @options[:pem_password])
69
+ if ssl_strict
70
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
71
+ http.ca_file = File.dirname(__FILE__) + '/../../certs/cacert.pem'
54
72
  else
55
- http.key = OpenSSL::PKey::RSA.new(@options[:pem])
73
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
74
+ end
75
+
76
+ if @options && !@options[:pem].blank?
77
+ http.cert = OpenSSL::X509::Certificate.new(@options[:pem])
78
+
79
+ if pem_password
80
+ raise ArgumentError, "The private key requires a password" if @options[:pem_password].blank?
81
+ http.key = OpenSSL::PKey::RSA.new(@options[:pem], @options[:pem_password])
82
+ else
83
+ http.key = OpenSSL::PKey::RSA.new(@options[:pem])
84
+ end
56
85
  end
57
86
  end
58
87
 
59
88
  retry_exceptions do
60
89
  begin
61
- http.post(uri.request_uri, data, headers).body
90
+ case method
91
+ when :get
92
+ http.get(uri.request_uri, headers).body
93
+ when :post
94
+ http.post(uri.request_uri, data, headers).body
95
+ end
62
96
  rescue EOFError => e
63
97
  raise ConnectionError, "The remote server dropped the connection"
64
98
  rescue Errno::ECONNRESET => e
@@ -69,21 +103,7 @@ module ActiveMerchant #:nodoc:
69
103
  raise ConnectionError, "The connection to the remote server timed out"
70
104
  end
71
105
  end
72
- end
73
-
74
- def retry_exceptions
75
- retries = MAX_RETRIES
76
- begin
77
- yield
78
- rescue RetriableConnectionError => e
79
- retries -= 1
80
- retry unless retries.zero?
81
- raise ConnectionError, e.message
82
- rescue ConnectionError
83
- retries -= 1
84
- retry if retry_safe && !retries.zero?
85
- raise
86
- end
87
106
  end
107
+
88
108
  end
89
- end
109
+ end