killbill 3.1.8 → 3.1.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1564801f1c0cf35922d6784c77c6bad9a0e16cb0
4
- data.tar.gz: f3f0d953fb91af7b5bf848ed44bad0d12f485c0b
3
+ metadata.gz: fecf6eec986317ba4b930aea485670c18fbc88b2
4
+ data.tar.gz: 642dbcbe75183170bfe68b07925653bf51855a29
5
5
  SHA512:
6
- metadata.gz: 287c4cbadcce9715807704728cc7a718e521bf4ec2ef807749c81a036b381a8ed680ccb21aa4d6c280cb93dfd4be369426534ff11bd35b87a2bd71060435adb3
7
- data.tar.gz: 22c5ca459cf77f5e096f76688c5fb0283076255a641ef2259be3c52e71dc8d7bdca31a6f8ea6ca11a7e25bd310460091cbd2d002ab4a3ba9e51080b72fc4de35
6
+ metadata.gz: 900a0cb3ce17d6060cac359fe685fe42b593a492fa97b4f1a9c418255524c18415a67641c09092716a82827c17d3c905eedab1036f76f23c57a761967adda8be
7
+ data.tar.gz: f03f0c261d3390cae2246a9a31464a0cc10ee5093ca414d8381eb8d1a300d4706df5aed100de725f3496a24c6871f39dcd2d774765c5c35b288cf8b5490fa700
data/Jarfile CHANGED
@@ -1,8 +1,8 @@
1
- jar 'org.kill-bill.billing:killbill-api', '0.9.8'
1
+ jar 'org.kill-bill.billing:killbill-api', '0.9.9'
2
2
  jar 'org.kill-bill.billing.plugin:killbill-plugin-api-notification', '0.7.4'
3
3
  jar 'org.kill-bill.billing.plugin:killbill-plugin-api-payment', '0.7.4'
4
4
  jar 'org.kill-bill.billing.plugin:killbill-plugin-api-currency', '0.7.4'
5
5
  jar 'org.kill-bill.billing.plugin:killbill-plugin-api-retry', '0.7.4'
6
6
  jar 'org.kill-bill.billing.plugin:killbill-plugin-api-invoice', '0.7.4'
7
- jar 'org.kill-bill.billing:killbill-util:tests', '0.11.3'
7
+ jar 'org.kill-bill.billing:killbill-util:tests', '0.11.9'
8
8
  jar 'javax.servlet:javax.servlet-api', '3.0.1'
data/NEWS CHANGED
@@ -1,3 +1,7 @@
1
+ 3.1.9
2
+ Fix memory leak in database connection handling
3
+ Change void implementation to be more generic (and work with Cybersource)
4
+
1
5
  3.1.8
2
6
  Make ActiveMerchant HTTP backend configurable, add support for Typhoeus
3
7
  generator:
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.1.8
1
+ 3.1.9
@@ -16,3 +16,4 @@
16
16
  # :jndi: 'killbill/osgi/jdbc'
17
17
  # :driver: 'com.mysql.jdbc.Driver'
18
18
  # :connection_alive_sql: 'select 1'
19
+ # :pool: 250
@@ -4,6 +4,7 @@ module Killbill
4
4
  module ActiveRecord
5
5
  require 'active_record'
6
6
  require 'active_merchant'
7
+ require 'time'
7
8
  require 'killbill/helpers/active_merchant/active_record/models/helpers'
8
9
 
9
10
  class PaymentMethod < ::ActiveRecord::Base
@@ -15,6 +16,8 @@ module Killbill
15
16
  @@quotes_cache = build_quotes_cache
16
17
 
17
18
  def self.from_response(kb_account_id, kb_payment_method_id, kb_tenant_id, cc_or_token, response, options, extra_params = {}, model = PaymentMethod)
19
+ # See Response#from_response
20
+ current_time = Time.now.utc
18
21
  model.new({
19
22
  :kb_account_id => kb_account_id,
20
23
  :kb_payment_method_id => kb_payment_method_id,
@@ -31,7 +34,9 @@ module Killbill
31
34
  :city => (options[:billing_address] || {})[:city],
32
35
  :state => (options[:billing_address] || {})[:state],
33
36
  :zip => (options[:billing_address] || {})[:zip],
34
- :country => (options[:billing_address] || {})[:country]
37
+ :country => (options[:billing_address] || {})[:country],
38
+ :created_at => current_time,
39
+ :updated_at => current_time
35
40
  }.merge!(extra_params))
36
41
  end
37
42
 
@@ -5,6 +5,7 @@ module Killbill
5
5
  require 'active_record'
6
6
  require 'active_merchant'
7
7
  require 'money'
8
+ require 'time'
8
9
  require 'killbill/helpers/active_merchant/active_record/models/helpers'
9
10
 
10
11
  class Response < ::ActiveRecord::Base
@@ -14,6 +15,8 @@ module Killbill
14
15
  self.abstract_class = true
15
16
 
16
17
  def self.from_response(api_call, kb_account_id, kb_payment_id, kb_payment_transaction_id, transaction_type, kb_tenant_id, response, extra_params = {}, model = Response)
18
+ # Under high load, Rails sometimes fails to set timestamps. Unclear why...
19
+ current_time = Time.now.utc
17
20
  model.new({
18
21
  :api_call => api_call,
19
22
  :kb_account_id => kb_account_id,
@@ -31,7 +34,9 @@ module Killbill
31
34
  :avs_result_postal_match => response.avs_result.kind_of?(::ActiveMerchant::Billing::AVSResult) ? response.avs_result.postal_match : response.avs_result['postal_match'],
32
35
  :cvv_result_code => response.cvv_result.kind_of?(::ActiveMerchant::Billing::CVVResult) ? response.cvv_result.code : response.cvv_result['code'],
33
36
  :cvv_result_message => response.cvv_result.kind_of?(::ActiveMerchant::Billing::CVVResult) ? response.cvv_result.message : response.cvv_result['message'],
34
- :success => response.success?
37
+ :success => response.success?,
38
+ :created_at => current_time,
39
+ :updated_at => current_time
35
40
  }.merge!(extra_params))
36
41
  end
37
42
 
@@ -62,7 +67,10 @@ module Killbill
62
67
  :kb_payment_transaction_id => kb_payment_transaction_id,
63
68
  :transaction_type => transaction_type,
64
69
  :txn_id => txn_id,
65
- "#{identifier}_response_id" => response.id)
70
+ "#{identifier}_response_id" => response.id,
71
+ # See Response#from_response
72
+ :created_at => response.created_at,
73
+ :updated_at => response.updated_at)
66
74
  transaction.save!(shared_activerecord_options)
67
75
  rescue => e
68
76
  exception = e
@@ -38,6 +38,10 @@ module Killbill
38
38
 
39
39
  @gateway.send(m, *args, &block)
40
40
  end
41
+
42
+ def respond_to?(method, include_private=false)
43
+ @gateway.respond_to?(method, include_private) || super
44
+ end
41
45
  end
42
46
  end
43
47
  end
@@ -107,6 +107,38 @@ module Killbill
107
107
  @accounts.find { |account| account.external_key == external_key.to_s }
108
108
  end
109
109
  end
110
+
111
+ class FakeJavaPaymentApi
112
+ attr_accessor :payments
113
+
114
+ def initialize
115
+ @payments = []
116
+ end
117
+
118
+ # For testing
119
+ def add_payment(kb_payment_id=SecureRandom.uuid, kb_payment_transaction_id=SecureRandom.uuid, kb_payment_transaction_external_key=SecureRandom.uuid, transaction_type=:PURCHASE)
120
+ kb_payment = get_payment kb_payment_id
121
+ if kb_payment.nil?
122
+ kb_payment = ::Killbill::Plugin::Model::Payment.new
123
+ kb_payment.id = kb_payment_id
124
+ kb_payment.transactions = []
125
+ @payments << kb_payment
126
+ end
127
+
128
+ kb_payment_transaction = ::Killbill::Plugin::Model::PaymentTransaction.new
129
+ kb_payment_transaction.id = kb_payment_transaction_id
130
+ kb_payment_transaction.transaction_type = transaction_type
131
+ kb_payment_transaction.external_key = kb_payment_transaction_external_key
132
+ kb_payment_transaction.created_date = Java::org.joda.time.DateTime.new(Java::org.joda.time.DateTimeZone::UTC)
133
+ kb_payment.transactions << kb_payment_transaction
134
+
135
+ kb_payment
136
+ end
137
+
138
+ def get_payment(id, with_plugin_info=false, properties=[], context=nil)
139
+ @payments.find { |payment| payment.id == id.to_s }
140
+ end
141
+ end
110
142
  end
111
143
  end
112
144
  end
@@ -31,32 +31,45 @@ module Killbill
31
31
 
32
32
  # return DB connections to the Pool if required
33
33
  def after_request
34
- ::ActiveRecord::Base.connection.close
34
+ pool = ::ActiveRecord::Base.connection_pool
35
+ return unless pool.active_connection?
36
+
37
+ connection = ::ActiveRecord::Base.connection
38
+ pool.remove(connection)
39
+ connection.disconnect!
40
+
41
+ @logger.debug "after_request: pool.active_connection? = #{pool.active_connection?}, connection.active? = #{connection.active?}, pool.connections.size = #{pool.connections.size}, connections = #{pool.connections.inspect}"
35
42
  end
36
43
 
37
44
  def authorize_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
45
+ kb_transaction = get_kb_transaction(kb_payment_id, kb_payment_transaction_id, context.tenant_id)
38
46
  amount_in_cents = to_cents(amount, currency)
39
47
 
40
48
  options = properties_to_hash(properties)
41
- options[:order_id] ||= kb_payment_transaction_id
49
+ options[:order_id] ||= kb_transaction.external_key
42
50
  options[:currency] ||= currency.to_s.upcase
43
51
  options[:description] ||= "Kill Bill authorization for #{kb_payment_transaction_id}"
44
52
 
45
53
  # Retrieve the payment method
46
54
  payment_source = get_payment_source(kb_payment_method_id, properties, options, context)
47
55
 
56
+ before_gateway(kb_transaction, nil, payment_source, amount_in_cents, currency, options)
57
+
48
58
  # Go to the gateway
49
59
  gw_response = gateway.authorize(amount_in_cents, payment_source, options)
50
60
  response, transaction = save_response_and_transaction(gw_response, :authorize, kb_account_id, context.tenant_id, kb_payment_id, kb_payment_transaction_id, :AUTHORIZE, amount_in_cents, currency)
51
61
 
62
+ after_gateway(response, transaction, gw_response)
63
+
52
64
  response.to_transaction_info_plugin(transaction)
53
65
  end
54
66
 
55
67
  def capture_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
68
+ kb_transaction = get_kb_transaction(kb_payment_id, kb_payment_transaction_id, context.tenant_id)
56
69
  amount_in_cents = to_cents(amount, currency)
57
70
 
58
71
  options = properties_to_hash(properties)
59
- options[:order_id] ||= kb_payment_transaction_id
72
+ options[:order_id] ||= kb_transaction.external_key
60
73
  options[:currency] ||= currency.to_s.upcase
61
74
  options[:description] ||= "Kill Bill capture for #{kb_payment_transaction_id}"
62
75
 
@@ -64,79 +77,116 @@ module Killbill
64
77
  # TODO We use the last AUTH transaction at the moment, is it good enough?
65
78
  authorization = @transaction_model.authorizations_from_kb_payment_id(kb_payment_id, context.tenant_id).last.txn_id
66
79
 
80
+ before_gateway(kb_transaction, authorization, nil, amount_in_cents, currency, options)
81
+
67
82
  # Go to the gateway
68
83
  gw_response = gateway.capture(amount_in_cents, authorization, options)
69
84
  response, transaction = save_response_and_transaction(gw_response, :capture, kb_account_id, context.tenant_id, kb_payment_id, kb_payment_transaction_id, :CAPTURE, amount_in_cents, currency)
70
85
 
86
+ after_gateway(response, transaction, gw_response)
87
+
71
88
  response.to_transaction_info_plugin(transaction)
72
89
  end
73
90
 
74
91
  def purchase_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
92
+ kb_transaction = get_kb_transaction(kb_payment_id, kb_payment_transaction_id, context.tenant_id)
75
93
  amount_in_cents = to_cents(amount, currency)
76
94
 
77
95
  options = properties_to_hash(properties)
78
- options[:order_id] ||= kb_payment_transaction_id
96
+ options[:order_id] ||= kb_transaction.external_key
79
97
  options[:currency] ||= currency.to_s.upcase
80
98
  options[:description] ||= "Kill Bill purchase for #{kb_payment_transaction_id}"
81
99
 
82
100
  # Retrieve the payment method
83
101
  payment_source = get_payment_source(kb_payment_method_id, properties, options, context)
84
102
 
103
+ before_gateway(kb_transaction, nil, payment_source, amount_in_cents, currency, options)
104
+
85
105
  # Go to the gateway
86
106
  gw_response = gateway.purchase(amount_in_cents, payment_source, options)
87
107
  response, transaction = save_response_and_transaction(gw_response, :purchase, kb_account_id, context.tenant_id, kb_payment_id, kb_payment_transaction_id, :PURCHASE, amount_in_cents, currency)
88
108
 
109
+ after_gateway(response, transaction, gw_response)
110
+
89
111
  response.to_transaction_info_plugin(transaction)
90
112
  end
91
113
 
92
114
  def void_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, properties, context)
115
+ kb_transaction = get_kb_transaction(kb_payment_id, kb_payment_transaction_id, context.tenant_id)
116
+
93
117
  options = properties_to_hash(properties)
118
+ options[:order_id] ||= kb_transaction.external_key
94
119
  options[:description] ||= "Kill Bill void for #{kb_payment_transaction_id}"
95
120
 
96
- # Retrieve the authorization
97
- # TODO We use the last AUTH transaction at the moment, is it good enough?
98
- authorization = @transaction_model.authorizations_from_kb_payment_id(kb_payment_id, context.tenant_id).last.txn_id
121
+ # If an authorization is being voided, we're performing an 'auth_reversal', otherwise,
122
+ # we're voiding an unsettled capture or purchase (which often needs to happen within 24 hours).
123
+ last_transaction = @transaction_model.purchases_from_kb_payment_id(kb_payment_id, context.tenant_id).last
124
+ if last_transaction.nil?
125
+ last_transaction = @transaction_model.captures_from_kb_payment_id(kb_payment_id, context.tenant_id).last
126
+ if last_transaction.nil?
127
+ last_transaction = @transaction_model.authorizations_from_kb_payment_id(kb_payment_id, context.tenant_id).last
128
+ if last_transaction.nil?
129
+ raise ArgumentError.new("Kill Bill payment #{kb_payment_id} has no auth, capture or purchase, thus cannot be voided")
130
+ end
131
+ end
132
+ end
133
+ authorization = last_transaction.txn_id
99
134
 
100
- # Go to the gateway
101
- gw_response = gateway.void(authorization, options)
135
+ before_gateway(kb_transaction, last_transaction, nil, nil, nil, options)
136
+
137
+ # Go to the gateway - while some gateways implementations are smart and have void support 'auth_reversal' and 'void' (e.g. Litle),
138
+ # others (e.g. CyberSource) implement different methods
139
+ gw_response = last_transaction.transaction_type == 'AUTHORIZE' && gateway.respond_to?(:auth_reversal) ? gateway.auth_reversal(last_transaction.amount_in_cents, authorization, options) : gateway.void(authorization, options)
102
140
  response, transaction = save_response_and_transaction(gw_response, :void, kb_account_id, context.tenant_id, kb_payment_id, kb_payment_transaction_id, :VOID)
103
141
 
142
+ after_gateway(response, transaction, gw_response)
143
+
104
144
  response.to_transaction_info_plugin(transaction)
105
145
  end
106
146
 
107
147
  def credit_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
148
+ kb_transaction = get_kb_transaction(kb_payment_id, kb_payment_transaction_id, context.tenant_id)
108
149
  amount_in_cents = to_cents(amount, currency)
109
150
 
110
151
  options = properties_to_hash(properties)
111
- options[:order_id] ||= kb_payment_transaction_id
152
+ options[:order_id] ||= kb_transaction.external_key
112
153
  options[:currency] ||= currency.to_s.upcase
113
154
  options[:description] ||= "Kill Bill credit for #{kb_payment_transaction_id}"
114
155
 
115
156
  # Retrieve the payment method
116
157
  payment_source = get_payment_source(kb_payment_method_id, properties, options, context)
117
158
 
159
+ before_gateway(kb_transaction, nil, payment_source, amount_in_cents, currency, options)
160
+
118
161
  # Go to the gateway
119
162
  gw_response = gateway.credit(amount_in_cents, payment_source, options)
120
163
  response, transaction = save_response_and_transaction(gw_response, :credit, kb_account_id, context.tenant_id, kb_payment_id, kb_payment_transaction_id, :CREDIT, amount_in_cents, currency)
121
164
 
165
+ after_gateway(response, transaction, gw_response)
166
+
122
167
  response.to_transaction_info_plugin(transaction)
123
168
  end
124
169
 
125
170
  def refund_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
171
+ kb_transaction = get_kb_transaction(kb_payment_id, kb_payment_transaction_id, context.tenant_id)
126
172
  amount_in_cents = to_cents(amount, currency)
127
173
 
128
174
  options = properties_to_hash(properties)
129
- options[:order_id] ||= kb_payment_transaction_id
175
+ options[:order_id] ||= kb_transaction.external_key
130
176
  options[:currency] ||= currency.to_s.upcase
131
177
  options[:description] ||= "Kill Bill refund for #{kb_payment_transaction_id}"
132
178
 
133
179
  # Find a transaction to refund
134
180
  transaction = @transaction_model.find_candidate_transaction_for_refund(kb_payment_id, context.tenant_id, amount_in_cents)
135
181
 
182
+ before_gateway(kb_transaction, transaction, nil, amount_in_cents, currency, options)
183
+
136
184
  # Go to the gateway
137
185
  gw_response = gateway.refund(amount_in_cents, transaction.txn_id, options)
138
186
  response, transaction = save_response_and_transaction(gw_response, :refund, kb_account_id, context.tenant_id, kb_payment_id, kb_payment_transaction_id, :REFUND, amount_in_cents, currency)
139
187
 
188
+ after_gateway(response, transaction, gw_response)
189
+
140
190
  response.to_transaction_info_plugin(transaction)
141
191
  end
142
192
 
@@ -352,6 +402,22 @@ module Killbill
352
402
 
353
403
  # Utilities
354
404
 
405
+ def get_kb_transaction(kb_payment_id, kb_payment_transaction_id, kb_tenant_id)
406
+ kb_payment = @kb_apis.payment_api.get_payment(kb_payment_id, false, [], @kb_apis.create_context(kb_tenant_id))
407
+ kb_transaction = kb_payment.transactions.find { |t| t.id == kb_payment_transaction_id }
408
+ # This should never happen...
409
+ raise ArgumentError.new("Unable to find Kill Bill transaction for id #{kb_payment_transaction_id}") if kb_transaction.nil?
410
+ kb_transaction
411
+ end
412
+
413
+ def before_gateway(kb_transaction, transaction, payment_source, amount_in_cents, currency, options)
414
+ # Can be used to implement idempotency for example: lookup the payment in the gateway
415
+ # and pass options[:skip_gw] if the payment has already been through
416
+ end
417
+
418
+ def after_gateway(response, transaction, gw_response)
419
+ end
420
+
355
421
  def to_cents(amount, currency)
356
422
  # 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)
357
423
  ::Monetize.from_numeric(amount, currency).cents.to_i
@@ -401,8 +467,8 @@ module Killbill
401
467
  prop.nil? ? nil : prop.value
402
468
  end
403
469
 
404
- def account_currency(kb_account_id)
405
- account = @kb_apis.account_user_api.get_account_by_id(kb_account_id, @kb_apis.create_context)
470
+ def account_currency(kb_account_id, kb_tenant_id)
471
+ account = @kb_apis.account_user_api.get_account_by_id(kb_account_id, @kb_apis.create_context(kb_tenant_id))
406
472
  account.currency
407
473
  end
408
474
 
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe Killbill::Plugin::ActiveMerchant::Utils do
4
+
5
+ it 'should close pool' do
6
+ # Rails' pooling is really just a glorified mapping between threads and connections
7
+ pool = ::ActiveRecord::Base.connection_pool
8
+
9
+ # Verify the reaper is a no-op. Management is in our hands
10
+ pool.reaper.frequency.should be_nil
11
+
12
+ # spec_helper created the table, so there is one active connection for that thread already
13
+ pool.active_connection?.should be_true
14
+ pool.connections.size.should == 1
15
+
16
+ # Fetch the underlying connection object. This shouldn't create any new connection.
17
+ # See activerecord-4.1.5/lib/active_record/connection_handling.rb, which proxies to
18
+ # the connection_handler from activerecord-4.1.5/lib/active_record/connection_adapters/abstract/connection_pool.rb
19
+ connection = ::ActiveRecord::Base.connection
20
+ pool.connections.size.should == 1
21
+ pool.connections[0].should == connection
22
+
23
+ # connection is an ActiveRecord::ConnectionAdapters::AbstractAdapter object, specific to the driver.
24
+ # For both straight JDBC and JNDI, it is an ActiveRecord::ConnectionAdapters::MysqlAdapter,
25
+ # subclass of ActiveRecord::ConnectionAdapters::JdbcAdapter (activerecord-jdbc-adapter-1.3.9/lib/arjdbc/jdbc/adapter.rb).
26
+ # The underlying connection is managed by ActiveRecord::ConnectionAdapters::JdbcConnection, which does the JDBC or JNDI lookup
27
+ # and proxies to Java (https://github.com/jruby/activerecord-jdbc-adapter/blob/master/src/java/arjdbc/jdbc/RubyJdbcConnection.java).
28
+ connection.active?.should be_true
29
+
30
+ # Tell Rails not to re-use this connection. We don't want them to stick in Rails hand.
31
+ # Instead, we want to force a checkout next time (put into c3p0's hands).
32
+ pool.remove(connection)
33
+ pool.active_connection?.should be_false
34
+ pool.connections.size.should == 0
35
+
36
+ # ActiveRecord connection management interface is defined in
37
+ # activerecord-4.1.5/lib/active_record/connection_adapters/abstract_adapter.rb
38
+ # Don't use ::ActiveRecord::Base.connection.close, which put the connection back into the pool.
39
+ connection.disconnect!
40
+
41
+ connection.active?.should be_false
42
+ end
43
+ end
@@ -23,6 +23,8 @@ describe Killbill::Plugin::ActiveMerchant::PaymentPlugin do
23
23
  ::Killbill::Test::TestPaymentMethod,
24
24
  ::Killbill::Test::TestTransaction,
25
25
  ::Killbill::Test::TestResponse)
26
+ @payment_api = ::Killbill::Plugin::ActiveMerchant::RSpec::FakeJavaPaymentApi.new
27
+ @plugin.kb_apis = ::Killbill::Plugin::KillbillApi.new('test', {:payment_api => @payment_api})
26
28
  @plugin.logger = Logger.new(STDOUT)
27
29
  @plugin.logger.level = Logger::INFO
28
30
  @plugin.conf_dir = File.dirname(file)
@@ -66,26 +68,32 @@ describe Killbill::Plugin::ActiveMerchant::PaymentPlugin do
66
68
  ::Killbill::Test::TestPaymentMethod.where(:kb_payment_method_id => @kb_payment_method_id).first.token.should == @payment_method_props.properties[0].value
67
69
 
68
70
  authorization_id = SecureRandom.uuid
71
+ @payment_api.add_payment(@kb_payment_id, authorization_id, SecureRandom.uuid, :AUTHORIZE)
69
72
  authorization = @plugin.authorize_payment(@kb_account_id, @kb_payment_id, authorization_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
70
73
  verify_transaction_info_plugin(authorization, authorization_id, :AUTHORIZE, 1)
71
74
 
72
75
  capture_id = SecureRandom.uuid
76
+ @payment_api.add_payment(@kb_payment_id, capture_id, SecureRandom.uuid, :CAPTURE)
73
77
  capture = @plugin.capture_payment(@kb_account_id, @kb_payment_id, capture_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
74
78
  verify_transaction_info_plugin(capture, capture_id, :CAPTURE, 2)
75
79
 
76
80
  purchase_id = SecureRandom.uuid
81
+ @payment_api.add_payment(@kb_payment_id, purchase_id, SecureRandom.uuid, :PURCHASE)
77
82
  purchase = @plugin.purchase_payment(@kb_account_id, @kb_payment_id, purchase_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
78
83
  verify_transaction_info_plugin(purchase, purchase_id, :PURCHASE, 3)
79
84
 
80
85
  void_id = SecureRandom.uuid
86
+ @payment_api.add_payment(@kb_payment_id, void_id, SecureRandom.uuid, :VOID)
81
87
  void = @plugin.void_payment(@kb_account_id, @kb_payment_id, void_id, @kb_payment_method_id, @properties, @call_context)
82
88
  verify_transaction_info_plugin(void, void_id, :VOID, 4)
83
89
 
84
90
  credit_id = SecureRandom.uuid
91
+ @payment_api.add_payment(@kb_payment_id, credit_id, SecureRandom.uuid, :CREDIT)
85
92
  credit = @plugin.credit_payment(@kb_account_id, @kb_payment_id, credit_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
86
93
  verify_transaction_info_plugin(credit, credit_id, :CREDIT, 5)
87
94
 
88
95
  refund_id = SecureRandom.uuid
96
+ @payment_api.add_payment(@kb_payment_id, refund_id, SecureRandom.uuid, :REFUND)
89
97
  refund = @plugin.refund_payment(@kb_account_id, @kb_payment_id, refund_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
90
98
  verify_transaction_info_plugin(refund, refund_id, :REFUND, 6)
91
99
 
@@ -58,9 +58,6 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::Response do
58
58
  # No associated transaction
59
59
  ptip.amount.should be_nil
60
60
  ptip.currency.should be_nil
61
- # Row not created
62
- ptip.created_date.should be_nil
63
- ptip.effective_date.should be_nil
64
61
  ptip.status.should == :PROCESSED
65
62
  ptip.gateway_error.should == 'Message'
66
63
  ptip.gateway_error_code.should be_nil
data/spec/spec_helper.rb CHANGED
@@ -13,6 +13,7 @@ require 'killbill/payment_test'
13
13
  require 'killbill/notification_test'
14
14
  require 'killbill/helpers/active_merchant'
15
15
  require 'killbill/helpers/active_merchant/active_record/models/helpers'
16
+ require 'killbill/helpers/active_merchant/killbill_spec_helper'
16
17
 
17
18
  require 'killbill/ext/active_merchant/typhoeus_connection'
18
19
 
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.8
4
+ version: 3.1.9
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-31 00:00:00.000000000 Z
11
+ date: 2014-09-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sinatra
@@ -404,6 +404,7 @@ files:
404
404
  - spec/killbill/base_plugin_spec.rb
405
405
  - spec/killbill/config_test.ru
406
406
  - spec/killbill/gen_conversions_spec.rb
407
+ - spec/killbill/helpers/connection_spec.rb
407
408
  - spec/killbill/helpers/payment_method_spec.rb
408
409
  - spec/killbill/helpers/payment_plugin_spec.rb
409
410
  - spec/killbill/helpers/response_spec.rb
@@ -454,6 +455,7 @@ test_files:
454
455
  - spec/killbill/base_plugin_spec.rb
455
456
  - spec/killbill/config_test.ru
456
457
  - spec/killbill/gen_conversions_spec.rb
458
+ - spec/killbill/helpers/connection_spec.rb
457
459
  - spec/killbill/helpers/payment_method_spec.rb
458
460
  - spec/killbill/helpers/payment_plugin_spec.rb
459
461
  - spec/killbill/helpers/response_spec.rb