killbill-cybersource 0.0.4 → 1.0.0

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/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.4
1
+ 1.0.0
data/cybersource.yml CHANGED
@@ -1,13 +1,34 @@
1
1
  :cybersource:
2
- :test: true
3
- :log_file: /var/tmp/cybersource.log
2
+ - :account_id: default
3
+ :test: true
4
+ :login: <%= ENV['LOGIN'] %>
5
+ :password: <%= ENV['PASSWORD'] %>
6
+ - :account_id: on_demand
7
+ :merchantID: <%= ENV['MERCHANT_ID'] %>
8
+ :username: <%= ENV['OD_USERNAME'] %>
9
+ :password: <%= ENV['OD_PASSWORD'] %>
4
10
 
5
11
  :database:
12
+ # SQLite (development)
6
13
  :adapter: sqlite3
7
14
  :database: test.db
8
15
  # For MySQL
9
- # :adapter: 'jdbc'
10
- # :username: 'your-username'
11
- # :password: 'your-password'
12
- # :driver: 'com.mysql.jdbc.Driver'
13
- # :url: 'jdbc:mysql://127.0.0.1:3306/your-database'
16
+ # :adapter: mysql
17
+ # :username: 'killbill'
18
+ # :password: 'killbill'
19
+ # :database: 'killbill' # or set the URL :
20
+ # #:url: jdbc:mysql://127.0.0.1:3306/killbill
21
+ # :driver: org.mariadb.jdbc.Driver # as in KB
22
+ # :pool: 30 # AR's default is max 5 connections
23
+ # In Kill Bill
24
+ # :adapter: mysql
25
+ # :jndi: 'killbill/osgi/jdbc'
26
+ # :pool: false # false-pool (JNDI pool's max)
27
+ # # uncomment if pool does not support JDBC4 :
28
+ # #:connection_alive_sql: 'select 1'
29
+ # # MySQL adapter #configure_connection defaults :
30
+ # # @@SESSION.sql_auto_is_null = 0,
31
+ # # @@SESSION.wait_timeout = 2147483,
32
+ # # @@SESSION.sql_mode = 'STRICT_ALL_TABLES'
33
+ # # ... can be disabled (on AR-JDBC 1.4) using :
34
+ # :configure_connection: false
data/db/ddl.sql CHANGED
@@ -5,10 +5,10 @@ CREATE TABLE `cybersource_payment_methods` (
5
5
  `cc_first_name` varchar(255) DEFAULT NULL,
6
6
  `cc_last_name` varchar(255) DEFAULT NULL,
7
7
  `cc_type` varchar(255) DEFAULT NULL,
8
- `cc_exp_month` int(11) DEFAULT NULL,
9
- `cc_exp_year` int(11) DEFAULT NULL,
10
- `cc_number` int(11) DEFAULT NULL,
11
- `cc_last_4` int(11) 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
12
  `cc_start_month` varchar(255) DEFAULT NULL,
13
13
  `cc_start_year` varchar(255) DEFAULT NULL,
14
14
  `cc_issue_number` varchar(255) DEFAULT NULL,
@@ -37,9 +37,10 @@ CREATE TABLE `cybersource_transactions` (
37
37
  `kb_payment_id` varchar(255) NOT NULL,
38
38
  `kb_payment_transaction_id` varchar(255) NOT NULL,
39
39
  `transaction_type` varchar(255) NOT NULL,
40
- `txn_id` varchar(255),
41
- `amount_in_cents` int(11),
42
- `currency` varchar(255),
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,
43
44
  `created_at` datetime NOT NULL,
44
45
  `updated_at` datetime NOT NULL,
45
46
  `kb_account_id` varchar(255) NOT NULL,
@@ -54,6 +55,7 @@ CREATE TABLE `cybersource_responses` (
54
55
  `kb_payment_id` varchar(255) DEFAULT NULL,
55
56
  `kb_payment_transaction_id` varchar(255) DEFAULT NULL,
56
57
  `transaction_type` varchar(255) DEFAULT NULL,
58
+ `payment_processor_account_id` varchar(255) DEFAULT NULL,
57
59
  `message` varchar(255) DEFAULT NULL,
58
60
  `authorization` varchar(255) DEFAULT NULL,
59
61
  `fraud_review` tinyint(1) DEFAULT NULL,
data/db/schema.rb CHANGED
@@ -7,15 +7,15 @@ ActiveRecord::Schema.define(:version => 20140410153635) do
7
7
  t.string "cc_first_name"
8
8
  t.string "cc_last_name"
9
9
  t.string "cc_type"
10
- t.integer "cc_exp_month"
11
- t.integer "cc_exp_year"
12
- t.integer "cc_number"
13
- t.integer "cc_last_4"
14
- t.integer "cc_start_month"
15
- t.integer "cc_start_year"
16
- t.integer "cc_issue_number"
17
- t.integer "cc_verification_value"
18
- t.integer "cc_track_data"
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
19
  t.string "address1"
20
20
  t.string "address2"
21
21
  t.string "city"
@@ -38,7 +38,9 @@ ActiveRecord::Schema.define(:version => 20140410153635) do
38
38
  t.string "kb_payment_id", :null => false
39
39
  t.string "kb_payment_transaction_id", :null => false
40
40
  t.string "transaction_type", :null => false
41
+ t.string "payment_processor_account_id"
41
42
  t.string "txn_id" # cybersource transaction id
43
+ # Both null for void
42
44
  t.integer "amount_in_cents"
43
45
  t.string "currency"
44
46
  t.datetime "created_at", :null => false
@@ -54,6 +56,7 @@ ActiveRecord::Schema.define(:version => 20140410153635) do
54
56
  t.string "kb_payment_id"
55
57
  t.string "kb_payment_transaction_id"
56
58
  t.string "transaction_type"
59
+ t.string "payment_processor_account_id"
57
60
  t.string "message"
58
61
  t.string "authorization"
59
62
  t.boolean "fraud_review"
@@ -12,36 +12,40 @@ Gem::Specification.new do |s|
12
12
 
13
13
  s.author = 'Kill Bill core team'
14
14
  s.email = 'killbilling-users@googlegroups.com'
15
- s.homepage = 'http://kill-bill.org'
15
+ s.homepage = 'http://killbill.io'
16
16
 
17
17
  s.files = `git ls-files`.split("\n")
18
18
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
19
  s.bindir = 'bin'
20
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
21
21
  s.require_paths = ['lib']
22
22
 
23
23
  s.rdoc_options << '--exclude' << '.'
24
24
 
25
- s.add_dependency 'killbill', '~> 3.1.11'
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'
25
+ s.add_dependency 'killbill', '~> 4.0.0'
26
+
33
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'
34
30
  if defined?(JRUBY_VERSION)
35
- s.add_dependency 'activerecord-jdbcmysql-adapter', '~> 1.3.7'
31
+ s.add_dependency 'activerecord-bogacs', '~> 0.3'
32
+ s.add_dependency 'activerecord-jdbc-adapter', '~> 1.3'
36
33
  # Required to avoid errors like java.lang.NoClassDefFoundError: org/bouncycastle/asn1/DERBoolean
37
- s.add_dependency 'jruby-openssl', '~> 0.9.4'
34
+ s.add_dependency 'jruby-openssl', '~> 0.9.6'
38
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'
39
42
 
40
- s.add_development_dependency 'jbundler', '~> 0.4.1'
43
+ s.add_development_dependency 'jbundler', '~> 0.4.3'
41
44
  s.add_development_dependency 'rake', '>= 10.0.0'
42
45
  s.add_development_dependency 'rspec', '~> 2.12.0'
43
46
  if defined?(JRUBY_VERSION)
44
- s.add_development_dependency 'activerecord-jdbcsqlite3-adapter', '~> 1.3.7'
47
+ s.add_development_dependency 'jdbc-sqlite3', '~> 3.7'
48
+ s.add_development_dependency 'jdbc-mariadb', '~> 1.1'
45
49
  else
46
50
  s.add_development_dependency 'sqlite3', '~> 1.3.7'
47
51
  end
data/lib/cybersource.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'openssl'
1
2
  require 'action_controller'
2
3
  require 'active_record'
3
4
  require 'action_view'
@@ -7,6 +8,7 @@ require 'base64'
7
8
  require 'bigdecimal'
8
9
  require 'money'
9
10
  require 'monetize'
11
+ require 'offsite_payments'
10
12
  require 'pathname'
11
13
  require 'sinatra'
12
14
  require 'singleton'
@@ -14,6 +14,14 @@ module Killbill #:nodoc:
14
14
  ::Killbill::Cybersource::CybersourceResponse)
15
15
  end
16
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
+
17
25
  def start_plugin
18
26
  super
19
27
  gateway = lookup_gateway(:on_demand)
@@ -26,6 +34,8 @@ module Killbill #:nodoc:
26
34
  # Pass extra parameters for the gateway here
27
35
  options = {}
28
36
 
37
+ add_required_options(kb_account_id, properties, options, context)
38
+
29
39
  properties = merge_properties(properties, options)
30
40
  super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
31
41
  end
@@ -34,6 +44,8 @@ module Killbill #:nodoc:
34
44
  # Pass extra parameters for the gateway here
35
45
  options = {}
36
46
 
47
+ add_required_options(kb_account_id, properties, options, context)
48
+
37
49
  properties = merge_properties(properties, options)
38
50
  super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
39
51
  end
@@ -42,6 +54,8 @@ module Killbill #:nodoc:
42
54
  # Pass extra parameters for the gateway here
43
55
  options = {}
44
56
 
57
+ add_required_options(kb_account_id, properties, options, context)
58
+
45
59
  properties = merge_properties(properties, options)
46
60
  super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
47
61
  end
@@ -50,6 +64,8 @@ module Killbill #:nodoc:
50
64
  # Pass extra parameters for the gateway here
51
65
  options = {}
52
66
 
67
+ add_required_options(kb_account_id, properties, options, context)
68
+
53
69
  properties = merge_properties(properties, options)
54
70
  super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, properties, context)
55
71
  end
@@ -58,6 +74,8 @@ module Killbill #:nodoc:
58
74
  # Pass extra parameters for the gateway here
59
75
  options = {}
60
76
 
77
+ add_required_options(kb_account_id, properties, options, context)
78
+
61
79
  properties = merge_properties(properties, options)
62
80
  super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
63
81
  end
@@ -66,6 +84,8 @@ module Killbill #:nodoc:
66
84
  # Pass extra parameters for the gateway here
67
85
  options = {}
68
86
 
87
+ add_required_options(kb_account_id, properties, options, context)
88
+
69
89
  properties = merge_properties(properties, options)
70
90
  super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
71
91
  end
@@ -165,7 +185,7 @@ module Killbill #:nodoc:
165
185
  # Make calls idempotent
166
186
  def before_gateway(gateway, kb_transaction, last_transaction, payment_source, amount_in_cents, currency, options)
167
187
  super
168
- return if @report_api.nil?
188
+ return if @report_api.nil? || options[:skip_gw]
169
189
 
170
190
  merchant_reference_code = options[:order_id]
171
191
  report = @report_api.single_transaction_report(merchant_reference_code, kb_transaction.created_date.strftime('%Y%m%d'))
@@ -181,6 +201,18 @@ module Killbill #:nodoc:
181
201
  rescue => e
182
202
  logger.warn "Error checking for duplicate payment: #{e.message}"
183
203
  end
204
+
205
+ def add_required_options(kb_account_id, properties, options, context)
206
+ if options[:email].nil?
207
+ email = find_value_from_properties(properties, 'email')
208
+ if email.nil?
209
+ # Note: we need to clone the context otherwise it will be transformed back to a Java one here
210
+ kb_account = @kb_apis.account_user_api.get_account_by_id(kb_account_id, @kb_apis.create_context(context.tenant_id))
211
+ email = kb_account.email
212
+ end
213
+ options[:email] = email
214
+ end
215
+ end
184
216
  end
185
217
  end
186
218
  end
@@ -8,21 +8,17 @@ configure do
8
8
  # Usage: rackup -Ilib -E test
9
9
  if development? or test?
10
10
  # Make sure the plugin is initialized
11
- plugin = ::Killbill::Cybersource::PaymentPlugin.new
12
- plugin.logger = Logger.new(STDOUT)
11
+ plugin = ::Killbill::Cybersource::PaymentPlugin.new
12
+ plugin.logger = Logger.new(STDOUT)
13
13
  plugin.logger.level = Logger::INFO
14
- plugin.conf_dir = File.dirname(File.dirname(__FILE__)) + '/..'
14
+ plugin.conf_dir = File.dirname(File.dirname(__FILE__)) + '/..'
15
15
  plugin.start_plugin
16
16
  end
17
17
  end
18
18
 
19
19
  helpers do
20
20
  def plugin(session = {})
21
- ::Killbill::Cybersource::PrivatePaymentPlugin.new(:cybersource,
22
- ::Killbill::Cybersource::CybersourcePaymentMethod,
23
- ::Killbill::Cybersource::CybersourceTransaction,
24
- ::Killbill::Cybersource::CybersourceResponse,
25
- session)
21
+ ::Killbill::Cybersource::PrivatePaymentPlugin.new(session)
26
22
  end
27
23
  end
28
24
 
@@ -6,12 +6,13 @@ module Killbill #:nodoc:
6
6
 
7
7
  has_one :cybersource_transaction
8
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)
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::Cybersource::CybersourceResponse)
10
10
  super(api_call,
11
11
  kb_account_id,
12
12
  kb_payment_id,
13
13
  kb_payment_transaction_id,
14
14
  transaction_type,
15
+ payment_processor_account_id,
15
16
  kb_tenant_id,
16
17
  response,
17
18
  {
@@ -33,6 +34,18 @@ module Killbill #:nodoc:
33
34
  }.merge!(extra_params),
34
35
  model)
35
36
  end
37
+
38
+ def first_reference_id
39
+ params_request_id
40
+ end
41
+
42
+ def second_reference_id
43
+ params_reconciliation_id
44
+ end
45
+
46
+ def gateway_error_code
47
+ params_reason_code
48
+ end
36
49
  end
37
50
  end
38
51
  end
@@ -1,6 +1,13 @@
1
1
  module Killbill #:nodoc:
2
2
  module Cybersource #:nodoc:
3
3
  class PrivatePaymentPlugin < ::Killbill::Plugin::ActiveMerchant::PrivatePaymentPlugin
4
+ def initialize(session = {})
5
+ super(:cybersource,
6
+ ::Killbill::Cybersource::CybersourcePaymentMethod,
7
+ ::Killbill::Cybersource::CybersourceTransaction,
8
+ ::Killbill::Cybersource::CybersourceResponse,
9
+ session)
10
+ end
4
11
  end
5
12
  end
6
13
  end
data/pom.xml CHANGED
@@ -1,6 +1,6 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <!--
3
- ~ Copyright 2014 The Billing Project, LLC
3
+ ~ Copyright 2014-2015 The Billing Project, LLC
4
4
  ~
5
5
  ~ The Billing Project licenses this file to you under the Apache License, version 2.0
6
6
  ~ (the "License"); you may not use this file except in compliance with the
@@ -25,7 +25,7 @@
25
25
  <groupId>org.kill-bill.billing.plugin.ruby</groupId>
26
26
  <artifactId>cybersource-plugin</artifactId>
27
27
  <packaging>pom</packaging>
28
- <version>0.0.4</version>
28
+ <version>1.0.0</version>
29
29
  <name>cybersource-plugin</name>
30
30
  <url>http://github.com/killbill/killbill-cybersource-plugin</url>
31
31
  <description>Plugin for accessing Cybersource as a payment gateway</description>
data/release.sh CHANGED
@@ -1,5 +1,8 @@
1
1
  set -e
2
2
 
3
+ BUNDLE=${BUNDLE-"bundle exec"}
4
+ MVN=${MVN-"mvn"}
5
+
3
6
  if [ 'GNU' != "$(tar --help | grep GNU | head -1 | awk '{print $1}')" ]; then
4
7
  echo 'Unable to release: make sure to use GNU tar'
5
8
  exit 1
@@ -14,28 +17,45 @@ else
14
17
  fi
15
18
 
16
19
  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
20
+ if [[ -z "$NO_RELEASE" && "$VERSION" != "$(cat $PWD/VERSION)" ]]; then
18
21
  echo 'Unable to release: make sure the versions in pom.xml and VERSION match'
19
22
  exit 1
20
23
  fi
21
24
 
22
25
  echo 'Cleaning up'
23
- rake killbill:clean ; rake build
26
+ $BUNDLE rake killbill:clean
27
+
28
+ echo 'Building gem'
29
+ $BUNDLE rake build
24
30
 
25
- echo 'Pushing the gem to Rubygems'
26
- rake release
31
+ if [[ -z "$NO_RELEASE" ]]; then
32
+ echo 'Pushing the gem to Rubygems'
33
+ $BUNDLE rake release
34
+ fi
27
35
 
28
36
  echo 'Building artifact'
29
- rake killbill:package
37
+ $BUNDLE rake killbill:package
30
38
 
31
39
  ARTIFACT="$PWD/pkg/killbill-cybersource-$VERSION.tar.gz"
32
40
  echo "Pushing $ARTIFACT to Maven Central"
33
- mvn gpg:sign-and-deploy-file \
34
- -DgroupId=org.kill-bill.billing.plugin.ruby \
35
- -DartifactId=cybersource-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
41
+
42
+ if [[ -z "$NO_RELEASE" ]]; then
43
+ GOAL=gpg:sign-and-deploy-file
44
+ REPOSITORY_ID=ossrh-releases
45
+ URL=https://oss.sonatype.org/service/local/staging/deploy/maven2/
46
+ else
47
+ GOAL=deploy:deploy-file
48
+ REPOSITORY_ID=sonatype-nexus-snapshots
49
+ URL=https://oss.sonatype.org/content/repositories/snapshots/
50
+ VERSION="$VERSION-SNAPSHOT"
51
+ fi
52
+
53
+ $MVN $GOAL \
54
+ -DgroupId=org.kill-bill.billing.plugin.ruby \
55
+ -DartifactId=cybersource-plugin \
56
+ -Dversion=$VERSION \
57
+ -Dpackaging=tar.gz \
58
+ -DrepositoryId=$REPOSITORY_ID \
59
+ -Durl=$URL \
60
+ -Dfile=$ARTIFACT \
61
+ -DpomFile=pom.xml