killbill-cybersource 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 +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>
|