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 +4 -4
- data/NEWS +7 -0
- data/Rakefile +16 -3
- data/VERSION +1 -1
- data/generators/active_merchant/templates/db/ddl.sql.rb +3 -3
- data/generators/active_merchant/templates/db/schema.rb +3 -2
- data/generators/active_merchant/templates/lib/models/payment_method.rb +2 -2
- data/generators/active_merchant/templates/plugin.gemspec.rb +1 -1
- data/killbill.gemspec +5 -1
- data/lib/killbill/ext/active_merchant/typhoeus_connection.rb +82 -0
- data/lib/killbill/helpers/active_merchant/active_record/models/response.rb +3 -3
- data/lib/killbill/helpers/active_merchant/configuration.rb +7 -1
- data/lib/killbill/helpers/active_merchant/gateway.rb +11 -2
- data/lib/killbill/helpers/active_merchant/payment_plugin.rb +15 -7
- data/spec/killbill/helpers/payment_plugin_spec.rb +115 -0
- data/spec/killbill/helpers/test_schema.rb +2 -2
- data/spec/killbill/payment_plugin_spec.rb +3 -4
- data/spec/killbill/remote/active_merchant_typhoeus_connection_spec.rb +53 -0
- data/spec/spec_helper.rb +3 -0
- metadata +63 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1564801f1c0cf35922d6784c77c6bad9a0e16cb0
|
4
|
+
data.tar.gz: f3f0d953fb91af7b5bf848ed44bad0d12f485c0b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
10
|
-
RSpec
|
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.
|
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)
|
41
|
-
`amount_in_cents` int(11)
|
42
|
-
`currency` varchar(255)
|
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
|
-
|
43
|
-
t.
|
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
|
-
|
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.
|
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,
|
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,
|
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?
|
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
|
-
|
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
|
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
|
-
#
|
169
|
-
|
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(
|
402
|
-
@logger.warn "Unsuccessful #{api_call}: #{
|
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,
|
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"
|
37
|
-
t.string "currency"
|
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, @
|
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, @
|
42
|
-
lambda { @plugin.set_default_payment_method(@kb_account_id, @
|
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.
|
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-
|
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
|