killbill-securenet 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/NEWS ADDED
@@ -0,0 +1,2 @@
1
+ 0.1.0
2
+ Initial release for Kill Bill 0.16.x
data/README.md ADDED
@@ -0,0 +1,87 @@
1
+ killbill-securenet-plugin
2
+ =========================
3
+
4
+ Plugin to use [SecureNet](http://www.securenet.com/) as a gateway.
5
+
6
+ Release builds are available on [Maven Central](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.kill-bill.billing.plugin.ruby%22%20AND%20a%3A%22securenet-plugin%22) with coordinates `org.kill-bill.billing.plugin.ruby:securenet-plugin`.
7
+
8
+ Kill Bill compatibility
9
+ -----------------------
10
+
11
+ | Plugin version | Kill Bill version |
12
+ | -------------: | ----------------: |
13
+ | 0.1.y | 0.16.z |
14
+
15
+ Requirements
16
+ ------------
17
+
18
+ The plugin needs a database. The latest version of the schema can be found [here](https://github.com/killbill/killbill-securenet-plugin/blob/master/db/ddl.sql).
19
+
20
+ Configuration
21
+ -------------
22
+
23
+ ```
24
+ curl -v \
25
+ -X POST \
26
+ -u admin:password \
27
+ -H 'X-Killbill-ApiKey: bob' \
28
+ -H 'X-Killbill-ApiSecret: lazar' \
29
+ -H 'X-Killbill-CreatedBy: admin' \
30
+ -H 'Content-Type: text/plain' \
31
+ -d ':securenet:
32
+ :login: "your-login"
33
+ :password: "your-password"' \
34
+ http://127.0.0.1:8080/1.0/kb/tenants/uploadPluginConfig/killbill-securenet
35
+ ```
36
+
37
+ To go to production, create a `securenet.yml` configuration file under `/var/tmp/bundles/plugins/ruby/killbill-securenet/x.y.z/` containing the following:
38
+
39
+ ```
40
+ :securenet:
41
+ :test: false
42
+ ```
43
+
44
+ Usage
45
+ -----
46
+
47
+ Note: integration with PayOS.js hasn't been done yet.
48
+
49
+ To store a credit card:
50
+
51
+ ```
52
+ curl -v \
53
+ -X POST \
54
+ -u admin:password \
55
+ -H 'X-Killbill-ApiKey: bob' \
56
+ -H 'X-Killbill-ApiSecret: lazar' \
57
+ -H 'X-Killbill-CreatedBy: admin' \
58
+ -H 'Content-Type: application/json' \
59
+ -d '{
60
+ "pluginName": "killbill-securenet",
61
+ "pluginInfo": {
62
+ "properties": [
63
+ {
64
+ "key": "ccFirstName",
65
+ "value": "John"
66
+ },
67
+ {
68
+ "key": "ccLastName",
69
+ "value": "Doe"
70
+ },
71
+ {
72
+ "key": "ccExpirationMonth",
73
+ "value": 12
74
+ },
75
+ {
76
+ "key": "ccExpirationYear",
77
+ "value": 2017
78
+ },
79
+ {
80
+ "key": "ccNumber",
81
+ "value": "4111111111111111"
82
+ }
83
+ ]
84
+ }
85
+ }' \
86
+ "http://127.0.0.1:8080/1.0/kb/accounts/2a55045a-ce1d-4344-942d-b825536328f9/paymentMethods?isDefault=true&pluginProperty=skip_gw=true"
87
+ ```
data/Rakefile ADDED
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env rake
2
+
3
+ # Install tasks to build and release the plugin
4
+ require 'bundler/setup'
5
+ Bundler::GemHelper.install_tasks
6
+
7
+ # Install test tasks
8
+ require 'rspec/core/rake_task'
9
+ namespace :test do
10
+ desc 'Run RSpec tests'
11
+ RSpec::Core::RakeTask.new do |task|
12
+ task.name = 'spec'
13
+ task.pattern = './spec/*/*_spec.rb'
14
+ end
15
+
16
+ namespace :remote do
17
+ desc 'Run RSpec remote tests'
18
+ RSpec::Core::RakeTask.new do |task|
19
+ task.name = 'spec'
20
+ task.pattern = './spec/*/remote/*_spec.rb'
21
+ end
22
+ end
23
+ end
24
+
25
+ # Install tasks to package the plugin for Killbill
26
+ require 'killbill/rake_task'
27
+ Killbill::PluginHelper.install_tasks
28
+
29
+ # Run tests by default
30
+ task :default => 'test:spec'
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/config.ru ADDED
@@ -0,0 +1,4 @@
1
+ require 'securenet'
2
+ require 'securenet/application'
3
+
4
+ run Sinatra::Application
data/db/ddl.sql ADDED
@@ -0,0 +1,75 @@
1
+ CREATE TABLE `securenet_payment_methods` (
2
+ `id` int(11) NOT NULL AUTO_INCREMENT,
3
+ `kb_payment_method_id` varchar(255) DEFAULT NULL,
4
+ `token` varchar(255) DEFAULT NULL,
5
+ `cc_first_name` varchar(255) DEFAULT NULL,
6
+ `cc_last_name` varchar(255) DEFAULT NULL,
7
+ `cc_type` varchar(255) DEFAULT NULL,
8
+ `cc_exp_month` varchar(255) DEFAULT NULL,
9
+ `cc_exp_year` varchar(255) DEFAULT NULL,
10
+ `cc_number` varchar(255) DEFAULT NULL,
11
+ `cc_last_4` varchar(255) DEFAULT NULL,
12
+ `cc_start_month` varchar(255) DEFAULT NULL,
13
+ `cc_start_year` varchar(255) DEFAULT NULL,
14
+ `cc_issue_number` varchar(255) DEFAULT NULL,
15
+ `cc_verification_value` varchar(255) DEFAULT NULL,
16
+ `cc_track_data` varchar(255) DEFAULT NULL,
17
+ `address1` varchar(255) DEFAULT NULL,
18
+ `address2` varchar(255) DEFAULT NULL,
19
+ `city` varchar(255) DEFAULT NULL,
20
+ `state` varchar(255) DEFAULT NULL,
21
+ `zip` varchar(255) DEFAULT NULL,
22
+ `country` varchar(255) DEFAULT NULL,
23
+ `is_deleted` tinyint(1) NOT NULL DEFAULT '0',
24
+ `created_at` datetime NOT NULL,
25
+ `updated_at` datetime NOT NULL,
26
+ `kb_account_id` varchar(255) DEFAULT NULL,
27
+ `kb_tenant_id` varchar(255) DEFAULT NULL,
28
+ PRIMARY KEY (`id`),
29
+ KEY `index_securenet_payment_methods_on_kb_account_id` (`kb_account_id`),
30
+ KEY `index_securenet_payment_methods_on_kb_payment_method_id` (`kb_payment_method_id`)
31
+ ) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
32
+
33
+ CREATE TABLE `securenet_transactions` (
34
+ `id` int(11) NOT NULL AUTO_INCREMENT,
35
+ `securenet_response_id` int(11) NOT NULL,
36
+ `api_call` varchar(255) NOT NULL,
37
+ `kb_payment_id` varchar(255) NOT NULL,
38
+ `kb_payment_transaction_id` varchar(255) NOT NULL,
39
+ `transaction_type` varchar(255) NOT NULL,
40
+ `payment_processor_account_id` varchar(255) DEFAULT NULL,
41
+ `txn_id` varchar(255) DEFAULT NULL,
42
+ `amount_in_cents` int(11) DEFAULT NULL,
43
+ `currency` varchar(255) DEFAULT NULL,
44
+ `created_at` datetime NOT NULL,
45
+ `updated_at` datetime NOT NULL,
46
+ `kb_account_id` varchar(255) NOT NULL,
47
+ `kb_tenant_id` varchar(255) NOT NULL,
48
+ PRIMARY KEY (`id`),
49
+ KEY `index_securenet_transactions_on_kb_payment_id` (`kb_payment_id`)
50
+ ) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
51
+
52
+ CREATE TABLE `securenet_responses` (
53
+ `id` int(11) NOT NULL AUTO_INCREMENT,
54
+ `api_call` varchar(255) NOT NULL,
55
+ `kb_payment_id` varchar(255) DEFAULT NULL,
56
+ `kb_payment_transaction_id` varchar(255) DEFAULT NULL,
57
+ `transaction_type` varchar(255) DEFAULT NULL,
58
+ `payment_processor_account_id` varchar(255) DEFAULT NULL,
59
+ `message` varchar(255) DEFAULT NULL,
60
+ `authorization` varchar(255) DEFAULT NULL,
61
+ `fraud_review` tinyint(1) DEFAULT NULL,
62
+ `test` tinyint(1) DEFAULT NULL,
63
+ `avs_result_code` varchar(255) DEFAULT NULL,
64
+ `avs_result_message` varchar(255) DEFAULT NULL,
65
+ `avs_result_street_match` varchar(255) DEFAULT NULL,
66
+ `avs_result_postal_match` varchar(255) DEFAULT NULL,
67
+ `cvv_result_code` varchar(255) DEFAULT NULL,
68
+ `cvv_result_message` varchar(255) DEFAULT NULL,
69
+ `success` tinyint(1) DEFAULT NULL,
70
+ `created_at` datetime NOT NULL,
71
+ `updated_at` datetime NOT NULL,
72
+ `kb_account_id` varchar(255) DEFAULT NULL,
73
+ `kb_tenant_id` varchar(255) DEFAULT NULL,
74
+ PRIMARY KEY (`id`)
75
+ ) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
data/db/schema.rb ADDED
@@ -0,0 +1,76 @@
1
+ require 'active_record'
2
+
3
+ ActiveRecord::Schema.define(:version => 20140410153635) do
4
+ create_table "securenet_payment_methods", :force => true do |t|
5
+ t.string "kb_payment_method_id" # NULL before Kill Bill knows about it
6
+ t.string "token" # securenet id
7
+ t.string "cc_first_name"
8
+ t.string "cc_last_name"
9
+ t.string "cc_type"
10
+ t.string "cc_exp_month"
11
+ t.string "cc_exp_year"
12
+ t.string "cc_number"
13
+ t.string "cc_last_4"
14
+ t.string "cc_start_month"
15
+ t.string "cc_start_year"
16
+ t.string "cc_issue_number"
17
+ t.string "cc_verification_value"
18
+ t.string "cc_track_data"
19
+ t.string "address1"
20
+ t.string "address2"
21
+ t.string "city"
22
+ t.string "state"
23
+ t.string "zip"
24
+ t.string "country"
25
+ t.boolean "is_deleted", :null => false, :default => false
26
+ t.datetime "created_at", :null => false
27
+ t.datetime "updated_at", :null => false
28
+ t.string "kb_account_id"
29
+ t.string "kb_tenant_id"
30
+ end
31
+
32
+ add_index(:securenet_payment_methods, :kb_account_id)
33
+ add_index(:securenet_payment_methods, :kb_payment_method_id)
34
+
35
+ create_table "securenet_transactions", :force => true do |t|
36
+ t.integer "securenet_response_id", :null => false
37
+ t.string "api_call", :null => false
38
+ t.string "kb_payment_id", :null => false
39
+ t.string "kb_payment_transaction_id", :null => false
40
+ t.string "transaction_type", :null => false
41
+ t.string "payment_processor_account_id"
42
+ t.string "txn_id" # securenet transaction id
43
+ # Both null for void
44
+ t.integer "amount_in_cents"
45
+ t.string "currency"
46
+ t.datetime "created_at", :null => false
47
+ t.datetime "updated_at", :null => false
48
+ t.string "kb_account_id", :null => false
49
+ t.string "kb_tenant_id", :null => false
50
+ end
51
+
52
+ add_index(:securenet_transactions, :kb_payment_id)
53
+
54
+ create_table "securenet_responses", :force => true do |t|
55
+ t.string "api_call", :null => false
56
+ t.string "kb_payment_id"
57
+ t.string "kb_payment_transaction_id"
58
+ t.string "transaction_type"
59
+ t.string "payment_processor_account_id"
60
+ t.string "message"
61
+ t.string "authorization"
62
+ t.boolean "fraud_review"
63
+ t.boolean "test"
64
+ t.string "avs_result_code"
65
+ t.string "avs_result_message"
66
+ t.string "avs_result_street_match"
67
+ t.string "avs_result_postal_match"
68
+ t.string "cvv_result_code"
69
+ t.string "cvv_result_message"
70
+ t.boolean "success"
71
+ t.datetime "created_at", :null => false
72
+ t.datetime "updated_at", :null => false
73
+ t.string "kb_account_id"
74
+ t.string "kb_tenant_id"
75
+ end
76
+ end
@@ -0,0 +1,52 @@
1
+ version = File.read(File.expand_path('../VERSION', __FILE__)).strip
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'killbill-securenet'
5
+ s.version = version
6
+ s.summary = 'Plugin to use SecureNet as a gateway.'
7
+ s.description = 'Kill Bill payment plugin for SecureNet.'
8
+
9
+ s.required_ruby_version = '>= 1.9.3'
10
+
11
+ s.license = 'Apache License (2.0)'
12
+
13
+ s.author = 'Kill Bill core team'
14
+ s.email = 'killbilling-users@googlegroups.com'
15
+ s.homepage = 'http://killbill.io'
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.bindir = 'bin'
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
21
+ s.require_paths = ['lib']
22
+
23
+ s.rdoc_options << '--exclude' << '.'
24
+
25
+ s.add_dependency 'killbill', '~> 7.0'
26
+
27
+ s.add_dependency 'sinatra', '~> 1.3.4'
28
+ s.add_dependency 'thread_safe', '~> 0.3.4'
29
+ s.add_dependency 'activerecord', '~> 4.1.0'
30
+ if defined?(JRUBY_VERSION)
31
+ s.add_dependency 'activerecord-bogacs', '~> 0.3'
32
+ s.add_dependency 'activerecord-jdbc-adapter', '~> 1.3'
33
+ # Required to avoid errors like java.lang.NoClassDefFoundError: org/bouncycastle/asn1/DERBoolean
34
+ s.add_dependency 'jruby-openssl', '~> 0.9.6'
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'
42
+
43
+ s.add_development_dependency 'jbundler', '~> 0.9.2'
44
+ s.add_development_dependency 'rake', '>= 10.0.0'
45
+ s.add_development_dependency 'rspec', '~> 2.12.0'
46
+ if defined?(JRUBY_VERSION)
47
+ s.add_development_dependency 'jdbc-sqlite3', '~> 3.7'
48
+ s.add_development_dependency 'jdbc-mariadb', '~> 1.1'
49
+ else
50
+ s.add_development_dependency 'sqlite3', '~> 1.3.7'
51
+ end
52
+ end
@@ -0,0 +1,3 @@
1
+ mainClass=Killbill::Securenet::PaymentPlugin
2
+ require=securenet
3
+ pluginType=PAYMENT
data/lib/securenet.rb ADDED
@@ -0,0 +1,24 @@
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 'securenet/api'
20
+ require 'securenet/private_api'
21
+
22
+ require 'securenet/models/payment_method'
23
+ require 'securenet/models/response'
24
+ require 'securenet/models/transaction'
@@ -0,0 +1,185 @@
1
+ module Killbill #:nodoc:
2
+ module Securenet #:nodoc:
3
+ class PaymentPlugin < ::Killbill::Plugin::ActiveMerchant::PaymentPlugin
4
+
5
+ def initialize
6
+ gateway_builder = Proc.new do |config|
7
+ ::ActiveMerchant::Billing::SecureNetGateway.new :login => config[:login], :password => config[:password]
8
+ end
9
+
10
+ super(gateway_builder,
11
+ :securenet,
12
+ ::Killbill::Securenet::SecurenetPaymentMethod,
13
+ ::Killbill::Securenet::SecurenetTransaction,
14
+ ::Killbill::Securenet::SecurenetResponse)
15
+ end
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
+
25
+ def authorize_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
26
+ # Pass extra parameters for the gateway here
27
+ options = {}
28
+
29
+ default_options(options, kb_payment_transaction_id)
30
+
31
+ properties = merge_properties(properties, options)
32
+ super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
33
+ end
34
+
35
+ def capture_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
36
+ # Pass extra parameters for the gateway here
37
+ options = {}
38
+
39
+ default_options(options, kb_payment_transaction_id)
40
+
41
+ properties = merge_properties(properties, options)
42
+ super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
43
+ end
44
+
45
+ def purchase_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
46
+ # Pass extra parameters for the gateway here
47
+ options = {}
48
+
49
+ default_options(options, kb_payment_transaction_id)
50
+
51
+ properties = merge_properties(properties, options)
52
+ super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
53
+ end
54
+
55
+ def void_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, properties, context)
56
+ # Pass extra parameters for the gateway here
57
+ options = {}
58
+
59
+ default_options(options, kb_payment_transaction_id)
60
+
61
+ properties = merge_properties(properties, options)
62
+ super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, properties, context)
63
+ end
64
+
65
+ def credit_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
66
+ # Pass extra parameters for the gateway here
67
+ options = {}
68
+
69
+ default_options(options, kb_payment_transaction_id)
70
+
71
+ properties = merge_properties(properties, options)
72
+ super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
73
+ end
74
+
75
+ def refund_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
76
+ # Pass extra parameters for the gateway here
77
+ options = {}
78
+
79
+ default_options(options, kb_payment_transaction_id)
80
+
81
+ properties = merge_properties(properties, options)
82
+ super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
83
+ end
84
+
85
+ def get_payment_info(kb_account_id, kb_payment_id, properties, context)
86
+ # Pass extra parameters for the gateway here
87
+ options = {}
88
+
89
+ properties = merge_properties(properties, options)
90
+ super(kb_account_id, kb_payment_id, properties, context)
91
+ end
92
+
93
+ def search_payments(search_key, offset, limit, properties, context)
94
+ # Pass extra parameters for the gateway here
95
+ options = {}
96
+
97
+ properties = merge_properties(properties, options)
98
+ super(search_key, offset, limit, properties, context)
99
+ end
100
+
101
+ def add_payment_method(kb_account_id, kb_payment_method_id, payment_method_props, set_default, properties, context)
102
+ # Pass extra parameters for the gateway here
103
+ options = {}
104
+
105
+ properties = merge_properties(properties, options)
106
+ super(kb_account_id, kb_payment_method_id, payment_method_props, set_default, properties, context)
107
+ end
108
+
109
+ def delete_payment_method(kb_account_id, kb_payment_method_id, properties, context)
110
+ # Pass extra parameters for the gateway here
111
+ options = {}
112
+
113
+ properties = merge_properties(properties, options)
114
+ super(kb_account_id, kb_payment_method_id, properties, context)
115
+ end
116
+
117
+ def get_payment_method_detail(kb_account_id, kb_payment_method_id, properties, context)
118
+ # Pass extra parameters for the gateway here
119
+ options = {}
120
+
121
+ properties = merge_properties(properties, options)
122
+ super(kb_account_id, kb_payment_method_id, properties, context)
123
+ end
124
+
125
+ def set_default_payment_method(kb_account_id, kb_payment_method_id, properties, context)
126
+ # TODO
127
+ end
128
+
129
+ def get_payment_methods(kb_account_id, refresh_from_gateway, properties, context)
130
+ # Pass extra parameters for the gateway here
131
+ options = {}
132
+
133
+ properties = merge_properties(properties, options)
134
+ super(kb_account_id, refresh_from_gateway, properties, context)
135
+ end
136
+
137
+ def search_payment_methods(search_key, offset, limit, properties, context)
138
+ # Pass extra parameters for the gateway here
139
+ options = {}
140
+
141
+ properties = merge_properties(properties, options)
142
+ super(search_key, offset, limit, properties, context)
143
+ end
144
+
145
+ def reset_payment_methods(kb_account_id, payment_methods, properties, context)
146
+ super
147
+ end
148
+
149
+ def build_form_descriptor(kb_account_id, descriptor_fields, properties, context)
150
+ # Pass extra parameters for the gateway here
151
+ options = {}
152
+ properties = merge_properties(properties, options)
153
+
154
+ # Add your custom static hidden tags here
155
+ options = {
156
+ #:token => config[:securenet][:token]
157
+ }
158
+ descriptor_fields = merge_properties(descriptor_fields, options)
159
+
160
+ super(kb_account_id, descriptor_fields, properties, context)
161
+ end
162
+
163
+ def process_notification(notification, properties, context)
164
+ # Pass extra parameters for the gateway here
165
+ options = {}
166
+ properties = merge_properties(properties, options)
167
+
168
+ super(notification, properties, context) do |gw_notification, service|
169
+ # Retrieve the payment
170
+ # gw_notification.kb_payment_id =
171
+ #
172
+ # Set the response body
173
+ # gw_notification.entity =
174
+ end
175
+ end
176
+
177
+ private
178
+
179
+ def default_options(options, kb_payment_transaction_id)
180
+ # SecureNet limits it to 25 characters
181
+ options[:order_id] ||= Killbill::Plugin::ActiveMerchant::Utils.compact_uuid(kb_payment_transaction_id)
182
+ end
183
+ end
184
+ end
185
+ end