killbill-stripe 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -3
- data/Gemfile +1 -1
- data/Jarfile +7 -5
- data/LICENSE +201 -0
- data/NEWS +1 -1
- data/README.md +26 -7
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/config.ru +1 -1
- data/db/ddl.sql +28 -5
- data/db/schema.rb +41 -17
- data/killbill-stripe.gemspec +14 -7
- data/lib/stripe.rb +10 -16
- data/lib/stripe/api.rb +143 -203
- data/lib/stripe/{config/application.rb → application.rb} +35 -20
- data/lib/stripe/models/payment_method.rb +58 -0
- data/lib/stripe/models/response.rb +80 -0
- data/lib/stripe/models/transaction.rb +11 -0
- data/lib/stripe/private_api.rb +28 -46
- data/pom.xml +3 -3
- data/release.sh +8 -8
- data/spec/spec_helper.rb +3 -16
- data/spec/stripe/base_plugin_spec.rb +26 -20
- data/spec/stripe/remote/integration_spec.rb +120 -167
- data/stripe.yml +21 -0
- metadata +104 -26
- data/lib/stripe/config/configuration.rb +0 -38
- data/lib/stripe/config/properties.rb +0 -23
- data/lib/stripe/models/stripe_payment_method.rb +0 -182
- data/lib/stripe/models/stripe_response.rb +0 -242
- data/lib/stripe/models/stripe_transaction.rb +0 -44
- data/lib/stripe/stripe/gateway.rb +0 -24
- data/lib/stripe/stripe_utils.rb +0 -27
- data/spec/stripe/stripe_payment_method_spec.rb +0 -97
- data/spec/stripe/stripe_response_spec.rb +0 -84
@@ -1,44 +0,0 @@
|
|
1
|
-
module Killbill::Stripe
|
2
|
-
class StripeTransaction < ActiveRecord::Base
|
3
|
-
belongs_to :stripe_response
|
4
|
-
attr_accessible :amount_in_cents, :currency, :api_call, :kb_payment_id, :stripe_txn_id
|
5
|
-
|
6
|
-
def self.from_kb_payment_id(kb_payment_id)
|
7
|
-
transaction_from_kb_payment_id :charge, kb_payment_id, :single
|
8
|
-
end
|
9
|
-
|
10
|
-
def self.refunds_from_kb_payment_id(kb_payment_id)
|
11
|
-
transaction_from_kb_payment_id :refund, kb_payment_id, :multiple
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.find_candidate_transaction_for_refund(kb_payment_id, amount_in_cents)
|
15
|
-
# Find one successful charge which amount is at least the amount we are trying to refund
|
16
|
-
stripe_transactions = StripeTransaction.where("stripe_transactions.amount_in_cents >= ?", amount_in_cents)
|
17
|
-
.find_all_by_api_call_and_kb_payment_id(:charge, kb_payment_id)
|
18
|
-
raise "Unable to find Stripe transaction id for payment #{kb_payment_id}" if stripe_transactions.size == 0
|
19
|
-
|
20
|
-
# We have candidates, but we now need to make sure we didn't refund more than for the specified amount
|
21
|
-
amount_refunded_in_cents = Killbill::Stripe::StripeTransaction.where("api_call = ? and kb_payment_id = ?", :refund, kb_payment_id)
|
22
|
-
.sum("amount_in_cents")
|
23
|
-
|
24
|
-
amount_left_to_refund_in_cents = -amount_refunded_in_cents
|
25
|
-
stripe_transactions.map { |transaction| amount_left_to_refund_in_cents += transaction.amount_in_cents }
|
26
|
-
raise "Amount #{amount_in_cents} too large to refund for payment #{kb_payment_id}" if amount_left_to_refund_in_cents < amount_in_cents
|
27
|
-
|
28
|
-
stripe_transactions.first
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
def self.transaction_from_kb_payment_id(api_call, kb_payment_id, how_many)
|
34
|
-
stripe_transactions = find_all_by_api_call_and_kb_payment_id(api_call, kb_payment_id)
|
35
|
-
raise "Unable to find Stripe transaction id for payment #{kb_payment_id}" if stripe_transactions.empty?
|
36
|
-
if how_many == :single
|
37
|
-
raise "Killbill payment mapping to multiple Stripe transactions for payment #{kb_payment_id}" if stripe_transactions.size > 1
|
38
|
-
stripe_transactions[0]
|
39
|
-
else
|
40
|
-
stripe_transactions
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
module Killbill::Stripe
|
2
|
-
class Gateway
|
3
|
-
def self.from_config(config)
|
4
|
-
if config[:test]
|
5
|
-
ActiveMerchant::Billing::Base.mode = :test
|
6
|
-
end
|
7
|
-
|
8
|
-
if config[:log_file]
|
9
|
-
ActiveMerchant::Billing::StripeGateway.wiredump_device = File.open(config[:log_file], 'w')
|
10
|
-
ActiveMerchant::Billing::StripeGateway.wiredump_device.sync = true
|
11
|
-
end
|
12
|
-
|
13
|
-
Gateway.new(config[:api_secret_key])
|
14
|
-
end
|
15
|
-
|
16
|
-
def initialize(api_secret_key)
|
17
|
-
@gateway = ActiveMerchant::Billing::StripeGateway.new(:login => api_secret_key)
|
18
|
-
end
|
19
|
-
|
20
|
-
def method_missing(m, *args, &block)
|
21
|
-
@gateway.send(m, *args, &block)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
data/lib/stripe/stripe_utils.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
module Killbill::Stripe
|
2
|
-
# Closest from a streaming API as we can get with ActiveRecord
|
3
|
-
class StreamyResultSet
|
4
|
-
include Enumerable
|
5
|
-
|
6
|
-
def initialize(limit, batch_size = 100, &delegate)
|
7
|
-
@limit = limit
|
8
|
-
@batch = [batch_size, limit].min
|
9
|
-
@delegate = delegate
|
10
|
-
end
|
11
|
-
|
12
|
-
def each(&block)
|
13
|
-
(0..(@limit - @batch)).step(@batch) do |i|
|
14
|
-
result = @delegate.call(i, @batch)
|
15
|
-
block.call(result)
|
16
|
-
# Optimization: bail out if no more results
|
17
|
-
break if result.nil? || result.empty?
|
18
|
-
end if @batch > 0
|
19
|
-
# Make sure to return DB connections to the Pool
|
20
|
-
ActiveRecord::Base.connection.close
|
21
|
-
end
|
22
|
-
|
23
|
-
def to_a
|
24
|
-
super.to_a.flatten
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,97 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Killbill::Stripe::StripePaymentMethod do
|
4
|
-
before :all do
|
5
|
-
Killbill::Stripe::StripePaymentMethod.delete_all
|
6
|
-
end
|
7
|
-
|
8
|
-
it 'should generate the right SQL query' do
|
9
|
-
# Check count query (search query numeric)
|
10
|
-
expected_query = "SELECT COUNT(DISTINCT \"stripe_payment_methods\".\"id\") FROM \"stripe_payment_methods\" WHERE (((((((((((((((\"stripe_payment_methods\".\"kb_account_id\" = '1234' OR \"stripe_payment_methods\".\"kb_payment_method_id\" = '1234') OR \"stripe_payment_methods\".\"stripe_customer_id\" = '1234') OR \"stripe_payment_methods\".\"stripe_card_id_or_token\" = '1234') OR \"stripe_payment_methods\".\"cc_type\" = '1234') OR \"stripe_payment_methods\".\"state\" = '1234') OR \"stripe_payment_methods\".\"zip\" = '1234') OR \"stripe_payment_methods\".\"cc_first_name\" LIKE '%1234%') OR \"stripe_payment_methods\".\"cc_last_name\" LIKE '%1234%') OR \"stripe_payment_methods\".\"address1\" LIKE '%1234%') OR \"stripe_payment_methods\".\"address2\" LIKE '%1234%') OR \"stripe_payment_methods\".\"city\" LIKE '%1234%') OR \"stripe_payment_methods\".\"country\" LIKE '%1234%') OR \"stripe_payment_methods\".\"cc_exp_month\" = 1234) OR \"stripe_payment_methods\".\"cc_exp_year\" = 1234) OR \"stripe_payment_methods\".\"cc_last_4\" = 1234) AND \"stripe_payment_methods\".\"kb_payment_method_id\" IS NOT NULL ORDER BY \"stripe_payment_methods\".\"id\""
|
11
|
-
# Note that Kill Bill will pass a String, even for numeric types
|
12
|
-
Killbill::Stripe::StripePaymentMethod.search_query('1234').to_sql.should == expected_query
|
13
|
-
|
14
|
-
# Check query with results (search query numeric)
|
15
|
-
expected_query = "SELECT DISTINCT \"stripe_payment_methods\".* FROM \"stripe_payment_methods\" WHERE (((((((((((((((\"stripe_payment_methods\".\"kb_account_id\" = '1234' OR \"stripe_payment_methods\".\"kb_payment_method_id\" = '1234') OR \"stripe_payment_methods\".\"stripe_customer_id\" = '1234') OR \"stripe_payment_methods\".\"stripe_card_id_or_token\" = '1234') OR \"stripe_payment_methods\".\"cc_type\" = '1234') OR \"stripe_payment_methods\".\"state\" = '1234') OR \"stripe_payment_methods\".\"zip\" = '1234') OR \"stripe_payment_methods\".\"cc_first_name\" LIKE '%1234%') OR \"stripe_payment_methods\".\"cc_last_name\" LIKE '%1234%') OR \"stripe_payment_methods\".\"address1\" LIKE '%1234%') OR \"stripe_payment_methods\".\"address2\" LIKE '%1234%') OR \"stripe_payment_methods\".\"city\" LIKE '%1234%') OR \"stripe_payment_methods\".\"country\" LIKE '%1234%') OR \"stripe_payment_methods\".\"cc_exp_month\" = 1234) OR \"stripe_payment_methods\".\"cc_exp_year\" = 1234) OR \"stripe_payment_methods\".\"cc_last_4\" = 1234) AND \"stripe_payment_methods\".\"kb_payment_method_id\" IS NOT NULL ORDER BY \"stripe_payment_methods\".\"id\" LIMIT 10 OFFSET 0"
|
16
|
-
# Note that Kill Bill will pass a String, even for numeric types
|
17
|
-
Killbill::Stripe::StripePaymentMethod.search_query('1234', 0, 10).to_sql.should == expected_query
|
18
|
-
|
19
|
-
# Check count query (search query string)
|
20
|
-
expected_query = "SELECT COUNT(DISTINCT \"stripe_payment_methods\".\"id\") FROM \"stripe_payment_methods\" WHERE ((((((((((((\"stripe_payment_methods\".\"kb_account_id\" = 'XXX' OR \"stripe_payment_methods\".\"kb_payment_method_id\" = 'XXX') OR \"stripe_payment_methods\".\"stripe_customer_id\" = 'XXX') OR \"stripe_payment_methods\".\"stripe_card_id_or_token\" = 'XXX') OR \"stripe_payment_methods\".\"cc_type\" = 'XXX') OR \"stripe_payment_methods\".\"state\" = 'XXX') OR \"stripe_payment_methods\".\"zip\" = 'XXX') OR \"stripe_payment_methods\".\"cc_first_name\" LIKE '%XXX%') OR \"stripe_payment_methods\".\"cc_last_name\" LIKE '%XXX%') OR \"stripe_payment_methods\".\"address1\" LIKE '%XXX%') OR \"stripe_payment_methods\".\"address2\" LIKE '%XXX%') OR \"stripe_payment_methods\".\"city\" LIKE '%XXX%') OR \"stripe_payment_methods\".\"country\" LIKE '%XXX%') AND \"stripe_payment_methods\".\"kb_payment_method_id\" IS NOT NULL ORDER BY \"stripe_payment_methods\".\"id\""
|
21
|
-
Killbill::Stripe::StripePaymentMethod.search_query('XXX').to_sql.should == expected_query
|
22
|
-
|
23
|
-
# Check query with results (search query string)
|
24
|
-
expected_query = "SELECT DISTINCT \"stripe_payment_methods\".* FROM \"stripe_payment_methods\" WHERE ((((((((((((\"stripe_payment_methods\".\"kb_account_id\" = 'XXX' OR \"stripe_payment_methods\".\"kb_payment_method_id\" = 'XXX') OR \"stripe_payment_methods\".\"stripe_customer_id\" = 'XXX') OR \"stripe_payment_methods\".\"stripe_card_id_or_token\" = 'XXX') OR \"stripe_payment_methods\".\"cc_type\" = 'XXX') OR \"stripe_payment_methods\".\"state\" = 'XXX') OR \"stripe_payment_methods\".\"zip\" = 'XXX') OR \"stripe_payment_methods\".\"cc_first_name\" LIKE '%XXX%') OR \"stripe_payment_methods\".\"cc_last_name\" LIKE '%XXX%') OR \"stripe_payment_methods\".\"address1\" LIKE '%XXX%') OR \"stripe_payment_methods\".\"address2\" LIKE '%XXX%') OR \"stripe_payment_methods\".\"city\" LIKE '%XXX%') OR \"stripe_payment_methods\".\"country\" LIKE '%XXX%') AND \"stripe_payment_methods\".\"kb_payment_method_id\" IS NOT NULL ORDER BY \"stripe_payment_methods\".\"id\" LIMIT 10 OFFSET 0"
|
25
|
-
Killbill::Stripe::StripePaymentMethod.search_query('XXX', 0, 10).to_sql.should == expected_query
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'should search all fields' do
|
29
|
-
do_search('foo').size.should == 0
|
30
|
-
|
31
|
-
pm = Killbill::Stripe::StripePaymentMethod.create :kb_account_id => '11-22-33-44',
|
32
|
-
:kb_payment_method_id => '55-66-77-88',
|
33
|
-
:stripe_customer_id => '123xka',
|
34
|
-
:stripe_card_id_or_token => 38102343,
|
35
|
-
:cc_first_name => 'ccFirstName',
|
36
|
-
:cc_last_name => 'ccLastName',
|
37
|
-
:cc_type => 'ccType',
|
38
|
-
:cc_exp_month => 10,
|
39
|
-
:cc_exp_year => 11,
|
40
|
-
:cc_last_4 => 1234,
|
41
|
-
:address1 => 'address1',
|
42
|
-
:address2 => 'address2',
|
43
|
-
:city => 'city',
|
44
|
-
:state => 'state',
|
45
|
-
:zip => 'zip',
|
46
|
-
:country => 'country'
|
47
|
-
|
48
|
-
do_search('foo').size.should == 0
|
49
|
-
do_search(pm.stripe_card_id_or_token).size.should == 1
|
50
|
-
do_search('ccType').size.should == 1
|
51
|
-
# Exact match only for cc_last_4
|
52
|
-
do_search('123').size.should == 0
|
53
|
-
do_search('1234').size.should == 1
|
54
|
-
# Test partial match
|
55
|
-
do_search('address').size.should == 1
|
56
|
-
do_search('Name').size.should == 1
|
57
|
-
|
58
|
-
pm2 = Killbill::Stripe::StripePaymentMethod.create :kb_account_id => '22-33-44-55',
|
59
|
-
:kb_payment_method_id => '66-77-88-99',
|
60
|
-
:stripe_customer_id => '123xka',
|
61
|
-
:stripe_card_id_or_token => 49384029302,
|
62
|
-
:cc_first_name => 'ccFirstName',
|
63
|
-
:cc_last_name => 'ccLastName',
|
64
|
-
:cc_type => 'ccType',
|
65
|
-
:cc_exp_month => 10,
|
66
|
-
:cc_exp_year => 11,
|
67
|
-
:cc_last_4 => 1234,
|
68
|
-
:address1 => 'address1',
|
69
|
-
:address2 => 'address2',
|
70
|
-
:city => 'city',
|
71
|
-
:state => 'state',
|
72
|
-
:zip => 'zip',
|
73
|
-
:country => 'country'
|
74
|
-
|
75
|
-
do_search('foo').size.should == 0
|
76
|
-
do_search(pm.stripe_card_id_or_token).size.should == 1
|
77
|
-
do_search(pm2.stripe_card_id_or_token).size.should == 1
|
78
|
-
do_search('ccType').size.should == 2
|
79
|
-
# Exact match only for cc_last_4
|
80
|
-
do_search('123').size.should == 0
|
81
|
-
do_search('1234').size.should == 2
|
82
|
-
# Test partial match
|
83
|
-
do_search('cc').size.should == 2
|
84
|
-
do_search('address').size.should == 2
|
85
|
-
do_search('Name').size.should == 2
|
86
|
-
end
|
87
|
-
|
88
|
-
private
|
89
|
-
|
90
|
-
def do_search(search_key)
|
91
|
-
pagination = Killbill::Stripe::StripePaymentMethod.search(search_key)
|
92
|
-
pagination.current_offset.should == 0
|
93
|
-
results = pagination.iterator.to_a
|
94
|
-
pagination.total_nb_records.should == results.size
|
95
|
-
results
|
96
|
-
end
|
97
|
-
end
|
@@ -1,84 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Killbill::Stripe::StripeResponse do
|
4
|
-
before :all do
|
5
|
-
Killbill::Stripe::StripeResponse.delete_all
|
6
|
-
end
|
7
|
-
|
8
|
-
it 'should generate the right SQL query' do
|
9
|
-
# Check count query (search query numeric)
|
10
|
-
expected_query = "SELECT COUNT(DISTINCT \"stripe_responses\".\"id\") FROM \"stripe_responses\" WHERE ((\"stripe_responses\".\"authorization\" = '1234' OR \"stripe_responses\".\"params_id\" = '1234') OR \"stripe_responses\".\"params_card_id\" = '1234') AND \"stripe_responses\".\"api_call\" = 'charge' AND \"stripe_responses\".\"success\" = 't' ORDER BY \"stripe_responses\".\"id\""
|
11
|
-
# Note that Kill Bill will pass a String, even for numeric types
|
12
|
-
Killbill::Stripe::StripeResponse.search_query('charge', '1234').to_sql.should == expected_query
|
13
|
-
|
14
|
-
# Check query with results (search query numeric)
|
15
|
-
expected_query = "SELECT DISTINCT \"stripe_responses\".* FROM \"stripe_responses\" WHERE ((\"stripe_responses\".\"authorization\" = '1234' OR \"stripe_responses\".\"params_id\" = '1234') OR \"stripe_responses\".\"params_card_id\" = '1234') AND \"stripe_responses\".\"api_call\" = 'charge' AND \"stripe_responses\".\"success\" = 't' ORDER BY \"stripe_responses\".\"id\" LIMIT 10 OFFSET 0"
|
16
|
-
# Note that Kill Bill will pass a String, even for numeric types
|
17
|
-
Killbill::Stripe::StripeResponse.search_query('charge', '1234', 0, 10).to_sql.should == expected_query
|
18
|
-
|
19
|
-
# Check count query (search query string)
|
20
|
-
expected_query = "SELECT COUNT(DISTINCT \"stripe_responses\".\"id\") FROM \"stripe_responses\" WHERE ((\"stripe_responses\".\"authorization\" = 'XXX' OR \"stripe_responses\".\"params_id\" = 'XXX') OR \"stripe_responses\".\"params_card_id\" = 'XXX') AND \"stripe_responses\".\"api_call\" = 'charge' AND \"stripe_responses\".\"success\" = 't' ORDER BY \"stripe_responses\".\"id\""
|
21
|
-
Killbill::Stripe::StripeResponse.search_query('charge', 'XXX').to_sql.should == expected_query
|
22
|
-
|
23
|
-
# Check query with results (search query string)
|
24
|
-
expected_query = "SELECT DISTINCT \"stripe_responses\".* FROM \"stripe_responses\" WHERE ((\"stripe_responses\".\"authorization\" = 'XXX' OR \"stripe_responses\".\"params_id\" = 'XXX') OR \"stripe_responses\".\"params_card_id\" = 'XXX') AND \"stripe_responses\".\"api_call\" = 'charge' AND \"stripe_responses\".\"success\" = 't' ORDER BY \"stripe_responses\".\"id\" LIMIT 10 OFFSET 0"
|
25
|
-
Killbill::Stripe::StripeResponse.search_query('charge', 'XXX', 0, 10).to_sql.should == expected_query
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'should search all fields' do
|
29
|
-
do_search('foo').size.should == 0
|
30
|
-
|
31
|
-
pm = Killbill::Stripe::StripeResponse.create :api_call => 'charge',
|
32
|
-
:kb_payment_id => '11-22-33-44',
|
33
|
-
:authorization => 'aa-bb-cc-dd',
|
34
|
-
:params_id => '55-66-77-88',
|
35
|
-
:params_card_id => 38102343,
|
36
|
-
:success => true
|
37
|
-
|
38
|
-
# Wrong api_call
|
39
|
-
ignored1 = Killbill::Stripe::StripeResponse.create :api_call => 'add_payment_method',
|
40
|
-
:kb_payment_id => pm.kb_payment_id,
|
41
|
-
:authorization => pm.authorization,
|
42
|
-
:params_id => pm.params_id,
|
43
|
-
:params_card_id => pm.params_card_id,
|
44
|
-
:success => true
|
45
|
-
|
46
|
-
# Not successful
|
47
|
-
ignored2 = Killbill::Stripe::StripeResponse.create :api_call => 'charge',
|
48
|
-
:kb_payment_id => pm.kb_payment_id,
|
49
|
-
:authorization => pm.authorization,
|
50
|
-
:params_id => pm.params_id,
|
51
|
-
:params_card_id => pm.params_card_id,
|
52
|
-
:success => false
|
53
|
-
|
54
|
-
do_search('foo').size.should == 0
|
55
|
-
do_search(pm.authorization).size.should == 1
|
56
|
-
do_search(pm.params_id).size.should == 1
|
57
|
-
do_search(pm.params_card_id).size.should == 1
|
58
|
-
|
59
|
-
pm2 = Killbill::Stripe::StripeResponse.create :api_call => 'charge',
|
60
|
-
:kb_payment_id => '11-22-33-44',
|
61
|
-
:authorization => 'AA-BB-CC-DD',
|
62
|
-
:params_id => '11-22-33-44',
|
63
|
-
:params_card_id => pm.params_card_id,
|
64
|
-
:success => true
|
65
|
-
|
66
|
-
do_search('foo').size.should == 0
|
67
|
-
do_search(pm.authorization).size.should == 1
|
68
|
-
do_search(pm.params_id).size.should == 1
|
69
|
-
do_search(pm.params_card_id).size.should == 2
|
70
|
-
do_search(pm2.authorization).size.should == 1
|
71
|
-
do_search(pm2.params_id).size.should == 1
|
72
|
-
do_search(pm2.params_card_id).size.should == 2
|
73
|
-
end
|
74
|
-
|
75
|
-
private
|
76
|
-
|
77
|
-
def do_search(search_key)
|
78
|
-
pagination = Killbill::Stripe::StripeResponse.search(search_key)
|
79
|
-
pagination.current_offset.should == 0
|
80
|
-
results = pagination.iterator.to_a
|
81
|
-
pagination.total_nb_records.should == results.size
|
82
|
-
results
|
83
|
-
end
|
84
|
-
end
|