killbill-stripe 0.2.3 → 1.0.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.
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