killbill 3.1.7 → 3.1.8

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 840154880668dbe44506afa06448cca00b735211
4
- data.tar.gz: ab55ade3ab7c798f73dd41ae6ea5416ccee13b54
3
+ metadata.gz: 1564801f1c0cf35922d6784c77c6bad9a0e16cb0
4
+ data.tar.gz: f3f0d953fb91af7b5bf848ed44bad0d12f485c0b
5
5
  SHA512:
6
- metadata.gz: 4a45e5751639706d0796ef92704f9ef92b3ee7ac14ff8e292254560d5b7e4bcb2bf59c0ff019948af8962c3b8810b82f168113d4d514f6746551238c2ae24bd9
7
- data.tar.gz: ce45e19db6c7fa36e955fd250c36cbae052f0d4b86761d10974928e03596b98058a045a571eb757704fc8f85aae4ed8635a919091759a44405d3bbd8fadf8744
6
+ metadata.gz: 287c4cbadcce9715807704728cc7a718e521bf4ec2ef807749c81a036b381a8ed680ccb21aa4d6c280cb93dfd4be369426534ff11bd35b87a2bd71060435adb3
7
+ data.tar.gz: 22c5ca459cf77f5e096f76688c5fb0283076255a641ef2259be3c52e71dc8d7bdca31a6f8ea6ca11a7e25bd310460091cbd2d002ab4a3ba9e51080b72fc4de35
data/NEWS CHANGED
@@ -1,3 +1,10 @@
1
+ 3.1.8
2
+ Make ActiveMerchant HTTP backend configurable, add support for Typhoeus
3
+ generator:
4
+ - Remove transactions.txn_id, transactions.amount_in_cents and transactions.currency NOT NULL constraint
5
+ - Update PaymentMethod.from_response signature
6
+ - Add :skip_gw option to skip the gateway entirely
7
+
1
8
  3.1.7
2
9
  Support more Logger APIs
3
10
 
data/Rakefile CHANGED
@@ -6,8 +6,21 @@ Bundler::GemHelper.install_tasks
6
6
 
7
7
  # Install test tasks
8
8
  require 'rspec/core/rake_task'
9
- desc "Run RSpec"
10
- RSpec::Core::RakeTask.new
9
+ namespace :test do
10
+ desc 'Run RSpec tests'
11
+ RSpec::Core::RakeTask.new do |task|
12
+ task.name = 'spec'
13
+ task.pattern = './spec/*/{,helpers/}*_spec.rb'
14
+ end
15
+
16
+ namespace :remote do
17
+ desc 'Run RSpec remote tests'
18
+ RSpec::Core::RakeTask.new do |task|
19
+ task.name = 'spec'
20
+ task.pattern = './spec/*/remote/*_spec.rb'
21
+ end
22
+ end
23
+ end
11
24
 
12
25
  # Run tests by default
13
- task :default => :spec
26
+ task :default => 'test:spec'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.1.7
1
+ 3.1.8
@@ -37,9 +37,9 @@ CREATE TABLE `<%= identifier %>_transactions` (
37
37
  `kb_payment_id` varchar(255) NOT NULL,
38
38
  `kb_payment_transaction_id` varchar(255) NOT NULL,
39
39
  `transaction_type` varchar(255) NOT NULL,
40
- `txn_id` varchar(255) NOT NULL,
41
- `amount_in_cents` int(11) NOT NULL,
42
- `currency` varchar(255) NOT NULL,
40
+ `txn_id` varchar(255) DEFAULT NULL,
41
+ `amount_in_cents` int(11) DEFAULT NULL,
42
+ `currency` varchar(255) DEFAULT NULL,
43
43
  `created_at` datetime NOT NULL,
44
44
  `updated_at` datetime NOT NULL,
45
45
  `kb_account_id` varchar(255) NOT NULL,
@@ -39,8 +39,9 @@ ActiveRecord::Schema.define(:version => 20140410153635) do
39
39
  t.string "kb_payment_transaction_id", :null => false
40
40
  t.string "transaction_type", :null => false
41
41
  t.string "txn_id" # <%= identifier %> transaction id
42
- t.integer "amount_in_cents", :null => false
43
- t.string "currency", :null => false
42
+ # Both null for void
43
+ t.integer "amount_in_cents"
44
+ t.string "currency"
44
45
  t.datetime "created_at", :null => false
45
46
  t.datetime "updated_at", :null => false
46
47
  t.string "kb_account_id", :null => false
@@ -4,7 +4,7 @@ module Killbill #:nodoc:
4
4
 
5
5
  self.table_name = '<%= identifier %>_payment_methods'
6
6
 
7
- def self.from_response(kb_account_id, kb_payment_method_id, kb_tenant_id, cc_or_token, response, options, extra_params = {})
7
+ def self.from_response(kb_account_id, kb_payment_method_id, kb_tenant_id, cc_or_token, response, options, extra_params = {}, model = ::Killbill::<%= class_name %>::<%= class_name %>PaymentMethod)
8
8
  super(kb_account_id,
9
9
  kb_payment_method_id,
10
10
  kb_tenant_id,
@@ -16,7 +16,7 @@ module Killbill #:nodoc:
16
16
  #:params_id => extract(response, 'id'),
17
17
  #:params_card_id => extract(response, 'card', 'id')
18
18
  }.merge!(extra_params),
19
- ::Killbill::<%= class_name %>::<%= class_name %>PaymentMethod)
19
+ model)
20
20
  end
21
21
  end
22
22
  end
@@ -22,7 +22,7 @@ Gem::Specification.new do |s|
22
22
 
23
23
  s.rdoc_options << '--exclude' << '.'
24
24
 
25
- s.add_dependency 'killbill', '~> 3.1.6'
25
+ s.add_dependency 'killbill', '~> 3.1.8'
26
26
  s.add_dependency 'activemerchant', '~> 1.42.9'
27
27
  s.add_dependency 'activerecord', '~> 4.1.0'
28
28
  s.add_dependency 'actionpack', '~> 4.1.0'
data/killbill.gemspec CHANGED
@@ -17,21 +17,25 @@ Gem::Specification.new do |s|
17
17
  s.files = `git ls-files`.split("\n")
18
18
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
19
  s.bindir = 'bin'
20
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
21
21
  s.require_paths = ["lib"]
22
22
 
23
23
  s.rdoc_options << '--exclude' << '.'
24
24
 
25
25
  s.add_dependency 'sinatra', '~> 1.3.4'
26
+ s.add_dependency 'typhoeus', '~> 0.6.9'
26
27
  s.add_dependency 'tzinfo', '~> 1.1.0'
27
28
 
28
29
  s.add_development_dependency 'activerecord', '~> 4.1.0'
29
30
  if defined?(JRUBY_VERSION)
31
+ s.add_development_dependency 'activerecord-jdbcmysql-adapter', '~> 1.3.7'
30
32
  s.add_development_dependency 'activerecord-jdbcsqlite3-adapter', '~> 1.3.7'
31
33
  else
32
34
  s.add_development_dependency 'sqlite3', '~> 1.3.7'
33
35
  end
34
36
  s.add_development_dependency 'activemerchant', '~> 1.42.0'
37
+ s.add_development_dependency 'monetize', '~> 0.3.0'
38
+ s.add_development_dependency 'money', '~> 6.1.1'
35
39
  s.add_development_dependency 'jbundler', '~> 0.4.3'
36
40
  s.add_development_dependency 'rack', '>= 1.5.2'
37
41
  s.add_development_dependency 'rake', '>= 0.8.7'
@@ -0,0 +1,82 @@
1
+ require 'benchmark'
2
+ require 'active_utils/common/error'
3
+ require 'active_utils/common/network_connection_retries'
4
+ require 'active_utils/common/connection'
5
+ require 'typhoeus'
6
+
7
+ module ActiveMerchant
8
+ class Connection
9
+
10
+ def request(method, body, headers = {})
11
+ request_start = Time.now.to_f
12
+
13
+ retry_exceptions(:max_retries => max_retries, :logger => logger, :tag => tag) do
14
+ begin
15
+ debug "connection_http_method=#{method.to_s.upcase} connection_uri=#{endpoint}", tag
16
+
17
+ result = nil
18
+ realtime = Benchmark.realtime do
19
+ options = {:method => method, :headers => headers}
20
+ options[:body] = body if body
21
+ result = http(endpoint.to_s, options)
22
+ end
23
+
24
+ debug '--> response_code=%d (body_length=%d total_time=%.4fs realtime=%.4fs)' % [result.code, result.body ? result.body.length : 0, result.total_time, realtime], tag
25
+ result
26
+ end
27
+ end
28
+ ensure
29
+ debug 'connection_request_total_time=%.4fs' % [Time.now.to_f - request_start], tag
30
+ end
31
+
32
+ private
33
+
34
+ def http(endpoint, options = {})
35
+ configure_ssl(options)
36
+
37
+ request = ::Typhoeus::Request.new(endpoint, options)
38
+ configure_debugging(request)
39
+
40
+ hydra = ::Typhoeus::Hydra.hydra
41
+ hydra.queue request
42
+ hydra.run
43
+
44
+ request.response
45
+ end
46
+
47
+ def configure_debugging(request)
48
+ request.on_complete do |response|
49
+ wiredump_device << 'Request: '
50
+ wiredump_device << response.request.base_url
51
+ wiredump_device << ' '
52
+ wiredump_device << response.request.options
53
+ wiredump_device << "\nResponse: "
54
+ wiredump_device << response.return_code
55
+ wiredump_device << ' '
56
+ wiredump_device << response.return_message
57
+ wiredump_device << ' '
58
+ wiredump_device << response.response_headers
59
+ wiredump_device << ' '
60
+ wiredump_device << response.response_body
61
+ wiredump_device << "\n\n"
62
+ end
63
+ end
64
+
65
+ def configure_ssl(options)
66
+ return unless endpoint.scheme == 'https'
67
+
68
+ if verify_peer
69
+ options[:ssl_verifypeer] ||= true
70
+ options[:ssl_verifyhost] ||= 2
71
+ # ca_file / ca_path configured in libcurl
72
+ else
73
+ options[:ssl_verifypeer] ||= false
74
+ options[:ssl_verifyhost] ||= 0
75
+ end
76
+ end
77
+
78
+ def log_with_retry_details(logger, attempts, time, message, tag)
79
+ NetworkConnectionRetries.log(logger, :debug, "connection_attempt=%d connection_request_time=%.4fs connection_msg=\"%s\"" % [attempts, time, message], tag)
80
+ end
81
+ end
82
+ end
@@ -35,19 +35,19 @@ module Killbill
35
35
  }.merge!(extra_params))
36
36
  end
37
37
 
38
- def self.create_response_and_transaction(identifier, transaction_model, api_call, kb_account_id, kb_payment_id, kb_payment_transaction_id, transaction_type, kb_tenant_id, am_response, amount_in_cents, currency, extra_params = {}, model = Response)
38
+ def self.create_response_and_transaction(identifier, transaction_model, api_call, kb_account_id, kb_payment_id, kb_payment_transaction_id, transaction_type, kb_tenant_id, gw_response, amount_in_cents, currency, extra_params = {}, model = Response)
39
39
  response, transaction, exception = nil
40
40
 
41
41
  # Rails wraps all create/save calls in a transaction. To speed things up, create a single transaction for both rows.
42
42
  # This has a small gotcha in the unhappy path though (see below).
43
43
  transaction do
44
44
  # Save the response to our logs
45
- response = from_response(api_call, kb_account_id, kb_payment_id, kb_payment_transaction_id, transaction_type, kb_tenant_id, am_response, extra_params, model)
45
+ response = from_response(api_call, kb_account_id, kb_payment_id, kb_payment_transaction_id, transaction_type, kb_tenant_id, gw_response, extra_params, model)
46
46
  response.save!(shared_activerecord_options)
47
47
 
48
48
  transaction = nil
49
49
  txn_id = response.txn_id
50
- if response.success and !kb_payment_id.blank? and !txn_id.blank?
50
+ if response.success and !kb_payment_id.blank?
51
51
  # Record the transaction
52
52
  # Note that we want to avoid throwing an exception here because we don't want to rollback the response row
53
53
  begin
@@ -19,7 +19,7 @@ module Killbill
19
19
  @@kb_apis = kb_apis
20
20
  @@test = @@config[gateway_name][:test]
21
21
 
22
- @@gateway = Gateway.wrap(gateway_builder, @@config[gateway_name.to_sym])
22
+ @@gateway = Gateway.wrap(gateway_builder, logger, @@config[gateway_name.to_sym])
23
23
 
24
24
  @@logger = logger
25
25
  @@logger.log_level = Logger::DEBUG if (@@config[:logger] || {})[:debug]
@@ -42,6 +42,12 @@ module Killbill
42
42
  @@logger.warn "Unable to establish a database connection: #{e}"
43
43
  end
44
44
 
45
+ # Configure the ActiveMerchant HTTP backend
46
+ connection_type = (@@config[:active_merchant] || {})[:connection_type]
47
+ if connection_type == :typhoeus
48
+ require 'killbill/ext/active_merchant/typhoeus_connection'
49
+ end
50
+
45
51
  @@initialized = true
46
52
  end
47
53
 
@@ -4,7 +4,9 @@ module Killbill
4
4
  require 'active_merchant'
5
5
 
6
6
  class Gateway
7
- def self.wrap(gateway_builder, config)
7
+ def self.wrap(gateway_builder, logger, config)
8
+ ::ActiveMerchant::Billing::Gateway.logger = logger
9
+
8
10
  if config[:test]
9
11
  ::ActiveMerchant::Billing::Base.mode = :test
10
12
  end
@@ -23,10 +25,17 @@ module Killbill
23
25
 
24
26
  # Unfortunate name...
25
27
  def capture(money, authorization, options = {})
26
- @gateway.capture(money, authorization, options)
28
+ method_missing(:capture, money, authorization, options)
27
29
  end
28
30
 
29
31
  def method_missing(m, *args, &block)
32
+ # The options hash should be the last argument, iterate through all to be safe
33
+ args.reverse.each do |arg|
34
+ if arg.respond_to?(:has_key?) && arg.has_key?(:skip_gw)
35
+ return ::ActiveMerchant::Billing::Response.new(true, 'Skipped Gateway call')
36
+ end
37
+ end
38
+
30
39
  @gateway.send(m, *args, &block)
31
40
  end
32
41
  end
@@ -2,6 +2,7 @@ module Killbill
2
2
  module Plugin
3
3
  module ActiveMerchant
4
4
  require 'active_record'
5
+ require 'monetize'
5
6
  require 'money'
6
7
 
7
8
  class PaymentPlugin < ::Killbill::Plugin::Payment
@@ -161,12 +162,19 @@ module Killbill
161
162
  payment_source = get_payment_source(nil, all_properties, options, context)
162
163
 
163
164
  # Go to the gateway
164
- gw_response = gateway.store payment_source, options
165
+ gw_response = gateway.store(payment_source, options)
165
166
  response, transaction = save_response_and_transaction gw_response, :add_payment_method, kb_account_id, context.tenant_id
166
167
 
167
168
  if response.success
168
- # response.authorization may be a String combination separated by ; - don't split it! Some plugins expect it as-is (they split it themselves)
169
- payment_method = @payment_method_model.from_response(kb_account_id, kb_payment_method_id, context.tenant_id, response.authorization, gw_response, options)
169
+ # If we have skipped the call to the gateway, we still need to store the payment method
170
+ if options[:skip_gw]
171
+ cc_or_token = payment_source
172
+ else
173
+ # response.authorization may be a String combination separated by ; - don't split it! Some plugins expect it as-is (they split it themselves)
174
+ cc_or_token = response.authorization
175
+ end
176
+
177
+ payment_method = @payment_method_model.from_response(kb_account_id, kb_payment_method_id, context.tenant_id, cc_or_token, gw_response, options, {}, @payment_method_model)
170
178
  payment_method.save!
171
179
  payment_method
172
180
  else
@@ -346,7 +354,7 @@ module Killbill
346
354
 
347
355
  def to_cents(amount, currency)
348
356
  # Use Money to compute the amount in cents, as it depends on the currency (1 cent of BTC is 1 Satoshi, not 0.01 BTC)
349
- Monetize.from_numeric(amount, currency).cents.to_i
357
+ ::Monetize.from_numeric(amount, currency).cents.to_i
350
358
  end
351
359
 
352
360
  def get_payment_source(kb_payment_method_id, properties, options, context)
@@ -398,10 +406,10 @@ module Killbill
398
406
  account.currency
399
407
  end
400
408
 
401
- def save_response_and_transaction(response, api_call, kb_account_id, kb_tenant_id, kb_payment_id=nil, kb_payment_transaction_id=nil, transaction_type=nil, amount_in_cents=0, currency=nil)
402
- @logger.warn "Unsuccessful #{api_call}: #{response.message}" unless response.success?
409
+ def save_response_and_transaction(gw_response, api_call, kb_account_id, kb_tenant_id, kb_payment_id=nil, kb_payment_transaction_id=nil, transaction_type=nil, amount_in_cents=0, currency=nil)
410
+ @logger.warn "Unsuccessful #{api_call}: #{gw_response.message}" unless gw_response.success?
403
411
 
404
- response, transaction = @response_model.create_response_and_transaction(@identifier, @transaction_model, api_call, kb_account_id, kb_payment_id, kb_payment_transaction_id, transaction_type, kb_tenant_id, response, amount_in_cents, currency, {}, @response_model)
412
+ response, transaction = @response_model.create_response_and_transaction(@identifier, @transaction_model, api_call, kb_account_id, kb_payment_id, kb_payment_transaction_id, transaction_type, kb_tenant_id, gw_response, amount_in_cents, currency, {}, @response_model)
405
413
 
406
414
  @logger.debug "Recorded transaction: #{transaction.inspect}" unless transaction.nil?
407
415
 
@@ -0,0 +1,115 @@
1
+ require 'spec_helper'
2
+ require 'spec/killbill/helpers/payment_method_spec'
3
+ require 'spec/killbill/helpers/response_spec'
4
+ require 'spec/killbill/helpers/transaction_spec'
5
+
6
+ describe Killbill::Plugin::ActiveMerchant::PaymentPlugin do
7
+
8
+ before(:all) do
9
+ Dir.mktmpdir do |dir|
10
+ file = File.new(File.join(dir, 'test.yml'), "w+")
11
+ file.write(<<-eos)
12
+ :test:
13
+ :test: true
14
+ # As defined by spec_helper.rb
15
+ :database:
16
+ :adapter: 'sqlite3'
17
+ :database: 'test.db'
18
+ eos
19
+ file.close
20
+
21
+ @plugin = ::Killbill::Plugin::ActiveMerchant::PaymentPlugin.new(Proc.new { |config| nil },
22
+ :test,
23
+ ::Killbill::Test::TestPaymentMethod,
24
+ ::Killbill::Test::TestTransaction,
25
+ ::Killbill::Test::TestResponse)
26
+ @plugin.logger = Logger.new(STDOUT)
27
+ @plugin.logger.level = Logger::INFO
28
+ @plugin.conf_dir = File.dirname(file)
29
+
30
+ # Start the plugin here - since the config file will be deleted
31
+ @plugin.start_plugin
32
+ end
33
+ end
34
+
35
+ before(:each) do
36
+ @kb_account_id = SecureRandom.uuid
37
+ @kb_payment_id = SecureRandom.uuid
38
+ @kb_payment_method_id = SecureRandom.uuid
39
+
40
+ @amount_in_cents = rand(100000)
41
+ @currency = 'USD'
42
+ @call_context = Killbill::Plugin::Model::CallContext.new
43
+ @call_context.tenant_id = SecureRandom.uuid
44
+
45
+ property = ::Killbill::Plugin::Model::PluginProperty.new
46
+ property.key = 'skip_gw'
47
+ property.value = 'true'
48
+ @properties = [property]
49
+
50
+ token = ::Killbill::Plugin::Model::PluginProperty.new
51
+ token.key = 'token'
52
+ token.value = SecureRandom.uuid
53
+ @payment_method_props = ::Killbill::Plugin::Model::PaymentMethodPlugin.new
54
+ @payment_method_props.properties = [token]
55
+ end
56
+
57
+ after(:all) do
58
+ @plugin.stop_plugin
59
+ end
60
+
61
+ it 'should implement payment plugin API calls' do
62
+ @plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context).size.should == 0
63
+
64
+ @plugin.add_payment_method(@kb_account_id, @kb_payment_method_id, @payment_method_props, true, @properties, @call_context)
65
+ @plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context).size.should == 1
66
+ ::Killbill::Test::TestPaymentMethod.where(:kb_payment_method_id => @kb_payment_method_id).first.token.should == @payment_method_props.properties[0].value
67
+
68
+ authorization_id = SecureRandom.uuid
69
+ authorization = @plugin.authorize_payment(@kb_account_id, @kb_payment_id, authorization_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
70
+ verify_transaction_info_plugin(authorization, authorization_id, :AUTHORIZE, 1)
71
+
72
+ capture_id = SecureRandom.uuid
73
+ capture = @plugin.capture_payment(@kb_account_id, @kb_payment_id, capture_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
74
+ verify_transaction_info_plugin(capture, capture_id, :CAPTURE, 2)
75
+
76
+ purchase_id = SecureRandom.uuid
77
+ purchase = @plugin.purchase_payment(@kb_account_id, @kb_payment_id, purchase_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
78
+ verify_transaction_info_plugin(purchase, purchase_id, :PURCHASE, 3)
79
+
80
+ void_id = SecureRandom.uuid
81
+ void = @plugin.void_payment(@kb_account_id, @kb_payment_id, void_id, @kb_payment_method_id, @properties, @call_context)
82
+ verify_transaction_info_plugin(void, void_id, :VOID, 4)
83
+
84
+ credit_id = SecureRandom.uuid
85
+ credit = @plugin.credit_payment(@kb_account_id, @kb_payment_id, credit_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
86
+ verify_transaction_info_plugin(credit, credit_id, :CREDIT, 5)
87
+
88
+ refund_id = SecureRandom.uuid
89
+ refund = @plugin.refund_payment(@kb_account_id, @kb_payment_id, refund_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
90
+ verify_transaction_info_plugin(refund, refund_id, :REFUND, 6)
91
+
92
+ @plugin.delete_payment_method(@kb_account_id, @kb_payment_method_id, @properties, @call_context)
93
+ @plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context).size.should == 0
94
+ end
95
+
96
+ private
97
+
98
+ def verify_transaction_info_plugin(t_info_plugin, kb_transaction_id, type, transaction_nb)
99
+ t_info_plugin.kb_payment_id.should == @kb_payment_id
100
+ t_info_plugin.kb_transaction_payment_id.should == kb_transaction_id
101
+ t_info_plugin.transaction_type.should == type
102
+ if type == :VOID
103
+ t_info_plugin.amount.should be_nil
104
+ t_info_plugin.currency.should be_nil
105
+ else
106
+ t_info_plugin.amount.should == @amount_in_cents
107
+ t_info_plugin.currency.should == @currency
108
+ end
109
+ t_info_plugin.status.should == :PROCESSED
110
+
111
+ transactions = @plugin.get_payment_info(@kb_account_id, @kb_payment_id, [], @call_context)
112
+ transactions.size.should == transaction_nb
113
+ transactions[transaction_nb - 1].to_json.should == t_info_plugin.to_json
114
+ end
115
+ end
@@ -33,8 +33,8 @@ ActiveRecord::Schema.define(:version => 20140410153635) do
33
33
  t.string "kb_payment_transaction_id", :null => false
34
34
  t.string "transaction_type", :null => false
35
35
  t.string "txn_id"
36
- t.integer "amount_in_cents", :null => false
37
- t.string "currency", :null => false
36
+ t.integer "amount_in_cents"
37
+ t.string "currency"
38
38
  t.datetime "created_at", :null => false
39
39
  t.datetime "updated_at", :null => false
40
40
  t.string "kb_account_id", :null => false
@@ -12,7 +12,6 @@ describe Killbill::Plugin::Payment do
12
12
  @currency = 'USD'
13
13
  @call_context = Killbill::Plugin::Model::CallContext.new
14
14
 
15
- @payment_method = Hash.new(:credit_card => SecureRandom.uuid)
16
15
  @kb_payment_method_id = SecureRandom.uuid
17
16
 
18
17
  @search_key = SecureRandom.uuid
@@ -36,10 +35,10 @@ describe Killbill::Plugin::Payment do
36
35
  lambda { @plugin.refund_payment(@kb_account_id, @kb_payment_id, @kb_payment_transaction_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context) }.should raise_error Killbill::Plugin::Payment::OperationUnsupportedByGatewayError
37
36
  lambda { @plugin.get_payment_info(@kb_account_id, @kb_payment_id, @properties, @call_context) }.should raise_error Killbill::Plugin::Payment::OperationUnsupportedByGatewayError
38
37
  lambda { @plugin.search_payments(@search_key, @offset, @limit, @properties, @call_context) }.should raise_error Killbill::Plugin::Payment::OperationUnsupportedByGatewayError
39
- lambda { @plugin.add_payment_method(@kb_account_id, @payment_method, @payment_method_props, true, @properties, @call_context) }.should raise_error Killbill::Plugin::Payment::OperationUnsupportedByGatewayError
38
+ lambda { @plugin.add_payment_method(@kb_account_id, @kb_payment_method_id, @payment_method_props, true, @properties, @call_context) }.should raise_error Killbill::Plugin::Payment::OperationUnsupportedByGatewayError
40
39
  lambda { @plugin.delete_payment_method(@kb_account_id, @kb_payment_method_id, @properties, @call_context) }.should raise_error Killbill::Plugin::Payment::OperationUnsupportedByGatewayError
41
- lambda { @plugin.get_payment_method_detail(@kb_account_id, @payment_method, @properties, @call_context) }.should raise_error Killbill::Plugin::Payment::OperationUnsupportedByGatewayError
42
- lambda { @plugin.set_default_payment_method(@kb_account_id, @payment_method, @properties, @call_context) }.should raise_error Killbill::Plugin::Payment::OperationUnsupportedByGatewayError
40
+ lambda { @plugin.get_payment_method_detail(@kb_account_id, @kb_payment_method_id, @properties, @call_context) }.should raise_error Killbill::Plugin::Payment::OperationUnsupportedByGatewayError
41
+ lambda { @plugin.set_default_payment_method(@kb_account_id, @kb_payment_method_id, @properties, @call_context) }.should raise_error Killbill::Plugin::Payment::OperationUnsupportedByGatewayError
43
42
  lambda { @plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context) }.should raise_error Killbill::Plugin::Payment::OperationUnsupportedByGatewayError
44
43
  lambda { @plugin.search_payment_methods(@search_key, @offset, @limit, @properties, @call_context) }.should raise_error Killbill::Plugin::Payment::OperationUnsupportedByGatewayError
45
44
  lambda { @plugin.reset_payment_methods(@kb_account_id, @payment_methods, @properties, @call_context) }.should raise_error Killbill::Plugin::Payment::OperationUnsupportedByGatewayError
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActiveMerchant::Connection do
4
+
5
+ before :all do
6
+ @logger = Logger.new(STDOUT)
7
+ @logger.level = Logger::DEBUG
8
+
9
+ @wiredump_device = Tempfile.new('foo')
10
+ end
11
+
12
+ after :all do
13
+ @wiredump_device.close
14
+ @wiredump_device.unlink
15
+ end
16
+
17
+ it 'should delegate to Typhoeus' do
18
+ response = ssl_get('https://github.com/killbill/killbill/blob/master/pom.xml')
19
+ response.code.should == 200
20
+ response.return_code.should == :ok
21
+ response.body.size.should > 0
22
+
23
+ response = ssl_get('https://github.com/killbill/killbill/blob/master/pomme.xml')
24
+ response.code.should == 404
25
+ response.return_code.should == :ok
26
+ response.body.size.should > 0
27
+
28
+ response = ssl_get('/something')
29
+ response.return_code.should == :url_malformat
30
+ response.body.size.should == 0
31
+ end
32
+
33
+ private
34
+
35
+ def ssl_get(endpoint, headers={})
36
+ ssl_request(:get, endpoint, nil, headers)
37
+ end
38
+
39
+ def ssl_request(method, endpoint, data, headers = {})
40
+ connection = ::ActiveMerchant::Connection.new(endpoint)
41
+ connection.open_timeout = 60
42
+ connection.read_timeout = 60
43
+ connection.retry_safe = true
44
+ connection.verify_peer = true
45
+ connection.logger = @logger
46
+ connection.tag = self.class.name
47
+ connection.wiredump_device = @wiredump_device
48
+ connection.pem = nil
49
+ connection.pem_password = nil
50
+
51
+ connection.request(method, data, headers)
52
+ end
53
+ end
data/spec/spec_helper.rb CHANGED
@@ -2,6 +2,7 @@ require 'java'
2
2
 
3
3
  require 'bundler'
4
4
  require 'logger'
5
+ require 'tempfile'
5
6
 
6
7
  require 'killbill'
7
8
  require 'killbill/killbill_logger'
@@ -13,6 +14,8 @@ require 'killbill/notification_test'
13
14
  require 'killbill/helpers/active_merchant'
14
15
  require 'killbill/helpers/active_merchant/active_record/models/helpers'
15
16
 
17
+ require 'killbill/ext/active_merchant/typhoeus_connection'
18
+
16
19
  %w(
17
20
  MockAccountUserApi
18
21
  ).each do |api|
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: killbill
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.7
4
+ version: 3.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kill Bill core team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-25 00:00:00.000000000 Z
11
+ date: 2014-08-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sinatra
@@ -24,6 +24,20 @@ dependencies:
24
24
  version: 1.3.4
25
25
  prerelease: false
26
26
  type: :runtime
27
+ - !ruby/object:Gem::Dependency
28
+ name: typhoeus
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 0.6.9
34
+ requirement: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ~>
37
+ - !ruby/object:Gem::Version
38
+ version: 0.6.9
39
+ prerelease: false
40
+ type: :runtime
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: tzinfo
29
43
  version_requirements: !ruby/object:Gem::Requirement
@@ -52,6 +66,20 @@ dependencies:
52
66
  version: 4.1.0
53
67
  prerelease: false
54
68
  type: :development
69
+ - !ruby/object:Gem::Dependency
70
+ name: activerecord-jdbcmysql-adapter
71
+ version_requirements: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: 1.3.7
76
+ requirement: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ~>
79
+ - !ruby/object:Gem::Version
80
+ version: 1.3.7
81
+ prerelease: false
82
+ type: :development
55
83
  - !ruby/object:Gem::Dependency
56
84
  name: activerecord-jdbcsqlite3-adapter
57
85
  version_requirements: !ruby/object:Gem::Requirement
@@ -80,6 +108,34 @@ dependencies:
80
108
  version: 1.42.0
81
109
  prerelease: false
82
110
  type: :development
111
+ - !ruby/object:Gem::Dependency
112
+ name: monetize
113
+ version_requirements: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: 0.3.0
118
+ requirement: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ~>
121
+ - !ruby/object:Gem::Version
122
+ version: 0.3.0
123
+ prerelease: false
124
+ type: :development
125
+ - !ruby/object:Gem::Dependency
126
+ name: money
127
+ version_requirements: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ~>
130
+ - !ruby/object:Gem::Version
131
+ version: 6.1.1
132
+ requirement: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ~>
135
+ - !ruby/object:Gem::Version
136
+ version: 6.1.1
137
+ prerelease: false
138
+ type: :development
83
139
  - !ruby/object:Gem::Dependency
84
140
  name: jbundler
85
141
  version_requirements: !ruby/object:Gem::Requirement
@@ -199,6 +255,7 @@ files:
199
255
  - lib/killbill.rb
200
256
  - lib/killbill/creator.rb
201
257
  - lib/killbill/currency.rb
258
+ - lib/killbill/ext/active_merchant/typhoeus_connection.rb
202
259
  - lib/killbill/gen/api/account.rb
203
260
  - lib/killbill/gen/api/account_api_exception.rb
204
261
  - lib/killbill/gen/api/account_audit_logs.rb
@@ -348,6 +405,7 @@ files:
348
405
  - spec/killbill/config_test.ru
349
406
  - spec/killbill/gen_conversions_spec.rb
350
407
  - spec/killbill/helpers/payment_method_spec.rb
408
+ - spec/killbill/helpers/payment_plugin_spec.rb
351
409
  - spec/killbill/helpers/response_spec.rb
352
410
  - spec/killbill/helpers/test_schema.rb
353
411
  - spec/killbill/helpers/transaction_spec.rb
@@ -362,6 +420,7 @@ files:
362
420
  - spec/killbill/payment_plugin_spec.rb
363
421
  - spec/killbill/payment_test.rb
364
422
  - spec/killbill/rack_handler_spec.rb
423
+ - spec/killbill/remote/active_merchant_typhoeus_connection_spec.rb
365
424
  - spec/spec_helper.rb
366
425
  homepage: http://kill-bill.org
367
426
  licenses:
@@ -396,6 +455,7 @@ test_files:
396
455
  - spec/killbill/config_test.ru
397
456
  - spec/killbill/gen_conversions_spec.rb
398
457
  - spec/killbill/helpers/payment_method_spec.rb
458
+ - spec/killbill/helpers/payment_plugin_spec.rb
399
459
  - spec/killbill/helpers/response_spec.rb
400
460
  - spec/killbill/helpers/test_schema.rb
401
461
  - spec/killbill/helpers/transaction_spec.rb
@@ -410,4 +470,5 @@ test_files:
410
470
  - spec/killbill/payment_plugin_spec.rb
411
471
  - spec/killbill/payment_test.rb
412
472
  - spec/killbill/rack_handler_spec.rb
473
+ - spec/killbill/remote/active_merchant_typhoeus_connection_spec.rb
413
474
  - spec/spec_helper.rb