killbill 3.1.12 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 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