killbill-stripe 0.2.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.3
1
+ 1.0.0
data/db/ddl.sql CHANGED
@@ -6,10 +6,10 @@ CREATE TABLE `stripe_payment_methods` (
6
6
  `cc_first_name` varchar(255) DEFAULT NULL,
7
7
  `cc_last_name` varchar(255) DEFAULT NULL,
8
8
  `cc_type` varchar(255) DEFAULT NULL,
9
- `cc_exp_month` int(11) DEFAULT NULL,
10
- `cc_exp_year` int(11) DEFAULT NULL,
11
- `cc_number` int(11) DEFAULT NULL,
12
- `cc_last_4` int(11) DEFAULT NULL,
9
+ `cc_exp_month` varchar(255) DEFAULT NULL,
10
+ `cc_exp_year` varchar(255) DEFAULT NULL,
11
+ `cc_number` varchar(255) DEFAULT NULL,
12
+ `cc_last_4` varchar(255) DEFAULT NULL,
13
13
  `cc_start_month` varchar(255) DEFAULT NULL,
14
14
  `cc_start_year` varchar(255) DEFAULT NULL,
15
15
  `cc_issue_number` varchar(255) DEFAULT NULL,
data/db/schema.rb CHANGED
@@ -8,15 +8,15 @@ ActiveRecord::Schema.define(:version => 20140410153635) do
8
8
  t.string "cc_first_name"
9
9
  t.string "cc_last_name"
10
10
  t.string "cc_type"
11
- t.integer "cc_exp_month"
12
- t.integer "cc_exp_year"
13
- t.integer "cc_number"
14
- t.integer "cc_last_4"
15
- t.integer "cc_start_month"
16
- t.integer "cc_start_year"
17
- t.integer "cc_issue_number"
18
- t.integer "cc_verification_value"
19
- t.integer "cc_track_data"
11
+ t.string "cc_exp_month"
12
+ t.string "cc_exp_year"
13
+ t.string "cc_number"
14
+ t.string "cc_last_4"
15
+ t.string "cc_start_month"
16
+ t.string "cc_start_year"
17
+ t.string "cc_issue_number"
18
+ t.string "cc_verification_value"
19
+ t.string "cc_track_data"
20
20
  t.string "address1"
21
21
  t.string "address2"
22
22
  t.string "city"
@@ -12,38 +12,40 @@ Gem::Specification.new do |s|
12
12
 
13
13
  s.author = 'Kill Bill core team'
14
14
  s.email = 'killbilling-users@googlegroups.com'
15
- s.homepage = 'http://kill-bill.org'
15
+ s.homepage = 'http://killbill.io'
16
16
 
17
17
  s.files = `git ls-files`.split("\n")
18
18
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
19
  s.bindir = 'bin'
20
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
21
21
  s.require_paths = ['lib']
22
22
 
23
23
  s.rdoc_options << '--exclude' << '.'
24
24
 
25
- s.add_dependency 'killbill', '~> 3.2.4'
25
+ s.add_dependency 'killbill', '~> 4.0.0'
26
+
27
+ s.add_dependency 'sinatra', '~> 1.3.4'
26
28
  s.add_dependency 'thread_safe', '~> 0.3.4'
27
- s.add_dependency 'activemerchant', '~> 1.44.1'
28
- s.add_dependency 'offsite_payments', '~> 2.0.1'
29
29
  s.add_dependency 'activerecord', '~> 4.1.0'
30
- s.add_dependency 'actionpack', '~> 4.1.0'
31
- s.add_dependency 'actionview', '~> 4.1.0'
32
- s.add_dependency 'activesupport', '~> 4.1.0'
33
- s.add_dependency 'money', '~> 6.1.1'
34
- s.add_dependency 'monetize', '~> 0.3.0'
35
- s.add_dependency 'sinatra', '~> 1.3.4'
36
30
  if defined?(JRUBY_VERSION)
37
- s.add_dependency 'activerecord-jdbcmysql-adapter', '~> 1.3.7'
31
+ s.add_dependency 'activerecord-bogacs', '~> 0.3'
32
+ s.add_dependency 'activerecord-jdbc-adapter', '~> 1.3'
38
33
  # Required to avoid errors like java.lang.NoClassDefFoundError: org/bouncycastle/asn1/DERBoolean
39
- s.add_dependency 'jruby-openssl', '~> 0.9.4'
34
+ s.add_dependency 'jruby-openssl', '~> 0.9.6'
40
35
  end
36
+ s.add_dependency 'actionpack', '~> 4.1.0'
37
+ s.add_dependency 'actionview', '~> 4.1.0'
38
+ s.add_dependency 'activemerchant', '~> 1.48.0'
39
+ s.add_dependency 'offsite_payments', '~> 2.1.0'
40
+ s.add_dependency 'monetize', '~> 1.1.0'
41
+ s.add_dependency 'money', '~> 6.5.1'
41
42
 
42
- s.add_development_dependency 'jbundler', '~> 0.4.1'
43
+ s.add_development_dependency 'jbundler', '~> 0.4.3'
43
44
  s.add_development_dependency 'rake', '>= 10.0.0'
44
45
  s.add_development_dependency 'rspec', '~> 2.12.0'
45
46
  if defined?(JRUBY_VERSION)
46
- s.add_development_dependency 'activerecord-jdbcsqlite3-adapter', '~> 1.3.7'
47
+ s.add_development_dependency 'jdbc-sqlite3', '~> 3.7'
48
+ s.add_development_dependency 'jdbc-mariadb', '~> 1.1'
47
49
  else
48
50
  s.add_development_dependency 'sqlite3', '~> 1.3.7'
49
51
  end
data/lib/stripe.rb CHANGED
@@ -22,4 +22,3 @@ require 'stripe/private_api'
22
22
  require 'stripe/models/payment_method'
23
23
  require 'stripe/models/response'
24
24
  require 'stripe/models/transaction'
25
-
data/lib/stripe/api.rb CHANGED
@@ -14,6 +14,14 @@ module Killbill #:nodoc:
14
14
  ::Killbill::Stripe::StripeResponse)
15
15
  end
16
16
 
17
+ def on_event(event)
18
+ # Require to deal with per tenant configuration invalidation
19
+ super(event)
20
+ #
21
+ # Custom event logic could be added below...
22
+ #
23
+ end
24
+
17
25
  def authorize_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
18
26
  pm = @payment_method_model.from_kb_payment_method_id(kb_payment_method_id, context.tenant_id)
19
27
 
@@ -92,6 +100,7 @@ module Killbill #:nodoc:
92
100
 
93
101
  # Pass extra parameters for the gateway here
94
102
  options = {
103
+ :email => @kb_apis.account_user_api.get_account_by_id(kb_account_id, @kb_apis.create_context(context.tenant_id)).email,
95
104
  # This will either update the current customer if present, or create a new one
96
105
  :customer => stripe_customer_id,
97
106
  # Magic field, see also private_api.rb (works only when creating an account)
@@ -186,6 +195,13 @@ module Killbill #:nodoc:
186
195
  # gw_notification.entity =
187
196
  end
188
197
  end
198
+
199
+ private
200
+
201
+ def get_payment_source(kb_payment_method_id, properties, options, context)
202
+ return nil if options[:customer_id]
203
+ super(kb_payment_method_id, properties, options, context)
204
+ end
189
205
  end
190
206
  end
191
207
  end
@@ -18,11 +18,7 @@ end
18
18
 
19
19
  helpers do
20
20
  def plugin(session = {})
21
- ::Killbill::Stripe::PrivatePaymentPlugin.new(:stripe,
22
- ::Killbill::Stripe::StripePaymentMethod,
23
- ::Killbill::Stripe::StripeTransaction,
24
- ::Killbill::Stripe::StripeResponse,
25
- session)
21
+ ::Killbill::Stripe::PrivatePaymentPlugin.new(session)
26
22
  end
27
23
  end
28
24
 
@@ -31,36 +27,35 @@ get '/plugins/killbill-stripe' do
31
27
  kb_account_id = request.GET['kb_account_id']
32
28
  required_parameter! :kb_account_id, kb_account_id
33
29
 
30
+ kb_tenant_id = request.GET['kb_tenant_id']
31
+ kb_tenant = request.env['killbill_tenant']
32
+ kb_tenant_id ||= kb_tenant.id.to_s unless kb_tenant.nil?
33
+
34
34
  # URL to Stripe.js
35
- stripejs_url = config[:stripe][:stripejs_url] || 'https://js.stripe.com/v2/'
35
+ stripejs_url = config(kb_tenant_id)[:stripe][:stripejs_url] || 'https://js.stripe.com/v2/'
36
36
  required_parameter! :stripejs_url, stripejs_url, 'is not configured'
37
37
 
38
38
  # Public API key
39
- publishable_key = config[:stripe][:api_publishable_key]
39
+ publishable_key = config(kb_tenant_id)[:stripe][:api_publishable_key]
40
40
  required_parameter! :publishable_key, publishable_key, 'is not configured'
41
41
 
42
- # Redirect
43
- success_page = params[:successPage] || '/plugins/killbill-stripe'
44
- required_parameter! :success_page, success_page, 'is not specified'
42
+ # Skip redirect? Useful for testing the flow with Kill Bill
43
+ no_redirect = request.GET['no_redirect'] == '1'
45
44
 
46
45
  locals = {
47
46
  :stripejs_url => stripejs_url,
48
47
  :publishable_key => publishable_key,
49
48
  :kb_account_id => kb_account_id,
50
- :success_page => success_page
49
+ :kb_tenant_id => kb_tenant_id,
50
+ :no_redirect => no_redirect
51
51
  }
52
52
  erb :stripejs, :locals => locals
53
53
  end
54
54
 
55
55
  # This is mainly for testing. Your application should redirect from the Stripe.js checkout above
56
56
  # to a custom endpoint where you call the Kill Bill add payment method JAX-RS API.
57
- # If you really want to use this endpoint, you'll have to call the Kill Bill refresh payment methods API
58
- # to get a Kill Bill payment method id assigned.
59
- post '/plugins/killbill-stripe' do
60
- pm = plugin.add_payment_method params
61
-
62
- status 201
63
- redirect '/plugins/killbill-stripe/1.0/pms/' + pm.id.to_s
57
+ post '/plugins/killbill-stripe', :provides => 'json' do
58
+ params.to_json
64
59
  end
65
60
 
66
61
  # curl -v http://127.0.0.1:9292/plugins/killbill-stripe/1.0/pms/1
@@ -88,4 +83,4 @@ get '/plugins/killbill-stripe/1.0/responses/:id', :provides => 'json' do
88
83
  else
89
84
  status 404
90
85
  end
91
- end
86
+ end
@@ -6,12 +6,15 @@ module Killbill #:nodoc:
6
6
 
7
7
  def self.from_response(kb_account_id, kb_payment_method_id, kb_tenant_id, cc_or_token, response, options, extra_params = {}, model = ::Killbill::Stripe::StripePaymentMethod)
8
8
  stripe_customer_id = self.stripe_customer_id_from_kb_account_id(kb_account_id, kb_tenant_id)
9
- unless stripe_customer_id.blank?
9
+ if !stripe_customer_id.blank? && response.respond_to?(:responses)
10
10
  card_response = response.responses.first.params
11
11
  customer_response = response.responses.last.params
12
- else
12
+ elsif response.params['sources']
13
13
  card_response = response.params['sources']['data'][0]
14
14
  customer_response = response.params
15
+ else
16
+ card_response = {}
17
+ customer_response = {}
15
18
  end
16
19
 
17
20
  super(kb_account_id,
@@ -50,7 +53,7 @@ module Killbill #:nodoc:
50
53
  stripe_customer_ids = Set.new
51
54
  pms.each { |pm| stripe_customer_ids << pm.stripe_customer_id }
52
55
  raise "No Stripe customer id found for account #{kb_account_id}" if stripe_customer_ids.empty?
53
- raise "Kill Bill account #{kb_account_id} mapping to multiple Stripe customers: #{stripe_customer_ids}" if stripe_customer_ids.size > 1
56
+ raise "Kill Bill account #{kb_account_id} mapping to multiple Stripe customers: #{stripe_customer_ids.to_a}" if stripe_customer_ids.size > 1
54
57
  stripe_customer_ids.first
55
58
  end
56
59
  end
@@ -1,34 +1,12 @@
1
1
  module Killbill #:nodoc:
2
2
  module Stripe #:nodoc:
3
3
  class PrivatePaymentPlugin < ::Killbill::Plugin::ActiveMerchant::PrivatePaymentPlugin
4
-
5
- def add_payment_method(params)
6
- payment_processor_account_id = params[:paymentProcessorAccountId] || :default
7
- stripe_customer_id = StripePaymentMethod.stripe_customer_id_from_kb_account_id(params[:kbAccountId], params[:kbTenantId])
8
-
9
- # This will either update the current customer if present, or create a new one
10
- stripe_response = gateway(payment_processor_account_id).store(params[:stripeToken], {:description => params[:kbAccountId], :customer => stripe_customer_id})
11
- response, _ = save_response_and_transaction(stripe_response, :add_payment_method, params[:kbAccountId], params[:kbTenantId], payment_processor_account_id)
12
- raise response.message unless response.success
13
-
14
- # Create the payment method (not associated to a Kill Bill payment method yet)
15
- Killbill::Stripe::StripePaymentMethod.create! :kb_account_id => params[:kbAccountId],
16
- :kb_payment_method_id => nil,
17
- :kb_tenant_id => params[:kbTenantId],
18
- :stripe_customer_id => stripe_customer_id,
19
- :token => params[:stripeToken],
20
- :cc_first_name => params[:stripeCardName],
21
- :cc_last_name => nil,
22
- :cc_type => params[:stripeCardType],
23
- :cc_exp_month => params[:stripeCardExpMonth],
24
- :cc_exp_year => params[:stripeCardExpYear],
25
- :cc_last_4 => params[:stripeCardLast4],
26
- :address1 => params[:stripeCardAddressLine1],
27
- :address2 => params[:stripeCardAddressLine2],
28
- :city => params[:stripeCardAddressCity],
29
- :state => params[:stripeCardAddressState],
30
- :zip => params[:stripeCardAddressZip],
31
- :country => params[:stripeCardAddressCountry] || params[:stripeCardCountry]
4
+ def initialize(session = {})
5
+ super(:stripe,
6
+ ::Killbill::Stripe::StripePaymentMethod,
7
+ ::Killbill::Stripe::StripeTransaction,
8
+ ::Killbill::Stripe::StripeResponse,
9
+ session)
32
10
  end
33
11
  end
34
12
  end
@@ -38,8 +38,12 @@
38
38
  $form.append($('<input type="hidden" name="stripeType" />').val(response.type));
39
39
  $form.append($('<input type="hidden" name="stripeObject" />').val(response.object));
40
40
  $form.append($('<input type="hidden" name="stripeUsed" />').val(response.used));
41
- // and re-submit
42
- $form.get(0).submit();
41
+ <% if no_redirect %>
42
+ console.log(response);
43
+ <% else %>
44
+ // and re-submit
45
+ $form.get(0).submit();
46
+ <% end %>
43
47
  }
44
48
  };
45
49
 
@@ -62,6 +66,7 @@
62
66
  <form method="post" id="payment-form" action="">
63
67
  <span class='payment-errors'></span>
64
68
  <input type="hidden" name="kbAccountId" value="<%= kb_account_id %>" />
69
+ <input type="hidden" name="kbTenantId" value="<%= kb_tenant_id %>" />
65
70
  <div class="form-row">
66
71
  <label>
67
72
  <span>Card Number</span>
data/pom.xml CHANGED
@@ -1,6 +1,6 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <!--
3
- ~ Copyright 2014 The Billing Project, LLC
3
+ ~ Copyright 2014-2015 The Billing Project, LLC
4
4
  ~
5
5
  ~ The Billing Project licenses this file to you under the Apache License, version 2.0
6
6
  ~ (the "License"); you may not use this file except in compliance with the
@@ -25,7 +25,7 @@
25
25
  <groupId>org.kill-bill.billing.plugin.ruby</groupId>
26
26
  <artifactId>stripe-plugin</artifactId>
27
27
  <packaging>pom</packaging>
28
- <version>0.2.3</version>
28
+ <version>1.0.0</version>
29
29
  <name>stripe-plugin</name>
30
30
  <url>http://github.com/killbill/killbill-stripe-plugin</url>
31
31
  <description>Plugin for accessing Stripe as a payment gateway</description>
data/release.sh CHANGED
@@ -1,5 +1,8 @@
1
1
  set -e
2
2
 
3
+ BUNDLE=${BUNDLE-"bundle exec"}
4
+ MVN=${MVN-"mvn"}
5
+
3
6
  if [ 'GNU' != "$(tar --help | grep GNU | head -1 | awk '{print $1}')" ]; then
4
7
  echo 'Unable to release: make sure to use GNU tar'
5
8
  exit 1
@@ -14,28 +17,45 @@ else
14
17
  fi
15
18
 
16
19
  VERSION=`grep -E '<version>([0-9]+\.[0-9]+\.[0-9]+)</version>' pom.xml | sed 's/[\t \n]*<version>\(.*\)<\/version>[\t \n]*/\1/'`
17
- if [ "$VERSION" != "$(cat $PWD/VERSION)" ]; then
20
+ if [[ -z "$NO_RELEASE" && "$VERSION" != "$(cat $PWD/VERSION)" ]]; then
18
21
  echo 'Unable to release: make sure the versions in pom.xml and VERSION match'
19
22
  exit 1
20
23
  fi
21
24
 
22
25
  echo 'Cleaning up'
23
- rake killbill:clean ; rake build
26
+ $BUNDLE rake killbill:clean
27
+
28
+ echo 'Building gem'
29
+ $BUNDLE rake build
24
30
 
25
- echo 'Pushing the gem to Rubygems'
26
- rake release
31
+ if [[ -z "$NO_RELEASE" ]]; then
32
+ echo 'Pushing the gem to Rubygems'
33
+ $BUNDLE rake release
34
+ fi
27
35
 
28
36
  echo 'Building artifact'
29
- rake killbill:package
37
+ $BUNDLE rake killbill:package
30
38
 
31
39
  ARTIFACT="$PWD/pkg/killbill-stripe-$VERSION.tar.gz"
32
40
  echo "Pushing $ARTIFACT to Maven Central"
33
- mvn gpg:sign-and-deploy-file \
34
- -DgroupId=org.kill-bill.billing.plugin.ruby \
35
- -DartifactId=stripe-plugin \
36
- -Dversion=$VERSION \
37
- -Dpackaging=tar.gz \
38
- -DrepositoryId=ossrh-releases \
39
- -Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ \
40
- -Dfile=$ARTIFACT \
41
- -DpomFile=pom.xml
41
+
42
+ if [[ -z "$NO_RELEASE" ]]; then
43
+ GOAL=gpg:sign-and-deploy-file
44
+ REPOSITORY_ID=ossrh-releases
45
+ URL=https://oss.sonatype.org/service/local/staging/deploy/maven2/
46
+ else
47
+ GOAL=deploy:deploy-file
48
+ REPOSITORY_ID=sonatype-nexus-snapshots
49
+ URL=https://oss.sonatype.org/content/repositories/snapshots/
50
+ VERSION="$VERSION-SNAPSHOT"
51
+ fi
52
+
53
+ $MVN $GOAL \
54
+ -DgroupId=org.kill-bill.billing.plugin.ruby \
55
+ -DartifactId=stripe-plugin \
56
+ -Dversion=$VERSION \
57
+ -Dpackaging=tar.gz \
58
+ -DrepositoryId=$REPOSITORY_ID \
59
+ -Durl=$URL \
60
+ -Dfile=$ARTIFACT \
61
+ -DpomFile=pom.xml
@@ -1,9 +1,12 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Killbill::Stripe::PaymentPlugin do
4
+
5
+ include ::Killbill::Plugin::ActiveMerchant::RSpec
6
+
4
7
  before(:each) do
5
8
  Dir.mktmpdir do |dir|
6
- file = File.new(File.join(dir, 'stripe.yml'), "w+")
9
+ file = File.new(File.join(dir, 'stripe.yml'), 'w+')
7
10
  file.write(<<-eos)
8
11
  :stripe:
9
12
  :api_secret_key: 'j2lkb12'
@@ -14,12 +17,7 @@ describe Killbill::Stripe::PaymentPlugin do
14
17
  eos
15
18
  file.close
16
19
 
17
- @plugin = Killbill::Stripe::PaymentPlugin.new
18
- @plugin.logger = Logger.new(STDOUT)
19
- @plugin.logger.level = Logger::INFO
20
- @plugin.conf_dir = File.dirname(file)
21
- @account_api = ::Killbill::Plugin::ActiveMerchant::RSpec::FakeJavaUserAccountApi.new
22
- @plugin.kb_apis = Killbill::Plugin::KillbillApi.new('stripe', {})
20
+ @plugin = build_plugin(::Killbill::Stripe::PaymentPlugin, 'stripe', File.dirname(file))
23
21
 
24
22
  # Start the plugin here - since the config file will be deleted
25
23
  @plugin.start_plugin
@@ -39,10 +37,12 @@ describe Killbill::Stripe::PaymentPlugin do
39
37
  verify_pms kb_account_id, 0, context
40
38
 
41
39
  # Create a pm with a kb_payment_method_id
42
- Killbill::Stripe::StripePaymentMethod.create :kb_account_id => kb_account_id,
40
+ Killbill::Stripe::StripePaymentMethod.create(:kb_account_id => kb_account_id,
43
41
  :kb_tenant_id => kb_tenant_id,
44
42
  :kb_payment_method_id => 'kb-1',
45
- :token => 'stripe-1'
43
+ :token => 'stripe-1',
44
+ :created_at => Time.now.utc,
45
+ :updated_at => Time.now.utc)
46
46
  verify_pms kb_account_id, 1, context
47
47
 
48
48
  # Add some in KillBill and reset
@@ -55,9 +55,11 @@ describe Killbill::Stripe::PaymentPlugin do
55
55
  verify_pms kb_account_id, 4, context
56
56
 
57
57
  # Add a payment method without a kb_payment_method_id
58
- Killbill::Stripe::StripePaymentMethod.create :kb_account_id => kb_account_id,
58
+ Killbill::Stripe::StripePaymentMethod.create(:kb_account_id => kb_account_id,
59
59
  :kb_tenant_id => kb_tenant_id,
60
- :token => 'stripe-5'
60
+ :token => 'stripe-5',
61
+ :created_at => Time.now.utc,
62
+ :updated_at => Time.now.utc)
61
63
  @plugin.get_payment_methods(kb_account_id, false, nil, context).size.should == 5
62
64
 
63
65
  # Verify we can match it