killbill-stripe 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +39 -0
- data/.travis.yml +19 -0
- data/Gemfile +3 -0
- data/Jarfile +6 -0
- data/NEWS +2 -0
- data/README.md +21 -0
- data/Rakefile +30 -0
- data/VERSION +1 -0
- data/config.ru +4 -0
- data/db/ddl.sql +99 -0
- data/db/schema.rb +99 -0
- data/killbill-stripe.gemspec +42 -0
- data/killbill.properties +3 -0
- data/lib/stripe/api.rb +248 -0
- data/lib/stripe/config/application.rb +76 -0
- data/lib/stripe/config/configuration.rb +38 -0
- data/lib/stripe/config/properties.rb +23 -0
- data/lib/stripe/models/stripe_payment_method.rb +182 -0
- data/lib/stripe/models/stripe_response.rb +242 -0
- data/lib/stripe/models/stripe_transaction.rb +44 -0
- data/lib/stripe/private_api.rb +52 -0
- data/lib/stripe/stripe/gateway.rb +24 -0
- data/lib/stripe/stripe_utils.rb +27 -0
- data/lib/stripe/views/stripejs.erb +88 -0
- data/lib/stripe.rb +30 -0
- data/pom.xml +44 -0
- data/release.sh +41 -0
- data/spec/spec_helper.rb +37 -0
- data/spec/stripe/base_plugin_spec.rb +85 -0
- data/spec/stripe/remote/integration_spec.rb +208 -0
- data/spec/stripe/stripe_payment_method_spec.rb +97 -0
- data/spec/stripe/stripe_response_spec.rb +84 -0
- metadata +222 -0
@@ -0,0 +1,44 @@
|
|
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
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Killbill::Stripe
|
2
|
+
class PrivatePaymentPlugin
|
3
|
+
include Singleton
|
4
|
+
|
5
|
+
def add_payment_method(params)
|
6
|
+
stripe_customer_id = StripePaymentMethod.stripe_customer_id_from_kb_account_id(params[:kbAccountId])
|
7
|
+
|
8
|
+
# This will either update the current customer if present, or create a new one
|
9
|
+
stripe_response = gateway.store params[:stripeToken], { :description => params[:kbAccountId], :customer => stripe_customer_id }
|
10
|
+
response = save_response stripe_response, :add_payment_method
|
11
|
+
raise response.message unless response.success
|
12
|
+
|
13
|
+
# Create the payment method (not associated to a Kill Bill payment method yet)
|
14
|
+
pm = Killbill::Stripe::StripePaymentMethod.create! :kb_account_id => params[:kbAccountId],
|
15
|
+
:kb_payment_method_id => nil,
|
16
|
+
:stripe_customer_id => stripe_customer_id,
|
17
|
+
:stripe_token => params[:stripeToken],
|
18
|
+
:cc_first_name => params[:stripeCardName],
|
19
|
+
:cc_last_name => nil,
|
20
|
+
:cc_type => params[:stripeCardType],
|
21
|
+
:cc_exp_month => params[:stripeCardExpMonth],
|
22
|
+
:cc_exp_year => params[:stripeCardExpYear],
|
23
|
+
:cc_last_4 => params[:stripeCardLast4],
|
24
|
+
:address1 => params[:stripeCardAddressLine1],
|
25
|
+
:address2 => params[:stripeCardAddressLine2],
|
26
|
+
:city => params[:stripeCardAddressCity],
|
27
|
+
:state => params[:stripeCardAddressState],
|
28
|
+
:zip => params[:stripeCardAddressZip],
|
29
|
+
:country => params[:stripeCardAddressCountry] || params[:stripeCardCountry]
|
30
|
+
pm
|
31
|
+
end
|
32
|
+
|
33
|
+
def save_response(stripe_response, api_call)
|
34
|
+
logger.warn "Unsuccessful #{api_call}: #{stripe_response.message}" unless stripe_response.success?
|
35
|
+
|
36
|
+
# Save the response to our logs
|
37
|
+
response = StripeResponse.from_response(api_call, nil, stripe_response)
|
38
|
+
response.save!
|
39
|
+
response
|
40
|
+
end
|
41
|
+
|
42
|
+
def gateway
|
43
|
+
# The gateway should have been configured when the plugin started
|
44
|
+
Killbill::Stripe.gateway
|
45
|
+
end
|
46
|
+
|
47
|
+
def logger
|
48
|
+
# The logger should have been configured when the plugin started
|
49
|
+
Killbill::Stripe.logger
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,24 @@
|
|
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
|
@@ -0,0 +1,27 @@
|
|
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
|
@@ -0,0 +1,88 @@
|
|
1
|
+
<!-- See https://stripe.com/docs/stripe.js and https://gist.github.com/briancollins/6365455 -->
|
2
|
+
<!DOCTYPE html>
|
3
|
+
<html>
|
4
|
+
<head>
|
5
|
+
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
|
6
|
+
<title>Stripe.js Checkout</title>
|
7
|
+
<script src="<%= stripejs_url %>" type="text/javascript"></script>
|
8
|
+
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
9
|
+
<script type="text/javascript">
|
10
|
+
Stripe.setPublishableKey("<%= publishable_key %>");
|
11
|
+
|
12
|
+
var stripeResponseHandler = function(status, response) {
|
13
|
+
var $form = $('#payment-form');
|
14
|
+
|
15
|
+
if (response.error) {
|
16
|
+
// Show the errors on the form
|
17
|
+
$form.find('.payment-errors').text(response.error.message);
|
18
|
+
$form.find('button').prop('disabled', false);
|
19
|
+
} else {
|
20
|
+
// Insert the response values into the form so it gets submitted to the server
|
21
|
+
$form.append($('<input type="hidden" name="stripeToken" />').val(response.id));
|
22
|
+
$form.append($('<input type="hidden" name="stripeCardName" />').val((response.card || {}).name));
|
23
|
+
$form.append($('<input type="hidden" name="stripeCardAddressLine1" />').val((response.card || {}).address_line1));
|
24
|
+
$form.append($('<input type="hidden" name="stripeCardAddressLine2" />').val((response.card || {}).address_line2));
|
25
|
+
$form.append($('<input type="hidden" name="stripeCardAddressCity" />').val((response.card || {}).address_city));
|
26
|
+
$form.append($('<input type="hidden" name="stripeCardAddressState" />').val((response.card || {}).address_state));
|
27
|
+
$form.append($('<input type="hidden" name="stripeCardAddressZip" />').val((response.card || {}).address_zip));
|
28
|
+
$form.append($('<input type="hidden" name="stripeCardAddressCountry" />').val((response.card || {}).address_country));
|
29
|
+
$form.append($('<input type="hidden" name="stripeCardCountry" />').val((response.card || {}).country));
|
30
|
+
$form.append($('<input type="hidden" name="stripeCardExpMonth" />').val((response.card || {}).exp_month));
|
31
|
+
$form.append($('<input type="hidden" name="stripeCardExpYear" />').val((response.card || {}).exp_year));
|
32
|
+
$form.append($('<input type="hidden" name="stripeCardLast4" />').val((response.card || {}).last4));
|
33
|
+
$form.append($('<input type="hidden" name="stripeCardFingerprint" />').val((response.card || {}).fingerprint));
|
34
|
+
$form.append($('<input type="hidden" name="stripeCardObject" />').val((response.card || {}).object));
|
35
|
+
$form.append($('<input type="hidden" name="stripeCardType" />').val((response.card || {}).type));
|
36
|
+
$form.append($('<input type="hidden" name="stripeCreated" />').val(response.created));
|
37
|
+
$form.append($('<input type="hidden" name="stripeLivemode" />').val(response.livemode));
|
38
|
+
$form.append($('<input type="hidden" name="stripeType" />').val(response.type));
|
39
|
+
$form.append($('<input type="hidden" name="stripeObject" />').val(response.object));
|
40
|
+
$form.append($('<input type="hidden" name="stripeUsed" />').val(response.used));
|
41
|
+
// and re-submit
|
42
|
+
$form.get(0).submit();
|
43
|
+
}
|
44
|
+
};
|
45
|
+
|
46
|
+
$(document).ready(function() {
|
47
|
+
$('#payment-form').submit(function(e) {
|
48
|
+
var $form = $(this);
|
49
|
+
|
50
|
+
// Disable the submit button to prevent repeated clicks
|
51
|
+
$form.find('button').prop('disabled', true);
|
52
|
+
|
53
|
+
Stripe.createToken($form, stripeResponseHandler);
|
54
|
+
|
55
|
+
// Prevent the form from submitting with the default action
|
56
|
+
return false;
|
57
|
+
});
|
58
|
+
});
|
59
|
+
</script>
|
60
|
+
</head>
|
61
|
+
<body>
|
62
|
+
<form method="post" id="payment-form" action="">
|
63
|
+
<span class='payment-errors'></span>
|
64
|
+
<input type="hidden" name="kbAccountId" value="<%= kb_account_id %>" />
|
65
|
+
<div class="form-row">
|
66
|
+
<label>
|
67
|
+
<span>Card Number</span>
|
68
|
+
<input type="text" size="20" data-stripe="number"/>
|
69
|
+
</label>
|
70
|
+
</div>
|
71
|
+
<div class="form-row">
|
72
|
+
<label>
|
73
|
+
<span>CVC</span>
|
74
|
+
<input type="text" size="4" data-stripe="cvc"/>
|
75
|
+
</label>
|
76
|
+
</div>
|
77
|
+
<div class="form-row">
|
78
|
+
<label>
|
79
|
+
<span>Expiration (MM/YYYY)</span>
|
80
|
+
<input type="text" size="2" data-stripe="exp-month"/>
|
81
|
+
</label>
|
82
|
+
<span> / </span>
|
83
|
+
<input type="text" size="4" data-stripe="exp-year"/>
|
84
|
+
</div>
|
85
|
+
<button type="submit">Save credit card</button>
|
86
|
+
</form>
|
87
|
+
</body>
|
88
|
+
</html>
|
data/lib/stripe.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'activemerchant'
|
3
|
+
require 'bigdecimal'
|
4
|
+
require 'money'
|
5
|
+
require 'pathname'
|
6
|
+
require 'set'
|
7
|
+
require 'sinatra'
|
8
|
+
require 'singleton'
|
9
|
+
require 'yaml'
|
10
|
+
|
11
|
+
require 'killbill'
|
12
|
+
|
13
|
+
require 'stripe/config/configuration'
|
14
|
+
require 'stripe/config/properties'
|
15
|
+
|
16
|
+
require 'stripe/api'
|
17
|
+
require 'stripe/private_api'
|
18
|
+
|
19
|
+
require 'stripe/models/stripe_payment_method'
|
20
|
+
require 'stripe/models/stripe_response'
|
21
|
+
require 'stripe/models/stripe_transaction'
|
22
|
+
|
23
|
+
require 'stripe/stripe_utils'
|
24
|
+
require 'stripe/stripe/gateway'
|
25
|
+
|
26
|
+
class Object
|
27
|
+
def blank?
|
28
|
+
respond_to?(:empty?) ? empty? : !self
|
29
|
+
end
|
30
|
+
end
|
data/pom.xml
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!--
|
3
|
+
~ Copyright 2010-2013 Ning, Inc.
|
4
|
+
~
|
5
|
+
~ Ning licenses this file to you under the Apache License, version 2.0
|
6
|
+
~ (the "License"); you may not use this file except in compliance with the
|
7
|
+
~ License. You may obtain a copy of the License at:
|
8
|
+
~
|
9
|
+
~ http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
~
|
11
|
+
~ Unless required by applicable law or agreed to in writing, software
|
12
|
+
~ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
13
|
+
~ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
14
|
+
~ License for the specific language governing permissions and limitations
|
15
|
+
~ under the License.
|
16
|
+
-->
|
17
|
+
|
18
|
+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
19
|
+
<parent>
|
20
|
+
<groupId>org.sonatype.oss</groupId>
|
21
|
+
<artifactId>oss-parent</artifactId>
|
22
|
+
<version>5</version>
|
23
|
+
</parent>
|
24
|
+
<modelVersion>4.0.0</modelVersion>
|
25
|
+
<groupId>org.kill-bill.billing.plugin.ruby</groupId>
|
26
|
+
<artifactId>stripe-plugin</artifactId>
|
27
|
+
<packaging>pom</packaging>
|
28
|
+
<version>0.1.0</version>
|
29
|
+
<name>stripe-plugin</name>
|
30
|
+
<url>http://github.com/killbill/killbill-stripe-plugin</url>
|
31
|
+
<description>Plugin for accessing Stripe as a payment gateway</description>
|
32
|
+
<licenses>
|
33
|
+
<license>
|
34
|
+
<name>Apache License 2.0</name>
|
35
|
+
<url>http://www.apache.org/licenses/LICENSE-2.0.html</url>
|
36
|
+
<distribution>repo</distribution>
|
37
|
+
</license>
|
38
|
+
</licenses>
|
39
|
+
<scm>
|
40
|
+
<connection>scm:git:git://github.com/killbill/killbill-stripe-plugin.git</connection>
|
41
|
+
<url>https://github.com/killbill/killbill-stripe-plugin/</url>
|
42
|
+
<developerConnection>scm:git:git@github.com:killbill/killbill-stripe-plugin.git</developerConnection>
|
43
|
+
</scm>
|
44
|
+
</project>
|
data/release.sh
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
set -e
|
2
|
+
|
3
|
+
if [ "GNU" != "$(tar --help | grep GNU | head -1 | awk '{print $1}')" ]; then
|
4
|
+
echo "Unable to release: make sure to use GNU tar"
|
5
|
+
exit 1
|
6
|
+
fi
|
7
|
+
|
8
|
+
if $(ruby -e'require "java"'); then
|
9
|
+
# Good
|
10
|
+
echo "Detected JRuby"
|
11
|
+
else
|
12
|
+
echo "Unable to release: make sure to use JRuby"
|
13
|
+
exit 1
|
14
|
+
fi
|
15
|
+
|
16
|
+
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
|
18
|
+
echo "Unable to release: make sure the versions in pom.xml and VERSION match"
|
19
|
+
exit 1
|
20
|
+
fi
|
21
|
+
|
22
|
+
echo "Cleaning up"
|
23
|
+
rake killbill:clean ; rake build
|
24
|
+
|
25
|
+
echo "Pushing the gem to Rubygems"
|
26
|
+
rake release
|
27
|
+
|
28
|
+
echo "Building artifact"
|
29
|
+
rake killbill:package
|
30
|
+
|
31
|
+
ARTIFACT="$PWD/pkg/killbill-stripe-$VERSION.tar.gz"
|
32
|
+
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
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
require 'stripe'
|
3
|
+
|
4
|
+
require 'logger'
|
5
|
+
|
6
|
+
require 'rspec'
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
config.color_enabled = true
|
10
|
+
config.tty = true
|
11
|
+
config.formatter = 'documentation'
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'active_record'
|
15
|
+
ActiveRecord::Base.establish_connection(
|
16
|
+
:adapter => 'sqlite3',
|
17
|
+
:database => 'test.db'
|
18
|
+
)
|
19
|
+
# For debugging
|
20
|
+
#ActiveRecord::Base.logger = Logger.new(STDOUT)
|
21
|
+
# Create the schema
|
22
|
+
require File.expand_path(File.dirname(__FILE__) + '../../db/schema.rb')
|
23
|
+
|
24
|
+
begin
|
25
|
+
require 'securerandom'
|
26
|
+
SecureRandom.uuid
|
27
|
+
rescue LoadError, NoMethodError
|
28
|
+
# See http://jira.codehaus.org/browse/JRUBY-6176
|
29
|
+
module SecureRandom
|
30
|
+
def self.uuid
|
31
|
+
ary = self.random_bytes(16).unpack("NnnnnN")
|
32
|
+
ary[2] = (ary[2] & 0x0fff) | 0x4000
|
33
|
+
ary[3] = (ary[3] & 0x3fff) | 0x8000
|
34
|
+
"%08x-%04x-%04x-%04x-%04x%08x" % ary
|
35
|
+
end unless respond_to?(:uuid)
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Killbill::Stripe::PaymentPlugin do
|
4
|
+
before(:each) do
|
5
|
+
Dir.mktmpdir do |dir|
|
6
|
+
file = File.new(File.join(dir, 'stripe.yml'), "w+")
|
7
|
+
file.write(<<-eos)
|
8
|
+
:stripe:
|
9
|
+
:api_secret_key: 'j2lkb12'
|
10
|
+
# As defined by spec_helper.rb
|
11
|
+
:database:
|
12
|
+
:adapter: 'sqlite3'
|
13
|
+
:database: 'test.db'
|
14
|
+
eos
|
15
|
+
file.close
|
16
|
+
|
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
|
+
|
22
|
+
# Start the plugin here - since the config file will be deleted
|
23
|
+
@plugin.start_plugin
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should start and stop correctly' do
|
28
|
+
@plugin.stop_plugin
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should reset payment methods' do
|
32
|
+
kb_account_id = '129384'
|
33
|
+
|
34
|
+
@plugin.get_payment_methods(kb_account_id).size.should == 0
|
35
|
+
verify_pms kb_account_id, 0
|
36
|
+
|
37
|
+
# Create a pm with a kb_payment_method_id
|
38
|
+
Killbill::Stripe::StripePaymentMethod.create :kb_account_id => kb_account_id,
|
39
|
+
:kb_payment_method_id => 'kb-1',
|
40
|
+
:stripe_card_id_or_token => 'stripe-1'
|
41
|
+
verify_pms kb_account_id, 1
|
42
|
+
|
43
|
+
# Add some in KillBill and reset
|
44
|
+
payment_methods = []
|
45
|
+
# Random order... Shouldn't matter...
|
46
|
+
payment_methods << create_pm_info_plugin(kb_account_id, 'kb-3', false, 'stripe-3')
|
47
|
+
payment_methods << create_pm_info_plugin(kb_account_id, 'kb-2', false, 'stripe-2')
|
48
|
+
payment_methods << create_pm_info_plugin(kb_account_id, 'kb-4', false, 'stripe-4')
|
49
|
+
@plugin.reset_payment_methods kb_account_id, payment_methods
|
50
|
+
verify_pms kb_account_id, 4
|
51
|
+
|
52
|
+
# Add a payment method without a kb_payment_method_id
|
53
|
+
Killbill::Stripe::StripePaymentMethod.create :kb_account_id => kb_account_id,
|
54
|
+
:stripe_card_id_or_token => 'stripe-5'
|
55
|
+
@plugin.get_payment_methods(kb_account_id).size.should == 5
|
56
|
+
|
57
|
+
# Verify we can match it
|
58
|
+
payment_methods << create_pm_info_plugin(kb_account_id, 'kb-5', false, 'stripe-5')
|
59
|
+
@plugin.reset_payment_methods kb_account_id, payment_methods
|
60
|
+
verify_pms kb_account_id, 5
|
61
|
+
|
62
|
+
@plugin.stop_plugin
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def verify_pms(kb_account_id, size)
|
68
|
+
pms = @plugin.get_payment_methods(kb_account_id)
|
69
|
+
pms.size.should == size
|
70
|
+
pms.each do |pm|
|
71
|
+
pm.account_id.should == kb_account_id
|
72
|
+
pm.is_default.should == false
|
73
|
+
pm.external_payment_method_id.should == 'stripe-' + pm.payment_method_id.split('-')[1]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def create_pm_info_plugin(kb_account_id, kb_payment_method_id, is_default, external_payment_method_id)
|
78
|
+
pm_info_plugin = Killbill::Plugin::Model::PaymentMethodInfoPlugin.new
|
79
|
+
pm_info_plugin.account_id = kb_account_id
|
80
|
+
pm_info_plugin.payment_method_id = kb_payment_method_id
|
81
|
+
pm_info_plugin.is_default = is_default
|
82
|
+
pm_info_plugin.external_payment_method_id = external_payment_method_id
|
83
|
+
pm_info_plugin
|
84
|
+
end
|
85
|
+
end
|