killbill 3.1.12 → 3.2.0

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: eb6ce6556b61301d292afa1aa2747c108fd4687e
4
- data.tar.gz: b3416f3c099da146bfbe28436af347b23e12c7ee
3
+ metadata.gz: 965d63f0683725af63c46999dd4b3bce2ed2bab6
4
+ data.tar.gz: 6a722d920223f7123dab21b7f1dbbb2277abbf12
5
5
  SHA512:
6
- metadata.gz: 341509f358870f14af3ed361cc6d32b8bd234b2a18277fefd88dac6ea5876c2533e4576b32523b0de739c112d3b6974bff147c44c88b9404ca2b6ef67ce6d1eb
7
- data.tar.gz: 0cf95757be6be80a1cf04757f284cdef25bccf4936db9d46ed02f8fe5ea2f0068092270fe9adbb0a934afb11c3207c36289dfc5eda7728bbc14baa2fe714dd1b
6
+ metadata.gz: ad59ce23431fcceb7352641ac951e642bc1cd5d91f501ad0022984f32afc68bf25d6312ce31d0c7fc87c5511a990302c65b60258127b0a481f3ab6ac06856e00
7
+ data.tar.gz: 1a670e318c45f7c630a2d8c238aa888e08427c423123c63214397f2ecaaf365e3b4347e25013e4398813df0f73b258952e8c45eef44904c3ab6e601137bcffbd
data/Jarfile CHANGED
@@ -1,8 +1,8 @@
1
1
  jar 'org.kill-bill.billing:killbill-api', '0.10.2'
2
- jar 'org.kill-bill.billing.plugin:killbill-plugin-api-notification', '0.8.1'
3
- jar 'org.kill-bill.billing.plugin:killbill-plugin-api-payment', '0.8.1'
4
- jar 'org.kill-bill.billing.plugin:killbill-plugin-api-currency', '0.8.1'
2
+ jar 'org.kill-bill.billing.plugin:killbill-plugin-api-notification', '0.8.2'
3
+ jar 'org.kill-bill.billing.plugin:killbill-plugin-api-payment', '0.8.2'
4
+ jar 'org.kill-bill.billing.plugin:killbill-plugin-api-currency', '0.8.2'
5
5
  jar 'org.kill-bill.billing.plugin:killbill-plugin-api-retry', '0.8.1'
6
- jar 'org.kill-bill.billing.plugin:killbill-plugin-api-invoice', '0.8.1'
7
- jar 'org.kill-bill.billing:killbill-util:tests', '0.11.9'
6
+ jar 'org.kill-bill.billing.plugin:killbill-plugin-api-invoice', '0.8.2'
7
+ jar 'org.kill-bill.billing:killbill-util:tests', '0.12.0'
8
8
  jar 'javax.servlet:javax.servlet-api', '3.0.1'
data/NEWS CHANGED
@@ -1,3 +1,10 @@
1
+ 3.2.0
2
+ ActiveMerchant:
3
+ - fix openssl require error with the latest version of active_utils
4
+ - fix gateway configuration parsing (add support for false values)
5
+ - store and retrieve the full credit card when not using a third-party vault
6
+ - switch database fields to varchar to support tokenized PANs (DDL change)
7
+
1
8
  3.1.12
2
9
  ActiveMerchant:
3
10
  - store payment_processor_account_id (DDL change)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.1.12
1
+ 3.2.0
@@ -1,8 +1,8 @@
1
1
  jar 'org.kill-bill.billing:killbill-api', '0.10.2'
2
- jar 'org.kill-bill.billing.plugin:killbill-plugin-api-notification', '0.8.1'
3
- jar 'org.kill-bill.billing.plugin:killbill-plugin-api-payment', '0.8.1'
4
- jar 'org.kill-bill.billing.plugin:killbill-plugin-api-currency', '0.8.1'
2
+ jar 'org.kill-bill.billing.plugin:killbill-plugin-api-notification', '0.8.2'
3
+ jar 'org.kill-bill.billing.plugin:killbill-plugin-api-payment', '0.8.2'
4
+ jar 'org.kill-bill.billing.plugin:killbill-plugin-api-currency', '0.8.2'
5
5
  jar 'org.kill-bill.billing.plugin:killbill-plugin-api-retry', '0.8.1'
6
- jar 'org.kill-bill.billing.plugin:killbill-plugin-api-invoice', '0.8.1'
7
- jar 'org.kill-bill.billing:killbill-util:tests', '0.11.9'
6
+ jar 'org.kill-bill.billing.plugin:killbill-plugin-api-invoice', '0.8.2'
7
+ jar 'org.kill-bill.billing:killbill-util:tests', '0.12.1'
8
8
  jar 'javax.servlet:javax.servlet-api', '3.0.1'
@@ -1,6 +1,5 @@
1
1
  :<%= identifier %>:
2
2
  :test: true
3
- :log_file: /var/tmp/<%= identifier %>.log
4
3
 
5
4
  :database:
6
5
  :adapter: sqlite3
@@ -14,6 +13,5 @@
14
13
  # In Kill Bill
15
14
  # :adapter: 'jdbcmysql'
16
15
  # :jndi: 'killbill/osgi/jdbc'
17
- # :driver: 'com.mysql.jdbc.Driver'
18
16
  # :connection_alive_sql: 'select 1'
19
17
  # :pool: 250
@@ -5,10 +5,10 @@ CREATE TABLE `<%= identifier %>_payment_methods` (
5
5
  `cc_first_name` varchar(255) DEFAULT NULL,
6
6
  `cc_last_name` varchar(255) DEFAULT NULL,
7
7
  `cc_type` varchar(255) DEFAULT NULL,
8
- `cc_exp_month` int(11) DEFAULT NULL,
9
- `cc_exp_year` int(11) DEFAULT NULL,
10
- `cc_number` int(11) DEFAULT NULL,
11
- `cc_last_4` int(11) DEFAULT NULL,
8
+ `cc_exp_month` varchar(255) DEFAULT NULL,
9
+ `cc_exp_year` varchar(255) DEFAULT NULL,
10
+ `cc_number` varchar(255) DEFAULT NULL,
11
+ `cc_last_4` varchar(255) DEFAULT NULL,
12
12
  `cc_start_month` varchar(255) DEFAULT NULL,
13
13
  `cc_start_year` varchar(255) DEFAULT NULL,
14
14
  `cc_issue_number` varchar(255) DEFAULT NULL,
@@ -7,15 +7,15 @@ ActiveRecord::Schema.define(:version => 20140410153635) do
7
7
  t.string "cc_first_name"
8
8
  t.string "cc_last_name"
9
9
  t.string "cc_type"
10
- t.integer "cc_exp_month"
11
- t.integer "cc_exp_year"
12
- t.integer "cc_number"
13
- t.integer "cc_last_4"
14
- t.integer "cc_start_month"
15
- t.integer "cc_start_year"
16
- t.integer "cc_issue_number"
17
- t.integer "cc_verification_value"
18
- t.integer "cc_track_data"
10
+ t.string "cc_exp_month"
11
+ t.string "cc_exp_year"
12
+ t.string "cc_number"
13
+ t.string "cc_last_4"
14
+ t.string "cc_start_month"
15
+ t.string "cc_start_year"
16
+ t.string "cc_issue_number"
17
+ t.string "cc_verification_value"
18
+ t.string "cc_track_data"
19
19
  t.string "address1"
20
20
  t.string "address2"
21
21
  t.string "city"
@@ -1,3 +1,4 @@
1
+ require 'openssl'
1
2
  require 'action_controller'
2
3
  require 'active_record'
3
4
  require 'action_view'
@@ -45,7 +45,7 @@ describe Killbill::<%= class_name %>::PaymentPlugin do
45
45
  Killbill::<%= class_name %>::<%= class_name %>Response.all.size.should == 1
46
46
  Killbill::<%= class_name %>::<%= class_name %>Transaction.all.size.should == 0
47
47
 
48
- payment_response = @plugin.purchase_payment(@pm.kb_account_id, @kb_payment.id, @kb_payment.transactions[0].id, SecureRandom.uuid, @amount, @currency, properties, @call_context)
48
+ payment_response = @plugin.purchase_payment(@pm.kb_account_id, @kb_payment.id, @kb_payment.transactions[0].id, @pm.kb_payment_method_id, @amount, @currency, properties, @call_context)
49
49
  payment_response.status.should eq(:PROCESSED), payment_response.gateway_error
50
50
  payment_response.amount.should == @amount
51
51
  payment_response.transaction_type.should == :PURCHASE
@@ -29,6 +29,7 @@ module Killbill
29
29
  :cc_exp_month => cc_or_token.kind_of?(::ActiveMerchant::Billing::CreditCard) ? cc_or_token.month : nil,
30
30
  :cc_exp_year => cc_or_token.kind_of?(::ActiveMerchant::Billing::CreditCard) ? cc_or_token.year : nil,
31
31
  :cc_last_4 => cc_or_token.kind_of?(::ActiveMerchant::Billing::CreditCard) ? cc_or_token.last_digits : nil,
32
+ :cc_number => cc_or_token.kind_of?(::ActiveMerchant::Billing::CreditCard) ? cc_or_token.number : nil,
32
33
  :address1 => (options[:billing_address] || {})[:address1],
33
34
  :address2 => (options[:billing_address] || {})[:address2],
34
35
  :city => (options[:billing_address] || {})[:city],
@@ -147,11 +148,14 @@ module Killbill
147
148
  def to_payment_method_plugin
148
149
  properties = []
149
150
  properties << create_plugin_property('token', external_payment_method_id)
151
+ properties << create_plugin_property('ccFirstName', cc_first_name)
152
+ properties << create_plugin_property('ccLastName', cc_last_name)
150
153
  properties << create_plugin_property('ccName', cc_name)
151
154
  properties << create_plugin_property('ccType', cc_type)
152
155
  properties << create_plugin_property('ccExpirationMonth', cc_exp_month)
153
156
  properties << create_plugin_property('ccExpirationYear', cc_exp_year)
154
157
  properties << create_plugin_property('ccLast4', cc_last_4)
158
+ properties << create_plugin_property('ccNumber', cc_number)
155
159
  properties << create_plugin_property('address1', address1)
156
160
  properties << create_plugin_property('address2', address2)
157
161
  properties << create_plugin_property('city', city)
@@ -19,14 +19,14 @@ module Killbill
19
19
  end
20
20
  ::ActiveMerchant::Billing::Gateway.wiredump_device.sync = true
21
21
 
22
- ::ActiveMerchant::Billing::Gateway.open_timeout = config[:open_timeout] if config[:open_timeout]
23
- ::ActiveMerchant::Billing::Gateway.read_timeout = config[:read_timeout] if config[:read_timeout]
24
- ::ActiveMerchant::Billing::Gateway.retry_safe = config[:retry_safe] if config[:retry_safe]
25
- ::ActiveMerchant::Billing::Gateway.ssl_strict = config[:ssl_strict] if config[:ssl_strict]
26
- ::ActiveMerchant::Billing::Gateway.ssl_version = config[:ssl_version] if config[:ssl_version]
27
- ::ActiveMerchant::Billing::Gateway.max_retries = config[:max_retries] if config[:max_retries]
28
- ::ActiveMerchant::Billing::Gateway.proxy_address = config[:proxy_address] if config[:proxy_address]
29
- ::ActiveMerchant::Billing::Gateway.proxy_port = config[:proxy_port] if config[:proxy_port]
22
+ ::ActiveMerchant::Billing::Gateway.open_timeout = config[:open_timeout] unless config[:open_timeout].nil?
23
+ ::ActiveMerchant::Billing::Gateway.read_timeout = config[:read_timeout] unless config[:read_timeout].nil?
24
+ ::ActiveMerchant::Billing::Gateway.retry_safe = config[:retry_safe] unless config[:retry_safe].nil?
25
+ ::ActiveMerchant::Billing::Gateway.ssl_strict = config[:ssl_strict] unless config[:ssl_strict].nil?
26
+ ::ActiveMerchant::Billing::Gateway.ssl_version = config[:ssl_version] unless config[:ssl_version].nil?
27
+ ::ActiveMerchant::Billing::Gateway.max_retries = config[:max_retries] unless config[:max_retries].nil?
28
+ ::ActiveMerchant::Billing::Gateway.proxy_address = config[:proxy_address] unless config[:proxy_address].nil?
29
+ ::ActiveMerchant::Billing::Gateway.proxy_port = config[:proxy_port] unless config[:proxy_port].nil?
30
30
 
31
31
  Gateway.new(config, gateway_builder.call(config))
32
32
  end
@@ -152,7 +152,12 @@ module Killbill
152
152
  options[:order_id] ||= kb_payment_method_id
153
153
 
154
154
  # Registering a card or a token
155
- payment_source = get_payment_source(nil, all_properties, options, context)
155
+ if options[:skip_gw]
156
+ # If nothing is passed, that's fine - we probably just want a placeholder row in the plugin
157
+ payment_source = get_payment_source(nil, all_properties, options, context) rescue nil
158
+ else
159
+ payment_source = get_payment_source(nil, all_properties, options, context)
160
+ end
156
161
 
157
162
  # Go to the gateway
158
163
  payment_processor_account_id = options[:payment_processor_account_id] || :default
@@ -161,7 +166,7 @@ module Killbill
161
166
  response, transaction = save_response_and_transaction(gw_response, :add_payment_method, kb_account_id, context.tenant_id, payment_processor_account_id)
162
167
 
163
168
  if response.success
164
- # If we have skipped the call to the gateway, we still need to store the payment method
169
+ # If we have skipped the call to the gateway, we still need to store the payment method (either a token or the full credit card)
165
170
  if options[:skip_gw]
166
171
  cc_or_token = payment_source
167
172
  else
@@ -442,12 +447,30 @@ module Killbill
442
447
  end
443
448
 
444
449
  def get_payment_source(kb_payment_method_id, properties, options, context)
450
+ # Use ccNumber for the real number (if stored locally) or an in-house token (proxy tokenization). It is assumed the rest
451
+ # of the card details are filled (expiration dates, etc.).
445
452
  cc_number = find_value_from_properties(properties, 'ccNumber')
453
+ # Use token for the token stored in an external vault. The token itself should be enough to process payments.
446
454
  cc_or_token = find_value_from_properties(properties, 'token') || find_value_from_properties(properties, 'cardId')
447
455
 
448
456
  if cc_number.blank? and cc_or_token.blank?
449
- # Existing token
450
- cc_or_token = @payment_method_model.from_kb_payment_method_id(kb_payment_method_id, context.tenant_id).token
457
+ # Lookup existing token
458
+ pm = @payment_method_model.from_kb_payment_method_id(kb_payment_method_id, context.tenant_id)
459
+ if pm.token.nil?
460
+ # Real credit card
461
+ cc_or_token = ::ActiveMerchant::Billing::CreditCard.new(
462
+ :number => pm.cc_number,
463
+ :brand => pm.cc_type,
464
+ :month => pm.cc_exp_month,
465
+ :year => pm.cc_exp_year,
466
+ :verification_value => pm.cc_verification_value,
467
+ :first_name => pm.cc_first_name,
468
+ :last_name => pm.cc_last_name
469
+ )
470
+ else
471
+ # Tokenized card
472
+ cc_or_token = pm.token
473
+ end
451
474
  elsif !cc_number.blank? and cc_or_token.blank?
452
475
  # Real credit card
453
476
  cc_or_token = ::ActiveMerchant::Billing::CreditCard.new(
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe Killbill::Plugin::ActiveMerchant::Gateway do
4
+
5
+ it 'should honor configuration options' do
6
+ gateway_builder = Proc.new {}
7
+ logger = Logger.new(STDOUT)
8
+ config = {}
9
+
10
+ verify_config
11
+
12
+ ::Killbill::Plugin::ActiveMerchant::Gateway.wrap(gateway_builder, logger, config)
13
+ verify_config(config)
14
+
15
+ config1 = {:open_timeout => 12, :ssl_version => 5}
16
+ ::Killbill::Plugin::ActiveMerchant::Gateway.wrap(gateway_builder, logger, config1)
17
+ verify_config(config1)
18
+
19
+ config2 = {:retry_safe => true, :ssl_strict => false, :max_retries => nil}
20
+ ::Killbill::Plugin::ActiveMerchant::Gateway.wrap(gateway_builder, logger, config2)
21
+ verify_config(config1.merge(config2).delete_if { |k, v| v.nil? })
22
+ end
23
+
24
+ private
25
+
26
+ def verify_config(config = {})
27
+ ::ActiveMerchant::Billing::Gateway.open_timeout.should == (config.has_key?(:open_timeout) ? config[:open_timeout] : 60)
28
+ ::ActiveMerchant::Billing::Gateway.read_timeout.should == (config.has_key?(:read_timeout) ? config[:read_timeout] : 60)
29
+ ::ActiveMerchant::Billing::Gateway.retry_safe.should == (config.has_key?(:retry_safe) ? config[:retry_safe] : false)
30
+ ::ActiveMerchant::Billing::Gateway.ssl_strict.should == (config.has_key?(:ssl_strict) ? config[:ssl_strict] : true)
31
+ ::ActiveMerchant::Billing::Gateway.ssl_version.should == (config.has_key?(:ssl_version) ? config[:ssl_version] : nil)
32
+ ::ActiveMerchant::Billing::Gateway.max_retries.should == (config.has_key?(:max_retries) ? config[:max_retries] : 3)
33
+ ::ActiveMerchant::Billing::Gateway.proxy_address.should == (config.has_key?(:proxy_address) ? config[:proxy_address] : nil)
34
+ ::ActiveMerchant::Billing::Gateway.proxy_port.should == (config.has_key?(:proxy_port) ? config[:proxy_port] : nil)
35
+ end
36
+ end
@@ -12,7 +12,7 @@ end
12
12
 
13
13
  describe Killbill::Plugin::ActiveMerchant::ActiveRecord::PaymentMethod do
14
14
 
15
- before :all do
15
+ before :each do
16
16
  ::Killbill::Test::TestPaymentMethod.delete_all
17
17
  end
18
18
 
@@ -50,9 +50,9 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::PaymentMethod do
50
50
  pm.cc_first_name.should == cc.first_name
51
51
  pm.cc_last_name.should == cc.last_name
52
52
  pm.cc_type.should == cc.brand
53
- pm.cc_exp_month.should == cc.month.to_i
54
- pm.cc_exp_year.should == cc.year.to_i
55
- pm.cc_last_4.should == cc.last_digits.to_i
53
+ pm.cc_exp_month.should == cc.month
54
+ pm.cc_exp_year.should == cc.year
55
+ pm.cc_last_4.should == cc.last_digits
56
56
  pm.address1.should == options[:billing_address][:address1]
57
57
  pm.address2.should == options[:billing_address][:address2]
58
58
  pm.city.should == options[:billing_address][:city]
@@ -71,9 +71,9 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::PaymentMethod do
71
71
  pm.cc_first_name.should == cc.first_name
72
72
  pm.cc_last_name.should == cc.last_name
73
73
  pm.cc_type.should == cc.brand
74
- pm.cc_exp_month.should == cc.month.to_i
75
- pm.cc_exp_year.should == cc.year.to_i
76
- pm.cc_last_4.should == cc.last_digits.to_i
74
+ pm.cc_exp_month.should == cc.month
75
+ pm.cc_exp_year.should == cc.year
76
+ pm.cc_last_4.should == cc.last_digits
77
77
  pm.address1.should be_nil
78
78
  pm.address2.should be_nil
79
79
  pm.city.should be_nil
@@ -132,7 +132,7 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::PaymentMethod do
132
132
  kb_tenant_id = SecureRandom.uuid
133
133
  response = ::ActiveMerchant::Billing::Response.new(true, nil, {}, {:authorization => SecureRandom.uuid})
134
134
  token = SecureRandom.uuid
135
- pm = ::Killbill::Test::TestPaymentMethod.from_response(kb_account_id, kb_payment_method_id, kb_tenant_id, token, response, {}, {}, ::Killbill::Test::TestPaymentMethod)
135
+ pm = ::Killbill::Test::TestPaymentMethod.from_response(kb_account_id, kb_payment_method_id, kb_tenant_id, token, response, {}, {}, ::Killbill::Test::TestPaymentMethod)
136
136
  pm.save!
137
137
 
138
138
  # Retrieve by account id
@@ -160,14 +160,39 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::PaymentMethod do
160
160
  expect { ::Killbill::Test::TestPaymentMethod.from_kb_payment_method_id(kb_payment_method_id, kb_tenant_id) }.to raise_error
161
161
  end
162
162
 
163
+ it 'should handle non-numeric credit card values' do
164
+ pm = ::Killbill::Test::TestPaymentMethod.create :kb_account_id => '11-22-33-44',
165
+ :kb_payment_method_id => '55-66-77-88',
166
+ :kb_tenant_id => '11-22-33',
167
+ :cc_first_name => 'ccFirstName',
168
+ :cc_last_name => 'ccLastName',
169
+ :cc_type => 'ccType',
170
+ :cc_exp_month => '07',
171
+ :cc_exp_year => '01',
172
+ :cc_last_4 => '0001',
173
+ :cc_number => 'some-proprietary-token-format',
174
+ :address1 => 'address1',
175
+ :address2 => 'address2',
176
+ :city => 'city',
177
+ :state => 'state',
178
+ :zip => 'zip',
179
+ :country => 'country'
180
+
181
+ pm = ::Killbill::Test::TestPaymentMethod.from_kb_payment_method_id(pm.kb_payment_method_id, pm.kb_tenant_id)
182
+ pm.cc_exp_month.should == '07'
183
+ pm.cc_exp_year.should == '01'
184
+ pm.cc_last_4.should == '0001'
185
+ pm.cc_number.should == 'some-proprietary-token-format'
186
+ end
187
+
163
188
  it 'should generate the right SQL query' do
164
189
  # Check count query (search query numeric)
165
- 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\""
190
+ 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\""
166
191
  # Note that Kill Bill will pass a String, even for numeric types
167
192
  ::Killbill::Test::TestPaymentMethod.search_query('1234', '11-22-33').to_sql.should == expected_query
168
193
 
169
194
  # Check query with results (search query numeric)
170
- 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"
195
+ 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"
171
196
  # Note that Kill Bill will pass a String, even for numeric types
172
197
  ::Killbill::Test::TestPaymentMethod.search_query('1234', '11-22-33', 0, 10).to_sql.should == expected_query
173
198
 
@@ -250,7 +275,7 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::PaymentMethod do
250
275
  pmp = pm.to_payment_method_plugin
251
276
  pmp.kb_payment_method_id.should == kb_payment_method_id
252
277
  pmp.external_payment_method_id.should == external_payment_method_id
253
- pmp.properties.size.should == 12
278
+ pmp.properties.size.should == 15
254
279
 
255
280
  # Verify conversion to PaymentMethodInfoPlugin
256
281
  pmip = pm.to_payment_method_info_plugin
@@ -4,6 +4,7 @@ require 'spec/killbill/helpers/response_spec'
4
4
  require 'spec/killbill/helpers/transaction_spec'
5
5
 
6
6
  describe Killbill::Plugin::ActiveMerchant::PaymentPlugin do
7
+ include Killbill::Plugin::ActiveMerchant::RSpec
7
8
 
8
9
  before(:all) do
9
10
  Dir.mktmpdir do |dir|
@@ -78,32 +79,32 @@ describe Killbill::Plugin::ActiveMerchant::PaymentPlugin do
78
79
 
79
80
  authorization_id = SecureRandom.uuid
80
81
  @payment_api.add_payment(@kb_payment_id, authorization_id, SecureRandom.uuid, :AUTHORIZE)
81
- authorization = @plugin.authorize_payment(@kb_account_id, @kb_payment_id, authorization_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
82
+ authorization = @plugin.authorize_payment(@kb_account_id, @kb_payment_id, authorization_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
82
83
  verify_transaction_info_plugin(authorization, authorization_id, :AUTHORIZE, 1)
83
84
 
84
85
  capture_id = SecureRandom.uuid
85
86
  @payment_api.add_payment(@kb_payment_id, capture_id, SecureRandom.uuid, :CAPTURE)
86
- capture = @plugin.capture_payment(@kb_account_id, @kb_payment_id, capture_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
87
+ capture = @plugin.capture_payment(@kb_account_id, @kb_payment_id, capture_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
87
88
  verify_transaction_info_plugin(capture, capture_id, :CAPTURE, 2)
88
89
 
89
90
  purchase_id = SecureRandom.uuid
90
91
  @payment_api.add_payment(@kb_payment_id, purchase_id, SecureRandom.uuid, :PURCHASE)
91
- purchase = @plugin.purchase_payment(@kb_account_id, @kb_payment_id, purchase_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
92
+ purchase = @plugin.purchase_payment(@kb_account_id, @kb_payment_id, purchase_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
92
93
  verify_transaction_info_plugin(purchase, purchase_id, :PURCHASE, 3)
93
94
 
94
95
  void_id = SecureRandom.uuid
95
96
  @payment_api.add_payment(@kb_payment_id, void_id, SecureRandom.uuid, :VOID)
96
- void = @plugin.void_payment(@kb_account_id, @kb_payment_id, void_id, @kb_payment_method_id, @properties, @call_context)
97
+ void = @plugin.void_payment(@kb_account_id, @kb_payment_id, void_id, @kb_payment_method_id, @properties, @call_context)
97
98
  verify_transaction_info_plugin(void, void_id, :VOID, 4)
98
99
 
99
100
  credit_id = SecureRandom.uuid
100
101
  @payment_api.add_payment(@kb_payment_id, credit_id, SecureRandom.uuid, :CREDIT)
101
- credit = @plugin.credit_payment(@kb_account_id, @kb_payment_id, credit_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
102
+ credit = @plugin.credit_payment(@kb_account_id, @kb_payment_id, credit_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
102
103
  verify_transaction_info_plugin(credit, credit_id, :CREDIT, 5)
103
104
 
104
105
  refund_id = SecureRandom.uuid
105
106
  @payment_api.add_payment(@kb_payment_id, refund_id, SecureRandom.uuid, :REFUND)
106
- refund = @plugin.refund_payment(@kb_account_id, @kb_payment_id, refund_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
107
+ refund = @plugin.refund_payment(@kb_account_id, @kb_payment_id, refund_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
107
108
  verify_transaction_info_plugin(refund, refund_id, :REFUND, 6)
108
109
 
109
110
  @plugin.delete_payment_method(@kb_account_id, @kb_payment_method_id, @properties, @call_context)
@@ -129,6 +130,97 @@ describe Killbill::Plugin::ActiveMerchant::PaymentPlugin do
129
130
  verify_transaction_info_plugin(capture, capture_id, :CAPTURE, 2, @ppai.value)
130
131
  end
131
132
 
133
+ it 'should support storing a credit card' do
134
+ @plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context).size.should == 0
135
+
136
+ properties = []
137
+ properties << create_pm_kv_info('ccNumber', '41111111111111111')
138
+ properties << create_pm_kv_info('ccFirstName', 'Paul')
139
+ properties << create_pm_kv_info('ccLastName', 'Dupond')
140
+ properties << create_pm_kv_info('ccType', 'VISA')
141
+ properties << create_pm_kv_info('ccExpirationMonth', '12')
142
+ properties << create_pm_kv_info('ccExpirationYear', '17')
143
+ payment_method_props = ::Killbill::Plugin::Model::PaymentMethodPlugin.new
144
+ payment_method_props.properties = properties
145
+ @plugin.add_payment_method(@kb_account_id, SecureRandom.uuid, payment_method_props, true, @properties, @call_context)
146
+
147
+ pms = @plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context)
148
+ pms.size.should == 1
149
+ pm = @plugin.get_payment_method_detail(@kb_account_id, pms[0].payment_method_id, @properties, @call_context)
150
+ @plugin.find_value_from_properties(pm.properties, 'token').should be_nil
151
+ @plugin.find_value_from_properties(pm.properties, 'ccFirstName').should == 'Paul'
152
+ @plugin.find_value_from_properties(pm.properties, 'ccLastName').should == 'Dupond'
153
+ @plugin.find_value_from_properties(pm.properties, 'ccType').should == 'visa'
154
+ @plugin.find_value_from_properties(pm.properties, 'ccExpirationMonth').should == '12'
155
+ @plugin.find_value_from_properties(pm.properties, 'ccExpirationYear').should == '17'
156
+ @plugin.find_value_from_properties(pm.properties, 'ccLast4').should == '1111'
157
+ @plugin.find_value_from_properties(pm.properties, 'ccNumber').should == '41111111111111111'
158
+
159
+ # Verify we can retrieve the payment source, during the payment call
160
+ source = @plugin.get_payment_source(pm.kb_payment_method_id, [], {}, @call_context)
161
+ source.is_a?(::ActiveMerchant::Billing::CreditCard).should be_true
162
+ source.first_name.should == 'Paul'
163
+ source.last_name.should == 'Dupond'
164
+ source.brand.should == 'visa'
165
+ source.month.should == 12
166
+ source.year.should == 17
167
+ source.number.should == '41111111111111111'
168
+ end
169
+
170
+ it 'should support storing a token' do
171
+ @plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context).size.should == 0
172
+
173
+ properties = []
174
+ properties << create_pm_kv_info('token', 'ABCDEF')
175
+ payment_method_props = ::Killbill::Plugin::Model::PaymentMethodPlugin.new
176
+ payment_method_props.properties = properties
177
+ @plugin.add_payment_method(@kb_account_id, SecureRandom.uuid, payment_method_props, true, @properties, @call_context)
178
+
179
+ pms = @plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context)
180
+ pms.size.should == 1
181
+ pm = @plugin.get_payment_method_detail(@kb_account_id, pms[0].payment_method_id, @properties, @call_context)
182
+ @plugin.find_value_from_properties(pm.properties, 'token').should == 'ABCDEF'
183
+ @plugin.find_value_from_properties(pm.properties, 'ccFirstName').should be_nil
184
+ @plugin.find_value_from_properties(pm.properties, 'ccLastName').should be_nil
185
+ @plugin.find_value_from_properties(pm.properties, 'ccType').should be_nil
186
+ @plugin.find_value_from_properties(pm.properties, 'ccExpirationMonth').should be_nil
187
+ @plugin.find_value_from_properties(pm.properties, 'ccExpirationYear').should be_nil
188
+ @plugin.find_value_from_properties(pm.properties, 'ccLast4').should be_nil
189
+ @plugin.find_value_from_properties(pm.properties, 'ccNumber').should be_nil
190
+
191
+ # Verify we can retrieve the payment source, during the payment call
192
+ source = @plugin.get_payment_source(pm.kb_payment_method_id, [], {}, @call_context)
193
+ source.should == 'ABCDEF'
194
+ end
195
+
196
+ it 'should support storing a placeholder row' do
197
+ @plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context).size.should == 0
198
+
199
+ @plugin.add_payment_method(@kb_account_id, SecureRandom.uuid, ::Killbill::Plugin::Model::PaymentMethodPlugin.new, true, @properties, @call_context)
200
+
201
+ pms = @plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context)
202
+ pms.size.should == 1
203
+ pm = @plugin.get_payment_method_detail(@kb_account_id, pms[0].payment_method_id, @properties, @call_context)
204
+ @plugin.find_value_from_properties(pm.properties, 'token').should be_nil
205
+ @plugin.find_value_from_properties(pm.properties, 'ccFirstName').should be_nil
206
+ @plugin.find_value_from_properties(pm.properties, 'ccLastName').should be_nil
207
+ @plugin.find_value_from_properties(pm.properties, 'ccType').should be_nil
208
+ @plugin.find_value_from_properties(pm.properties, 'ccExpirationMonth').should be_nil
209
+ @plugin.find_value_from_properties(pm.properties, 'ccExpirationYear').should be_nil
210
+ @plugin.find_value_from_properties(pm.properties, 'ccLast4').should be_nil
211
+ @plugin.find_value_from_properties(pm.properties, 'ccNumber').should be_nil
212
+
213
+ # Verify we can retrieve the payment source, during the payment call
214
+ source = @plugin.get_payment_source(pm.kb_payment_method_id, [], {}, @call_context)
215
+ source.is_a?(::ActiveMerchant::Billing::CreditCard).should be_true
216
+ source.first_name.should be_nil
217
+ source.last_name.should be_nil
218
+ source.brand.should be_nil
219
+ source.month.should be_nil
220
+ source.year.should be_nil
221
+ source.number.should be_nil
222
+ end
223
+
132
224
  private
133
225
 
134
226
  def verify_transaction_info_plugin(t_info_plugin, kb_transaction_id, type, transaction_nb, payment_processor_account_id='default')
@@ -7,9 +7,15 @@ ActiveRecord::Schema.define(:version => 20140410153635) do
7
7
  t.string "cc_first_name"
8
8
  t.string "cc_last_name"
9
9
  t.string "cc_type"
10
- t.integer "cc_exp_month"
11
- t.integer "cc_exp_year"
12
- t.integer "cc_last_4"
10
+ t.string "cc_exp_month"
11
+ t.string "cc_exp_year"
12
+ t.string "cc_number"
13
+ t.string "cc_last_4"
14
+ t.string "cc_start_month"
15
+ t.string "cc_start_year"
16
+ t.string "cc_issue_number"
17
+ t.string "cc_verification_value"
18
+ t.string "cc_track_data"
13
19
  t.string "address1"
14
20
  t.string "address2"
15
21
  t.string "city"
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.12
4
+ version: 3.2.0
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-10-23 00:00:00.000000000 Z
11
+ date: 2014-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sinatra
@@ -451,6 +451,7 @@ files:
451
451
  - spec/killbill/gen_conversions_spec.rb
452
452
  - spec/killbill/helpers/configuration_spec.rb
453
453
  - spec/killbill/helpers/connection_spec.rb
454
+ - spec/killbill/helpers/gateway_spec.rb
454
455
  - spec/killbill/helpers/killbill_spec_helper_spec.rb
455
456
  - spec/killbill/helpers/payment_method_spec.rb
456
457
  - spec/killbill/helpers/payment_plugin_spec.rb
@@ -506,6 +507,7 @@ test_files:
506
507
  - spec/killbill/gen_conversions_spec.rb
507
508
  - spec/killbill/helpers/configuration_spec.rb
508
509
  - spec/killbill/helpers/connection_spec.rb
510
+ - spec/killbill/helpers/gateway_spec.rb
509
511
  - spec/killbill/helpers/killbill_spec_helper_spec.rb
510
512
  - spec/killbill/helpers/payment_method_spec.rb
511
513
  - spec/killbill/helpers/payment_plugin_spec.rb