killbill-braintree_blue 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +36 -0
- data/.travis.yml +19 -0
- data/Gemfile +3 -0
- data/Jarfile +8 -0
- data/LICENSE +201 -0
- data/NEWS +2 -0
- data/README.md +10 -0
- data/Rakefile +30 -0
- data/VERSION +1 -0
- data/braintree_blue.yml +25 -0
- data/config.ru +4 -0
- data/db/ddl.sql +88 -0
- data/db/schema.rb +89 -0
- data/killbill-braintree_blue.gemspec +50 -0
- data/killbill.properties +3 -0
- data/lib/braintree_blue/api.rb +178 -0
- data/lib/braintree_blue/application.rb +80 -0
- data/lib/braintree_blue/models/payment_method.rb +55 -0
- data/lib/braintree_blue/models/response.rb +47 -0
- data/lib/braintree_blue/models/transaction.rb +11 -0
- data/lib/braintree_blue/private_api.rb +13 -0
- data/lib/braintree_blue/views/form.erb +8 -0
- data/lib/braintree_blue.rb +25 -0
- data/pom.xml +44 -0
- data/release.sh +41 -0
- data/spec/braintree_blue/base_plugin_spec.rb +64 -0
- data/spec/braintree_blue/braintree_blue_payment_method_spec.rb +81 -0
- data/spec/braintree_blue/braintree_blue_response_spec.rb +64 -0
- data/spec/braintree_blue/remote/integration_spec.rb +132 -0
- data/spec/spec_helper.rb +24 -0
- metadata +318 -0
@@ -0,0 +1,178 @@
|
|
1
|
+
module Killbill #:nodoc:
|
2
|
+
module BraintreeBlue #:nodoc:
|
3
|
+
class PaymentPlugin < ::Killbill::Plugin::ActiveMerchant::PaymentPlugin
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
gateway_builder = Proc.new do |config|
|
7
|
+
# Change this if needed
|
8
|
+
::ActiveMerchant::Billing::BraintreeBlueGateway.new :merchant_id => config[:merchant_id],
|
9
|
+
:public_key => config[:public_key],
|
10
|
+
:private_key => config[:private_key]
|
11
|
+
end
|
12
|
+
|
13
|
+
super(gateway_builder,
|
14
|
+
:braintree_blue,
|
15
|
+
::Killbill::BraintreeBlue::BraintreeBluePaymentMethod,
|
16
|
+
::Killbill::BraintreeBlue::BraintreeBlueTransaction,
|
17
|
+
::Killbill::BraintreeBlue::BraintreeBlueResponse)
|
18
|
+
end
|
19
|
+
|
20
|
+
def authorize_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
21
|
+
# Pass extra parameters for the gateway here
|
22
|
+
options = { }
|
23
|
+
|
24
|
+
options.merge(get_merchant_id(currency))
|
25
|
+
|
26
|
+
properties = merge_properties(properties, options)
|
27
|
+
super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
28
|
+
end
|
29
|
+
|
30
|
+
def capture_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
31
|
+
# Pass extra parameters for the gateway here
|
32
|
+
options = {}
|
33
|
+
options.merge(get_merchant_id(currency))
|
34
|
+
properties = merge_properties(properties, options)
|
35
|
+
super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
36
|
+
end
|
37
|
+
|
38
|
+
def purchase_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
39
|
+
# Pass extra parameters for the gateway here
|
40
|
+
options = {}
|
41
|
+
options.merge(get_merchant_id(currency))
|
42
|
+
properties = merge_properties(properties, options)
|
43
|
+
super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
44
|
+
end
|
45
|
+
|
46
|
+
def void_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, properties, context)
|
47
|
+
# Pass extra parameters for the gateway here
|
48
|
+
options = {}
|
49
|
+
options.merge(get_merchant_id(currency))
|
50
|
+
properties = merge_properties(properties, options)
|
51
|
+
super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, properties, context)
|
52
|
+
end
|
53
|
+
|
54
|
+
def credit_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
55
|
+
# Pass extra parameters for the gateway here
|
56
|
+
options = {}
|
57
|
+
options.merge(get_merchant_id(currency))
|
58
|
+
properties = merge_properties(properties, options)
|
59
|
+
super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
60
|
+
end
|
61
|
+
|
62
|
+
def refund_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
63
|
+
# Pass extra parameters for the gateway here
|
64
|
+
options = {}
|
65
|
+
options.merge(get_merchant_id(currency))
|
66
|
+
properties = merge_properties(properties, options)
|
67
|
+
super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
68
|
+
end
|
69
|
+
|
70
|
+
def get_payment_info(kb_account_id, kb_payment_id, properties, context)
|
71
|
+
# Pass extra parameters for the gateway here
|
72
|
+
options = {}
|
73
|
+
properties = merge_properties(properties, options)
|
74
|
+
super(kb_account_id, kb_payment_id, properties, context)
|
75
|
+
end
|
76
|
+
|
77
|
+
def search_payments(search_key, offset, limit, properties, context)
|
78
|
+
# Pass extra parameters for the gateway here
|
79
|
+
options = {}
|
80
|
+
options.merge(get_merchant_id(currency))
|
81
|
+
properties = merge_properties(properties, options)
|
82
|
+
super(search_key, offset, limit, properties, context)
|
83
|
+
end
|
84
|
+
|
85
|
+
def add_payment_method(kb_account_id, kb_payment_method_id, payment_method_props, set_default, properties, context)
|
86
|
+
braintree_customer_id = BraintreeBluePaymentMethod.braintree_customer_id_from_kb_account_id(kb_account_id, context.tenant_id)
|
87
|
+
|
88
|
+
options = {
|
89
|
+
:customer => braintree_customer_id,
|
90
|
+
:company => kb_account_id
|
91
|
+
}
|
92
|
+
properties = merge_properties(properties, options)
|
93
|
+
super(kb_account_id, kb_payment_method_id, payment_method_props, set_default, properties, context)
|
94
|
+
end
|
95
|
+
|
96
|
+
def delete_payment_method(kb_account_id, kb_payment_method_id, properties, context)
|
97
|
+
# Pass extra parameters for the gateway here
|
98
|
+
options = {}
|
99
|
+
properties = merge_properties(properties, options)
|
100
|
+
super(kb_account_id, kb_payment_method_id, properties, context)
|
101
|
+
end
|
102
|
+
|
103
|
+
def get_payment_method_detail(kb_account_id, kb_payment_method_id, properties, context)
|
104
|
+
# Pass extra parameters for the gateway here
|
105
|
+
options = {}
|
106
|
+
properties = merge_properties(properties, options)
|
107
|
+
super(kb_account_id, kb_payment_method_id, properties, context)
|
108
|
+
end
|
109
|
+
|
110
|
+
def set_default_payment_method(kb_account_id, kb_payment_method_id, properties, context)
|
111
|
+
# TODO
|
112
|
+
end
|
113
|
+
|
114
|
+
def get_payment_methods(kb_account_id, refresh_from_gateway, properties, context)
|
115
|
+
# Pass extra parameters for the gateway here
|
116
|
+
options = {}
|
117
|
+
properties = merge_properties(properties, options)
|
118
|
+
super(kb_account_id, refresh_from_gateway, properties, context)
|
119
|
+
end
|
120
|
+
|
121
|
+
def search_payment_methods(search_key, offset, limit, properties, context)
|
122
|
+
# Pass extra parameters for the gateway here
|
123
|
+
options = {}
|
124
|
+
properties = merge_properties(properties, options)
|
125
|
+
super(search_key, offset, limit, properties, context)
|
126
|
+
end
|
127
|
+
|
128
|
+
def reset_payment_methods(kb_account_id, payment_methods, properties, context)
|
129
|
+
super
|
130
|
+
end
|
131
|
+
|
132
|
+
def build_form_descriptor(kb_account_id, descriptor_fields, properties, context)
|
133
|
+
# Pass extra parameters for the gateway here
|
134
|
+
options = {}
|
135
|
+
properties = merge_properties(properties, options)
|
136
|
+
|
137
|
+
# Add your custom static hidden tags here
|
138
|
+
options = {
|
139
|
+
#:token => config[:braintree_blue][:token]
|
140
|
+
}
|
141
|
+
descriptor_fields = merge_properties(descriptor_fields, options)
|
142
|
+
|
143
|
+
super(kb_account_id, descriptor_fields, properties, context)
|
144
|
+
end
|
145
|
+
|
146
|
+
def process_notification(notification, properties, context)
|
147
|
+
# Pass extra parameters for the gateway here
|
148
|
+
options = {}
|
149
|
+
properties = merge_properties(properties, options)
|
150
|
+
|
151
|
+
super(notification, properties, context) do |gw_notification, service|
|
152
|
+
# Retrieve the payment
|
153
|
+
# gw_notification.kb_payment_id =
|
154
|
+
#
|
155
|
+
# Set the response body
|
156
|
+
# gw_notification.entity =
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def get_merchant_id(currency)
|
161
|
+
|
162
|
+
options = {}
|
163
|
+
if (config[:braintree_blue][:multicurrency])
|
164
|
+
case currency
|
165
|
+
when "USD"
|
166
|
+
options = { :merchant_account_id => config[:multicurrency][:USD] }
|
167
|
+
when "EUR"
|
168
|
+
options = { :merchant_account_id => config[:multicurrency][:EUR] }
|
169
|
+
when "PLN"
|
170
|
+
options = { :merchant_account_id => config[:multicurrency][:PLN] }
|
171
|
+
end
|
172
|
+
end
|
173
|
+
options
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# -- encoding : utf-8 --
|
2
|
+
|
3
|
+
set :views, File.expand_path(File.dirname(__FILE__) + '/views')
|
4
|
+
|
5
|
+
include Killbill::Plugin::ActiveMerchant::Sinatra
|
6
|
+
|
7
|
+
configure do
|
8
|
+
# Usage: rackup -Ilib -E test
|
9
|
+
if development? or test?
|
10
|
+
# Make sure the plugin is initialized
|
11
|
+
plugin = ::Killbill::BraintreeBlue::PaymentPlugin.new
|
12
|
+
plugin.logger = Logger.new(STDOUT)
|
13
|
+
plugin.logger.level = Logger::INFO
|
14
|
+
plugin.conf_dir = File.dirname(File.dirname(__FILE__)) + '/..'
|
15
|
+
plugin.start_plugin
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
helpers do
|
20
|
+
def plugin(session = {})
|
21
|
+
::Killbill::BraintreeBlue::PrivatePaymentPlugin.new(session)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# curl -v http://127.0.0.1:9292/plugins/killbill-braintree_blue/form
|
26
|
+
get '/plugins/killbill-braintree_blue/form', :provides => 'html' do
|
27
|
+
order_id = request.GET['order_id']
|
28
|
+
account_id = request.GET['account_id']
|
29
|
+
options = {
|
30
|
+
:amount => request.GET['amount'],
|
31
|
+
:currency => request.GET['currency'],
|
32
|
+
:test => request.GET['test'],
|
33
|
+
:credential2 => request.GET['credential2'],
|
34
|
+
:credential3 => request.GET['credential3'],
|
35
|
+
:credential4 => request.GET['credential4'],
|
36
|
+
:country => request.GET['country'],
|
37
|
+
:account_name => request.GET['account_name'],
|
38
|
+
:transaction_type => request.GET['transaction_type'],
|
39
|
+
:authcode => request.GET['authcode'],
|
40
|
+
:notify_url => request.GET['notify_url'],
|
41
|
+
:return_url => request.GET['return_url'],
|
42
|
+
:redirect_param => request.GET['redirect_param'],
|
43
|
+
:forward_url => request.GET['forward_url']
|
44
|
+
}
|
45
|
+
|
46
|
+
@form = plugin(session).payment_form_for(order_id, account_id, :braintree_blue, options) do |service|
|
47
|
+
# Add your custom hidden tags here, e.g.
|
48
|
+
#service.token = config[:braintree_blue][:token]
|
49
|
+
submit_tag 'Submit'
|
50
|
+
end
|
51
|
+
|
52
|
+
erb :form
|
53
|
+
end
|
54
|
+
|
55
|
+
# curl -v http://127.0.0.1:9292/plugins/killbill-braintree_blue/1.0/pms/1
|
56
|
+
get '/plugins/killbill-braintree_blue/1.0/pms/:id', :provides => 'json' do
|
57
|
+
if pm = ::Killbill::BraintreeBlue::BraintreeBluePaymentMethod.find_by_id(params[:id].to_i)
|
58
|
+
pm.to_json
|
59
|
+
else
|
60
|
+
status 404
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# curl -v http://127.0.0.1:9292/plugins/killbill-braintree_blue/1.0/transactions/1
|
65
|
+
get '/plugins/killbill-braintree_blue/1.0/transactions/:id', :provides => 'json' do
|
66
|
+
if transaction = ::Killbill::BraintreeBlue::BraintreeBlueTransaction.find_by_id(params[:id].to_i)
|
67
|
+
transaction.to_json
|
68
|
+
else
|
69
|
+
status 404
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# curl -v http://127.0.0.1:9292/plugins/killbill-braintree_blue/1.0/responses/1
|
74
|
+
get '/plugins/killbill-braintree_blue/1.0/responses/:id', :provides => 'json' do
|
75
|
+
if transaction = ::Killbill::BraintreeBlue::BraintreeBlueResponse.find_by_id(params[:id].to_i)
|
76
|
+
transaction.to_json
|
77
|
+
else
|
78
|
+
status 404
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Killbill #:nodoc:
|
2
|
+
module BraintreeBlue #:nodoc:
|
3
|
+
class BraintreeBluePaymentMethod < ::Killbill::Plugin::ActiveMerchant::ActiveRecord::PaymentMethod
|
4
|
+
|
5
|
+
self.table_name = 'braintree_blue_payment_methods'
|
6
|
+
|
7
|
+
def self.from_response(kb_account_id, kb_payment_method_id, kb_tenant_id, cc_or_token, response, options, extra_params = {}, model = ::Killbill::BraintreeBlue::BraintreeBluePaymentMethod)
|
8
|
+
|
9
|
+
braintree_customer_id = self.braintree_customer_id_from_kb_account_id(kb_account_id, kb_tenant_id)
|
10
|
+
|
11
|
+
unless braintree_customer_id.blank?
|
12
|
+
card_response = response.responses.first.params
|
13
|
+
customer_response = response.responses.last.params
|
14
|
+
else
|
15
|
+
card_response = response.params['braintree_customer']['credit_cards'][0]
|
16
|
+
customer_response = response.params['braintree_customer']
|
17
|
+
end
|
18
|
+
|
19
|
+
super(kb_account_id,
|
20
|
+
kb_payment_method_id,
|
21
|
+
kb_tenant_id,
|
22
|
+
cc_or_token,
|
23
|
+
response,
|
24
|
+
options,
|
25
|
+
{
|
26
|
+
:braintree_customer_id => customer_response['id'],
|
27
|
+
:token => customer_response['id'],
|
28
|
+
:cc_type => card_response['card_type'],
|
29
|
+
:cc_exp_month => card_response['expiration_date'].split('/').first,
|
30
|
+
:cc_exp_year => card_response['expiration_date'].split('/').last,
|
31
|
+
:cc_last_4 => card_response['last_4'],
|
32
|
+
:cc_first_name => customer_response['first_name'],
|
33
|
+
:cc_last_name => customer_response['last_name']
|
34
|
+
}.merge!(extra_params),
|
35
|
+
model)
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.search_where_clause(t, search_key)
|
39
|
+
super.or(t[:braintree_customer_id].eq(search_key))
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.braintree_customer_id_from_kb_account_id(kb_account_id, tenant_id)
|
43
|
+
pms = from_kb_account_id(kb_account_id, tenant_id)
|
44
|
+
return nil if pms.empty?
|
45
|
+
|
46
|
+
braintree_customer_ids = Set.new
|
47
|
+
pms.each { |pm| braintree_customer_ids << pm.braintree_customer_id }
|
48
|
+
raise "No Braintree customer id found for account #{kb_account_id}" if braintree_customer_ids.empty?
|
49
|
+
raise "Kill Bill account #{kb_account_id} mapping to multiple Braintree customers: #{braintree_customer_ids}" if braintree_customer_ids.size > 1
|
50
|
+
braintree_customer_ids.first
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Killbill #:nodoc:
|
2
|
+
module BraintreeBlue #:nodoc:
|
3
|
+
class BraintreeBlueResponse < ::Killbill::Plugin::ActiveMerchant::ActiveRecord::Response
|
4
|
+
|
5
|
+
self.table_name = 'braintree_blue_responses'
|
6
|
+
|
7
|
+
has_one :braintree_blue_transaction
|
8
|
+
|
9
|
+
def self.from_response(api_call, kb_account_id, kb_payment_id, kb_payment_transaction_id, transaction_type, payment_processor_account_id, kb_tenant_id, response, extra_params = {}, model = ::Killbill::BraintreeBlue::BraintreeBlueResponse)
|
10
|
+
|
11
|
+
super(api_call,
|
12
|
+
kb_account_id,
|
13
|
+
kb_payment_id,
|
14
|
+
kb_payment_transaction_id,
|
15
|
+
transaction_type,
|
16
|
+
payment_processor_account_id,
|
17
|
+
kb_tenant_id,
|
18
|
+
response,
|
19
|
+
{
|
20
|
+
:params_braintree_customer_id => extract(response, 'braintree_customer','id'),
|
21
|
+
:params_braintree_customer_first_name => extract(response, 'braintree_customer','first_name'),
|
22
|
+
:params_braintree_customer_last_name => extract(response, 'braintree_customer','last_name'),
|
23
|
+
:params_braintree_customer_email => extract(response, 'braintree_customer','email'),
|
24
|
+
:params_braintree_customer_customer_vault_id => extract(response, 'braintree_customer','customer_vault_id'),
|
25
|
+
:params_braintree_customer_credit_card_token => extract(response, 'braintree_customer','credit_card_token'),
|
26
|
+
:params_braintree_customer_credit_card_bin => extract(response, 'card_response','bin'),
|
27
|
+
:params_braintree_customer_credit_card_expiration_date => extract(response, 'card_response','expiration_date'),
|
28
|
+
:params_braintree_customer_credit_card_last_4 => extract(response, 'card_response','last_4'),
|
29
|
+
:params_braintree_customer_credit_card_card_type => extract(response, 'card_response','card_type'),
|
30
|
+
:params_braintree_customer_credit_card_masked_number => extract(response, 'card_response','masked_number')
|
31
|
+
}.merge!(extra_params),
|
32
|
+
model)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.search_where_clause(t, search_key)
|
36
|
+
where_clause = t[:params_braintree_customer_id].eq(search_key)
|
37
|
+
.or(t[:params_braintree_customer_credit_card_token].eq(search_key))
|
38
|
+
|
39
|
+
# Only search successful payments and refunds
|
40
|
+
where_clause = where_clause.and(t[:success].eq(true))
|
41
|
+
|
42
|
+
super.or(where_clause)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Killbill #:nodoc:
|
2
|
+
module BraintreeBlue #:nodoc:
|
3
|
+
class BraintreeBlueTransaction < ::Killbill::Plugin::ActiveMerchant::ActiveRecord::Transaction
|
4
|
+
|
5
|
+
self.table_name = 'braintree_blue_transactions'
|
6
|
+
|
7
|
+
belongs_to :braintree_blue_response
|
8
|
+
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Killbill #:nodoc:
|
2
|
+
module BraintreeBlue #:nodoc:
|
3
|
+
class PrivatePaymentPlugin < ::Killbill::Plugin::ActiveMerchant::PrivatePaymentPlugin
|
4
|
+
def initialize(session = {})
|
5
|
+
super(:braintree_blue,
|
6
|
+
::Killbill::BraintreeBlue::BraintreeBluePaymentMethod,
|
7
|
+
::Killbill::BraintreeBlue::BraintreeBlueTransaction,
|
8
|
+
::Killbill::BraintreeBlue::BraintreeBlueResponse,
|
9
|
+
session)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'action_controller'
|
3
|
+
require 'active_record'
|
4
|
+
require 'action_view'
|
5
|
+
require 'active_merchant'
|
6
|
+
require 'active_support'
|
7
|
+
require 'bigdecimal'
|
8
|
+
require 'money'
|
9
|
+
require 'monetize'
|
10
|
+
require 'offsite_payments'
|
11
|
+
require 'pathname'
|
12
|
+
require 'sinatra'
|
13
|
+
require 'singleton'
|
14
|
+
require 'yaml'
|
15
|
+
|
16
|
+
require 'killbill'
|
17
|
+
require 'killbill/helpers/active_merchant'
|
18
|
+
|
19
|
+
require 'braintree_blue/api'
|
20
|
+
require 'braintree_blue/private_api'
|
21
|
+
|
22
|
+
require 'braintree_blue/models/payment_method'
|
23
|
+
require 'braintree_blue/models/response'
|
24
|
+
require 'braintree_blue/models/transaction'
|
25
|
+
|
data/pom.xml
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!--
|
3
|
+
~ Copyright 2014 The Billing Project, LLC
|
4
|
+
~
|
5
|
+
~ The Billing Project 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>braintree_blue-plugin</artifactId>
|
27
|
+
<packaging>pom</packaging>
|
28
|
+
<version>0.0.1</version>
|
29
|
+
<name>braintree_blue-plugin</name>
|
30
|
+
<url>http://github.com/killbill/killbill-braintree_blue-plugin</url>
|
31
|
+
<description>Plugin for accessing BraintreeBlue 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-braintree_blue-plugin.git</connection>
|
41
|
+
<url>https://github.com/killbill/killbill-braintree_blue-plugin/</url>
|
42
|
+
<developerConnection>scm:git:git@github.com:killbill/killbill-braintree_blue-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-braintree_blue-$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=braintree_blue-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
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Killbill::BraintreeBlue::PaymentPlugin do
|
4
|
+
before(:each) do
|
5
|
+
Dir.mktmpdir do |dir|
|
6
|
+
file = File.new(File.join(dir, 'braintree_blue.yml'), "w+")
|
7
|
+
file.write(<<-eos)
|
8
|
+
:braintree_blue:
|
9
|
+
:test: true
|
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::BraintreeBlue::PaymentPlugin.new
|
18
|
+
@plugin.logger = Logger.new(STDOUT)
|
19
|
+
@plugin.logger.level = Logger::INFO
|
20
|
+
@plugin.conf_dir = File.dirname(file)
|
21
|
+
@plugin.kb_apis = Killbill::Plugin::KillbillApi.new('braintree_blue', {})
|
22
|
+
|
23
|
+
# Start the plugin here - since the config file will be deleted
|
24
|
+
@plugin.start_plugin
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should start and stop correctly' do
|
29
|
+
@plugin.stop_plugin
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should generate forms correctly' do
|
33
|
+
=begin
|
34
|
+
kb_account_id = SecureRandom.uuid
|
35
|
+
kb_tenant_id = SecureRandom.uuid
|
36
|
+
context = @plugin.kb_apis.create_context(kb_tenant_id)
|
37
|
+
fields = @plugin.hash_to_properties({
|
38
|
+
:order_id => '1234',
|
39
|
+
:amount => 10
|
40
|
+
})
|
41
|
+
form = @plugin.build_form_descriptor kb_account_id, fields, [], context
|
42
|
+
|
43
|
+
form.kb_account_id.should == kb_account_id
|
44
|
+
form.form_method.should == 'POST'
|
45
|
+
form.form_url.should == 'https://braintree_blue.com'
|
46
|
+
|
47
|
+
form_fields = @plugin.properties_to_hash(form.form_fields)
|
48
|
+
=end
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should receive notifications correctly' do
|
52
|
+
=begin
|
53
|
+
|
54
|
+
description = 'description'
|
55
|
+
|
56
|
+
kb_tenant_id = SecureRandom.uuid
|
57
|
+
context = @plugin.kb_apis.create_context(kb_tenant_id)
|
58
|
+
properties = @plugin.hash_to_properties({ :description => description })
|
59
|
+
|
60
|
+
notification = ""
|
61
|
+
gw_notification = @plugin.process_notification notification, properties, context
|
62
|
+
=end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Killbill::BraintreeBlue::BraintreeBluePaymentMethod do
|
4
|
+
before :all do
|
5
|
+
Killbill::BraintreeBlue::BraintreeBluePaymentMethod.delete_all
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should search all fields' do
|
9
|
+
kb_tenant_id = '77-88-99-00'
|
10
|
+
|
11
|
+
do_search('foo', kb_tenant_id).size.should == 0
|
12
|
+
|
13
|
+
pm = Killbill::BraintreeBlue::BraintreeBluePaymentMethod.create :kb_account_id => '11-22-33-44',
|
14
|
+
:kb_payment_method_id => '55-66-77-88',
|
15
|
+
:kb_tenant_id => kb_tenant_id,
|
16
|
+
:braintree_customer_id => '123xka',
|
17
|
+
:token => '38102343',
|
18
|
+
:cc_first_name => 'ccFirstName',
|
19
|
+
:cc_last_name => 'ccLastName',
|
20
|
+
:cc_type => 'ccType',
|
21
|
+
:cc_exp_month => 10,
|
22
|
+
:cc_exp_year => 11,
|
23
|
+
:cc_last_4 => 1234,
|
24
|
+
:address1 => 'address1',
|
25
|
+
:address2 => 'address2',
|
26
|
+
:city => 'city',
|
27
|
+
:state => 'state',
|
28
|
+
:zip => 'zip',
|
29
|
+
:country => 'country'
|
30
|
+
|
31
|
+
do_search('foo', kb_tenant_id).size.should == 0
|
32
|
+
do_search(pm.token, kb_tenant_id).size.should == 1
|
33
|
+
do_search('ccType', kb_tenant_id).size.should == 1
|
34
|
+
# Exact match only for cc_last_4
|
35
|
+
do_search('123', kb_tenant_id).size.should == 0
|
36
|
+
do_search('1234', kb_tenant_id).size.should == 1
|
37
|
+
# Test partial match
|
38
|
+
do_search('address', kb_tenant_id).size.should == 1
|
39
|
+
do_search('Name', kb_tenant_id).size.should == 1
|
40
|
+
|
41
|
+
pm2 = Killbill::BraintreeBlue::BraintreeBluePaymentMethod.create :kb_account_id => '22-33-44-55',
|
42
|
+
:kb_payment_method_id => '66-77-88-99',
|
43
|
+
:kb_tenant_id => kb_tenant_id,
|
44
|
+
:braintree_customer_id => '123xka',
|
45
|
+
:token => '49384029302',
|
46
|
+
:cc_first_name => 'ccFirstName',
|
47
|
+
:cc_last_name => 'ccLastName',
|
48
|
+
:cc_type => 'ccType',
|
49
|
+
:cc_exp_month => 10,
|
50
|
+
:cc_exp_year => 11,
|
51
|
+
:cc_last_4 => 1234,
|
52
|
+
:address1 => 'address1',
|
53
|
+
:address2 => 'address2',
|
54
|
+
:city => 'city',
|
55
|
+
:state => 'state',
|
56
|
+
:zip => 'zip',
|
57
|
+
:country => 'country'
|
58
|
+
|
59
|
+
do_search('foo', kb_tenant_id).size.should == 0
|
60
|
+
do_search(pm.token, kb_tenant_id).size.should == 1
|
61
|
+
do_search(pm2.token, kb_tenant_id).size.should == 1
|
62
|
+
do_search('ccType', kb_tenant_id).size.should == 2
|
63
|
+
# Exact match only for cc_last_4
|
64
|
+
do_search('123', kb_tenant_id).size.should == 0
|
65
|
+
do_search('1234', kb_tenant_id).size.should == 2
|
66
|
+
# Test partial match
|
67
|
+
do_search('cc', kb_tenant_id).size.should == 2
|
68
|
+
do_search('address', kb_tenant_id).size.should == 2
|
69
|
+
do_search('Name', kb_tenant_id).size.should == 2
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def do_search(search_key, kb_tenant_id)
|
75
|
+
pagination = Killbill::BraintreeBlue::BraintreeBluePaymentMethod.search(search_key, kb_tenant_id)
|
76
|
+
pagination.current_offset.should == 0
|
77
|
+
results = pagination.iterator.to_a
|
78
|
+
pagination.total_nb_records.should == results.size
|
79
|
+
results
|
80
|
+
end
|
81
|
+
end
|