killbill-stripe 0.1.0 → 0.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 +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
data/killbill-stripe.gemspec
CHANGED
@@ -18,24 +18,31 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
19
|
s.bindir = 'bin'
|
20
20
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
|
-
s.require_paths = [
|
21
|
+
s.require_paths = ['lib']
|
22
22
|
|
23
23
|
s.rdoc_options << '--exclude' << '.'
|
24
24
|
|
25
|
-
s.add_dependency 'killbill', '~> 3.
|
26
|
-
s.add_dependency 'activemerchant', '~> 1.
|
27
|
-
s.add_dependency '
|
28
|
-
s.add_dependency '
|
25
|
+
s.add_dependency 'killbill', '~> 3.1.12'
|
26
|
+
s.add_dependency 'activemerchant', '~> 1.44.1'
|
27
|
+
s.add_dependency 'offsite_payments', '~> 2.0.1'
|
28
|
+
s.add_dependency 'activerecord', '~> 4.1.0'
|
29
|
+
s.add_dependency 'actionpack', '~> 4.1.0'
|
30
|
+
s.add_dependency 'actionview', '~> 4.1.0'
|
31
|
+
s.add_dependency 'activesupport', '~> 4.1.0'
|
32
|
+
s.add_dependency 'money', '~> 6.1.1'
|
33
|
+
s.add_dependency 'monetize', '~> 0.3.0'
|
29
34
|
s.add_dependency 'sinatra', '~> 1.3.4'
|
30
35
|
if defined?(JRUBY_VERSION)
|
31
|
-
s.add_dependency 'activerecord-jdbcmysql-adapter', '~> 1.
|
36
|
+
s.add_dependency 'activerecord-jdbcmysql-adapter', '~> 1.3.7'
|
37
|
+
# Required to avoid errors like java.lang.NoClassDefFoundError: org/bouncycastle/asn1/DERBoolean
|
38
|
+
s.add_dependency 'jruby-openssl', '~> 0.9.4'
|
32
39
|
end
|
33
40
|
|
34
41
|
s.add_development_dependency 'jbundler', '~> 0.4.1'
|
35
42
|
s.add_development_dependency 'rake', '>= 10.0.0'
|
36
43
|
s.add_development_dependency 'rspec', '~> 2.12.0'
|
37
44
|
if defined?(JRUBY_VERSION)
|
38
|
-
s.add_development_dependency 'activerecord-jdbcsqlite3-adapter', '~> 1.
|
45
|
+
s.add_development_dependency 'activerecord-jdbcsqlite3-adapter', '~> 1.3.7'
|
39
46
|
else
|
40
47
|
s.add_development_dependency 'sqlite3', '~> 1.3.7'
|
41
48
|
end
|
data/lib/stripe.rb
CHANGED
@@ -1,30 +1,24 @@
|
|
1
|
+
require 'action_controller'
|
1
2
|
require 'active_record'
|
2
|
-
require '
|
3
|
+
require 'action_view'
|
4
|
+
require 'active_merchant'
|
5
|
+
require 'active_support'
|
3
6
|
require 'bigdecimal'
|
4
7
|
require 'money'
|
8
|
+
require 'monetize'
|
9
|
+
require 'offsite_payments'
|
5
10
|
require 'pathname'
|
6
|
-
require 'set'
|
7
11
|
require 'sinatra'
|
8
12
|
require 'singleton'
|
9
13
|
require 'yaml'
|
10
14
|
|
11
15
|
require 'killbill'
|
12
|
-
|
13
|
-
require 'stripe/config/configuration'
|
14
|
-
require 'stripe/config/properties'
|
16
|
+
require 'killbill/helpers/active_merchant'
|
15
17
|
|
16
18
|
require 'stripe/api'
|
17
19
|
require 'stripe/private_api'
|
18
20
|
|
19
|
-
require 'stripe/models/
|
20
|
-
require 'stripe/models/
|
21
|
-
require 'stripe/models/
|
22
|
-
|
23
|
-
require 'stripe/stripe_utils'
|
24
|
-
require 'stripe/stripe/gateway'
|
21
|
+
require 'stripe/models/payment_method'
|
22
|
+
require 'stripe/models/response'
|
23
|
+
require 'stripe/models/transaction'
|
25
24
|
|
26
|
-
class Object
|
27
|
-
def blank?
|
28
|
-
respond_to?(:empty?) ? empty? : !self
|
29
|
-
end
|
30
|
-
end
|
data/lib/stripe/api.rb
CHANGED
@@ -1,248 +1,188 @@
|
|
1
|
-
module Killbill
|
2
|
-
|
3
|
-
|
4
|
-
Killbill::Stripe.initialize! @logger, @conf_dir, @kb_apis
|
1
|
+
module Killbill #:nodoc:
|
2
|
+
module Stripe #:nodoc:
|
3
|
+
class PaymentPlugin < ::Killbill::Plugin::ActiveMerchant::PaymentPlugin
|
5
4
|
|
6
|
-
|
5
|
+
def initialize
|
6
|
+
gateway_builder = Proc.new do |config|
|
7
|
+
::ActiveMerchant::Billing::StripeGateway.new :login => config[:api_secret_key]
|
8
|
+
end
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
+
super(gateway_builder,
|
11
|
+
:stripe,
|
12
|
+
::Killbill::Stripe::StripePaymentMethod,
|
13
|
+
::Killbill::Stripe::StripeTransaction,
|
14
|
+
::Killbill::Stripe::StripeResponse)
|
15
|
+
end
|
10
16
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
17
|
+
def authorize_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
18
|
+
pm = @payment_method_model.from_kb_payment_method_id(kb_payment_method_id, context.tenant_id)
|
19
|
+
|
20
|
+
# Pass extra parameters for the gateway here
|
21
|
+
options = {
|
22
|
+
:customer => pm.stripe_customer_id
|
23
|
+
}
|
15
24
|
|
16
|
-
|
17
|
-
|
18
|
-
|
25
|
+
properties = merge_properties(properties, options)
|
26
|
+
super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
27
|
+
end
|
19
28
|
|
20
|
-
|
21
|
-
|
22
|
-
|
29
|
+
def capture_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
30
|
+
# Pass extra parameters for the gateway here
|
31
|
+
options = {}
|
23
32
|
|
24
|
-
|
25
|
-
|
26
|
-
|
33
|
+
properties = merge_properties(properties, options)
|
34
|
+
super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
35
|
+
end
|
27
36
|
|
28
|
-
|
29
|
-
|
30
|
-
options[:customer] ||= pm.stripe_customer_id
|
37
|
+
def purchase_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
38
|
+
pm = @payment_method_model.from_kb_payment_method_id(kb_payment_method_id, context.tenant_id)
|
31
39
|
|
32
|
-
|
33
|
-
|
34
|
-
|
40
|
+
# Pass extra parameters for the gateway here
|
41
|
+
options = {
|
42
|
+
:customer => pm.stripe_customer_id
|
43
|
+
}
|
35
44
|
|
36
|
-
|
37
|
-
|
45
|
+
properties = merge_properties(properties, options)
|
46
|
+
super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
47
|
+
end
|
38
48
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
stripe_transaction.stripe_response.to_payment_response
|
43
|
-
end
|
49
|
+
def void_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, properties, context)
|
50
|
+
# Pass extra parameters for the gateway here
|
51
|
+
options = {}
|
44
52
|
|
45
|
-
|
46
|
-
|
47
|
-
|
53
|
+
properties = merge_properties(properties, options)
|
54
|
+
super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, properties, context)
|
55
|
+
end
|
48
56
|
|
49
|
-
|
57
|
+
def credit_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
58
|
+
# Pass extra parameters for the gateway here
|
59
|
+
options = {}
|
50
60
|
|
51
|
-
|
52
|
-
|
53
|
-
|
61
|
+
properties = merge_properties(properties, options)
|
62
|
+
super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
63
|
+
end
|
54
64
|
|
55
|
-
|
56
|
-
|
65
|
+
def refund_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
66
|
+
# Pass extra parameters for the gateway here
|
67
|
+
options = {}
|
57
68
|
|
58
|
-
|
59
|
-
|
60
|
-
|
69
|
+
properties = merge_properties(properties, options)
|
70
|
+
super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
71
|
+
end
|
61
72
|
|
62
|
-
|
63
|
-
|
73
|
+
def get_payment_info(kb_account_id, kb_payment_id, properties, context)
|
74
|
+
# Pass extra parameters for the gateway here
|
75
|
+
options = {}
|
64
76
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
# This will either update the current customer if present, or create a new one
|
70
|
-
options[:customer] ||= stripe_customer_id
|
71
|
-
options[:set_default] ||= set_default
|
72
|
-
|
73
|
-
# Magic field, see also private_api.rb (works only when creating an account)
|
74
|
-
if options[:customer].blank?
|
75
|
-
options[:description] ||= kb_account_id
|
76
|
-
else
|
77
|
-
options[:description] = nil
|
78
|
-
end
|
79
|
-
|
80
|
-
# Registering a card or a token from Stripe.js?
|
81
|
-
cc_or_token = find_value_from_payment_method_props(payment_method_props, 'token') || find_value_from_payment_method_props(payment_method_props, 'cardId')
|
82
|
-
if cc_or_token.blank?
|
83
|
-
# Nope - real credit card
|
84
|
-
cc_or_token = ActiveMerchant::Billing::CreditCard.new(
|
85
|
-
:number => find_value_from_payment_method_props(payment_method_props, 'ccNumber'),
|
86
|
-
:month => find_value_from_payment_method_props(payment_method_props, 'ccExpirationMonth'),
|
87
|
-
:year => find_value_from_payment_method_props(payment_method_props, 'ccExpirationYear'),
|
88
|
-
:verification_value => find_value_from_payment_method_props(payment_method_props, 'ccVerificationValue'),
|
89
|
-
:first_name => find_value_from_payment_method_props(payment_method_props, 'ccFirstName'),
|
90
|
-
:last_name => find_value_from_payment_method_props(payment_method_props, 'ccLastName')
|
91
|
-
)
|
92
|
-
end
|
93
|
-
|
94
|
-
options[:billing_address] ||= {
|
95
|
-
:address1 => find_value_from_payment_method_props(payment_method_props, 'address1'),
|
96
|
-
:address2 => find_value_from_payment_method_props(payment_method_props, 'address2'),
|
97
|
-
:city => find_value_from_payment_method_props(payment_method_props, 'city'),
|
98
|
-
:zip => find_value_from_payment_method_props(payment_method_props, 'zip'),
|
99
|
-
:state => find_value_from_payment_method_props(payment_method_props, 'state'),
|
100
|
-
:country => find_value_from_payment_method_props(payment_method_props, 'country')
|
101
|
-
}
|
102
|
-
|
103
|
-
# Go to Stripe
|
104
|
-
stripe_response = Killbill::Stripe.gateway.store cc_or_token, options
|
105
|
-
response = save_response_and_transaction stripe_response, :add_payment_method
|
106
|
-
|
107
|
-
if response.success
|
108
|
-
unless stripe_customer_id.blank?
|
109
|
-
card_response = stripe_response.responses.first.params
|
110
|
-
customer_response = stripe_response.responses.last.params
|
111
|
-
else
|
112
|
-
card_response = stripe_response.params['cards']['data'][0]
|
113
|
-
customer_response = stripe_response.params
|
114
|
-
end
|
77
|
+
properties = merge_properties(properties, options)
|
78
|
+
super(kb_account_id, kb_payment_id, properties, context)
|
79
|
+
end
|
115
80
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
:cc_type => card_response['type'],
|
123
|
-
:cc_exp_month => card_response['exp_month'],
|
124
|
-
:cc_exp_year => card_response['exp_year'],
|
125
|
-
:cc_last_4 => card_response['last4'],
|
126
|
-
:address1 => card_response['address_line1'],
|
127
|
-
:address2 => card_response['address_line2'],
|
128
|
-
:city => card_response['address_city'],
|
129
|
-
:state => card_response['address_state'],
|
130
|
-
:zip => card_response['address_zip'],
|
131
|
-
:country => card_response['address_country']
|
132
|
-
else
|
133
|
-
raise response.message
|
81
|
+
def search_payments(search_key, offset, limit, properties, context)
|
82
|
+
# Pass extra parameters for the gateway here
|
83
|
+
options = {}
|
84
|
+
|
85
|
+
properties = merge_properties(properties, options)
|
86
|
+
super(search_key, offset, limit, properties, context)
|
134
87
|
end
|
135
|
-
end
|
136
88
|
|
137
|
-
|
138
|
-
|
89
|
+
def add_payment_method(kb_account_id, kb_payment_method_id, payment_method_props, set_default, properties, context)
|
90
|
+
# Do we have a customer for that account already?
|
91
|
+
stripe_customer_id = StripePaymentMethod.stripe_customer_id_from_kb_account_id(kb_account_id, context.tenant_id)
|
139
92
|
|
140
|
-
|
141
|
-
|
142
|
-
|
93
|
+
# Pass extra parameters for the gateway here
|
94
|
+
options = {
|
95
|
+
# This will either update the current customer if present, or create a new one
|
96
|
+
:customer => stripe_customer_id,
|
97
|
+
# Magic field, see also private_api.rb (works only when creating an account)
|
98
|
+
:description => kb_account_id
|
99
|
+
}
|
143
100
|
|
144
|
-
|
145
|
-
|
146
|
-
else
|
147
|
-
raise response.message
|
101
|
+
properties = merge_properties(properties, options)
|
102
|
+
super(kb_account_id, kb_payment_method_id, payment_method_props, set_default, properties, context)
|
148
103
|
end
|
149
|
-
end
|
150
104
|
|
151
|
-
|
152
|
-
|
153
|
-
end
|
105
|
+
def delete_payment_method(kb_account_id, kb_payment_method_id, properties, context)
|
106
|
+
pm = StripePaymentMethod.from_kb_payment_method_id(kb_payment_method_id, context.tenant_id)
|
154
107
|
|
155
|
-
|
156
|
-
|
108
|
+
# Pass extra parameters for the gateway here
|
109
|
+
options = {
|
110
|
+
:customer_id => pm.stripe_customer_id
|
111
|
+
}
|
157
112
|
|
158
|
-
|
159
|
-
|
160
|
-
|
113
|
+
properties = merge_properties(properties, options)
|
114
|
+
super(kb_account_id, kb_payment_method_id, properties, context)
|
115
|
+
end
|
161
116
|
|
162
|
-
|
163
|
-
#
|
164
|
-
|
165
|
-
|
117
|
+
def get_payment_method_detail(kb_account_id, kb_payment_method_id, properties, context)
|
118
|
+
# Pass extra parameters for the gateway here
|
119
|
+
options = {}
|
120
|
+
|
121
|
+
properties = merge_properties(properties, options)
|
122
|
+
super(kb_account_id, kb_payment_method_id, properties, context)
|
166
123
|
end
|
167
|
-
end
|
168
124
|
|
169
|
-
|
170
|
-
|
171
|
-
end
|
125
|
+
def set_default_payment_method(kb_account_id, kb_payment_method_id, properties, context)
|
126
|
+
pm = StripePaymentMethod.from_kb_payment_method_id(kb_payment_method_id, context.tenant_id)
|
172
127
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
stripe_pms = StripePaymentMethod.from_kb_account_id(kb_account_id)
|
177
|
-
|
178
|
-
payment_methods.delete_if do |payment_method_info_plugin|
|
179
|
-
should_be_deleted = false
|
180
|
-
stripe_pms.each do |stripe_pm|
|
181
|
-
# Do stripe_pm and payment_method_info_plugin represent the same Stripe payment method?
|
182
|
-
if stripe_pm.external_payment_method_id == payment_method_info_plugin.external_payment_method_id
|
183
|
-
# Do we already have a kb_payment_method_id?
|
184
|
-
if stripe_pm.kb_payment_method_id == payment_method_info_plugin.payment_method_id
|
185
|
-
should_be_deleted = true
|
186
|
-
break
|
187
|
-
elsif stripe_pm.kb_payment_method_id.nil?
|
188
|
-
# We didn't have the kb_payment_method_id - update it
|
189
|
-
stripe_pm.kb_payment_method_id = payment_method_info_plugin.payment_method_id
|
190
|
-
should_be_deleted = stripe_pm.save
|
191
|
-
break
|
192
|
-
# Otherwise the same card points to 2 different kb_payment_method_id. This should never happen,
|
193
|
-
# but we cowardly will insert a second row below
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|
128
|
+
# Update the default payment method on the customer object
|
129
|
+
stripe_response = gateway.update_customer(pm.stripe_customer_id, :default_card => pm.token)
|
130
|
+
response, transaction = save_response_and_transaction stripe_response, :set_default_payment_method, kb_account_id, context.tenant_id
|
197
131
|
|
198
|
-
|
132
|
+
if response.success
|
133
|
+
# TODO Update our records
|
134
|
+
else
|
135
|
+
raise response.message
|
136
|
+
end
|
199
137
|
end
|
200
138
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
:kb_payment_method_id => payment_method_info_plugin.payment_method_id,
|
205
|
-
:stripe_card_id_or_token => payment_method_info_plugin.external_payment_method_id
|
206
|
-
end
|
207
|
-
end
|
139
|
+
def get_payment_methods(kb_account_id, refresh_from_gateway, properties, context)
|
140
|
+
# Pass extra parameters for the gateway here
|
141
|
+
options = {}
|
208
142
|
|
209
|
-
|
210
|
-
|
211
|
-
|
143
|
+
properties = merge_properties(properties, options)
|
144
|
+
super(kb_account_id, refresh_from_gateway, properties, context)
|
145
|
+
end
|
212
146
|
|
213
|
-
|
214
|
-
|
215
|
-
|
147
|
+
def search_payment_methods(search_key, offset, limit, properties, context)
|
148
|
+
# Pass extra parameters for the gateway here
|
149
|
+
options = {}
|
216
150
|
|
217
|
-
|
218
|
-
|
219
|
-
|
151
|
+
properties = merge_properties(properties, options)
|
152
|
+
super(search_key, offset, limit, properties, context)
|
153
|
+
end
|
220
154
|
|
221
|
-
|
155
|
+
def reset_payment_methods(kb_account_id, payment_methods, properties, context)
|
156
|
+
super
|
157
|
+
end
|
222
158
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
end
|
159
|
+
def build_form_descriptor(kb_account_id, descriptor_fields, properties, context)
|
160
|
+
# Pass extra parameters for the gateway here
|
161
|
+
options = {}
|
162
|
+
properties = merge_properties(properties, options)
|
228
163
|
|
229
|
-
|
230
|
-
|
164
|
+
# Add your custom static hidden tags here
|
165
|
+
options = {
|
166
|
+
#:token => config[:stripe][:token]
|
167
|
+
}
|
168
|
+
descriptor_fields = merge_properties(descriptor_fields, options)
|
231
169
|
|
232
|
-
|
233
|
-
|
234
|
-
response.save!
|
170
|
+
super(kb_account_id, descriptor_fields, properties, context)
|
171
|
+
end
|
235
172
|
|
236
|
-
|
237
|
-
#
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
173
|
+
def process_notification(notification, properties, context)
|
174
|
+
# Pass extra parameters for the gateway here
|
175
|
+
options = {}
|
176
|
+
properties = merge_properties(properties, options)
|
177
|
+
|
178
|
+
super(notification, properties, context) do |gw_notification, service|
|
179
|
+
# Retrieve the payment
|
180
|
+
# gw_notification.kb_payment_id =
|
181
|
+
#
|
182
|
+
# Set the response body
|
183
|
+
# gw_notification.entity =
|
184
|
+
end
|
244
185
|
end
|
245
|
-
response
|
246
186
|
end
|
247
187
|
end
|
248
188
|
end
|