killbill 3.1.1 → 3.1.2

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: 1317a97f82ee47ef1edb43f6ae039412692e9796
4
- data.tar.gz: 6d2dac9de214407b21145f82a6e11a6c5c039f9d
3
+ metadata.gz: 9b3dc2f6f6f18ecb0b78208ee9b4866ab4e64135
4
+ data.tar.gz: 67e7e0f1fc22c8bd8ac6f673226a281ee77a6d44
5
5
  SHA512:
6
- metadata.gz: a9afc87e7362830ccd361ada67e17d7195c5b23145aa32044036d5c48b866da55a94994e7dceaaf2c3f5858c4ecf21c6fe4c5c5dcf7106cfd585b27b590ffc05
7
- data.tar.gz: a6d19179afdf5241037b95984d3eff53d08bd68fba3783a2103036b4b23dacbc1dd5dc241f25138887bd519d0c586557f14bdbb045a8ae3200c8566b5f211479
6
+ metadata.gz: a0a93615aea2fbfe61c7239ff7ebce66c6c281ee49f085b20f04718e0994fb32ecc02bc426150665c0e5a25ea1c5061f251bb3ea259780e29c5dd252f1be7373
7
+ data.tar.gz: 54bf15ca7cf02ab75b3644da9bdb4101a04d58439b0d0deccf12736e3f4cc1231370cd29ae806d3293e205fa1a48b108a75a72060d179be97ccbb08b9a6e9033
data/NEWS CHANGED
@@ -1,3 +1,7 @@
1
+ 3.1.2
2
+ Make ActiveMerchant plugins multi-tenant
3
+ Add support for ActiveMerchant integrations
4
+
1
5
  3.1.1
2
6
  Regenerate files for killbill-api 0.9.5 and killbill-plugin-api 0.7.2
3
7
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.1.1
1
+ 3.1.2
@@ -1,6 +1,5 @@
1
1
  CREATE TABLE `<%= identifier %>_payment_methods` (
2
2
  `id` int(11) NOT NULL AUTO_INCREMENT,
3
- `kb_account_id` varchar(255) NOT NULL,
4
3
  `kb_payment_method_id` varchar(255) DEFAULT NULL,
5
4
  `token` varchar(255) DEFAULT NULL,
6
5
  `cc_first_name` varchar(255) DEFAULT NULL,
@@ -24,6 +23,8 @@ CREATE TABLE `<%= identifier %>_payment_methods` (
24
23
  `is_deleted` tinyint(1) NOT NULL DEFAULT '0',
25
24
  `created_at` datetime NOT NULL,
26
25
  `updated_at` datetime NOT NULL,
26
+ `kb_account_id` varchar(255) DEFAULT NULL,
27
+ `kb_tenant_id` varchar(255) DEFAULT NULL,
27
28
  PRIMARY KEY (`id`),
28
29
  KEY `index_<%= identifier %>_payment_methods_on_kb_account_id` (`kb_account_id`),
29
30
  KEY `index_<%= identifier %>_payment_methods_on_kb_payment_method_id` (`kb_payment_method_id`)
@@ -39,6 +40,8 @@ CREATE TABLE `<%= identifier %>_transactions` (
39
40
  `currency` varchar(255) NOT NULL,
40
41
  `created_at` datetime NOT NULL,
41
42
  `updated_at` datetime NOT NULL,
43
+ `kb_account_id` varchar(255) NOT NULL,
44
+ `kb_tenant_id` varchar(255) NOT NULL,
42
45
  PRIMARY KEY (`id`),
43
46
  KEY `index_<%= identifier %>_transactions_on_kb_payment_id` (`kb_payment_id`)
44
47
  ) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
@@ -60,5 +63,7 @@ CREATE TABLE `<%= identifier %>_responses` (
60
63
  `success` tinyint(1) DEFAULT NULL,
61
64
  `created_at` datetime NOT NULL,
62
65
  `updated_at` datetime NOT NULL,
66
+ `kb_account_id` varchar(255) DEFAULT NULL,
67
+ `kb_tenant_id` varchar(255) DEFAULT NULL,
63
68
  PRIMARY KEY (`id`)
64
69
  ) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
@@ -2,7 +2,6 @@ require 'active_record'
2
2
 
3
3
  ActiveRecord::Schema.define(:version => 20140410153635) do
4
4
  create_table "<%= identifier %>_payment_methods", :force => true do |t|
5
- t.string "kb_account_id", :null => false
6
5
  t.string "kb_payment_method_id" # NULL before Kill Bill knows about it
7
6
  t.string "token" # <%= identifier %> id
8
7
  t.string "cc_first_name"
@@ -26,6 +25,8 @@ ActiveRecord::Schema.define(:version => 20140410153635) do
26
25
  t.boolean "is_deleted", :null => false, :default => false
27
26
  t.datetime "created_at", :null => false
28
27
  t.datetime "updated_at", :null => false
28
+ t.string "kb_account_id"
29
+ t.string "kb_tenant_id"
29
30
  end
30
31
 
31
32
  add_index(:<%= identifier %>_payment_methods, :kb_account_id)
@@ -40,6 +41,8 @@ ActiveRecord::Schema.define(:version => 20140410153635) do
40
41
  t.string "currency", :null => false
41
42
  t.datetime "created_at", :null => false
42
43
  t.datetime "updated_at", :null => false
44
+ t.string "kb_account_id", :null => false
45
+ t.string "kb_tenant_id", :null => false
43
46
  end
44
47
 
45
48
  add_index(:<%= identifier %>_transactions, :kb_payment_id)
@@ -60,5 +63,7 @@ ActiveRecord::Schema.define(:version => 20140410153635) do
60
63
  t.boolean "success"
61
64
  t.datetime "created_at", :null => false
62
65
  t.datetime "updated_at", :null => false
66
+ t.string "kb_account_id"
67
+ t.string "kb_tenant_id"
63
68
  end
64
69
  end
@@ -20,7 +20,7 @@ module Killbill #:nodoc:
20
20
  options = {}
21
21
 
22
22
  properties = merge_properties(properties, options)
23
- super(kb_account_id, kb_payment_id, kb_payment_method_id, amount, currency, context, properties)
23
+ super(kb_account_id, kb_payment_id, kb_payment_method_id, amount, currency, properties, context)
24
24
  end
25
25
 
26
26
  def capture_payment(kb_account_id, kb_payment_id, kb_payment_method_id, amount, currency, properties, context)
@@ -103,16 +103,36 @@ module Killbill #:nodoc:
103
103
  super
104
104
  end
105
105
 
106
- def reset_payment_methods(kb_account_id, payment_methods, properties)
106
+ def reset_payment_methods(kb_account_id, payment_methods, properties, context)
107
107
  super
108
108
  end
109
109
 
110
110
  def build_form_descriptor(kb_account_id, descriptor_fields, properties, context)
111
- super
111
+ # Pass extra parameters for the gateway here
112
+ options = {}
113
+ properties = merge_properties(properties, options)
114
+
115
+ # Add your custom static hidden tags here
116
+ options = {
117
+ #:token => config[:<%= identifier %>][:token]
118
+ }
119
+ descriptor_fields = merge_properties(descriptor_fields, options)
120
+
121
+ super(kb_account_id, descriptor_fields, properties, context)
112
122
  end
113
123
 
114
124
  def process_notification(notification, properties, context)
115
- super
125
+ # Pass extra parameters for the gateway here
126
+ options = {}
127
+ properties = merge_properties(properties, options)
128
+
129
+ super(notification, properties, context) do |gw_notification, service|
130
+ # Retrieve the payment
131
+ # gw_notification.kb_payment_id =
132
+ #
133
+ # Set the response body
134
+ # gw_notification.entity =
135
+ end
116
136
  end
117
137
  end
118
138
  end
@@ -8,10 +8,10 @@ configure do
8
8
  # Usage: rackup -Ilib -E test
9
9
  if development? or test?
10
10
  # Make sure the plugin is initialized
11
- plugin = ::Killbill::<%= class_name %>::PaymentPlugin.new
12
- plugin.logger = Logger.new(STDOUT)
11
+ plugin = ::Killbill::<%= class_name %>::PaymentPlugin.new
12
+ plugin.logger = Logger.new(STDOUT)
13
13
  plugin.logger.level = Logger::INFO
14
- plugin.conf_dir = File.dirname(File.dirname(__FILE__)) + '/..'
14
+ plugin.conf_dir = File.dirname(File.dirname(__FILE__)) + '/..'
15
15
  plugin.start_plugin
16
16
  end
17
17
  end
@@ -28,23 +28,23 @@ end
28
28
 
29
29
  # curl -v http://127.0.0.1:9292/plugins/killbill-<%= identifier %>/form
30
30
  get '/plugins/killbill-<%= identifier %>/form', :provides => 'html' do
31
- order_id = request.GET['order_id']
31
+ order_id = request.GET['order_id']
32
32
  account_id = request.GET['account_id']
33
- options = {
34
- :amount => request.GET['amount'],
35
- :currency => request.GET['currency'],
36
- :test => request.GET['test'],
37
- :credential2 => request.GET['credential2'],
38
- :credential3 => request.GET['credential3'],
39
- :credential4 => request.GET['credential4'],
40
- :country => request.GET['country'],
41
- :account_name => request.GET['account_name'],
33
+ options = {
34
+ :amount => request.GET['amount'],
35
+ :currency => request.GET['currency'],
36
+ :test => request.GET['test'],
37
+ :credential2 => request.GET['credential2'],
38
+ :credential3 => request.GET['credential3'],
39
+ :credential4 => request.GET['credential4'],
40
+ :country => request.GET['country'],
41
+ :account_name => request.GET['account_name'],
42
42
  :transaction_type => request.GET['transaction_type'],
43
- :authcode => request.GET['authcode'],
44
- :notify_url => request.GET['notify_url'],
45
- :return_url => request.GET['return_url'],
46
- :redirect_param => request.GET['redirect_param'],
47
- :forward_url => request.GET['forward_url']
43
+ :authcode => request.GET['authcode'],
44
+ :notify_url => request.GET['notify_url'],
45
+ :return_url => request.GET['return_url'],
46
+ :redirect_param => request.GET['redirect_param'],
47
+ :forward_url => request.GET['forward_url']
48
48
  }
49
49
 
50
50
  @form = plugin(session).payment_form_for(order_id, account_id, :<%= identifier %>, options) do |service|
@@ -81,4 +81,4 @@ get '/plugins/killbill-<%= identifier %>/1.0/responses/:id', :provides => 'json'
81
81
  else
82
82
  status 404
83
83
  end
84
- end
84
+ end
@@ -4,9 +4,10 @@ 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, 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 = {})
8
8
  super(kb_account_id,
9
9
  kb_payment_method_id,
10
+ kb_tenant_id,
10
11
  cc_or_token,
11
12
  response,
12
13
  options,
@@ -6,9 +6,11 @@ module Killbill #:nodoc:
6
6
 
7
7
  has_one :<%= identifier %>_transaction
8
8
 
9
- def self.from_response(api_call, kb_payment_id, response, extra_params = {})
9
+ def self.from_response(api_call, kb_account_id, kb_payment_id, kb_tenant_id, response, extra_params = {})
10
10
  super(api_call,
11
+ kb_account_id,
11
12
  kb_payment_id,
13
+ kb_tenant_id,
12
14
  response,
13
15
  {
14
16
  # Pass custom key/values here
@@ -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.0'
25
+ s.add_dependency 'killbill', '~> 3.1.2'
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'
@@ -14,10 +14,11 @@ describe Killbill::<%= class_name %>::PaymentPlugin do
14
14
  eos
15
15
  file.close
16
16
 
17
- @plugin = Killbill::<%= class_name %>::PaymentPlugin.new
18
- @plugin.logger = Logger.new(STDOUT)
17
+ @plugin = Killbill::<%= class_name %>::PaymentPlugin.new
18
+ @plugin.logger = Logger.new(STDOUT)
19
19
  @plugin.logger.level = Logger::INFO
20
- @plugin.conf_dir = File.dirname(file)
20
+ @plugin.conf_dir = File.dirname(file)
21
+ @plugin.kb_apis = Killbill::Plugin::KillbillApi.new('<%= identifier %>', {})
21
22
 
22
23
  # Start the plugin here - since the config file will be deleted
23
24
  @plugin.start_plugin
@@ -27,4 +28,32 @@ describe Killbill::<%= class_name %>::PaymentPlugin do
27
28
  it 'should start and stop correctly' do
28
29
  @plugin.stop_plugin
29
30
  end
31
+
32
+ it 'should generate forms correctly' do
33
+ kb_account_id = SecureRandom.uuid
34
+ kb_tenant_id = SecureRandom.uuid
35
+ context = @plugin.kb_apis.create_context(kb_tenant_id)
36
+ fields = @plugin.hash_to_properties({
37
+ :order_id => '1234',
38
+ :amount => 10
39
+ })
40
+ form = @plugin.build_form_descriptor kb_account_id, fields, [], context
41
+
42
+ form.kb_account_id.should == kb_account_id
43
+ form.form_method.should == 'POST'
44
+ form.form_url.should == 'https://<%= identifier %>.com'
45
+
46
+ form_fields = @plugin.properties_to_hash(form.form_fields)
47
+ end
48
+
49
+ it 'should receive notifications correctly' do
50
+ description = 'description'
51
+
52
+ kb_tenant_id = SecureRandom.uuid
53
+ context = @plugin.kb_apis.create_context(kb_tenant_id)
54
+ properties = @plugin.hash_to_properties({ :description => description })
55
+
56
+ notification = ""
57
+ gw_notification = @plugin.process_notification notification, properties, context
58
+ end
30
59
  end
@@ -647,8 +647,8 @@ module Killbill
647
647
  end
648
648
  end
649
649
 
650
- java_signature 'Java::void resetPaymentMethods(Java::java.util.UUID, Java::java.util.List, Java::java.lang.Iterable)'
651
- def reset_payment_methods(kbAccountId, paymentMethods, properties)
650
+ java_signature 'Java::void resetPaymentMethods(Java::java.util.UUID, Java::java.util.List, Java::java.lang.Iterable, Java::org.killbill.billing.util.callcontext.CallContext)'
651
+ def reset_payment_methods(kbAccountId, paymentMethods, properties, context)
652
652
 
653
653
  # conversion for kbAccountId [type = java.util.UUID]
654
654
  kbAccountId = kbAccountId.nil? ? nil : kbAccountId.to_s
@@ -670,8 +670,11 @@ module Killbill
670
670
  tmp << m
671
671
  end
672
672
  properties = tmp
673
+
674
+ # conversion for context [type = org.killbill.billing.util.callcontext.CallContext]
675
+ context = Killbill::Plugin::Model::CallContext.new.to_ruby(context) unless context.nil?
673
676
  begin
674
- @delegate_plugin.reset_payment_methods(kbAccountId, paymentMethods, properties)
677
+ @delegate_plugin.reset_payment_methods(kbAccountId, paymentMethods, properties, context)
675
678
  rescue Exception => e
676
679
  message = "Failure in reset_payment_methods: #{e}"
677
680
  unless e.backtrace.nil?
@@ -11,9 +11,10 @@ module Killbill
11
11
 
12
12
  self.abstract_class = true
13
13
 
14
- def self.from_response(kb_account_id, kb_payment_method_id, cc_or_token, response, options, extra_params = {}, model = PaymentMethod)
14
+ def self.from_response(kb_account_id, kb_payment_method_id, kb_tenant_id, cc_or_token, response, options, extra_params = {}, model = PaymentMethod)
15
15
  model.new({
16
16
  :kb_account_id => kb_account_id,
17
+ :kb_tenant_id => kb_tenant_id,
17
18
  :kb_payment_method_id => kb_payment_method_id,
18
19
  :token => response.authorization,
19
20
  :cc_first_name => cc_or_token.kind_of?(::ActiveMerchant::Billing::CreditCard) ? cc_or_token.first_name : nil,
@@ -31,19 +32,19 @@ module Killbill
31
32
  }.merge!(extra_params))
32
33
  end
33
34
 
34
- def self.from_kb_account_id(kb_account_id)
35
- where('kb_account_id = ? AND is_deleted = ?', kb_account_id, false)
35
+ def self.from_kb_account_id(kb_account_id, kb_tenant_id)
36
+ where('kb_account_id = ? AND kb_tenant_id = ? AND is_deleted = ?', kb_account_id, kb_tenant_id, false)
36
37
  end
37
38
 
38
- def self.from_kb_payment_method_id(kb_payment_method_id)
39
- payment_methods = where('kb_payment_method_id = ? AND is_deleted = ?', kb_payment_method_id, false)
39
+ def self.from_kb_payment_method_id(kb_payment_method_id, kb_tenant_id)
40
+ payment_methods = where('kb_payment_method_id = ? AND kb_tenant_id = ? AND is_deleted = ?', kb_payment_method_id, kb_tenant_id, false)
40
41
  raise "No payment method found for payment method #{kb_payment_method_id}" if payment_methods.empty?
41
42
  raise "Kill Bill payment method #{kb_payment_method_id} mapping to multiple active plugin payment methods" if payment_methods.size > 1
42
43
  payment_methods[0]
43
44
  end
44
45
 
45
- def self.mark_as_deleted!(kb_payment_method_id)
46
- payment_method = from_kb_payment_method_id(kb_payment_method_id)
46
+ def self.mark_as_deleted!(kb_payment_method_id, kb_tenant_id)
47
+ payment_method = from_kb_payment_method_id(kb_payment_method_id, kb_tenant_id)
47
48
  payment_method.is_deleted = true
48
49
  payment_method.save!
49
50
  end
@@ -74,10 +75,10 @@ module Killbill
74
75
  end
75
76
 
76
77
  # VisibleForTesting
77
- def self.search_query(search_key, offset = nil, limit = nil)
78
+ def self.search_query(search_key, kb_tenant_id, offset = nil, limit = nil)
78
79
  t = self.arel_table
79
80
 
80
- query = t.where(search_where_clause(t, search_key))
81
+ query = t.where(search_where_clause(t, search_key).and(t[:kb_tenant_id].eq(kb_tenant_id)))
81
82
  .order(t[:id])
82
83
 
83
84
  if offset.blank? and limit.blank?
@@ -93,16 +94,16 @@ module Killbill
93
94
  query
94
95
  end
95
96
 
96
- def self.search(search_key, offset = 0, limit = 100)
97
+ def self.search(search_key, kb_tenant_id, offset = 0, limit = 100)
97
98
  pagination = Killbill::Plugin::Model::Pagination.new
98
99
  pagination.current_offset = offset
99
- pagination.total_nb_records = self.count_by_sql(self.search_query(search_key))
100
+ pagination.total_nb_records = self.count_by_sql(self.search_query(search_key, kb_tenant_id))
100
101
  pagination.max_nb_records = self.count
101
102
  pagination.next_offset = (!pagination.total_nb_records.nil? && offset + limit >= pagination.total_nb_records) ? nil : offset + limit
102
103
  # Reduce the limit if the specified value is larger than the number of records
103
104
  actual_limit = [pagination.max_nb_records, limit].min
104
105
  pagination.iterator = StreamyResultSet.new(actual_limit) do |offset,limit|
105
- self.find_by_sql(self.search_query(search_key, offset, limit))
106
+ self.find_by_sql(self.search_query(search_key, kb_tenant_id, offset, limit))
106
107
  .map(&:to_payment_method_response)
107
108
  end
108
109
  pagination
@@ -13,10 +13,12 @@ module Killbill
13
13
 
14
14
  self.abstract_class = true
15
15
 
16
- def self.from_response(api_call, kb_payment_id, response, extra_params = {}, model = Response)
16
+ def self.from_response(api_call, kb_account_id, kb_payment_id, kb_tenant_id, response, extra_params = {}, model = Response)
17
17
  model.new({
18
18
  :api_call => api_call,
19
+ :kb_account_id => kb_account_id,
19
20
  :kb_payment_id => kb_payment_id,
21
+ :kb_tenant_id => kb_tenant_id,
20
22
  :message => response.message,
21
23
  :authorization => response.authorization,
22
24
  :fraud_review => response.fraud_review?,
@@ -55,10 +57,10 @@ module Killbill
55
57
  end
56
58
 
57
59
  # VisibleForTesting
58
- def self.search_query(api_call, search_key, offset = nil, limit = nil)
60
+ def self.search_query(api_call, search_key, kb_tenant_id, offset = nil, limit = nil)
59
61
  t = self.arel_table
60
62
 
61
- query = t.where(search_where_clause(t, search_key, api_call))
63
+ query = t.where(search_where_clause(t, search_key, api_call).and(t[:kb_tenant_id].eq(kb_tenant_id)))
62
64
  .order(t[:id])
63
65
 
64
66
  if offset.blank? and limit.blank?
@@ -74,17 +76,17 @@ module Killbill
74
76
  query
75
77
  end
76
78
 
77
- def self.search(search_key, offset = 0, limit = 100, type = :payment)
79
+ def self.search(search_key, kb_tenant_id, offset = 0, limit = 100, type = :payment)
78
80
  api_call = type == :payment ? 'charge' : 'refund'
79
81
  pagination = ::Killbill::Plugin::Model::Pagination.new
80
82
  pagination.current_offset = offset
81
- pagination.total_nb_records = self.count_by_sql(self.search_query(api_call, search_key))
83
+ pagination.total_nb_records = self.count_by_sql(self.search_query(api_call, search_key, kb_tenant_id))
82
84
  pagination.max_nb_records = self.where(:api_call => api_call, :success => true).count
83
85
  pagination.next_offset = (!pagination.total_nb_records.nil? && offset + limit >= pagination.total_nb_records) ? nil : offset + limit
84
86
  # Reduce the limit if the specified value is larger than the number of records
85
87
  actual_limit = [pagination.max_nb_records, limit].min
86
88
  pagination.iterator = ::Killbill::Plugin::ActiveMerchant::ActiveRecord::StreamyResultSet.new(actual_limit) do |offset, limit|
87
- self.find_by_sql(self.search_query(api_call, search_key, offset, limit))
89
+ self.find_by_sql(self.search_query(api_call, search_key, kb_tenant_id, offset, limit))
88
90
  .map { |x| type == :payment ? x.to_payment_response : x.to_refund_response }
89
91
  end
90
92
  pagination
@@ -8,29 +8,29 @@ module Killbill
8
8
 
9
9
  self.abstract_class = true
10
10
 
11
- def self.authorization_from_kb_payment_id(kb_payment_id)
12
- transaction_from_kb_payment_id :authorize, kb_payment_id, :single
11
+ def self.authorization_from_kb_payment_id(kb_payment_id, kb_tenant_id)
12
+ transaction_from_kb_payment_id :authorize, kb_payment_id, kb_tenant_id, :single
13
13
  end
14
14
 
15
- def self.charge_from_kb_payment_id(kb_payment_id)
16
- transaction_from_kb_payment_id :charge, kb_payment_id, :single
15
+ def self.charge_from_kb_payment_id(kb_payment_id, kb_tenant_id)
16
+ transaction_from_kb_payment_id :charge, kb_payment_id, kb_tenant_id, :single
17
17
  end
18
18
 
19
- def self.refunds_from_kb_payment_id(kb_payment_id)
20
- transaction_from_kb_payment_id :refund, kb_payment_id, :multiple
19
+ def self.refunds_from_kb_payment_id(kb_payment_id, kb_tenant_id)
20
+ transaction_from_kb_payment_id :refund, kb_payment_id, kb_tenant_id, :multiple
21
21
  end
22
22
 
23
- def self.find_candidate_transaction_for_refund(kb_payment_id, amount_in_cents)
23
+ def self.find_candidate_transaction_for_refund(kb_payment_id, kb_tenant_id, amount_in_cents)
24
24
  begin
25
- do_find_candidate_transaction_for_refund :authorize, kb_payment_id, amount_in_cents
25
+ do_find_candidate_transaction_for_refund :authorize, kb_payment_id, kb_tenant_id, amount_in_cents
26
26
  rescue
27
- do_find_candidate_transaction_for_refund :charge, kb_payment_id, amount_in_cents
27
+ do_find_candidate_transaction_for_refund :charge, kb_payment_id, kb_tenant_id, amount_in_cents
28
28
  end
29
29
  end
30
30
 
31
- def self.do_find_candidate_transaction_for_refund(api_call, kb_payment_id, amount_in_cents)
31
+ def self.do_find_candidate_transaction_for_refund(api_call, kb_payment_id, kb_tenant_id, amount_in_cents)
32
32
  # Find one successful charge which amount is at least the amount we are trying to refund
33
- transactions = where('amount_in_cents >= ? AND api_call = ? and kb_payment_id = ?', amount_in_cents, api_call, kb_payment_id)
33
+ transactions = where('amount_in_cents >= ? AND api_call = ? AND kb_tenant_id = ? AND kb_payment_id = ?', amount_in_cents, api_call, kb_tenant_id, kb_payment_id)
34
34
  raise "Unable to find transaction for payment #{kb_payment_id} and api_call #{api_call}" if transactions.size == 0
35
35
 
36
36
  # We have candidates, but we now need to make sure we didn't refund more than for the specified amount
@@ -46,8 +46,8 @@ module Killbill
46
46
 
47
47
  private
48
48
 
49
- def self.transaction_from_kb_payment_id(api_call, kb_payment_id, how_many)
50
- transactions = where('api_call = ? and kb_payment_id = ?', api_call, kb_payment_id)
49
+ def self.transaction_from_kb_payment_id(api_call, kb_payment_id, kb_tenant_id, how_many)
50
+ transactions = where('api_call = ? AND kb_tenant_id = ? AND kb_payment_id = ?', api_call, kb_tenant_id, kb_payment_id)
51
51
  raise "Unable to find transaction id for payment #{kb_payment_id}" if transactions.empty?
52
52
  if how_many == :single
53
53
  raise "Kill Bill payment #{kb_payment_id} mapping to multiple plugin transactions" if transactions.size > 1
@@ -3,7 +3,7 @@ module Killbill
3
3
  module ActiveMerchant
4
4
  module RSpec
5
5
 
6
- def create_payment_method(payment_method_model=::Killbill::Plugin::ActiveMerchant::ActiveRecord::PaymentMethod, kb_account_id=nil)
6
+ def create_payment_method(payment_method_model=::Killbill::Plugin::ActiveMerchant::ActiveRecord::PaymentMethod, kb_account_id=nil, kb_tenant_id=nil)
7
7
  kb_payment_method_id = SecureRandom.uuid
8
8
 
9
9
  if kb_account_id.nil?
@@ -13,7 +13,11 @@ module Killbill
13
13
  create_kb_account kb_account_id
14
14
  end
15
15
 
16
- account = @plugin.kb_apis.account_user_api.get_account_by_id(kb_account_id, @plugin.kb_apis.create_context)
16
+ context = @plugin.kb_apis.create_context(kb_tenant_id)
17
+ account = @plugin.kb_apis.account_user_api.get_account_by_id(kb_account_id, context)
18
+
19
+ # The rest is pure Ruby
20
+ context = context.to_ruby(context)
17
21
 
18
22
  # Generate a token
19
23
  cc_number = '4242424242424242'
@@ -50,9 +54,9 @@ module Killbill
50
54
 
51
55
  info = Killbill::Plugin::Model::PaymentMethodPlugin.new
52
56
  info.properties = properties
53
- payment_method = @plugin.add_payment_method(kb_account_id, kb_payment_method_id, info, true, nil)
57
+ payment_method = @plugin.add_payment_method(kb_account_id, kb_payment_method_id, info, true, [], context)
54
58
 
55
- pm = payment_method_model.from_kb_payment_method_id kb_payment_method_id
59
+ pm = payment_method_model.from_kb_payment_method_id kb_payment_method_id, context.tenant_id
56
60
  pm.should == payment_method
57
61
  pm.kb_account_id.should == kb_account_id
58
62
  pm.kb_payment_method_id.should == kb_payment_method_id
@@ -90,7 +94,7 @@ module Killbill
90
94
  end
91
95
 
92
96
  def create_pm_kv_info(key, value)
93
- prop = ::Killbill::Plugin::Model::PaymentMethodKVInfo.new
97
+ prop = ::Killbill::Plugin::Model::PluginProperty.new
94
98
  prop.key = key
95
99
  prop.value = value
96
100
  prop
@@ -40,7 +40,7 @@ module Killbill
40
40
  amount_in_cents = Monetize.from_numeric(amount, currency).cents.to_i
41
41
 
42
42
  # If the authorization was already made, just return the status (one auth per kb payment id)
43
- transaction = @transaction_model.authorization_from_kb_payment_id(kb_payment_id) rescue nil
43
+ transaction = @transaction_model.authorization_from_kb_payment_id(kb_payment_id, context.tenant_id) rescue nil
44
44
  return transaction.send("#{@identifier}_response").to_payment_response(transaction) unless transaction.nil?
45
45
 
46
46
  options[:order_id] ||= kb_payment_id
@@ -49,7 +49,7 @@ module Killbill
49
49
 
50
50
  # Retrieve the payment method
51
51
  if options[:credit_card].blank?
52
- pm = @payment_method_model.from_kb_payment_method_id(kb_payment_method_id)
52
+ pm = @payment_method_model.from_kb_payment_method_id(kb_payment_method_id, context.tenant_id)
53
53
  payment_source = pm.token
54
54
  else
55
55
  payment_source = ::ActiveMerchant::Billing::CreditCard.new(options[:credit_card])
@@ -57,7 +57,7 @@ module Killbill
57
57
 
58
58
  # Go to the gateway
59
59
  gw_response = gateway.authorize amount_in_cents, payment_source, options
60
- response, transaction = save_response_and_transaction gw_response, :authorize, kb_payment_id, amount_in_cents, currency
60
+ response, transaction = save_response_and_transaction gw_response, :authorize, kb_account_id, context.tenant_id, kb_payment_id, amount_in_cents, currency
61
61
 
62
62
  response.to_payment_response(transaction)
63
63
  end
@@ -73,11 +73,11 @@ module Killbill
73
73
  options[:description] ||= "Kill Bill capture for #{kb_payment_id}"
74
74
 
75
75
  # Retrieve the authorization
76
- authorization = @transaction_model.authorization_from_kb_payment_id(kb_payment_id).txn_id
76
+ authorization = @transaction_model.authorization_from_kb_payment_id(kb_payment_id, context.tenant_id).txn_id
77
77
 
78
78
  # Go to the gateway
79
79
  gw_response = gateway.capture amount_in_cents, authorization, options
80
- response, transaction = save_response_and_transaction gw_response, :capture, kb_payment_id, amount_in_cents, currency
80
+ response, transaction = save_response_and_transaction gw_response, :capture, kb_account_id, context.tenant_id, kb_payment_id, amount_in_cents, currency
81
81
 
82
82
  response.to_payment_response(transaction)
83
83
  end
@@ -87,11 +87,11 @@ module Killbill
87
87
  options[:description] ||= "Kill Bill void for #{kb_payment_id}"
88
88
 
89
89
  # Retrieve the authorization
90
- authorization = @transaction_model.authorization_from_kb_payment_id(kb_payment_id).txn_id
90
+ authorization = @transaction_model.authorization_from_kb_payment_id(kb_payment_id, context.tenant_id).txn_id
91
91
 
92
92
  # Go to the gateway
93
93
  gw_response = gateway.void authorization, options
94
- response, transaction = save_response_and_transaction gw_response, :void, kb_payment_id
94
+ response, transaction = save_response_and_transaction gw_response, :void, kb_account_id, context.tenant_id, kb_payment_id
95
95
 
96
96
  response.to_payment_response(transaction)
97
97
  end
@@ -103,7 +103,7 @@ module Killbill
103
103
  amount_in_cents = Monetize.from_numeric(amount, currency).cents.to_i
104
104
 
105
105
  # If the payment was already made, just return the status
106
- transaction = @transaction_model.charge_from_kb_payment_id(kb_payment_id) rescue nil
106
+ transaction = @transaction_model.charge_from_kb_payment_id(kb_payment_id, context.tenant_id) rescue nil
107
107
  return transaction.send("#{@identifier}_response").to_payment_response(transaction) unless transaction.nil?
108
108
 
109
109
  options[:order_id] ||= kb_payment_id
@@ -112,7 +112,7 @@ module Killbill
112
112
 
113
113
  # Retrieve the payment method
114
114
  if options[:credit_card].blank?
115
- pm = @payment_method_model.from_kb_payment_method_id(kb_payment_method_id)
115
+ pm = @payment_method_model.from_kb_payment_method_id(kb_payment_method_id, context.tenant_id)
116
116
  payment_source = pm.token
117
117
  else
118
118
  payment_source = ::ActiveMerchant::Billing::CreditCard.new(options[:credit_card])
@@ -120,7 +120,7 @@ module Killbill
120
120
 
121
121
  # Go to the gateway
122
122
  gw_response = gateway.purchase amount_in_cents, payment_source, options
123
- response, transaction = save_response_and_transaction gw_response, :charge, kb_payment_id, amount_in_cents, currency
123
+ response, transaction = save_response_and_transaction gw_response, :charge, kb_account_id, context.tenant_id, kb_payment_id, amount_in_cents, currency
124
124
 
125
125
  response.to_payment_response(transaction)
126
126
  end
@@ -131,11 +131,11 @@ module Killbill
131
131
  # 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)
132
132
  amount_in_cents = Monetize.from_numeric(amount, currency).cents.to_i
133
133
 
134
- transaction = @transaction_model.find_candidate_transaction_for_refund(kb_payment_id, amount_in_cents)
134
+ transaction = @transaction_model.find_candidate_transaction_for_refund(kb_payment_id, context.tenant_id, amount_in_cents)
135
135
 
136
136
  # Go to the gateway
137
137
  gw_response = gateway.refund amount_in_cents, transaction.txn_id, options
138
- response, transaction = save_response_and_transaction gw_response, :refund, kb_payment_id, amount_in_cents, currency
138
+ response, transaction = save_response_and_transaction gw_response, :refund, kb_account_id, context.tenant_id, kb_payment_id, amount_in_cents, currency
139
139
 
140
140
  response.to_refund_response(transaction)
141
141
  end
@@ -144,7 +144,7 @@ module Killbill
144
144
  options = properties_to_hash(properties)
145
145
 
146
146
  # We assume the payment is immutable in the Gateway and only look at our tables
147
- transaction = @transaction_model.charge_from_kb_payment_id(kb_payment_id)
147
+ transaction = @transaction_model.charge_from_kb_payment_id(kb_payment_id, context.tenant_id)
148
148
 
149
149
  transaction.send("#{@identifier}_response").to_payment_response(transaction)
150
150
  end
@@ -153,7 +153,7 @@ module Killbill
153
153
  options = properties_to_hash(properties)
154
154
 
155
155
  # We assume the refund is immutable in the Gateway and only look at our tables
156
- transactions = @transaction_model.refunds_from_kb_payment_id(kb_payment_id)
156
+ transactions = @transaction_model.refunds_from_kb_payment_id(kb_payment_id, context.tenant_id)
157
157
 
158
158
  transactions.map { |t| t.send("#{@identifier}_response").to_refund_response(t) }
159
159
  end
@@ -194,10 +194,10 @@ module Killbill
194
194
 
195
195
  # Go to the gateway
196
196
  gw_response = gateway.store cc_or_token, options
197
- response, transaction = save_response_and_transaction gw_response, :add_payment_method
197
+ response, transaction = save_response_and_transaction gw_response, :add_payment_method, kb_account_id, context.tenant_id
198
198
 
199
199
  if response.success
200
- payment_method = @payment_method_model.from_response(kb_account_id, kb_payment_method_id, cc_or_token, gw_response, options)
200
+ payment_method = @payment_method_model.from_response(kb_account_id, kb_payment_method_id, context.tenant_id, cc_or_token, gw_response, options)
201
201
  payment_method.save!
202
202
  payment_method
203
203
  else
@@ -208,7 +208,7 @@ module Killbill
208
208
  def delete_payment_method(kb_account_id, kb_payment_method_id, properties, context)
209
209
  options = properties_to_hash(properties)
210
210
 
211
- pm = @payment_method_model.from_kb_payment_method_id(kb_payment_method_id)
211
+ pm = @payment_method_model.from_kb_payment_method_id(kb_payment_method_id, context.tenant_id)
212
212
 
213
213
  # Delete the card
214
214
  if options[:customer_id]
@@ -216,10 +216,10 @@ module Killbill
216
216
  else
217
217
  gw_response = gateway.unstore(pm.token, options)
218
218
  end
219
- response, transaction = save_response_and_transaction gw_response, :delete_payment_method
219
+ response, transaction = save_response_and_transaction gw_response, :delete_payment_method, kb_account_id, context.tenant_id
220
220
 
221
221
  if response.success
222
- @payment_method_model.mark_as_deleted! kb_payment_method_id
222
+ @payment_method_model.mark_as_deleted! kb_payment_method_id, context.tenant_id
223
223
  else
224
224
  raise response.message
225
225
  end
@@ -227,20 +227,20 @@ module Killbill
227
227
 
228
228
  def get_payment_method_detail(kb_account_id, kb_payment_method_id, properties, context)
229
229
  options = properties_to_hash(properties)
230
- @payment_method_model.from_kb_payment_method_id(kb_payment_method_id).to_payment_method_response
230
+ @payment_method_model.from_kb_payment_method_id(kb_payment_method_id, context.tenant_id).to_payment_method_response
231
231
  end
232
232
 
233
233
  def get_payment_methods(kb_account_id, refresh_from_gateway = false, properties, context)
234
234
  options = properties_to_hash(properties)
235
- @payment_method_model.from_kb_account_id(kb_account_id).collect { |pm| pm.to_payment_method_info_response }
235
+ @payment_method_model.from_kb_account_id(kb_account_id, context.tenant_id).collect { |pm| pm.to_payment_method_info_response }
236
236
  end
237
237
 
238
- def reset_payment_methods(kb_account_id, payment_methods, properties)
238
+ def reset_payment_methods(kb_account_id, payment_methods, properties, context)
239
239
  return if payment_methods.nil?
240
240
 
241
241
  options = properties_to_hash(properties)
242
242
 
243
- pms = @payment_method_model.from_kb_account_id(kb_account_id)
243
+ pms = @payment_method_model.from_kb_account_id(kb_account_id, context.tenant_id)
244
244
 
245
245
  payment_methods.delete_if do |payment_method_info_plugin|
246
246
  should_be_deleted = false
@@ -268,42 +268,126 @@ module Killbill
268
268
  payment_methods.each do |payment_method_info_plugin|
269
269
  pm = @payment_method_model.create :kb_account_id => kb_account_id,
270
270
  :kb_payment_method_id => payment_method_info_plugin.payment_method_id,
271
+ :kb_tenant_id => context.tenant_id,
271
272
  :token => payment_method_info_plugin.external_payment_method_id
272
273
  end
273
274
  end
274
275
 
275
276
  def search_payments(search_key, offset = 0, limit = 100, properties, context)
276
277
  options = properties_to_hash(properties)
277
- @response_model.search(search_key, offset, limit, :payment)
278
+ @response_model.search(search_key, context.tenant_id, offset, limit, :payment)
278
279
  end
279
280
 
280
281
  def search_refunds(search_key, offset = 0, limit = 100, properties, context)
281
282
  options = properties_to_hash(properties)
282
- @response_model.search(search_key, offset, limit, :refund)
283
+ @response_model.search(search_key, context.tenant_id, offset, limit, :refund)
283
284
  end
284
285
 
285
286
  def search_payment_methods(search_key, offset = 0, limit = 100, properties, context)
286
287
  options = properties_to_hash(properties)
287
- @payment_method_model.search(search_key, offset, limit)
288
+ @payment_method_model.search(search_key, context.tenant_id, offset, limit)
288
289
  end
289
290
 
290
291
  def build_form_descriptor(kb_account_id, descriptor_fields, properties, context)
291
- options = properties_to_hash(properties)
292
+ options = properties_to_hash(descriptor_fields)
293
+ order = options.delete(:order_id)
294
+ account = options.delete(:account_id)
295
+ service_options = {
296
+ :amount => options.delete(:amount),
297
+ :currency => options.delete(:currency),
298
+ :test => options.delete(:test),
299
+ :credential2 => options.delete(:credential2),
300
+ :credential3 => options.delete(:credential3),
301
+ :credential4 => options.delete(:credential4),
302
+ :country => options.delete(:country),
303
+ :account_name => options.delete(:account_name),
304
+ :transaction_type => options.delete(:transaction_type),
305
+ :authcode => options.delete(:authcode),
306
+ :notify_url => options.delete(:notify_url),
307
+ :return_url => options.delete(:return_url),
308
+ :redirect_param => options.delete(:redirect_param),
309
+ :forward_url => options.delete(:forward_url)
310
+ }
311
+
312
+ # Retrieve the ActiveMerchant integration
313
+ integration_module = ::ActiveMerchant::Billing::Integrations.const_get(@identifier.to_s.camelize)
314
+ service_class = integration_module.const_get('Helper')
315
+ service = service_class.new(order, account, service_options)
316
+
317
+ # Add the specified fields
318
+ options.each do |field, value|
319
+ mapping = service_class.mappings[field]
320
+ next if mapping.nil?
321
+ case mapping
322
+ when Array
323
+ mapping.each{ |field2| service.add_field(field2, value) }
324
+ when Hash
325
+ options2 = value.is_a?(Hash) ? value : {}
326
+ mapping.each{ |key, field2| service.add_field(field2, options2[key]) }
327
+ else
328
+ service.add_field(mapping, value)
329
+ end
330
+ end
331
+
332
+ form_fields = {}
333
+ service.form_fields.each do |field, value|
334
+ form_fields[field] = value
335
+ end
336
+ service.raw_html_fields.each do |field, value|
337
+ form_fields[field] = value
338
+ end
339
+
340
+ # Build the response object
341
+ descriptor = ::Killbill::Plugin::Model::HostedPaymentPageFormDescriptor.new
342
+ descriptor.kb_account_id = kb_account_id
343
+ descriptor.form_method = service.form_method || 'POST'
344
+ descriptor.form_url = service.respond_to?(:credential_based_url) ? service.credential_based_url : integration_module.service_url
345
+ descriptor.form_fields = hash_to_properties(form_fields)
346
+ # Any other custom property
347
+ descriptor.properties = hash_to_properties({})
348
+
349
+ descriptor
292
350
  end
293
351
 
294
- def process_notification(notification, properties, context)
352
+ def process_notification(notification, properties, context, &proc)
295
353
  options = properties_to_hash(properties)
354
+
355
+ # Retrieve the ActiveMerchant integration
356
+ integration_module = ::ActiveMerchant::Billing::Integrations.const_get(@identifier.to_s.camelize)
357
+ service_class = integration_module.const_get('Notification')
358
+ # notification is either a body or a query string
359
+ service = service_class.new(notification, options)
360
+
361
+ if service.respond_to? :acknowledge
362
+ service.acknowledge
363
+ end
364
+
365
+ gw_notification = ::Killbill::Plugin::Model::GatewayNotification.new
366
+ gw_notification.kb_payment_id = nil
367
+ gw_notification.status = service.status == 'Completed' ? 200 : 400
368
+ gw_notification.headers = {}
369
+ gw_notification.properties = []
370
+
371
+ if service.respond_to? :success_response
372
+ gw_notification.entity = service.success_response(properties_to_hash(properties))
373
+ else
374
+ gw_notification.entity = ''
375
+ end
376
+
377
+ yield(gw_notification, service) if block_given?
378
+
379
+ gw_notification
296
380
  end
297
381
 
298
382
  # Utilities
299
383
 
300
384
  # Deprecated
301
385
  def find_value_from_payment_method_props(payment_method_props, key)
302
- find_value_from_properties(payment_method_props, key)
386
+ find_value_from_properties(payment_method_props.properties, key)
303
387
  end
304
388
 
305
389
  def find_value_from_properties(properties, key)
306
- prop = (payment_method_props.properties.find { |kv| kv.key == key })
390
+ prop = (properties.find { |kv| kv.key == key })
307
391
  prop.nil? ? nil : prop.value
308
392
  end
309
393
 
@@ -312,11 +396,11 @@ module Killbill
312
396
  account.currency
313
397
  end
314
398
 
315
- def save_response_and_transaction(response, api_call, kb_payment_id=nil, amount_in_cents=0, currency=nil)
399
+ def save_response_and_transaction(response, api_call, kb_account_id, kb_tenant_id, kb_payment_id=nil, amount_in_cents=0, currency=nil)
316
400
  @logger.warn "Unsuccessful #{api_call}: #{response.message}" unless response.success?
317
401
 
318
402
  # Save the response to our logs
319
- response = @response_model.from_response(api_call, kb_payment_id, response)
403
+ response = @response_model.from_response(api_call, kb_account_id, kb_payment_id, kb_tenant_id, response)
320
404
  response.save!
321
405
 
322
406
  transaction = nil
@@ -324,6 +408,8 @@ module Killbill
324
408
  if response.success and !kb_payment_id.blank? and !txn_id.blank?
325
409
  # Record the transaction
326
410
  transaction = response.send("create_#{@identifier}_transaction!",
411
+ :kb_account_id => kb_account_id,
412
+ :kb_tenant_id => kb_tenant_id,
327
413
  :amount_in_cents => amount_in_cents,
328
414
  :currency => currency,
329
415
  :api_call => api_call,
@@ -339,9 +425,17 @@ module Killbill
339
425
  ::Killbill::Plugin::ActiveMerchant.gateway
340
426
  end
341
427
 
428
+ def config
429
+ ::Killbill::Plugin::ActiveMerchant.config
430
+ end
431
+
432
+ def hash_to_properties(options)
433
+ merge_properties([], options)
434
+ end
435
+
342
436
  def properties_to_hash(properties, options = {})
343
437
  merged = {}
344
- properties.each do |p|
438
+ (properties || []).each do |p|
345
439
  merged[p.key.to_sym] = p.value
346
440
  end
347
441
  merged.merge(options)
@@ -55,7 +55,7 @@ module Killbill
55
55
  raise OperationUnsupportedByGatewayError
56
56
  end
57
57
 
58
- def reset_payment_methods(kb_account_id, payment_methods, properties)
58
+ def reset_payment_methods(kb_account_id, payment_methods, properties, context)
59
59
  raise OperationUnsupportedByGatewayError
60
60
  end
61
61
  end
@@ -18,22 +18,22 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::PaymentMethod do
18
18
 
19
19
  it 'should generate the right SQL query' do
20
20
  # Check count query (search query numeric)
21
- expected_query = "SELECT COUNT(DISTINCT \"test_payment_methods\".\"id\") FROM \"test_payment_methods\" WHERE ((((((((((((((\"test_payment_methods\".\"kb_account_id\" = '1234' OR \"test_payment_methods\".\"kb_payment_method_id\" = '1234') OR \"test_payment_methods\".\"token\" = '1234') OR \"test_payment_methods\".\"cc_type\" = '1234') OR \"test_payment_methods\".\"state\" = '1234') OR \"test_payment_methods\".\"zip\" = '1234') OR \"test_payment_methods\".\"cc_first_name\" LIKE '%1234%') OR \"test_payment_methods\".\"cc_last_name\" LIKE '%1234%') OR \"test_payment_methods\".\"address1\" LIKE '%1234%') OR \"test_payment_methods\".\"address2\" LIKE '%1234%') OR \"test_payment_methods\".\"city\" LIKE '%1234%') OR \"test_payment_methods\".\"country\" LIKE '%1234%') OR \"test_payment_methods\".\"cc_exp_month\" = 1234) OR \"test_payment_methods\".\"cc_exp_year\" = 1234) OR \"test_payment_methods\".\"cc_last_4\" = 1234) ORDER BY \"test_payment_methods\".\"id\""
21
+ expected_query = "SELECT COUNT(DISTINCT \"test_payment_methods\".\"id\") FROM \"test_payment_methods\" WHERE ((((((((((((((\"test_payment_methods\".\"kb_account_id\" = '1234' OR \"test_payment_methods\".\"kb_payment_method_id\" = '1234') OR \"test_payment_methods\".\"token\" = '1234') OR \"test_payment_methods\".\"cc_type\" = '1234') OR \"test_payment_methods\".\"state\" = '1234') OR \"test_payment_methods\".\"zip\" = '1234') OR \"test_payment_methods\".\"cc_first_name\" LIKE '%1234%') OR \"test_payment_methods\".\"cc_last_name\" LIKE '%1234%') OR \"test_payment_methods\".\"address1\" LIKE '%1234%') OR \"test_payment_methods\".\"address2\" LIKE '%1234%') OR \"test_payment_methods\".\"city\" LIKE '%1234%') OR \"test_payment_methods\".\"country\" LIKE '%1234%') OR \"test_payment_methods\".\"cc_exp_month\" = 1234) OR \"test_payment_methods\".\"cc_exp_year\" = 1234) OR \"test_payment_methods\".\"cc_last_4\" = 1234) AND \"test_payment_methods\".\"kb_tenant_id\" = '11-22-33' ORDER BY \"test_payment_methods\".\"id\""
22
22
  # Note that Kill Bill will pass a String, even for numeric types
23
- ::Killbill::Test::TestPaymentMethod.search_query('1234').to_sql.should == expected_query
23
+ ::Killbill::Test::TestPaymentMethod.search_query('1234', '11-22-33').to_sql.should == expected_query
24
24
 
25
25
  # Check query with results (search query numeric)
26
- expected_query = "SELECT DISTINCT \"test_payment_methods\".* FROM \"test_payment_methods\" WHERE ((((((((((((((\"test_payment_methods\".\"kb_account_id\" = '1234' OR \"test_payment_methods\".\"kb_payment_method_id\" = '1234') OR \"test_payment_methods\".\"token\" = '1234') OR \"test_payment_methods\".\"cc_type\" = '1234') OR \"test_payment_methods\".\"state\" = '1234') OR \"test_payment_methods\".\"zip\" = '1234') OR \"test_payment_methods\".\"cc_first_name\" LIKE '%1234%') OR \"test_payment_methods\".\"cc_last_name\" LIKE '%1234%') OR \"test_payment_methods\".\"address1\" LIKE '%1234%') OR \"test_payment_methods\".\"address2\" LIKE '%1234%') OR \"test_payment_methods\".\"city\" LIKE '%1234%') OR \"test_payment_methods\".\"country\" LIKE '%1234%') OR \"test_payment_methods\".\"cc_exp_month\" = 1234) OR \"test_payment_methods\".\"cc_exp_year\" = 1234) OR \"test_payment_methods\".\"cc_last_4\" = 1234) ORDER BY \"test_payment_methods\".\"id\" LIMIT 10 OFFSET 0"
26
+ expected_query = "SELECT DISTINCT \"test_payment_methods\".* FROM \"test_payment_methods\" WHERE ((((((((((((((\"test_payment_methods\".\"kb_account_id\" = '1234' OR \"test_payment_methods\".\"kb_payment_method_id\" = '1234') OR \"test_payment_methods\".\"token\" = '1234') OR \"test_payment_methods\".\"cc_type\" = '1234') OR \"test_payment_methods\".\"state\" = '1234') OR \"test_payment_methods\".\"zip\" = '1234') OR \"test_payment_methods\".\"cc_first_name\" LIKE '%1234%') OR \"test_payment_methods\".\"cc_last_name\" LIKE '%1234%') OR \"test_payment_methods\".\"address1\" LIKE '%1234%') OR \"test_payment_methods\".\"address2\" LIKE '%1234%') OR \"test_payment_methods\".\"city\" LIKE '%1234%') OR \"test_payment_methods\".\"country\" LIKE '%1234%') OR \"test_payment_methods\".\"cc_exp_month\" = 1234) OR \"test_payment_methods\".\"cc_exp_year\" = 1234) OR \"test_payment_methods\".\"cc_last_4\" = 1234) AND \"test_payment_methods\".\"kb_tenant_id\" = '11-22-33' ORDER BY \"test_payment_methods\".\"id\" LIMIT 10 OFFSET 0"
27
27
  # Note that Kill Bill will pass a String, even for numeric types
28
- ::Killbill::Test::TestPaymentMethod.search_query('1234', 0, 10).to_sql.should == expected_query
28
+ ::Killbill::Test::TestPaymentMethod.search_query('1234', '11-22-33', 0, 10).to_sql.should == expected_query
29
29
 
30
30
  # Check count query (search query string)
31
- expected_query = "SELECT COUNT(DISTINCT \"test_payment_methods\".\"id\") FROM \"test_payment_methods\" WHERE (((((((((((\"test_payment_methods\".\"kb_account_id\" = 'XXX' OR \"test_payment_methods\".\"kb_payment_method_id\" = 'XXX') OR \"test_payment_methods\".\"token\" = 'XXX') OR \"test_payment_methods\".\"cc_type\" = 'XXX') OR \"test_payment_methods\".\"state\" = 'XXX') OR \"test_payment_methods\".\"zip\" = 'XXX') OR \"test_payment_methods\".\"cc_first_name\" LIKE '%XXX%') OR \"test_payment_methods\".\"cc_last_name\" LIKE '%XXX%') OR \"test_payment_methods\".\"address1\" LIKE '%XXX%') OR \"test_payment_methods\".\"address2\" LIKE '%XXX%') OR \"test_payment_methods\".\"city\" LIKE '%XXX%') OR \"test_payment_methods\".\"country\" LIKE '%XXX%') ORDER BY \"test_payment_methods\".\"id\""
32
- ::Killbill::Test::TestPaymentMethod.search_query('XXX').to_sql.should == expected_query
31
+ expected_query = "SELECT COUNT(DISTINCT \"test_payment_methods\".\"id\") FROM \"test_payment_methods\" WHERE (((((((((((\"test_payment_methods\".\"kb_account_id\" = 'XXX' OR \"test_payment_methods\".\"kb_payment_method_id\" = 'XXX') OR \"test_payment_methods\".\"token\" = 'XXX') OR \"test_payment_methods\".\"cc_type\" = 'XXX') OR \"test_payment_methods\".\"state\" = 'XXX') OR \"test_payment_methods\".\"zip\" = 'XXX') OR \"test_payment_methods\".\"cc_first_name\" LIKE '%XXX%') OR \"test_payment_methods\".\"cc_last_name\" LIKE '%XXX%') OR \"test_payment_methods\".\"address1\" LIKE '%XXX%') OR \"test_payment_methods\".\"address2\" LIKE '%XXX%') OR \"test_payment_methods\".\"city\" LIKE '%XXX%') OR \"test_payment_methods\".\"country\" LIKE '%XXX%') AND \"test_payment_methods\".\"kb_tenant_id\" = '11-22-33' ORDER BY \"test_payment_methods\".\"id\""
32
+ ::Killbill::Test::TestPaymentMethod.search_query('XXX', '11-22-33').to_sql.should == expected_query
33
33
 
34
34
  # Check query with results (search query string)
35
- expected_query = "SELECT DISTINCT \"test_payment_methods\".* FROM \"test_payment_methods\" WHERE (((((((((((\"test_payment_methods\".\"kb_account_id\" = 'XXX' OR \"test_payment_methods\".\"kb_payment_method_id\" = 'XXX') OR \"test_payment_methods\".\"token\" = 'XXX') OR \"test_payment_methods\".\"cc_type\" = 'XXX') OR \"test_payment_methods\".\"state\" = 'XXX') OR \"test_payment_methods\".\"zip\" = 'XXX') OR \"test_payment_methods\".\"cc_first_name\" LIKE '%XXX%') OR \"test_payment_methods\".\"cc_last_name\" LIKE '%XXX%') OR \"test_payment_methods\".\"address1\" LIKE '%XXX%') OR \"test_payment_methods\".\"address2\" LIKE '%XXX%') OR \"test_payment_methods\".\"city\" LIKE '%XXX%') OR \"test_payment_methods\".\"country\" LIKE '%XXX%') ORDER BY \"test_payment_methods\".\"id\" LIMIT 10 OFFSET 0"
36
- ::Killbill::Test::TestPaymentMethod.search_query('XXX', 0, 10).to_sql.should == expected_query
35
+ expected_query = "SELECT DISTINCT \"test_payment_methods\".* FROM \"test_payment_methods\" WHERE (((((((((((\"test_payment_methods\".\"kb_account_id\" = 'XXX' OR \"test_payment_methods\".\"kb_payment_method_id\" = 'XXX') OR \"test_payment_methods\".\"token\" = 'XXX') OR \"test_payment_methods\".\"cc_type\" = 'XXX') OR \"test_payment_methods\".\"state\" = 'XXX') OR \"test_payment_methods\".\"zip\" = 'XXX') OR \"test_payment_methods\".\"cc_first_name\" LIKE '%XXX%') OR \"test_payment_methods\".\"cc_last_name\" LIKE '%XXX%') OR \"test_payment_methods\".\"address1\" LIKE '%XXX%') OR \"test_payment_methods\".\"address2\" LIKE '%XXX%') OR \"test_payment_methods\".\"city\" LIKE '%XXX%') OR \"test_payment_methods\".\"country\" LIKE '%XXX%') AND \"test_payment_methods\".\"kb_tenant_id\" = '11-22-33' ORDER BY \"test_payment_methods\".\"id\" LIMIT 10 OFFSET 0"
36
+ ::Killbill::Test::TestPaymentMethod.search_query('XXX', '11-22-33', 0, 10).to_sql.should == expected_query
37
37
  end
38
38
 
39
39
  it 'should search all fields' do
@@ -41,6 +41,7 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::PaymentMethod do
41
41
 
42
42
  pm = ::Killbill::Test::TestPaymentMethod.create :kb_account_id => '11-22-33-44',
43
43
  :kb_payment_method_id => '55-66-77-88',
44
+ :kb_tenant_id => '11-22-33',
44
45
  :cc_first_name => 'ccFirstName',
45
46
  :cc_last_name => 'ccLastName',
46
47
  :cc_type => 'ccType',
@@ -65,6 +66,7 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::PaymentMethod do
65
66
 
66
67
  pm2 = ::Killbill::Test::TestPaymentMethod.create :kb_account_id => '22-33-44-55',
67
68
  :kb_payment_method_id => '66-77-88-99',
69
+ :kb_tenant_id => '11-22-33',
68
70
  :cc_first_name => 'ccFirstName',
69
71
  :cc_last_name => 'ccLastName',
70
72
  :cc_type => 'ccType',
@@ -92,7 +94,7 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::PaymentMethod do
92
94
  private
93
95
 
94
96
  def do_search(search_key)
95
- pagination = ::Killbill::Test::TestPaymentMethod.search(search_key)
97
+ pagination = ::Killbill::Test::TestPaymentMethod.search(search_key, '11-22-33')
96
98
  pagination.current_offset.should == 0
97
99
  results = pagination.iterator.to_a
98
100
  pagination.total_nb_records.should == results.size
@@ -18,45 +18,53 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::Response do
18
18
 
19
19
  it 'should generate the right SQL query' do
20
20
  # Check count query (search query numeric)
21
- expected_query = "SELECT COUNT(DISTINCT \"test_responses\".\"id\") FROM \"test_responses\" WHERE (((\"test_responses\".\"kb_payment_id\" = '1234' OR \"test_responses\".\"message\" = '1234') OR \"test_responses\".\"authorization\" = '1234') OR \"test_responses\".\"fraud_review\" = '1234') AND \"test_responses\".\"api_call\" = 'charge' AND \"test_responses\".\"success\" = 't' ORDER BY \"test_responses\".\"id\""
21
+ expected_query = "SELECT COUNT(DISTINCT \"test_responses\".\"id\") FROM \"test_responses\" WHERE (((\"test_responses\".\"kb_payment_id\" = '1234' OR \"test_responses\".\"message\" = '1234') OR \"test_responses\".\"authorization\" = '1234') OR \"test_responses\".\"fraud_review\" = '1234') AND \"test_responses\".\"api_call\" = 'charge' AND \"test_responses\".\"success\" = 't' AND \"test_responses\".\"kb_tenant_id\" = '11-22-33' ORDER BY \"test_responses\".\"id\""
22
22
  # Note that Kill Bill will pass a String, even for numeric types
23
- ::Killbill::Test::TestResponse.search_query('charge', '1234').to_sql.should == expected_query
23
+ ::Killbill::Test::TestResponse.search_query('charge', '1234', '11-22-33').to_sql.should == expected_query
24
24
 
25
25
  # Check query with results (search query numeric)
26
- expected_query = "SELECT DISTINCT \"test_responses\".* FROM \"test_responses\" WHERE (((\"test_responses\".\"kb_payment_id\" = '1234' OR \"test_responses\".\"message\" = '1234') OR \"test_responses\".\"authorization\" = '1234') OR \"test_responses\".\"fraud_review\" = '1234') AND \"test_responses\".\"api_call\" = 'charge' AND \"test_responses\".\"success\" = 't' ORDER BY \"test_responses\".\"id\" LIMIT 10 OFFSET 0"
26
+ expected_query = "SELECT DISTINCT \"test_responses\".* FROM \"test_responses\" WHERE (((\"test_responses\".\"kb_payment_id\" = '1234' OR \"test_responses\".\"message\" = '1234') OR \"test_responses\".\"authorization\" = '1234') OR \"test_responses\".\"fraud_review\" = '1234') AND \"test_responses\".\"api_call\" = 'charge' AND \"test_responses\".\"success\" = 't' AND \"test_responses\".\"kb_tenant_id\" = '11-22-33' ORDER BY \"test_responses\".\"id\" LIMIT 10 OFFSET 0"
27
27
  # Note that Kill Bill will pass a String, even for numeric types
28
- ::Killbill::Test::TestResponse.search_query('charge', '1234', 0, 10).to_sql.should == expected_query
28
+ ::Killbill::Test::TestResponse.search_query('charge', '1234', '11-22-33', 0, 10).to_sql.should == expected_query
29
29
 
30
30
  # Check count query (search query string)
31
- expected_query = "SELECT COUNT(DISTINCT \"test_responses\".\"id\") FROM \"test_responses\" WHERE (((\"test_responses\".\"kb_payment_id\" = 'XXX' OR \"test_responses\".\"message\" = 'XXX') OR \"test_responses\".\"authorization\" = 'XXX') OR \"test_responses\".\"fraud_review\" = 'XXX') AND \"test_responses\".\"api_call\" = 'charge' AND \"test_responses\".\"success\" = 't' ORDER BY \"test_responses\".\"id\""
32
- ::Killbill::Test::TestResponse.search_query('charge', 'XXX').to_sql.should == expected_query
31
+ expected_query = "SELECT COUNT(DISTINCT \"test_responses\".\"id\") FROM \"test_responses\" WHERE (((\"test_responses\".\"kb_payment_id\" = 'XXX' OR \"test_responses\".\"message\" = 'XXX') OR \"test_responses\".\"authorization\" = 'XXX') OR \"test_responses\".\"fraud_review\" = 'XXX') AND \"test_responses\".\"api_call\" = 'charge' AND \"test_responses\".\"success\" = 't' AND \"test_responses\".\"kb_tenant_id\" = '11-22-33' ORDER BY \"test_responses\".\"id\""
32
+ ::Killbill::Test::TestResponse.search_query('charge', 'XXX', '11-22-33').to_sql.should == expected_query
33
33
 
34
34
  # Check query with results (search query string)
35
- expected_query = "SELECT DISTINCT \"test_responses\".* FROM \"test_responses\" WHERE (((\"test_responses\".\"kb_payment_id\" = 'XXX' OR \"test_responses\".\"message\" = 'XXX') OR \"test_responses\".\"authorization\" = 'XXX') OR \"test_responses\".\"fraud_review\" = 'XXX') AND \"test_responses\".\"api_call\" = 'charge' AND \"test_responses\".\"success\" = 't' ORDER BY \"test_responses\".\"id\" LIMIT 10 OFFSET 0"
36
- ::Killbill::Test::TestResponse.search_query('charge', 'XXX', 0, 10).to_sql.should == expected_query
35
+ expected_query = "SELECT DISTINCT \"test_responses\".* FROM \"test_responses\" WHERE (((\"test_responses\".\"kb_payment_id\" = 'XXX' OR \"test_responses\".\"message\" = 'XXX') OR \"test_responses\".\"authorization\" = 'XXX') OR \"test_responses\".\"fraud_review\" = 'XXX') AND \"test_responses\".\"api_call\" = 'charge' AND \"test_responses\".\"success\" = 't' AND \"test_responses\".\"kb_tenant_id\" = '11-22-33' ORDER BY \"test_responses\".\"id\" LIMIT 10 OFFSET 0"
36
+ ::Killbill::Test::TestResponse.search_query('charge', 'XXX', '11-22-33', 0, 10).to_sql.should == expected_query
37
37
  end
38
38
 
39
39
  it 'should search all fields' do
40
40
  do_search('foo').size.should == 0
41
41
 
42
42
  pm = ::Killbill::Test::TestResponse.create :api_call => 'charge',
43
+ :kb_account_id => '55-66-77-88',
43
44
  :kb_payment_id => '11-22-33-44',
45
+ :kb_tenant_id => '11-22-33',
44
46
  :success => true
45
47
 
46
48
  # Wrong api_call
47
49
  ignored1 = ::Killbill::Test::TestResponse.create :api_call => 'add_payment_method',
50
+ :kb_account_id => '55-66-77-88',
48
51
  :kb_payment_id => pm.kb_payment_id,
52
+ :kb_tenant_id => '11-22-33',
49
53
  :success => true
50
54
 
51
55
  # Not successful
52
56
  ignored2 = ::Killbill::Test::TestResponse.create :api_call => 'charge',
57
+ :kb_account_id => '55-66-77-88',
53
58
  :kb_payment_id => pm.kb_payment_id,
59
+ :kb_tenant_id => '11-22-33',
54
60
  :success => false
55
61
 
56
62
  do_search(pm.kb_payment_id).size.should == 1
57
63
 
58
64
  pm2 = ::Killbill::Test::TestResponse.create :api_call => 'charge',
65
+ :kb_account_id => '55-66-77-88',
59
66
  :kb_payment_id => pm.kb_payment_id,
67
+ :kb_tenant_id => '11-22-33',
60
68
  :success => true
61
69
 
62
70
  do_search(pm.kb_payment_id).size.should == 2
@@ -65,7 +73,7 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::Response do
65
73
  private
66
74
 
67
75
  def do_search(search_key)
68
- pagination = ::Killbill::Test::TestResponse.search(search_key)
76
+ pagination = ::Killbill::Test::TestResponse.search(search_key, '11-22-33')
69
77
  pagination.current_offset.should == 0
70
78
  results = pagination.iterator.to_a
71
79
  pagination.total_nb_records.should == results.size
@@ -2,7 +2,6 @@ require 'active_record'
2
2
 
3
3
  ActiveRecord::Schema.define(:version => 20140410153635) do
4
4
  create_table "test_payment_methods", :force => true do |t|
5
- t.string "kb_account_id", :null => false
6
5
  t.string "kb_payment_method_id" # NULL before Kill Bill knows about it
7
6
  t.string "token"
8
7
  t.string "cc_first_name"
@@ -20,6 +19,8 @@ ActiveRecord::Schema.define(:version => 20140410153635) do
20
19
  t.boolean "is_deleted", :null => false, :default => false
21
20
  t.datetime "created_at", :null => false
22
21
  t.datetime "updated_at", :null => false
22
+ t.string "kb_account_id", :null => false
23
+ t.string "kb_tenant_id", :null => false
23
24
  end
24
25
 
25
26
  add_index(:test_payment_methods, :kb_account_id)
@@ -33,6 +34,8 @@ ActiveRecord::Schema.define(:version => 20140410153635) do
33
34
  t.string "currency", :null => false
34
35
  t.datetime "created_at", :null => false
35
36
  t.datetime "updated_at", :null => false
37
+ t.string "kb_account_id", :null => false
38
+ t.string "kb_tenant_id", :null => false
36
39
  end
37
40
 
38
41
  add_index(:test_transactions, :kb_payment_id)
@@ -53,5 +56,7 @@ ActiveRecord::Schema.define(:version => 20140410153635) do
53
56
  t.boolean "success"
54
57
  t.datetime "created_at", :null => false
55
58
  t.datetime "updated_at", :null => false
59
+ t.string "kb_account_id", :null => false
60
+ t.string "kb_tenant_id", :null => false
56
61
  end
57
62
  end
@@ -4,6 +4,7 @@ require 'spec_helper'
4
4
  describe Killbill::Plugin::Api::PaymentPluginApi do
5
5
 
6
6
  before(:all) do
7
+ @call_context = Killbill::Plugin::Model::CallContext.new
7
8
  logger = ::Logger.new(STDOUT)
8
9
  @paymentPluginApi = Killbill::Plugin::Api::PaymentPluginApi.new("Killbill::Plugin::PaymentTest", { "logger" => logger })
9
10
  @kb_account_id = java.util.UUID.fromString("aa5c926e-3d9d-4435-b44b-719d7b583256")
@@ -117,11 +118,11 @@ describe Killbill::Plugin::Api::PaymentPluginApi do
117
118
  end
118
119
 
119
120
  it "should_test_reset_payment_methods_ok" do
120
- @paymentPluginApi.reset_payment_methods(@kb_account_id, java.util.ArrayList.new, @properties)
121
+ @paymentPluginApi.reset_payment_methods(@kb_account_id, java.util.ArrayList.new, @properties, @call_context)
121
122
  end
122
123
 
123
124
  it "should_test_reset_payment_methods_exception" do
124
125
  @paymentPluginApi.delegate_plugin.send(:raise_exception_on_next_calls)
125
- lambda { @paymentPluginApi.reset_payment_methods(@kb_account_id, java.util.ArrayList.new, @properties) }.should raise_error Java::org.killbill.billing.payment.plugin.api.PaymentPluginApiException
126
+ lambda { @paymentPluginApi.reset_payment_methods(@kb_account_id, java.util.ArrayList.new, @properties, @call_context) }.should raise_error Java::org.killbill.billing.payment.plugin.api.PaymentPluginApiException
126
127
  end
127
128
  end
@@ -33,6 +33,6 @@ describe Killbill::Plugin::Payment do
33
33
 
34
34
  lambda { @plugin.get_payment_method_detail(@kb_account_id, @payment_method, @properties, @call_context) }.should raise_error Killbill::Plugin::Payment::OperationUnsupportedByGatewayError
35
35
  lambda { @plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context) }.should raise_error Killbill::Plugin::Payment::OperationUnsupportedByGatewayError
36
- lambda { @plugin.reset_payment_methods(@kb_account_id, @properties, @payment_methods) }.should raise_error Killbill::Plugin::Payment::OperationUnsupportedByGatewayError
36
+ lambda { @plugin.reset_payment_methods(@kb_account_id, @properties, @payment_methods, @call_context) }.should raise_error Killbill::Plugin::Payment::OperationUnsupportedByGatewayError
37
37
  end
38
38
  end
@@ -82,7 +82,7 @@ module Killbill
82
82
  end
83
83
  end
84
84
 
85
- def reset_payment_methods(kb_account_id, payment_methods, properties)
85
+ def reset_payment_methods(kb_account_id, payment_methods, properties, context)
86
86
  if @raise_exception
87
87
  raise StandardError.new("Test exception")
88
88
  end
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.1
4
+ version: 3.1.2
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-04-28 00:00:00.000000000 Z
11
+ date: 2014-04-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sinatra