killbill 3.0.0 → 3.1.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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Jarfile +5 -5
- data/NEWS +4 -0
- data/README.md +45 -8
- data/VERSION +1 -1
- data/generators/active_merchant/active_merchant_generator.rb +38 -0
- data/generators/active_merchant/templates/.gitignore.rb +36 -0
- data/generators/active_merchant/templates/.travis.yml.rb +19 -0
- data/generators/active_merchant/templates/Gemfile.rb +3 -0
- data/generators/active_merchant/templates/Jarfile.rb +6 -0
- data/generators/active_merchant/templates/LICENSE.rb +201 -0
- data/generators/active_merchant/templates/NEWS.rb +2 -0
- data/generators/active_merchant/templates/Rakefile.rb +30 -0
- data/generators/active_merchant/templates/VERSION.rb +1 -0
- data/generators/active_merchant/templates/config.ru.rb +4 -0
- data/generators/active_merchant/templates/config.yml.rb +13 -0
- data/generators/active_merchant/templates/db/ddl.sql.rb +64 -0
- data/generators/active_merchant/templates/db/schema.rb +64 -0
- data/generators/active_merchant/templates/killbill.properties.rb +3 -0
- data/generators/active_merchant/templates/lib/api.rb +119 -0
- data/generators/active_merchant/templates/lib/application.rb +84 -0
- data/generators/active_merchant/templates/lib/models/payment_method.rb +22 -0
- data/generators/active_merchant/templates/lib/models/response.rb +22 -0
- data/generators/active_merchant/templates/lib/models/transaction.rb +11 -0
- data/generators/active_merchant/templates/lib/plugin.rb +23 -0
- data/generators/active_merchant/templates/lib/private_api.rb +6 -0
- data/generators/active_merchant/templates/lib/views/form.erb +8 -0
- data/generators/active_merchant/templates/plugin.gemspec.rb +48 -0
- data/generators/active_merchant/templates/pom.xml.rb +44 -0
- data/generators/active_merchant/templates/release.sh.rb +41 -0
- data/generators/active_merchant/templates/spec/base_plugin_spec.rb +30 -0
- data/generators/active_merchant/templates/spec/integration_spec.rb +31 -0
- data/generators/active_merchant/templates/spec/spec_helper.rb +24 -0
- data/generators/killbill_generator.rb +38 -0
- data/killbill.gemspec +10 -2
- data/lib/killbill/gen/api/block.rb +82 -0
- data/lib/killbill/gen/api/direct_payment.rb +176 -0
- data/lib/killbill/gen/api/direct_payment_api.rb +329 -0
- data/lib/killbill/gen/api/direct_payment_transaction.rb +156 -0
- data/lib/killbill/gen/api/fixed.rb +63 -0
- data/lib/killbill/gen/api/invoice_item.rb +7 -1
- data/lib/killbill/gen/api/invoice_item_formatter.rb +7 -1
- data/lib/killbill/gen/api/invoice_user_api.rb +18 -136
- data/lib/killbill/gen/api/migration_plan.rb +6 -6
- data/lib/killbill/gen/api/payment_api.rb +216 -54
- data/lib/killbill/gen/api/payment_method_plugin.rb +3 -3
- data/lib/killbill/gen/api/plan.rb +6 -6
- data/lib/killbill/gen/api/plan_phase.rb +16 -23
- data/lib/killbill/gen/api/plugin_property.rb +71 -0
- data/lib/killbill/gen/api/recurring.rb +63 -0
- data/lib/killbill/gen/api/require_gen.rb +10 -1
- data/lib/killbill/gen/api/static_catalog.rb +8 -1
- data/lib/killbill/gen/api/tier.rb +77 -0
- data/lib/killbill/gen/api/tiered_block.rb +88 -0
- data/lib/killbill/gen/api/usage.rb +111 -0
- data/lib/killbill/gen/api/usage_user_api.rb +59 -3
- data/lib/killbill/gen/plugin-api/billing_address.rb +85 -0
- data/lib/killbill/gen/plugin-api/customer.rb +73 -0
- data/lib/killbill/gen/plugin-api/hosted_payment_page_descriptor_fields.rb +145 -0
- data/lib/killbill/gen/plugin-api/hosted_payment_page_form_descriptor.rb +80 -0
- data/lib/killbill/gen/plugin-api/hosted_payment_page_notification.rb +129 -0
- data/lib/killbill/gen/plugin-api/payment_info_plugin.rb +20 -1
- data/lib/killbill/gen/plugin-api/payment_plugin_api.rb +358 -39
- data/lib/killbill/gen/plugin-api/refund_info_plugin.rb +20 -1
- data/lib/killbill/gen/plugin-api/require_gen.rb +3 -0
- data/lib/killbill/helpers/active_merchant.rb +21 -0
- data/lib/killbill/helpers/active_merchant/active_record.rb +17 -0
- data/lib/killbill/helpers/active_merchant/active_record/models/helpers.rb +25 -0
- data/lib/killbill/helpers/active_merchant/active_record/models/payment_method.rb +195 -0
- data/lib/killbill/helpers/active_merchant/active_record/models/response.rb +178 -0
- data/lib/killbill/helpers/active_merchant/active_record/models/streamy_result_set.rb +35 -0
- data/lib/killbill/helpers/active_merchant/active_record/models/transaction.rb +63 -0
- data/lib/killbill/helpers/active_merchant/configuration.rb +54 -0
- data/lib/killbill/helpers/active_merchant/core_ext.rb +41 -0
- data/lib/killbill/helpers/active_merchant/gateway.rb +35 -0
- data/lib/killbill/helpers/active_merchant/killbill_spec_helper.rb +117 -0
- data/lib/killbill/helpers/active_merchant/payment_plugin.rb +365 -0
- data/lib/killbill/helpers/active_merchant/private_payment_plugin.rb +119 -0
- data/lib/killbill/helpers/active_merchant/properties.rb +20 -0
- data/lib/killbill/helpers/active_merchant/sinatra.rb +30 -0
- data/lib/killbill/helpers/active_merchant/utils.rb +23 -0
- data/lib/killbill/payment.rb +22 -10
- data/script/generate +15 -0
- data/spec/killbill/helpers/payment_method_spec.rb +101 -0
- data/spec/killbill/helpers/response_spec.rb +74 -0
- data/spec/killbill/helpers/test_schema.rb +57 -0
- data/spec/killbill/helpers/utils_spec.rb +22 -0
- data/spec/killbill/payment_plugin_api_spec.rb +23 -18
- data/spec/killbill/payment_plugin_spec.rb +11 -10
- data/spec/killbill/payment_test.rb +9 -9
- data/spec/spec_helper.rb +8 -3
- metadata +130 -5
|
@@ -32,7 +32,7 @@ module Killbill
|
|
|
32
32
|
|
|
33
33
|
include org.killbill.billing.payment.plugin.api.RefundInfoPlugin
|
|
34
34
|
|
|
35
|
-
attr_accessor :kb_payment_id, :amount, :currency, :created_date, :effective_date, :status, :gateway_error, :gateway_error_code, :first_refund_reference_id, :second_refund_reference_id
|
|
35
|
+
attr_accessor :kb_payment_id, :amount, :currency, :created_date, :effective_date, :status, :gateway_error, :gateway_error_code, :first_refund_reference_id, :second_refund_reference_id, :properties
|
|
36
36
|
|
|
37
37
|
def initialize()
|
|
38
38
|
end
|
|
@@ -77,6 +77,15 @@ module Killbill
|
|
|
77
77
|
|
|
78
78
|
# conversion for second_refund_reference_id [type = java.lang.String]
|
|
79
79
|
@second_refund_reference_id = @second_refund_reference_id.to_s unless @second_refund_reference_id.nil?
|
|
80
|
+
|
|
81
|
+
# conversion for properties [type = java.util.List]
|
|
82
|
+
tmp = java.util.ArrayList.new
|
|
83
|
+
(@properties || []).each do |m|
|
|
84
|
+
# conversion for m [type = org.killbill.billing.payment.api.PluginProperty]
|
|
85
|
+
m = m.to_java unless m.nil?
|
|
86
|
+
tmp.add(m)
|
|
87
|
+
end
|
|
88
|
+
@properties = tmp
|
|
80
89
|
self
|
|
81
90
|
end
|
|
82
91
|
|
|
@@ -124,6 +133,16 @@ module Killbill
|
|
|
124
133
|
|
|
125
134
|
# conversion for second_refund_reference_id [type = java.lang.String]
|
|
126
135
|
@second_refund_reference_id = j_obj.second_refund_reference_id
|
|
136
|
+
|
|
137
|
+
# conversion for properties [type = java.util.List]
|
|
138
|
+
@properties = j_obj.properties
|
|
139
|
+
tmp = []
|
|
140
|
+
(@properties || []).each do |m|
|
|
141
|
+
# conversion for m [type = org.killbill.billing.payment.api.PluginProperty]
|
|
142
|
+
m = Killbill::Plugin::Model::PluginProperty.new.to_ruby(m) unless m.nil?
|
|
143
|
+
tmp << m
|
|
144
|
+
end
|
|
145
|
+
@properties = tmp
|
|
127
146
|
self
|
|
128
147
|
end
|
|
129
148
|
|
|
@@ -23,6 +23,9 @@
|
|
|
23
23
|
#
|
|
24
24
|
|
|
25
25
|
|
|
26
|
+
require 'killbill/gen/plugin-api/hosted_payment_page_descriptor_fields'
|
|
27
|
+
require 'killbill/gen/plugin-api/hosted_payment_page_form_descriptor'
|
|
28
|
+
require 'killbill/gen/plugin-api/hosted_payment_page_notification'
|
|
26
29
|
require 'killbill/gen/plugin-api/payment_method_info_plugin'
|
|
27
30
|
require 'killbill/gen/plugin-api/payment_plugin_api'
|
|
28
31
|
require 'killbill/gen/plugin-api/payment_plugin_api_exception'
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Killbill
|
|
2
|
+
module Plugin
|
|
3
|
+
module ActiveMerchant
|
|
4
|
+
require 'killbill'
|
|
5
|
+
|
|
6
|
+
require 'active_support/core_ext'
|
|
7
|
+
require File.dirname(__FILE__) + '/active_merchant/core_ext.rb'
|
|
8
|
+
require File.dirname(__FILE__) + '/active_merchant/configuration.rb'
|
|
9
|
+
|
|
10
|
+
Dir[File.dirname(__FILE__) + '/active_merchant/*.rb'].each do |f|
|
|
11
|
+
# Get camelized class name
|
|
12
|
+
filename = File.basename(f, '.rb')
|
|
13
|
+
# Camelize the string to get the class name
|
|
14
|
+
class_name = filename.camelize.to_sym
|
|
15
|
+
|
|
16
|
+
# Register for autoloading
|
|
17
|
+
autoload class_name, f
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Killbill
|
|
2
|
+
module Plugin
|
|
3
|
+
module ActiveMerchant
|
|
4
|
+
module ActiveRecord
|
|
5
|
+
Dir[File.dirname(__FILE__) + '/active_record/models/*.rb'].each do |f|
|
|
6
|
+
# Get camelized class name
|
|
7
|
+
filename = File.basename(f, '.rb')
|
|
8
|
+
# Camelize the string to get the class name
|
|
9
|
+
class_name = filename.camelize.to_sym
|
|
10
|
+
|
|
11
|
+
# Register for autoloading
|
|
12
|
+
autoload class_name, f
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Killbill
|
|
2
|
+
module Plugin
|
|
3
|
+
module ActiveMerchant
|
|
4
|
+
module Helpers
|
|
5
|
+
|
|
6
|
+
# Useful helper to extract params from AM response objects, e.g. extract(response, 'card', 'address_country')
|
|
7
|
+
def extract(response, key1, key2=nil, key3=nil)
|
|
8
|
+
return nil if response.nil? || response.params.nil?
|
|
9
|
+
level1 = response.params[key1]
|
|
10
|
+
|
|
11
|
+
if level1.nil? or (key2.nil? and key3.nil?)
|
|
12
|
+
return level1
|
|
13
|
+
end
|
|
14
|
+
level2 = level1[key2]
|
|
15
|
+
|
|
16
|
+
if level2.nil? or key3.nil?
|
|
17
|
+
return level2
|
|
18
|
+
else
|
|
19
|
+
return level2[key3]
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
module Killbill
|
|
2
|
+
module Plugin
|
|
3
|
+
module ActiveMerchant
|
|
4
|
+
module ActiveRecord
|
|
5
|
+
require 'active_record'
|
|
6
|
+
require 'killbill/helpers/active_merchant/active_record/models/helpers'
|
|
7
|
+
|
|
8
|
+
class PaymentMethod < ::ActiveRecord::Base
|
|
9
|
+
|
|
10
|
+
extend ::Killbill::Plugin::ActiveMerchant::Helpers
|
|
11
|
+
|
|
12
|
+
self.abstract_class = true
|
|
13
|
+
|
|
14
|
+
def self.from_response(kb_account_id, kb_payment_method_id, cc_or_token, response, options, extra_params = {}, model = PaymentMethod)
|
|
15
|
+
model.new({
|
|
16
|
+
:kb_account_id => kb_account_id,
|
|
17
|
+
:kb_payment_method_id => kb_payment_method_id,
|
|
18
|
+
:token => response.authorization,
|
|
19
|
+
:cc_first_name => cc_or_token.kind_of?(::ActiveMerchant::Billing::CreditCard) ? cc_or_token.first_name : nil,
|
|
20
|
+
:cc_last_name => cc_or_token.kind_of?(::ActiveMerchant::Billing::CreditCard) ? cc_or_token.last_name : nil,
|
|
21
|
+
:cc_type => cc_or_token.kind_of?(::ActiveMerchant::Billing::CreditCard) ? cc_or_token.brand : nil,
|
|
22
|
+
:cc_exp_month => cc_or_token.kind_of?(::ActiveMerchant::Billing::CreditCard) ? cc_or_token.month : nil,
|
|
23
|
+
:cc_exp_year => cc_or_token.kind_of?(::ActiveMerchant::Billing::CreditCard) ? cc_or_token.year : nil,
|
|
24
|
+
:cc_last_4 => cc_or_token.kind_of?(::ActiveMerchant::Billing::CreditCard) ? cc_or_token.last_digits : nil,
|
|
25
|
+
:address1 => (options[:billing_address] || {})[:address1],
|
|
26
|
+
:address2 => (options[:billing_address] || {})[:address2],
|
|
27
|
+
:city => (options[:billing_address] || {})[:city],
|
|
28
|
+
:state => (options[:billing_address] || {})[:state],
|
|
29
|
+
:zip => (options[:billing_address] || {})[:zip],
|
|
30
|
+
:country => (options[:billing_address] || {})[:country]
|
|
31
|
+
}.merge!(extra_params))
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.from_kb_account_id(kb_account_id)
|
|
35
|
+
where('kb_account_id = ? AND is_deleted = ?', kb_account_id, false)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.from_kb_payment_method_id(kb_payment_method_id)
|
|
39
|
+
payment_methods = where('kb_payment_method_id = ? AND is_deleted = ?', kb_payment_method_id, false)
|
|
40
|
+
raise "No payment method found for payment method #{kb_payment_method_id}" if payment_methods.empty?
|
|
41
|
+
raise "Kill Bill payment method #{kb_payment_method_id} mapping to multiple active plugin payment methods" if payment_methods.size > 1
|
|
42
|
+
payment_methods[0]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def self.mark_as_deleted!(kb_payment_method_id)
|
|
46
|
+
payment_method = from_kb_payment_method_id(kb_payment_method_id)
|
|
47
|
+
payment_method.is_deleted = true
|
|
48
|
+
payment_method.save!
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Override in your plugin if needed
|
|
52
|
+
def self.search_where_clause(t, search_key)
|
|
53
|
+
where_clause = t[:kb_account_id].eq(search_key)
|
|
54
|
+
.or(t[:kb_payment_method_id].eq(search_key))
|
|
55
|
+
.or(t[:token].eq(search_key))
|
|
56
|
+
.or(t[:cc_type].eq(search_key))
|
|
57
|
+
.or(t[:state].eq(search_key))
|
|
58
|
+
.or(t[:zip].eq(search_key))
|
|
59
|
+
.or(t[:cc_first_name].matches("%#{search_key}%"))
|
|
60
|
+
.or(t[:cc_last_name].matches("%#{search_key}%"))
|
|
61
|
+
.or(t[:address1].matches("%#{search_key}%"))
|
|
62
|
+
.or(t[:address2].matches("%#{search_key}%"))
|
|
63
|
+
.or(t[:city].matches("%#{search_key}%"))
|
|
64
|
+
.or(t[:country].matches("%#{search_key}%"))
|
|
65
|
+
|
|
66
|
+
# Coming from Kill Bill, search_key will always be a String. Check to see if it represents a numeric for numeric-only fields
|
|
67
|
+
if search_key.is_a?(Numeric) or search_key.to_s =~ /\A[-+]?[0-9]*\.?[0-9]+\Z/
|
|
68
|
+
where_clause = where_clause.or(t[:cc_exp_month].eq(search_key))
|
|
69
|
+
.or(t[:cc_exp_year].eq(search_key))
|
|
70
|
+
.or(t[:cc_last_4].eq(search_key))
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
where_clause
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# VisibleForTesting
|
|
77
|
+
def self.search_query(search_key, offset = nil, limit = nil)
|
|
78
|
+
t = self.arel_table
|
|
79
|
+
|
|
80
|
+
query = t.where(search_where_clause(t, search_key))
|
|
81
|
+
.order(t[:id])
|
|
82
|
+
|
|
83
|
+
if offset.blank? and limit.blank?
|
|
84
|
+
# true is for count distinct
|
|
85
|
+
query.project(t[:id].count(true))
|
|
86
|
+
else
|
|
87
|
+
query.skip(offset) unless offset.blank?
|
|
88
|
+
query.take(limit) unless limit.blank?
|
|
89
|
+
query.project(t[Arel.star])
|
|
90
|
+
# Not chainable
|
|
91
|
+
query.distinct
|
|
92
|
+
end
|
|
93
|
+
query
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def self.search(search_key, offset = 0, limit = 100)
|
|
97
|
+
pagination = Killbill::Plugin::Model::Pagination.new
|
|
98
|
+
pagination.current_offset = offset
|
|
99
|
+
pagination.total_nb_records = self.count_by_sql(self.search_query(search_key))
|
|
100
|
+
pagination.max_nb_records = self.count
|
|
101
|
+
pagination.next_offset = (!pagination.total_nb_records.nil? && offset + limit >= pagination.total_nb_records) ? nil : offset + limit
|
|
102
|
+
# Reduce the limit if the specified value is larger than the number of records
|
|
103
|
+
actual_limit = [pagination.max_nb_records, limit].min
|
|
104
|
+
pagination.iterator = StreamyResultSet.new(actual_limit) do |offset,limit|
|
|
105
|
+
self.find_by_sql(self.search_query(search_key, offset, limit))
|
|
106
|
+
.map(&:to_payment_method_response)
|
|
107
|
+
end
|
|
108
|
+
pagination
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Override in your plugin if needed
|
|
112
|
+
def external_payment_method_id
|
|
113
|
+
token
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Override in your plugin if needed
|
|
117
|
+
def is_default
|
|
118
|
+
false
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def to_payment_method_response
|
|
122
|
+
properties = []
|
|
123
|
+
properties << create_pm_kv_info('token', external_payment_method_id)
|
|
124
|
+
properties << create_pm_kv_info('ccName', cc_name)
|
|
125
|
+
properties << create_pm_kv_info('ccType', cc_type)
|
|
126
|
+
properties << create_pm_kv_info('ccExpirationMonth', cc_exp_month)
|
|
127
|
+
properties << create_pm_kv_info('ccExpirationYear', cc_exp_year)
|
|
128
|
+
properties << create_pm_kv_info('ccLast4', cc_last_4)
|
|
129
|
+
properties << create_pm_kv_info('address1', address1)
|
|
130
|
+
properties << create_pm_kv_info('address2', address2)
|
|
131
|
+
properties << create_pm_kv_info('city', city)
|
|
132
|
+
properties << create_pm_kv_info('state', state)
|
|
133
|
+
properties << create_pm_kv_info('zip', zip)
|
|
134
|
+
properties << create_pm_kv_info('country', country)
|
|
135
|
+
|
|
136
|
+
pm_plugin = Killbill::Plugin::Model::PaymentMethodPlugin.new
|
|
137
|
+
pm_plugin.kb_payment_method_id = kb_payment_method_id
|
|
138
|
+
pm_plugin.external_payment_method_id = external_payment_method_id
|
|
139
|
+
pm_plugin.is_default_payment_method = is_default
|
|
140
|
+
pm_plugin.properties = properties
|
|
141
|
+
pm_plugin.type = 'CreditCard'
|
|
142
|
+
pm_plugin.cc_name = cc_name
|
|
143
|
+
pm_plugin.cc_type = cc_type
|
|
144
|
+
pm_plugin.cc_expiration_month = cc_exp_month
|
|
145
|
+
pm_plugin.cc_expiration_year = cc_exp_year
|
|
146
|
+
pm_plugin.cc_last4 = cc_last_4
|
|
147
|
+
pm_plugin.address1 = address1
|
|
148
|
+
pm_plugin.address2 = address2
|
|
149
|
+
pm_plugin.city = city
|
|
150
|
+
pm_plugin.state = state
|
|
151
|
+
pm_plugin.zip = zip
|
|
152
|
+
pm_plugin.country = country
|
|
153
|
+
|
|
154
|
+
pm_plugin
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def to_payment_method_info_response
|
|
158
|
+
pm_info_plugin = Killbill::Plugin::Model::PaymentMethodInfoPlugin.new
|
|
159
|
+
pm_info_plugin.account_id = kb_account_id
|
|
160
|
+
pm_info_plugin.payment_method_id = kb_payment_method_id
|
|
161
|
+
pm_info_plugin.is_default = is_default
|
|
162
|
+
pm_info_plugin.external_payment_method_id = external_payment_method_id
|
|
163
|
+
pm_info_plugin
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def cc_name
|
|
167
|
+
if cc_first_name and cc_last_name
|
|
168
|
+
"#{cc_first_name} #{cc_last_name}"
|
|
169
|
+
elsif cc_first_name
|
|
170
|
+
cc_first_name
|
|
171
|
+
elsif cc_last_name
|
|
172
|
+
cc_last_name
|
|
173
|
+
else
|
|
174
|
+
nil
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
private
|
|
179
|
+
|
|
180
|
+
# Deprecated
|
|
181
|
+
def create_pm_kv_info(key, value)
|
|
182
|
+
create_plugin_property(key, value)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def create_plugin_property(key, value)
|
|
186
|
+
prop = Killbill::Plugin::Model::PluginProperty.new
|
|
187
|
+
prop.key = key
|
|
188
|
+
prop.value = value
|
|
189
|
+
prop
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
end
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
module Killbill
|
|
2
|
+
module Plugin
|
|
3
|
+
module ActiveMerchant
|
|
4
|
+
module ActiveRecord
|
|
5
|
+
require 'active_record'
|
|
6
|
+
require 'active_merchant'
|
|
7
|
+
require 'money'
|
|
8
|
+
require 'killbill/helpers/active_merchant/active_record/models/helpers'
|
|
9
|
+
|
|
10
|
+
class Response < ::ActiveRecord::Base
|
|
11
|
+
|
|
12
|
+
extend ::Killbill::Plugin::ActiveMerchant::Helpers
|
|
13
|
+
|
|
14
|
+
self.abstract_class = true
|
|
15
|
+
|
|
16
|
+
def self.from_response(api_call, kb_payment_id, response, extra_params = {}, model = Response)
|
|
17
|
+
model.new({
|
|
18
|
+
:api_call => api_call,
|
|
19
|
+
:kb_payment_id => kb_payment_id,
|
|
20
|
+
:message => response.message,
|
|
21
|
+
:authorization => response.authorization,
|
|
22
|
+
:fraud_review => response.fraud_review?,
|
|
23
|
+
:test => response.test?,
|
|
24
|
+
:avs_result_code => response.avs_result.kind_of?(::ActiveMerchant::Billing::AVSResult) ? response.avs_result.code : response.avs_result['code'],
|
|
25
|
+
:avs_result_message => response.avs_result.kind_of?(::ActiveMerchant::Billing::AVSResult) ? response.avs_result.message : response.avs_result['message'],
|
|
26
|
+
:avs_result_street_match => response.avs_result.kind_of?(::ActiveMerchant::Billing::AVSResult) ? response.avs_result.street_match : response.avs_result['street_match'],
|
|
27
|
+
:avs_result_postal_match => response.avs_result.kind_of?(::ActiveMerchant::Billing::AVSResult) ? response.avs_result.postal_match : response.avs_result['postal_match'],
|
|
28
|
+
:cvv_result_code => response.cvv_result.kind_of?(::ActiveMerchant::Billing::CVVResult) ? response.cvv_result.code : response.cvv_result['code'],
|
|
29
|
+
:cvv_result_message => response.cvv_result.kind_of?(::ActiveMerchant::Billing::CVVResult) ? response.cvv_result.message : response.cvv_result['message'],
|
|
30
|
+
:success => response.success?
|
|
31
|
+
}.merge!(extra_params))
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def to_payment_response(transaction=nil)
|
|
35
|
+
to_killbill_response :payment, transaction
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def to_refund_response(transaction=nil)
|
|
39
|
+
to_killbill_response :refund, transaction
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Override in your plugin if needed
|
|
43
|
+
def self.search_where_clause(t, search_key, api_call)
|
|
44
|
+
# Exact matches only
|
|
45
|
+
where_clause = t[:kb_payment_id].eq(search_key)
|
|
46
|
+
.or(t[:message].eq(search_key))
|
|
47
|
+
.or(t[:authorization].eq(search_key))
|
|
48
|
+
.or(t[:fraud_review].eq(search_key))
|
|
49
|
+
|
|
50
|
+
# Only search successful payments and refunds
|
|
51
|
+
where_clause = where_clause.and(t[:api_call].eq(api_call))
|
|
52
|
+
.and(t[:success].eq(true))
|
|
53
|
+
|
|
54
|
+
where_clause
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# VisibleForTesting
|
|
58
|
+
def self.search_query(api_call, search_key, offset = nil, limit = nil)
|
|
59
|
+
t = self.arel_table
|
|
60
|
+
|
|
61
|
+
query = t.where(search_where_clause(t, search_key, api_call))
|
|
62
|
+
.order(t[:id])
|
|
63
|
+
|
|
64
|
+
if offset.blank? and limit.blank?
|
|
65
|
+
# true is for count distinct
|
|
66
|
+
query.project(t[:id].count(true))
|
|
67
|
+
else
|
|
68
|
+
query.skip(offset) unless offset.blank?
|
|
69
|
+
query.take(limit) unless limit.blank?
|
|
70
|
+
query.project(t[Arel.star])
|
|
71
|
+
# Not chainable
|
|
72
|
+
query.distinct
|
|
73
|
+
end
|
|
74
|
+
query
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def self.search(search_key, offset = 0, limit = 100, type = :payment)
|
|
78
|
+
api_call = type == :payment ? 'charge' : 'refund'
|
|
79
|
+
pagination = ::Killbill::Plugin::Model::Pagination.new
|
|
80
|
+
pagination.current_offset = offset
|
|
81
|
+
pagination.total_nb_records = self.count_by_sql(self.search_query(api_call, search_key))
|
|
82
|
+
pagination.max_nb_records = self.where(:api_call => api_call, :success => true).count
|
|
83
|
+
pagination.next_offset = (!pagination.total_nb_records.nil? && offset + limit >= pagination.total_nb_records) ? nil : offset + limit
|
|
84
|
+
# Reduce the limit if the specified value is larger than the number of records
|
|
85
|
+
actual_limit = [pagination.max_nb_records, limit].min
|
|
86
|
+
pagination.iterator = ::Killbill::Plugin::ActiveMerchant::ActiveRecord::StreamyResultSet.new(actual_limit) do |offset, limit|
|
|
87
|
+
self.find_by_sql(self.search_query(api_call, search_key, offset, limit))
|
|
88
|
+
.map { |x| type == :payment ? x.to_payment_response : x.to_refund_response }
|
|
89
|
+
end
|
|
90
|
+
pagination
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Override in your plugin if needed
|
|
94
|
+
def txn_id
|
|
95
|
+
authorization
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Override in your plugin if needed
|
|
99
|
+
def first_payment_reference_id
|
|
100
|
+
nil
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Override in your plugin if needed
|
|
104
|
+
def second_payment_reference_id
|
|
105
|
+
nil
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Override in your plugin if needed
|
|
109
|
+
def first_reference_id
|
|
110
|
+
nil
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Override in your plugin if needed
|
|
114
|
+
def second_reference_id
|
|
115
|
+
nil
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Override in your plugin if needed
|
|
119
|
+
def effective_date
|
|
120
|
+
created_at
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Override in your plugin if needed
|
|
124
|
+
def gateway_error
|
|
125
|
+
message
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Override in your plugin if needed
|
|
129
|
+
def gateway_error_code
|
|
130
|
+
nil
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
private
|
|
134
|
+
|
|
135
|
+
def to_killbill_response(type, transaction)
|
|
136
|
+
if transaction.nil?
|
|
137
|
+
amount_in_cents = nil
|
|
138
|
+
currency = nil
|
|
139
|
+
created_date = created_at
|
|
140
|
+
else
|
|
141
|
+
amount_in_cents = transaction.amount_in_cents
|
|
142
|
+
currency = transaction.currency
|
|
143
|
+
created_date = transaction.created_at
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
if type == :payment
|
|
147
|
+
p_info_plugin = Killbill::Plugin::Model::PaymentInfoPlugin.new
|
|
148
|
+
p_info_plugin.kb_payment_id = kb_payment_id
|
|
149
|
+
p_info_plugin.amount = Money.new(amount_in_cents, currency).to_d if currency
|
|
150
|
+
p_info_plugin.currency = currency
|
|
151
|
+
p_info_plugin.created_date = created_date
|
|
152
|
+
p_info_plugin.effective_date = effective_date
|
|
153
|
+
p_info_plugin.status = (success ? :PROCESSED : :ERROR)
|
|
154
|
+
p_info_plugin.gateway_error = gateway_error
|
|
155
|
+
p_info_plugin.gateway_error_code = gateway_error_code
|
|
156
|
+
p_info_plugin.first_payment_reference_id = first_reference_id
|
|
157
|
+
p_info_plugin.second_payment_reference_id = second_reference_id
|
|
158
|
+
p_info_plugin
|
|
159
|
+
else
|
|
160
|
+
r_info_plugin = Killbill::Plugin::Model::RefundInfoPlugin.new
|
|
161
|
+
r_info_plugin.kb_payment_id = kb_payment_id
|
|
162
|
+
r_info_plugin.amount = Money.new(amount_in_cents, currency).to_d if currency
|
|
163
|
+
r_info_plugin.currency = currency
|
|
164
|
+
r_info_plugin.created_date = created_date
|
|
165
|
+
r_info_plugin.effective_date = effective_date
|
|
166
|
+
r_info_plugin.status = (success ? :PROCESSED : :ERROR)
|
|
167
|
+
r_info_plugin.gateway_error = gateway_error
|
|
168
|
+
r_info_plugin.gateway_error_code = gateway_error_code
|
|
169
|
+
r_info_plugin.first_refund_reference_id = first_reference_id
|
|
170
|
+
r_info_plugin.second_refund_reference_id = second_reference_id
|
|
171
|
+
r_info_plugin
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|