killbill-cybersource 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +36 -0
- data/.travis.yml +19 -0
- data/Gemfile +6 -0
- data/Jarfile +8 -0
- data/LICENSE +201 -0
- data/NEWS +2 -0
- data/README.md +4 -0
- data/Rakefile +30 -0
- data/VERSION +1 -0
- data/config.ru +4 -0
- data/cybersource.yml +13 -0
- data/db/ddl.sql +88 -0
- data/db/schema.rb +88 -0
- data/killbill-cybersource.gemspec +48 -0
- data/killbill.properties +3 -0
- data/lib/cybersource.rb +23 -0
- data/lib/cybersource/api.rb +158 -0
- data/lib/cybersource/application.rb +84 -0
- data/lib/cybersource/models/payment_method.rb +23 -0
- data/lib/cybersource/models/response.rb +38 -0
- data/lib/cybersource/models/transaction.rb +11 -0
- data/lib/cybersource/private_api.rb +6 -0
- data/lib/cybersource/views/form.erb +8 -0
- data/pom.xml +44 -0
- data/release.sh +41 -0
- data/spec/cybersource/base_plugin_spec.rb +30 -0
- data/spec/cybersource/remote/integration_spec.rb +92 -0
- data/spec/spec_helper.rb +24 -0
- metadata +286 -0
@@ -0,0 +1,48 @@
|
|
1
|
+
version = File.read(File.expand_path('../VERSION', __FILE__)).strip
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'killbill-cybersource'
|
5
|
+
s.version = version
|
6
|
+
s.summary = 'Plugin to use Cybersource as a gateway.'
|
7
|
+
s.description = 'Kill Bill payment plugin for Cybersource.'
|
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://kill-bill.org'
|
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', '~> 3.1.9'
|
26
|
+
s.add_dependency 'activemerchant', '~> 1.42.9'
|
27
|
+
s.add_dependency 'activerecord', '~> 4.1.0'
|
28
|
+
s.add_dependency 'actionpack', '~> 4.1.0'
|
29
|
+
s.add_dependency 'actionview', '~> 4.1.0'
|
30
|
+
s.add_dependency 'activesupport', '~> 4.1.0'
|
31
|
+
s.add_dependency 'money', '~> 6.1.1'
|
32
|
+
s.add_dependency 'monetize', '~> 0.3.0'
|
33
|
+
s.add_dependency 'sinatra', '~> 1.3.4'
|
34
|
+
if defined?(JRUBY_VERSION)
|
35
|
+
s.add_dependency 'activerecord-jdbcmysql-adapter', '~> 1.3.7'
|
36
|
+
# Required to avoid errors like java.lang.NoClassDefFoundError: org/bouncycastle/asn1/DERBoolean
|
37
|
+
s.add_dependency 'jruby-openssl', '~> 0.9.4'
|
38
|
+
end
|
39
|
+
|
40
|
+
s.add_development_dependency 'jbundler', '~> 0.4.1'
|
41
|
+
s.add_development_dependency 'rake', '>= 10.0.0'
|
42
|
+
s.add_development_dependency 'rspec', '~> 2.12.0'
|
43
|
+
if defined?(JRUBY_VERSION)
|
44
|
+
s.add_development_dependency 'activerecord-jdbcsqlite3-adapter', '~> 1.3.7'
|
45
|
+
else
|
46
|
+
s.add_development_dependency 'sqlite3', '~> 1.3.7'
|
47
|
+
end
|
48
|
+
end
|
data/killbill.properties
ADDED
data/lib/cybersource.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'action_controller'
|
2
|
+
require 'active_record'
|
3
|
+
require 'action_view'
|
4
|
+
require 'active_merchant'
|
5
|
+
require 'active_support'
|
6
|
+
require 'bigdecimal'
|
7
|
+
require 'money'
|
8
|
+
require 'monetize'
|
9
|
+
require 'pathname'
|
10
|
+
require 'sinatra'
|
11
|
+
require 'singleton'
|
12
|
+
require 'yaml'
|
13
|
+
|
14
|
+
require 'killbill'
|
15
|
+
require 'killbill/helpers/active_merchant'
|
16
|
+
|
17
|
+
require 'cybersource/api'
|
18
|
+
require 'cybersource/private_api'
|
19
|
+
|
20
|
+
require 'cybersource/models/payment_method'
|
21
|
+
require 'cybersource/models/response'
|
22
|
+
require 'cybersource/models/transaction'
|
23
|
+
|
@@ -0,0 +1,158 @@
|
|
1
|
+
module Killbill #:nodoc:
|
2
|
+
module Cybersource #:nodoc:
|
3
|
+
class PaymentPlugin < ::Killbill::Plugin::ActiveMerchant::PaymentPlugin
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
gateway_builder = Proc.new do |config|
|
7
|
+
::ActiveMerchant::Billing::CyberSourceGateway.new :login => config[:login], :password => config[:password]
|
8
|
+
end
|
9
|
+
|
10
|
+
super(gateway_builder,
|
11
|
+
:cybersource,
|
12
|
+
::Killbill::Cybersource::CybersourcePaymentMethod,
|
13
|
+
::Killbill::Cybersource::CybersourceTransaction,
|
14
|
+
::Killbill::Cybersource::CybersourceResponse)
|
15
|
+
end
|
16
|
+
|
17
|
+
def authorize_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
18
|
+
# Pass extra parameters for the gateway here
|
19
|
+
options = {}
|
20
|
+
|
21
|
+
properties = merge_properties(properties, options)
|
22
|
+
super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
23
|
+
end
|
24
|
+
|
25
|
+
def capture_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
|
+
properties = merge_properties(properties, options)
|
30
|
+
super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
31
|
+
end
|
32
|
+
|
33
|
+
def purchase_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
34
|
+
# Pass extra parameters for the gateway here
|
35
|
+
options = {}
|
36
|
+
|
37
|
+
properties = merge_properties(properties, options)
|
38
|
+
super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
39
|
+
end
|
40
|
+
|
41
|
+
def void_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, properties, context)
|
42
|
+
# Pass extra parameters for the gateway here
|
43
|
+
options = {}
|
44
|
+
|
45
|
+
properties = merge_properties(properties, options)
|
46
|
+
super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, properties, context)
|
47
|
+
end
|
48
|
+
|
49
|
+
def credit_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
50
|
+
# Pass extra parameters for the gateway here
|
51
|
+
options = {}
|
52
|
+
|
53
|
+
properties = merge_properties(properties, options)
|
54
|
+
super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
55
|
+
end
|
56
|
+
|
57
|
+
def refund_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
58
|
+
# Pass extra parameters for the gateway here
|
59
|
+
options = {}
|
60
|
+
|
61
|
+
properties = merge_properties(properties, options)
|
62
|
+
super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
63
|
+
end
|
64
|
+
|
65
|
+
def get_payment_info(kb_account_id, kb_payment_id, properties, context)
|
66
|
+
# Pass extra parameters for the gateway here
|
67
|
+
options = {}
|
68
|
+
|
69
|
+
properties = merge_properties(properties, options)
|
70
|
+
super(kb_account_id, kb_payment_id, properties, context)
|
71
|
+
end
|
72
|
+
|
73
|
+
def search_payments(search_key, offset, limit, properties, context)
|
74
|
+
# Pass extra parameters for the gateway here
|
75
|
+
options = {}
|
76
|
+
|
77
|
+
properties = merge_properties(properties, options)
|
78
|
+
super(search_key, offset, limit, properties, context)
|
79
|
+
end
|
80
|
+
|
81
|
+
def add_payment_method(kb_account_id, kb_payment_method_id, payment_method_props, set_default, properties, context)
|
82
|
+
# Pass extra parameters for the gateway here
|
83
|
+
options = {}
|
84
|
+
|
85
|
+
properties = merge_properties(properties, options)
|
86
|
+
super(kb_account_id, kb_payment_method_id, payment_method_props, set_default, properties, context)
|
87
|
+
end
|
88
|
+
|
89
|
+
def delete_payment_method(kb_account_id, kb_payment_method_id, properties, context)
|
90
|
+
# Pass extra parameters for the gateway here
|
91
|
+
options = {}
|
92
|
+
|
93
|
+
properties = merge_properties(properties, options)
|
94
|
+
super(kb_account_id, kb_payment_method_id, properties, context)
|
95
|
+
end
|
96
|
+
|
97
|
+
def get_payment_method_detail(kb_account_id, kb_payment_method_id, properties, context)
|
98
|
+
# Pass extra parameters for the gateway here
|
99
|
+
options = {}
|
100
|
+
|
101
|
+
properties = merge_properties(properties, options)
|
102
|
+
super(kb_account_id, kb_payment_method_id, properties, context)
|
103
|
+
end
|
104
|
+
|
105
|
+
def set_default_payment_method(kb_account_id, kb_payment_method_id, properties, context)
|
106
|
+
# TODO
|
107
|
+
end
|
108
|
+
|
109
|
+
def get_payment_methods(kb_account_id, refresh_from_gateway, properties, context)
|
110
|
+
# Pass extra parameters for the gateway here
|
111
|
+
options = {}
|
112
|
+
|
113
|
+
properties = merge_properties(properties, options)
|
114
|
+
super(kb_account_id, refresh_from_gateway, properties, context)
|
115
|
+
end
|
116
|
+
|
117
|
+
def search_payment_methods(search_key, offset, limit, properties, context)
|
118
|
+
# Pass extra parameters for the gateway here
|
119
|
+
options = {}
|
120
|
+
|
121
|
+
properties = merge_properties(properties, options)
|
122
|
+
super(search_key, offset, limit, properties, context)
|
123
|
+
end
|
124
|
+
|
125
|
+
def reset_payment_methods(kb_account_id, payment_methods, properties, context)
|
126
|
+
super
|
127
|
+
end
|
128
|
+
|
129
|
+
def build_form_descriptor(kb_account_id, descriptor_fields, properties, context)
|
130
|
+
# Pass extra parameters for the gateway here
|
131
|
+
options = {}
|
132
|
+
properties = merge_properties(properties, options)
|
133
|
+
|
134
|
+
# Add your custom static hidden tags here
|
135
|
+
options = {
|
136
|
+
#:token => config[:cybersource][:token]
|
137
|
+
}
|
138
|
+
descriptor_fields = merge_properties(descriptor_fields, options)
|
139
|
+
|
140
|
+
super(kb_account_id, descriptor_fields, properties, context)
|
141
|
+
end
|
142
|
+
|
143
|
+
def process_notification(notification, properties, context)
|
144
|
+
# Pass extra parameters for the gateway here
|
145
|
+
options = {}
|
146
|
+
properties = merge_properties(properties, options)
|
147
|
+
|
148
|
+
super(notification, properties, context) do |gw_notification, service|
|
149
|
+
# Retrieve the payment
|
150
|
+
# gw_notification.kb_payment_id =
|
151
|
+
#
|
152
|
+
# Set the response body
|
153
|
+
# gw_notification.entity =
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
@@ -0,0 +1,84 @@
|
|
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::Cybersource::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::Cybersource::PrivatePaymentPlugin.new(:cybersource,
|
22
|
+
::Killbill::Cybersource::CybersourcePaymentMethod,
|
23
|
+
::Killbill::Cybersource::CybersourceTransaction,
|
24
|
+
::Killbill::Cybersource::CybersourceResponse,
|
25
|
+
session)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# curl -v http://127.0.0.1:9292/plugins/killbill-cybersource/form
|
30
|
+
get '/plugins/killbill-cybersource/form', :provides => 'html' do
|
31
|
+
order_id = request.GET['order_id']
|
32
|
+
account_id = request.GET['account_id']
|
33
|
+
options = {
|
34
|
+
:amount => request.GET['amount'],
|
35
|
+
:currency => request.GET['currency'],
|
36
|
+
:test => request.GET['test'],
|
37
|
+
:credential2 => request.GET['credential2'],
|
38
|
+
:credential3 => request.GET['credential3'],
|
39
|
+
:credential4 => request.GET['credential4'],
|
40
|
+
:country => request.GET['country'],
|
41
|
+
:account_name => request.GET['account_name'],
|
42
|
+
:transaction_type => request.GET['transaction_type'],
|
43
|
+
:authcode => request.GET['authcode'],
|
44
|
+
:notify_url => request.GET['notify_url'],
|
45
|
+
:return_url => request.GET['return_url'],
|
46
|
+
:redirect_param => request.GET['redirect_param'],
|
47
|
+
:forward_url => request.GET['forward_url']
|
48
|
+
}
|
49
|
+
|
50
|
+
@form = plugin(session).payment_form_for(order_id, account_id, :cybersource, options) do |service|
|
51
|
+
# Add your custom hidden tags here, e.g.
|
52
|
+
#service.token = config[:cybersource][:token]
|
53
|
+
submit_tag 'Submit'
|
54
|
+
end
|
55
|
+
|
56
|
+
erb :form
|
57
|
+
end
|
58
|
+
|
59
|
+
# curl -v http://127.0.0.1:9292/plugins/killbill-cybersource/1.0/pms/1
|
60
|
+
get '/plugins/killbill-cybersource/1.0/pms/:id', :provides => 'json' do
|
61
|
+
if pm = ::Killbill::Cybersource::CybersourcePaymentMethod.find_by_id(params[:id].to_i)
|
62
|
+
pm.to_json
|
63
|
+
else
|
64
|
+
status 404
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# curl -v http://127.0.0.1:9292/plugins/killbill-cybersource/1.0/transactions/1
|
69
|
+
get '/plugins/killbill-cybersource/1.0/transactions/:id', :provides => 'json' do
|
70
|
+
if transaction = ::Killbill::Cybersource::CybersourceTransaction.find_by_id(params[:id].to_i)
|
71
|
+
transaction.to_json
|
72
|
+
else
|
73
|
+
status 404
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# curl -v http://127.0.0.1:9292/plugins/killbill-cybersource/1.0/responses/1
|
78
|
+
get '/plugins/killbill-cybersource/1.0/responses/:id', :provides => 'json' do
|
79
|
+
if transaction = ::Killbill::Cybersource::CybersourceResponse.find_by_id(params[:id].to_i)
|
80
|
+
transaction.to_json
|
81
|
+
else
|
82
|
+
status 404
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Killbill #:nodoc:
|
2
|
+
module Cybersource #:nodoc:
|
3
|
+
class CybersourcePaymentMethod < ::Killbill::Plugin::ActiveMerchant::ActiveRecord::PaymentMethod
|
4
|
+
|
5
|
+
self.table_name = 'cybersource_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::Cybersource::CybersourcePaymentMethod)
|
8
|
+
super(kb_account_id,
|
9
|
+
kb_payment_method_id,
|
10
|
+
kb_tenant_id,
|
11
|
+
cc_or_token,
|
12
|
+
response,
|
13
|
+
options,
|
14
|
+
{
|
15
|
+
# Pass custom key/values here
|
16
|
+
#:params_id => extract(response, 'id'),
|
17
|
+
#:params_card_id => extract(response, 'card', 'id')
|
18
|
+
}.merge!(extra_params),
|
19
|
+
model)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Killbill #:nodoc:
|
2
|
+
module Cybersource #:nodoc:
|
3
|
+
class CybersourceResponse < ::Killbill::Plugin::ActiveMerchant::ActiveRecord::Response
|
4
|
+
|
5
|
+
self.table_name = 'cybersource_responses'
|
6
|
+
|
7
|
+
has_one :cybersource_transaction
|
8
|
+
|
9
|
+
def self.from_response(api_call, kb_account_id, kb_payment_id, kb_payment_transaction_id, transaction_type, kb_tenant_id, response, extra_params = {}, model = ::Killbill::Cybersource::CybersourceResponse)
|
10
|
+
super(api_call,
|
11
|
+
kb_account_id,
|
12
|
+
kb_payment_id,
|
13
|
+
kb_payment_transaction_id,
|
14
|
+
transaction_type,
|
15
|
+
kb_tenant_id,
|
16
|
+
response,
|
17
|
+
{
|
18
|
+
:params_merchant_reference_code => extract(response, 'merchantReferenceCode'),
|
19
|
+
:params_request_id => extract(response, 'requestID'),
|
20
|
+
:params_decision => extract(response, 'decision'),
|
21
|
+
:params_reason_code => extract(response, 'reasonCode'),
|
22
|
+
:params_request_token => extract(response, 'requestToken'),
|
23
|
+
:params_currency => extract(response, 'currency'),
|
24
|
+
:params_amount => extract(response, 'amount'),
|
25
|
+
:params_authorization_code => extract(response, 'authorizationCode'),
|
26
|
+
:params_avs_code => extract(response, 'avsCode'),
|
27
|
+
:params_avs_code_raw => extract(response, 'avsCodeRaw'),
|
28
|
+
:params_cv_code => extract(response, 'cvCode'),
|
29
|
+
:params_authorized_date_time => extract(response, 'authorizedDateTime'),
|
30
|
+
:params_processor_response => extract(response, 'processorResponse'),
|
31
|
+
:params_reconciliation_id => extract(response, 'reconciliationID'),
|
32
|
+
:params_subscription_id => extract(response, 'subscriptionID'),
|
33
|
+
}.merge!(extra_params),
|
34
|
+
model)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
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>cybersource-plugin</artifactId>
|
27
|
+
<packaging>pom</packaging>
|
28
|
+
<version>0.0.1</version>
|
29
|
+
<name>cybersource-plugin</name>
|
30
|
+
<url>http://github.com/killbill/killbill-cybersource-plugin</url>
|
31
|
+
<description>Plugin for accessing Cybersource 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-cybersource-plugin.git</connection>
|
41
|
+
<url>https://github.com/killbill/killbill-cybersource-plugin/</url>
|
42
|
+
<developerConnection>scm:git:git@github.com:killbill/killbill-cybersource-plugin.git</developerConnection>
|
43
|
+
</scm>
|
44
|
+
</project>
|