killbill-litle 1.0.2 → 1.0.3
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/Jarfile +2 -2
- data/README.md +39 -1
- data/VERSION +1 -1
- data/db/ddl.sql +55 -0
- data/killbill-litle.gemspec +2 -2
- data/lib/litle/api.rb +16 -16
- data/lib/litle/config/application.rb +8 -8
- data/lib/litle/config/configuration.rb +2 -1
- data/lib/litle/models/litle_payment_method.rb +1 -1
- data/lib/litle/models/litle_response.rb +18 -7
- data/lib/litle/models/litle_transaction.rb +17 -0
- data/lib/litle/views/paypage.erb +32 -15
- data/pom.xml +1 -1
- data/release.sh +16 -0
- data/spec/litle/base_plugin_spec.rb +1 -1
- data/spec/litle/integration_spec.rb +36 -12
- metadata +7 -6
data/Jarfile
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
jar 'com.ning.billing:killbill-api', '0.1.
|
|
2
|
-
jar 'com.ning.billing:killbill-util:tests', '0.1.
|
|
1
|
+
jar 'com.ning.billing:killbill-api', '0.1.78'
|
|
2
|
+
jar 'com.ning.billing:killbill-util:tests', '0.1.78'
|
|
3
3
|
jar 'javax.servlet:javax.servlet-api', '3.0.1'
|
data/README.md
CHANGED
|
@@ -4,4 +4,42 @@
|
|
|
4
4
|
killbill-litle-plugin
|
|
5
5
|
=====================
|
|
6
6
|
|
|
7
|
-
Plugin to use Litle & Co. as a gateway
|
|
7
|
+
Plugin to use Litle & Co. as a gateway.
|
|
8
|
+
|
|
9
|
+
Requirements
|
|
10
|
+
------------
|
|
11
|
+
|
|
12
|
+
The plugin needs a database. The latest version of the schema can be found here: https://raw.github.com/killbill/killbill-litle-plugin/master/db/ddl.sql.
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
Configuration
|
|
16
|
+
-------------
|
|
17
|
+
|
|
18
|
+
The plugin expects a `litle.yml` configuration file containing the following:
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
:litle:
|
|
22
|
+
:merchant_id: 'your-merchant-id'
|
|
23
|
+
:password: 'your-password'
|
|
24
|
+
:username: 'your-username'
|
|
25
|
+
# Optional, if you are using PayPage
|
|
26
|
+
:secure_page_url: 'litle-secure-page-url'
|
|
27
|
+
:paypage_id: 'litle-paypage-id'
|
|
28
|
+
:log_file: '/var/tmp/litle.log'
|
|
29
|
+
# Switch to false for production
|
|
30
|
+
:test: true
|
|
31
|
+
|
|
32
|
+
:database:
|
|
33
|
+
:adapter: 'sqlite3'
|
|
34
|
+
:database: 'test.db'
|
|
35
|
+
# For MySQL
|
|
36
|
+
# :adapter: 'jdbc'
|
|
37
|
+
# :username: 'your-username'
|
|
38
|
+
# :password: 'your-password'
|
|
39
|
+
# :driver: 'com.mysql.jdbc.Driver'
|
|
40
|
+
# :url: 'jdbc:mysql://127.0.0.1:3306/your-database'
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
By default, the plugin will look at the plugin directory root (where `killbill.properties` is located) to find this file.
|
|
44
|
+
Alternatively, set the Kill Bill system property `-Dcom.ning.billing.osgi.bundles.jruby.conf.dir=/my/directory` to specify another location.
|
|
45
|
+
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.0.
|
|
1
|
+
1.0.3
|
data/db/ddl.sql
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
CREATE TABLE `litle_payment_methods` (
|
|
2
|
+
`id` int(11) NOT NULL AUTO_INCREMENT,
|
|
3
|
+
`kb_account_id` varchar(255) NOT NULL,
|
|
4
|
+
`kb_payment_method_id` varchar(255) DEFAULT NULL,
|
|
5
|
+
`litle_token` varchar(255) NOT NULL,
|
|
6
|
+
`is_deleted` tinyint(1) NOT NULL DEFAULT '0',
|
|
7
|
+
`created_at` datetime NOT NULL,
|
|
8
|
+
`updated_at` datetime NOT NULL,
|
|
9
|
+
PRIMARY KEY (`id`)
|
|
10
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
|
11
|
+
|
|
12
|
+
CREATE TABLE `litle_transactions` (
|
|
13
|
+
`id` int(11) NOT NULL AUTO_INCREMENT,
|
|
14
|
+
`litle_response_id` int(11) NOT NULL,
|
|
15
|
+
`api_call` varchar(255) NOT NULL,
|
|
16
|
+
`kb_payment_id` varchar(255) NOT NULL,
|
|
17
|
+
`litle_txn_id` varchar(255) NOT NULL,
|
|
18
|
+
`amount_in_cents` int(11) NOT NULL,
|
|
19
|
+
`created_at` datetime NOT NULL,
|
|
20
|
+
`updated_at` datetime NOT NULL,
|
|
21
|
+
PRIMARY KEY (`id`)
|
|
22
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
|
23
|
+
|
|
24
|
+
CREATE TABLE `litle_responses` (
|
|
25
|
+
`id` int(11) NOT NULL AUTO_INCREMENT,
|
|
26
|
+
`api_call` varchar(255) NOT NULL,
|
|
27
|
+
`kb_payment_id` varchar(255) DEFAULT NULL,
|
|
28
|
+
`message` varchar(255) DEFAULT NULL,
|
|
29
|
+
`authorization` varchar(255) DEFAULT NULL,
|
|
30
|
+
`fraud_review` tinyint(1) DEFAULT NULL,
|
|
31
|
+
`test` tinyint(1) DEFAULT NULL,
|
|
32
|
+
`params_litleonelineresponse_message` varchar(255) DEFAULT NULL,
|
|
33
|
+
`params_litleonelineresponse_response` varchar(255) DEFAULT NULL,
|
|
34
|
+
`params_litleonelineresponse_version` varchar(255) DEFAULT NULL,
|
|
35
|
+
`params_litleonelineresponse_xmlns` varchar(255) DEFAULT NULL,
|
|
36
|
+
`params_litleonelineresponse_saleresponse_customer_id` varchar(255) DEFAULT NULL,
|
|
37
|
+
`params_litleonelineresponse_saleresponse_id` varchar(255) DEFAULT NULL,
|
|
38
|
+
`params_litleonelineresponse_saleresponse_report_group` varchar(255) DEFAULT NULL,
|
|
39
|
+
`params_litleonelineresponse_saleresponse_litle_txn_id` varchar(255) DEFAULT NULL,
|
|
40
|
+
`params_litleonelineresponse_saleresponse_order_id` varchar(255) DEFAULT NULL,
|
|
41
|
+
`params_litleonelineresponse_saleresponse_response` varchar(255) DEFAULT NULL,
|
|
42
|
+
`params_litleonelineresponse_saleresponse_response_time` varchar(255) DEFAULT NULL,
|
|
43
|
+
`params_litleonelineresponse_saleresponse_message` varchar(255) DEFAULT NULL,
|
|
44
|
+
`params_litleonelineresponse_saleresponse_auth_code` varchar(255) DEFAULT NULL,
|
|
45
|
+
`avs_result_code` varchar(255) DEFAULT NULL,
|
|
46
|
+
`avs_result_message` varchar(255) DEFAULT NULL,
|
|
47
|
+
`avs_result_street_match` varchar(255) DEFAULT NULL,
|
|
48
|
+
`avs_result_postal_match` varchar(255) DEFAULT NULL,
|
|
49
|
+
`cvv_result_code` varchar(255) DEFAULT NULL,
|
|
50
|
+
`cvv_result_message` varchar(255) DEFAULT NULL,
|
|
51
|
+
`success` tinyint(1) DEFAULT NULL,
|
|
52
|
+
`created_at` datetime NOT NULL,
|
|
53
|
+
`updated_at` datetime NOT NULL,
|
|
54
|
+
PRIMARY KEY (`id`)
|
|
55
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
data/killbill-litle.gemspec
CHANGED
|
@@ -22,8 +22,8 @@ Gem::Specification.new do |s|
|
|
|
22
22
|
|
|
23
23
|
s.rdoc_options << '--exclude' << '.'
|
|
24
24
|
|
|
25
|
-
s.add_dependency 'killbill', '~> 1.0.
|
|
26
|
-
s.add_dependency 'activemerchant', '~>
|
|
25
|
+
s.add_dependency 'killbill', '~> 1.0.16'
|
|
26
|
+
s.add_dependency 'activemerchant', '~> 2.0.0'
|
|
27
27
|
s.add_dependency 'activerecord', '~> 3.2.1'
|
|
28
28
|
s.add_dependency 'sinatra', '~> 1.3.4'
|
|
29
29
|
# LitleOnline gem dependencies
|
data/lib/litle/api.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module Killbill::Litle
|
|
2
2
|
class PaymentPlugin < Killbill::Plugin::Payment
|
|
3
3
|
def start_plugin
|
|
4
|
-
Killbill::Litle.initialize!
|
|
4
|
+
Killbill::Litle.initialize! @logger, @conf_dir
|
|
5
5
|
@gateway = Killbill::Litle.gateway
|
|
6
6
|
|
|
7
7
|
super
|
|
@@ -15,6 +15,11 @@ module Killbill::Litle
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def process_payment(kb_account_id, kb_payment_id, kb_payment_method_id, amount_in_cents, currency, options = {})
|
|
18
|
+
# If the payment was already made, just return the status
|
|
19
|
+
# TODO Should we set the Litle Id field to check for dups (https://www.litle.com/mc-secure/DupeChecking_V1.2.pdf)?
|
|
20
|
+
litle_transaction = LitleTransaction.from_kb_payment_id(kb_payment_id) rescue nil
|
|
21
|
+
return litle_transaction.litle_response.to_payment_response unless litle_transaction.nil?
|
|
22
|
+
|
|
18
23
|
# Required argument
|
|
19
24
|
# Note! The field is limited to 25 chars, so we convert the UUID (in hex) to base64
|
|
20
25
|
options[:order_id] ||= Utils.compact_uuid kb_payment_id
|
|
@@ -25,16 +30,14 @@ module Killbill::Litle
|
|
|
25
30
|
token = get_token(kb_payment_method_id)
|
|
26
31
|
|
|
27
32
|
# Go to Litle
|
|
28
|
-
litle_response = @gateway.purchase amount_in_cents, token, options
|
|
33
|
+
litle_response = @gateway.purchase amount_in_cents, ActiveMerchant::Billing::LitleGateway::LitleCardToken.new(:token => token), options
|
|
29
34
|
response = save_response_and_transaction litle_response, :charge, kb_payment_id, amount_in_cents
|
|
30
35
|
|
|
31
36
|
response.to_payment_response
|
|
32
37
|
end
|
|
33
38
|
|
|
34
39
|
def process_refund(kb_account_id, kb_payment_id, amount_in_cents, currency, options = {})
|
|
35
|
-
|
|
36
|
-
litle_transaction = LitleTransaction.where("litle_transactions.amount_in_cents >= ?", amount_in_cents).find_last_by_api_call_and_kb_payment_id(:charge, kb_payment_id)
|
|
37
|
-
raise "Unable to find Litle transaction id for payment #{kb_payment_id}" if litle_transaction.nil?
|
|
40
|
+
litle_transaction = LitleTransaction.find_candidate_transaction_for_refund(kb_payment_id, amount_in_cents)
|
|
38
41
|
|
|
39
42
|
# Set a default report group
|
|
40
43
|
options[:merchant] ||= report_group_for_currency(currency)
|
|
@@ -55,12 +58,13 @@ module Killbill::Litle
|
|
|
55
58
|
litle_transaction.litle_response.to_payment_response
|
|
56
59
|
end
|
|
57
60
|
|
|
58
|
-
def add_payment_method(kb_account_id, kb_payment_method_id, payment_method_props, set_default, options = {})
|
|
61
|
+
def add_payment_method(kb_account_id, kb_payment_method_id, payment_method_props, set_default=true, options = {})
|
|
59
62
|
# Set a default report group
|
|
60
63
|
options[:merchant] ||= report_group_for_account(kb_account_id)
|
|
61
64
|
|
|
62
|
-
|
|
63
|
-
|
|
65
|
+
# TODO Add support for real credit cards
|
|
66
|
+
token = (payment_method_props.properties.find { |kv| kv.key == 'paypageRegistrationId' }).value
|
|
67
|
+
litle_response = @gateway.store token, options
|
|
64
68
|
response = save_response_and_transaction litle_response, :add_payment_method
|
|
65
69
|
|
|
66
70
|
LitlePaymentMethod.create :kb_account_id => kb_account_id, :kb_payment_method_id => kb_payment_method_id, :litle_token => response.litle_token
|
|
@@ -81,15 +85,11 @@ module Killbill::Litle
|
|
|
81
85
|
private
|
|
82
86
|
|
|
83
87
|
def report_group_for_account(kb_account_id)
|
|
84
|
-
=
|
|
85
|
-
|
|
86
|
-
currency = account.get_currency
|
|
88
|
+
account = @kb_apis.get_account_by_id(kb_account_id)
|
|
89
|
+
currency = account.currency
|
|
87
90
|
report_group_for_currency(currency)
|
|
88
|
-
rescue APINotAvailableError
|
|
91
|
+
rescue Killbill::Plugin::JKillbillApi::APINotAvailableError
|
|
89
92
|
"Default Report Group"
|
|
90
|
-
=end
|
|
91
|
-
# STEPH hack until we support making API calls-- with context
|
|
92
|
-
report_group_for_currency('USD')
|
|
93
93
|
end
|
|
94
94
|
|
|
95
95
|
def report_group_for_currency(currency)
|
|
@@ -108,7 +108,7 @@ module Killbill::Litle
|
|
|
108
108
|
response = LitleResponse.from_response(api_call, kb_payment_id, litle_response)
|
|
109
109
|
response.save!
|
|
110
110
|
|
|
111
|
-
if response.success and !response.litle_txn_id.blank?
|
|
111
|
+
if response.success and !kb_payment_id.blank? and !response.litle_txn_id.blank?
|
|
112
112
|
# Record the transaction
|
|
113
113
|
transaction = response.create_litle_transaction!(:amount_in_cents => amount_in_cents, :api_call => api_call, :kb_payment_id => kb_payment_id, :litle_txn_id => response.litle_txn_id)
|
|
114
114
|
@logger.debug "Recorded transaction: #{transaction.inspect}"
|
|
@@ -20,19 +20,19 @@ get '/plugins/killbill-litle' do
|
|
|
20
20
|
:merchant_txn_id => request.GET['merchant_txn_id'] || '1',
|
|
21
21
|
:order_id => request.GET['order_id'] || '1',
|
|
22
22
|
:report_group => request.GET['report_group'] || 'Default Report Group',
|
|
23
|
+
:success_page => params[:successPage] || '/plugins/killbill-litle/checkout',
|
|
24
|
+
:failure_page => params[:failurePage]
|
|
23
25
|
}
|
|
24
26
|
erb :paypage, :views => File.expand_path(File.dirname(__FILE__) + '/../views'), :locals => locals
|
|
25
27
|
end
|
|
26
28
|
|
|
27
29
|
post '/plugins/killbill-litle/checkout' do
|
|
28
|
-
data = request.
|
|
30
|
+
data = request.body.read
|
|
29
31
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
halt 500, {'Content-Type' => 'text/plain'}, "Error: #{e}"
|
|
35
|
-
end
|
|
32
|
+
halt 400, "kb_account_id and response_paypage_registration_id must be specified!" if data['kb_account_id'].blank? or data['response_paypage_registration_id'].blank?
|
|
33
|
+
|
|
34
|
+
pm = plugin.register_token! data['kb_account_id'], data['response_paypage_registration_id']
|
|
35
|
+
redirect "/plugins/killbill-litle/1.0/pms/#{pm.id}"
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
# curl -v http://127.0.0.1:9292/plugins/killbill-litle/1.0/pms/1
|
|
@@ -51,4 +51,4 @@ get '/plugins/killbill-litle/1.0/transactions/:id', :provides => 'json' do
|
|
|
51
51
|
else
|
|
52
52
|
status 404
|
|
53
53
|
end
|
|
54
|
-
end
|
|
54
|
+
end
|
|
@@ -7,9 +7,10 @@ module Killbill::Litle
|
|
|
7
7
|
mattr_reader :initialized
|
|
8
8
|
mattr_reader :test
|
|
9
9
|
|
|
10
|
-
def self.initialize!(
|
|
10
|
+
def self.initialize!(logger=Logger.new(STDOUT), conf_dir=File.expand_path('../../../', File.dirname(__FILE__)))
|
|
11
11
|
@@logger = logger
|
|
12
12
|
|
|
13
|
+
config_file = "#{conf_dir}/litle.yml"
|
|
13
14
|
@@config = Properties.new(config_file)
|
|
14
15
|
@@config.parse!
|
|
15
16
|
@@test = @@config[:litle][:test]
|
|
@@ -26,7 +26,7 @@ module Killbill::Litle
|
|
|
26
26
|
# No extra information is stored in Litle
|
|
27
27
|
properties = []
|
|
28
28
|
|
|
29
|
-
Killbill::Plugin::
|
|
29
|
+
Killbill::Plugin::Model::PaymentMethodPlugin.new(external_payment_method_id, is_default, properties, "CreditCard", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
32
|
end
|
|
@@ -41,7 +41,9 @@ module Killbill::Litle
|
|
|
41
41
|
nil
|
|
42
42
|
else
|
|
43
43
|
# Litle seems to return the precision sometimes along with the txnId (e.g. 053499651324799+19)
|
|
44
|
-
|
|
44
|
+
# And sometimes it adds a ;credit
|
|
45
|
+
# TODO Figure out WTF is going on here
|
|
46
|
+
("%f" % potential_litle_txn_id.split(';')[0].split('+')[0]).to_i
|
|
45
47
|
end
|
|
46
48
|
end
|
|
47
49
|
|
|
@@ -77,30 +79,39 @@ module Killbill::Litle
|
|
|
77
79
|
end
|
|
78
80
|
|
|
79
81
|
def to_payment_response
|
|
80
|
-
to_killbill_response
|
|
82
|
+
to_killbill_response :payment
|
|
81
83
|
end
|
|
82
84
|
|
|
83
85
|
def to_refund_response
|
|
84
|
-
to_killbill_response
|
|
86
|
+
to_killbill_response :refund
|
|
85
87
|
end
|
|
86
88
|
|
|
87
89
|
private
|
|
88
90
|
|
|
89
|
-
def to_killbill_response(
|
|
91
|
+
def to_killbill_response(type)
|
|
90
92
|
if litle_transaction.nil?
|
|
91
93
|
amount_in_cents = nil
|
|
92
94
|
created_date = created_at
|
|
95
|
+
first_payment_reference_id = nil
|
|
96
|
+
second_payment_reference_id = nil
|
|
93
97
|
else
|
|
94
98
|
amount_in_cents = litle_transaction.amount_in_cents
|
|
95
99
|
created_date = litle_transaction.created_at
|
|
100
|
+
first_payment_reference_id = litle_transaction.litle_txn_id
|
|
101
|
+
second_payment_reference_id = litle_transaction.id.to_s
|
|
96
102
|
end
|
|
97
103
|
|
|
98
104
|
effective_date = params_litleonelineresponse_saleresponse_response_time || created_date
|
|
99
|
-
|
|
100
|
-
gateway_error = params_litleonelineresponse_saleresponse_message
|
|
105
|
+
gateway_error = message || params_litleonelineresponse_saleresponse_message
|
|
101
106
|
gateway_error_code = params_litleonelineresponse_saleresponse_response
|
|
102
107
|
|
|
103
|
-
|
|
108
|
+
if type == :payment
|
|
109
|
+
status = success ? Killbill::Plugin::Model::PaymentPluginStatus.new(:PROCESSED) : Killbill::Plugin::Model::PaymentPluginStatus.new(:ERROR)
|
|
110
|
+
Killbill::Plugin::Model::PaymentInfoPlugin.new(amount_in_cents, created_date, effective_date, status, gateway_error, gateway_error_code, first_payment_reference_id, second_payment_reference_id)
|
|
111
|
+
else
|
|
112
|
+
status = success ? Killbill::Plugin::Model::RefundPluginStatus.new(:PROCESSED) : Killbill::Plugin::Model::RefundPluginStatus.new(:ERROR)
|
|
113
|
+
Killbill::Plugin::Model::RefundInfoPlugin.new(amount_in_cents, created_date, effective_date, status, gateway_error, gateway_error_code, first_payment_reference_id)
|
|
114
|
+
end
|
|
104
115
|
end
|
|
105
116
|
|
|
106
117
|
def self.extract(response, key1, key2=nil, key3=nil)
|
|
@@ -9,5 +9,22 @@ module Killbill::Litle
|
|
|
9
9
|
raise "Killbill payment mapping to multiple Litle transactions for payment #{kb_payment_id}" if litle_transactions.size > 1
|
|
10
10
|
litle_transactions[0]
|
|
11
11
|
end
|
|
12
|
+
|
|
13
|
+
def self.find_candidate_transaction_for_refund(kb_payment_id, amount_in_cents)
|
|
14
|
+
# Find one successful charge which amount is at least the amount we are trying to refund
|
|
15
|
+
litle_transactions = LitleTransaction.where("litle_transactions.amount_in_cents >= ?", amount_in_cents)
|
|
16
|
+
.find_all_by_api_call_and_kb_payment_id(:charge, kb_payment_id)
|
|
17
|
+
raise "Unable to find Litle transaction id for payment #{kb_payment_id}" if litle_transactions.size == 0
|
|
18
|
+
|
|
19
|
+
# We have candidates, but we now need to make sure we didn't refund more than for the specified amount
|
|
20
|
+
amount_refunded_in_cents = Killbill::Litle::LitleTransaction.where("api_call = ? and kb_payment_id = ?", :refund, kb_payment_id)
|
|
21
|
+
.sum("amount_in_cents")
|
|
22
|
+
|
|
23
|
+
amount_left_to_refund_in_cents = -amount_refunded_in_cents
|
|
24
|
+
litle_transactions.map { |transaction| amount_left_to_refund_in_cents += transaction.amount_in_cents }
|
|
25
|
+
raise "Amount #{amount_in_cents} too large to refund for payment #{kb_payment_id}" if amount_left_to_refund_in_cents < amount_in_cents
|
|
26
|
+
|
|
27
|
+
litle_transactions.first
|
|
28
|
+
end
|
|
12
29
|
end
|
|
13
30
|
end
|
data/lib/litle/views/paypage.erb
CHANGED
|
@@ -2,11 +2,29 @@
|
|
|
2
2
|
<html>
|
|
3
3
|
<head>
|
|
4
4
|
<title>Pay Page Checkout</title>
|
|
5
|
-
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
|
6
5
|
<script src="<%= secure_page_url %>/LitlePayPage/litle-api.js" type="text/javascript"></script>
|
|
7
6
|
<script>
|
|
8
7
|
$(document).ready(
|
|
9
8
|
function() {
|
|
9
|
+
function handleError(errorMessage) {
|
|
10
|
+
<% if failure_page %>
|
|
11
|
+
var form = document.createElement("form");
|
|
12
|
+
form.setAttribute("method", "post");
|
|
13
|
+
form.setAttribute("action", "<%= failure_page %>");
|
|
14
|
+
|
|
15
|
+
var hiddenField = document.createElement("input");
|
|
16
|
+
hiddenField.setAttribute("type", "hidden");
|
|
17
|
+
hiddenField.setAttribute("name", "errorMessage");
|
|
18
|
+
hiddenField.setAttribute("value", errorMessage);
|
|
19
|
+
form.appendChild(hiddenField);
|
|
20
|
+
|
|
21
|
+
document.body.appendChild(form);
|
|
22
|
+
form.submit();
|
|
23
|
+
<% else %>
|
|
24
|
+
alert(errorMessage);
|
|
25
|
+
<% end %>
|
|
26
|
+
}
|
|
27
|
+
|
|
10
28
|
function setLitleResponseFields(response) {
|
|
11
29
|
document.getElementById('response_code').value = response.response;
|
|
12
30
|
document.getElementById('response_message').value = response.message;
|
|
@@ -21,34 +39,34 @@
|
|
|
21
39
|
}
|
|
22
40
|
|
|
23
41
|
function timeoutOnLitle() {
|
|
24
|
-
|
|
42
|
+
handleError("We are experiencing technical difficulties. Please try your query again later.");
|
|
25
43
|
}
|
|
26
44
|
|
|
27
45
|
function onErrorAfterLitle(response) {
|
|
28
46
|
setLitleResponseFields(response);
|
|
29
47
|
if (response.response == '871') {
|
|
30
|
-
|
|
48
|
+
handleError("Invalid card number. Check and retry. (Not Mod10)");
|
|
31
49
|
}
|
|
32
50
|
else if (response.response == '872') {
|
|
33
|
-
|
|
51
|
+
handleError("Invalid card number. Check and retry. (Too short)");
|
|
34
52
|
}
|
|
35
53
|
else if (response.response == '873') {
|
|
36
|
-
|
|
54
|
+
handleError("Invalid card number. Check and retry. (Too long)");
|
|
37
55
|
}
|
|
38
56
|
else if (response.response == '874') {
|
|
39
|
-
|
|
57
|
+
handleError("Invalid card number. Check and retry. (Not a number)");
|
|
40
58
|
}
|
|
41
59
|
else if (response.response == '875') {
|
|
42
|
-
|
|
60
|
+
handleError("We are experiencing technical difficulties. Please try your query again later.");
|
|
43
61
|
}
|
|
44
62
|
else if (response.response == '876') {
|
|
45
|
-
|
|
63
|
+
handleError("Invalid card number. Check and retry. (Failure from Server)");
|
|
46
64
|
}
|
|
47
65
|
else if (response.response == '880') {
|
|
48
|
-
|
|
66
|
+
handleError("Invalid report group. Check and retry. (Failure from Server)");
|
|
49
67
|
}
|
|
50
68
|
else if (response.response == '889') {
|
|
51
|
-
|
|
69
|
+
handleError("We are experiencing technical difficulties. Please try your query again later.");
|
|
52
70
|
}
|
|
53
71
|
return false;
|
|
54
72
|
}
|
|
@@ -81,8 +99,7 @@
|
|
|
81
99
|
</script>
|
|
82
100
|
</head>
|
|
83
101
|
<body>
|
|
84
|
-
<
|
|
85
|
-
<form method="post" id="form_checkout" name="form_checkout" action="/plugins/killbill-litle/checkout">
|
|
102
|
+
<form method="post" id="form_checkout" name="form_checkout" action="<%= success_page %>">
|
|
86
103
|
<input type="hidden" id="kb_account_id" name="kb_account_id" value="<%= kb_account_id %>"/>
|
|
87
104
|
|
|
88
105
|
<input type="hidden" id="request_paypage_id" name="request_paypage_id" value="<%= paypage_id %>"/>
|
|
@@ -99,7 +116,7 @@
|
|
|
99
116
|
<tr><td> </td></tr>
|
|
100
117
|
<tr><td></td><td align="right">
|
|
101
118
|
<script>
|
|
102
|
-
document.write('<button type="button" id="submitId" onclick="callLitle()">Check out
|
|
119
|
+
document.write('<button type="button" id="submitId" onclick="callLitle()">Check out</button>');
|
|
103
120
|
</script>
|
|
104
121
|
<noscript>
|
|
105
122
|
<button type="button" id="submitId">Enable JavaScript!</button>
|
|
@@ -118,8 +135,8 @@
|
|
|
118
135
|
</body>
|
|
119
136
|
<script>
|
|
120
137
|
function callLitle() {
|
|
121
|
-
if(typeof sendToLitle != 'function') {
|
|
122
|
-
|
|
138
|
+
if (typeof sendToLitle != 'function') {
|
|
139
|
+
handleError("We are experiencing technical difficulties. Please try your query again later (API unavailable).");
|
|
123
140
|
}
|
|
124
141
|
}
|
|
125
142
|
</script>
|
data/pom.xml
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
<groupId>com.ning.killbill.ruby</groupId>
|
|
26
26
|
<artifactId>litle-plugin</artifactId>
|
|
27
27
|
<packaging>pom</packaging>
|
|
28
|
-
<version>1.0.
|
|
28
|
+
<version>1.0.2</version>
|
|
29
29
|
<name>litle-plugin</name>
|
|
30
30
|
<scm>
|
|
31
31
|
<connection>scm:git:git://github.com/killbill/killbill-litle-plugin.git</connection>
|
data/release.sh
CHANGED
|
@@ -1,4 +1,20 @@
|
|
|
1
|
+
set -e
|
|
2
|
+
|
|
1
3
|
VERSION=`grep -E '<version>([0-9]+\.[0-9]+\.[0-9]+)</version>' pom.xml | sed 's/[\t \n]*<version>\(.*\)<\/version>[\t \n]*/\1/'`
|
|
4
|
+
if [ "$VERSION" != "$(cat $PWD/VERSION)" ]; then
|
|
5
|
+
echo "Unable to release: make sure the versions in pom.xml and VERSION match"
|
|
6
|
+
exit 1
|
|
7
|
+
fi
|
|
8
|
+
|
|
9
|
+
echo "Cleaning up"
|
|
10
|
+
rake killbill:clean ; rake build
|
|
11
|
+
|
|
12
|
+
echo "Pushing the gem to Rubygems"
|
|
13
|
+
rake release
|
|
14
|
+
|
|
15
|
+
echo "Building artifact"
|
|
16
|
+
rake killbill:package
|
|
17
|
+
|
|
2
18
|
ARTIFACT="$PWD/pkg/killbill-litle-$VERSION.tar.gz"
|
|
3
19
|
echo "Pushing $ARTIFACT to Maven Central"
|
|
4
20
|
mvn gpg:sign-and-deploy-file \
|
|
@@ -15,8 +15,8 @@ eos
|
|
|
15
15
|
file.close
|
|
16
16
|
|
|
17
17
|
@plugin = Killbill::Litle::PaymentPlugin.new
|
|
18
|
-
@plugin.root = File.dirname(file)
|
|
19
18
|
@plugin.logger = Logger.new(STDOUT)
|
|
19
|
+
@plugin.conf_dir = File.dirname(file)
|
|
20
20
|
|
|
21
21
|
# Start the plugin here - since the config file will be deleted
|
|
22
22
|
@plugin.start_plugin
|
|
@@ -3,11 +3,27 @@ require 'logger'
|
|
|
3
3
|
|
|
4
4
|
ActiveMerchant::Billing::Base.mode = :test
|
|
5
5
|
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class KillbillApiWithFakeGetAccountById < Killbill::Plugin::KillbillApi
|
|
9
|
+
|
|
10
|
+
def initialize(japi_proxy)
|
|
11
|
+
super(japi_proxy)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Returns an account where we specify the currency for the report group
|
|
15
|
+
def get_account_by_id(id)
|
|
16
|
+
Killbill::Plugin::Model::Account.new(id, nil, nil, nil, nil, nil, 1, nil, 1, 'USD', nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, true)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
6
20
|
describe Killbill::Litle::PaymentPlugin do
|
|
7
21
|
before(:each) do
|
|
8
22
|
@plugin = Killbill::Litle::PaymentPlugin.new
|
|
9
|
-
|
|
23
|
+
kb_apis = KillbillApiWithFakeGetAccountById.new(nil)
|
|
24
|
+
@plugin.kb_apis = kb_apis
|
|
10
25
|
@plugin.logger = Logger.new(STDOUT)
|
|
26
|
+
@plugin.conf_dir = File.expand_path(File.dirname(__FILE__) + '../../../')
|
|
11
27
|
@plugin.start_plugin
|
|
12
28
|
end
|
|
13
29
|
|
|
@@ -38,8 +54,8 @@ describe Killbill::Litle::PaymentPlugin do
|
|
|
38
54
|
kb_payment_id = SecureRandom.uuid
|
|
39
55
|
|
|
40
56
|
payment_response = @plugin.process_payment pm.kb_account_id, kb_payment_id, pm.kb_payment_method_id, amount_in_cents, currency
|
|
41
|
-
payment_response.
|
|
42
|
-
payment_response.status.should == Killbill::Plugin::
|
|
57
|
+
payment_response.amount.should == amount_in_cents
|
|
58
|
+
payment_response.status.should == Killbill::Plugin::Model::PaymentPluginStatus.new(:PROCESSED)
|
|
43
59
|
|
|
44
60
|
# Verify our table directly
|
|
45
61
|
response = Killbill::Litle::LitleResponse.find_by_api_call_and_kb_payment_id :charge, kb_payment_id
|
|
@@ -49,15 +65,15 @@ describe Killbill::Litle::PaymentPlugin do
|
|
|
49
65
|
response.params_litleonelineresponse_saleresponse_order_id.should == Killbill::Litle::Utils.compact_uuid(kb_payment_id)
|
|
50
66
|
|
|
51
67
|
payment_response = @plugin.get_payment_info pm.kb_account_id, kb_payment_id
|
|
52
|
-
payment_response.
|
|
53
|
-
payment_response.status.should == Killbill::Plugin::
|
|
68
|
+
payment_response.amount.should == amount_in_cents
|
|
69
|
+
payment_response.status.should == Killbill::Plugin::Model::PaymentPluginStatus.new(:PROCESSED)
|
|
54
70
|
|
|
55
71
|
# Check we cannot refund an amount greater than the original charge
|
|
56
72
|
lambda { @plugin.process_refund pm.kb_account_id, kb_payment_id, amount_in_cents + 1, currency }.should raise_error RuntimeError
|
|
57
73
|
|
|
58
74
|
refund_response = @plugin.process_refund pm.kb_account_id, kb_payment_id, amount_in_cents, currency
|
|
59
|
-
refund_response.
|
|
60
|
-
refund_response.status.should == Killbill::Plugin::
|
|
75
|
+
refund_response.amount.should == amount_in_cents
|
|
76
|
+
refund_response.status.should == Killbill::Plugin::Model::RefundPluginStatus.new(:PROCESSED)
|
|
61
77
|
|
|
62
78
|
# Verify our table directly
|
|
63
79
|
response = Killbill::Litle::LitleResponse.find_by_api_call_and_kb_payment_id :refund, kb_payment_id
|
|
@@ -69,8 +85,8 @@ describe Killbill::Litle::PaymentPlugin do
|
|
|
69
85
|
second_kb_payment_id = SecureRandom.uuid
|
|
70
86
|
|
|
71
87
|
payment_response = @plugin.process_payment pm.kb_account_id, second_kb_payment_id, pm.kb_payment_method_id, second_amount_in_cents, currency
|
|
72
|
-
payment_response.
|
|
73
|
-
payment_response.status.should == Killbill::Plugin::
|
|
88
|
+
payment_response.amount.should == second_amount_in_cents
|
|
89
|
+
payment_response.status.should == Killbill::Plugin::Model::PaymentPluginStatus.new(:PROCESSED)
|
|
74
90
|
end
|
|
75
91
|
|
|
76
92
|
private
|
|
@@ -78,8 +94,16 @@ describe Killbill::Litle::PaymentPlugin do
|
|
|
78
94
|
def create_payment_method
|
|
79
95
|
kb_account_id = SecureRandom.uuid
|
|
80
96
|
kb_payment_method_id = SecureRandom.uuid
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
97
|
+
|
|
98
|
+
# Generate a token in Litle
|
|
99
|
+
paypage_registration_id = '123456789012345678901324567890abcdefghi'
|
|
100
|
+
info = Killbill::Plugin::Model::PaymentMethodPlugin.new nil, nil, [Killbill::Plugin::Model::PaymentMethodKVInfo.new(false, "paypageRegistrationId", paypage_registration_id)], nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil
|
|
101
|
+
payment_method = @plugin.add_payment_method(kb_account_id, kb_payment_method_id, info)
|
|
102
|
+
|
|
103
|
+
pm = Killbill::Litle::LitlePaymentMethod.from_kb_payment_method_id kb_payment_method_id
|
|
104
|
+
pm.kb_account_id.should == kb_account_id
|
|
105
|
+
pm.kb_payment_method_id.should == kb_payment_method_id
|
|
106
|
+
pm.litle_token.should_not be_nil
|
|
107
|
+
pm
|
|
84
108
|
end
|
|
85
109
|
end
|
metadata
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
name: killbill-litle
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease:
|
|
5
|
-
version: 1.0.
|
|
5
|
+
version: 1.0.3
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
8
8
|
- Killbill core team
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2013-
|
|
12
|
+
date: 2013-05-21 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: killbill
|
|
@@ -17,13 +17,13 @@ dependencies:
|
|
|
17
17
|
requirements:
|
|
18
18
|
- - "~>"
|
|
19
19
|
- !ruby/object:Gem::Version
|
|
20
|
-
version: 1.0.
|
|
20
|
+
version: 1.0.16
|
|
21
21
|
none: false
|
|
22
22
|
requirement: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: 1.0.
|
|
26
|
+
version: 1.0.16
|
|
27
27
|
none: false
|
|
28
28
|
prerelease: false
|
|
29
29
|
type: :runtime
|
|
@@ -33,13 +33,13 @@ dependencies:
|
|
|
33
33
|
requirements:
|
|
34
34
|
- - "~>"
|
|
35
35
|
- !ruby/object:Gem::Version
|
|
36
|
-
version:
|
|
36
|
+
version: 2.0.0
|
|
37
37
|
none: false
|
|
38
38
|
requirement: !ruby/object:Gem::Requirement
|
|
39
39
|
requirements:
|
|
40
40
|
- - "~>"
|
|
41
41
|
- !ruby/object:Gem::Version
|
|
42
|
-
version:
|
|
42
|
+
version: 2.0.0
|
|
43
43
|
none: false
|
|
44
44
|
prerelease: false
|
|
45
45
|
type: :runtime
|
|
@@ -217,6 +217,7 @@ files:
|
|
|
217
217
|
- Rakefile
|
|
218
218
|
- VERSION
|
|
219
219
|
- config.ru
|
|
220
|
+
- db/ddl.sql
|
|
220
221
|
- db/schema.rb
|
|
221
222
|
- killbill-litle.gemspec
|
|
222
223
|
- killbill.properties
|