killbill-litle 1.10.0 → 2.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.
- checksums.yaml +4 -4
- data/.gitignore +4 -5
- data/.travis.yml +22 -3
- data/Gemfile +1 -1
- data/Gemfile.head +5 -0
- data/Gemfile.lock +129 -0
- data/Jarfile +9 -6
- data/Jarfile.lock +58 -0
- data/LICENSE +201 -0
- data/NEWS +3 -0
- data/README.md +58 -98
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/config.ru +1 -1
- data/db/ddl.sql +32 -21
- data/db/schema.rb +44 -32
- data/killbill-litle.gemspec +20 -16
- data/lib/litle.rb +82 -12
- data/lib/litle/api.rb +144 -204
- data/lib/litle/application.rb +96 -0
- data/lib/litle/models/payment_method.rb +21 -0
- data/lib/litle/models/response.rb +44 -0
- data/lib/litle/models/transaction.rb +11 -0
- data/lib/litle/private_api.rb +42 -13
- data/lib/litle/views/paypage.erb +8 -5
- data/litle.yml +33 -11
- data/pom.xml +3 -2
- data/release.sh +41 -21
- data/spec/litle/base_plugin_spec.rb +35 -62
- data/spec/litle/remote/certification_spec.rb +713 -0
- data/spec/litle/remote/integration_spec.rb +97 -168
- data/spec/spec_helper.rb +3 -16
- metadata +102 -55
- data/lib/litle/config/application.rb +0 -66
- data/lib/litle/config/configuration.rb +0 -51
- data/lib/litle/config/properties.rb +0 -23
- data/lib/litle/litle/gateway.rb +0 -32
- data/lib/litle/models/litle_payment_method.rb +0 -167
- data/lib/litle/models/litle_response.rb +0 -199
- data/lib/litle/models/litle_transaction.rb +0 -44
- data/spec/litle/currency_conversion_spec.rb +0 -21
- data/spec/litle/litle_payment_method_spec.rb +0 -95
- data/spec/litle/litle_response_spec.rb +0 -91
- data/spec/litle/utils_spec.rb +0 -22
@@ -1,66 +0,0 @@
|
|
1
|
-
configure do
|
2
|
-
# Usage: rackup -Ilib -E test
|
3
|
-
if development? or test?
|
4
|
-
Killbill::Litle.initialize! unless Killbill::Litle.initialized
|
5
|
-
end
|
6
|
-
end
|
7
|
-
|
8
|
-
helpers do
|
9
|
-
def plugin
|
10
|
-
Killbill::Litle::PrivatePaymentPlugin.instance
|
11
|
-
end
|
12
|
-
|
13
|
-
def required_parameter!(parameter_name, parameter_value, message='must be specified!')
|
14
|
-
halt 400, "#{parameter_name} #{message}" if parameter_value.blank?
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
after do
|
19
|
-
# return DB connections to the Pool if required
|
20
|
-
ActiveRecord::Base.connection.close
|
21
|
-
end
|
22
|
-
|
23
|
-
# http://127.0.0.1:9292/plugins/killbill-litle
|
24
|
-
get '/plugins/killbill-litle' do
|
25
|
-
kb_account_id = request.GET['kb_account_id']
|
26
|
-
required_parameter! :kb_account_id, kb_account_id
|
27
|
-
|
28
|
-
secure_page_url = Killbill::Litle.config[:litle][:secure_page_url]
|
29
|
-
required_parameter! :secure_page_url, secure_page_url, 'is not configured'
|
30
|
-
|
31
|
-
# Allow currency override if needed
|
32
|
-
currency = request.GET['currency'] || plugin.get_currency(kb_account_id)
|
33
|
-
paypage_id = Killbill::Litle.config[:litle][:paypage_id][currency.to_sym]
|
34
|
-
required_parameter! :paypage_id, paypage_id, "is not configured for currency #{currency.to_sym}"
|
35
|
-
|
36
|
-
locals = {
|
37
|
-
:currency => currency,
|
38
|
-
:secure_page_url => secure_page_url,
|
39
|
-
:paypage_id => paypage_id,
|
40
|
-
:kb_account_id => kb_account_id,
|
41
|
-
:merchant_txn_id => request.GET['merchant_txn_id'] || '1',
|
42
|
-
:order_id => request.GET['order_id'] || '1',
|
43
|
-
:report_group => request.GET['report_group'] || 'Default Report Group',
|
44
|
-
:success_page => params[:successPage],
|
45
|
-
:failure_page => params[:failurePage]
|
46
|
-
}
|
47
|
-
erb :paypage, :views => File.expand_path(File.dirname(__FILE__) + '/../views'), :locals => locals
|
48
|
-
end
|
49
|
-
|
50
|
-
# curl -v http://127.0.0.1:9292/plugins/killbill-litle/1.0/pms/1
|
51
|
-
get '/plugins/killbill-litle/1.0/pms/:id', :provides => 'json' do
|
52
|
-
if pm = Killbill::Litle::LitlePaymentMethod.find_by_id(params[:id].to_i)
|
53
|
-
pm.to_json
|
54
|
-
else
|
55
|
-
status 404
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
# curl -v http://127.0.0.1:9292/plugins/killbill-litle/1.0/transactions/1
|
60
|
-
get '/plugins/killbill-litle/1.0/transactions/:id', :provides => 'json' do
|
61
|
-
if transaction = Killbill::Litle::LitleTransaction.find_by_id(params[:id].to_i)
|
62
|
-
transaction.to_json
|
63
|
-
else
|
64
|
-
status 404
|
65
|
-
end
|
66
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
require 'logger'
|
2
|
-
|
3
|
-
module Killbill::Litle
|
4
|
-
mattr_reader :logger
|
5
|
-
mattr_reader :config
|
6
|
-
mattr_reader :gateways
|
7
|
-
mattr_reader :currency_conversions
|
8
|
-
mattr_reader :kb_apis
|
9
|
-
mattr_reader :initialized
|
10
|
-
mattr_reader :test
|
11
|
-
|
12
|
-
def self.initialize!(logger=Logger.new(STDOUT), conf_dir=File.expand_path('../../../', File.dirname(__FILE__)), kb_apis = nil)
|
13
|
-
@@logger = logger
|
14
|
-
@@kb_apis = kb_apis
|
15
|
-
|
16
|
-
config_file = "#{conf_dir}/litle.yml"
|
17
|
-
@@config = Properties.new(config_file)
|
18
|
-
@@config.parse!
|
19
|
-
@@test = @@config[:litle][:test]
|
20
|
-
|
21
|
-
@@logger.log_level = Logger::DEBUG if (@@config[:logger] || {})[:debug]
|
22
|
-
|
23
|
-
@@gateways = Killbill::Litle::Gateway.from_config(@@config[:litle])
|
24
|
-
|
25
|
-
@@currency_conversions = @@config[:currency_conversions]
|
26
|
-
|
27
|
-
if defined?(JRUBY_VERSION)
|
28
|
-
# See https://github.com/jruby/activerecord-jdbc-adapter/issues/302
|
29
|
-
require 'jdbc/mysql'
|
30
|
-
Jdbc::MySQL.load_driver(:require) if Jdbc::MySQL.respond_to?(:load_driver)
|
31
|
-
end
|
32
|
-
|
33
|
-
ActiveRecord::Base.establish_connection(@@config[:database])
|
34
|
-
ActiveRecord::Base.logger = @@logger
|
35
|
-
|
36
|
-
@@initialized = true
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.converted_currency(currency)
|
40
|
-
currency_sym = currency.to_s.upcase.to_sym
|
41
|
-
@@currency_conversions && @@currency_conversions[currency_sym]
|
42
|
-
end
|
43
|
-
|
44
|
-
|
45
|
-
def self.gateway_for_currency(currency)
|
46
|
-
currency_sym = currency.to_s.upcase.to_sym
|
47
|
-
gateway = @@gateways[currency_sym]
|
48
|
-
raise "Gateway for #{currency} not configured!" if gateway.nil?
|
49
|
-
gateway
|
50
|
-
end
|
51
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
module Killbill::Litle
|
2
|
-
class Properties
|
3
|
-
def initialize(file = 'litle.yml')
|
4
|
-
@config_file = Pathname.new(file).expand_path
|
5
|
-
end
|
6
|
-
|
7
|
-
def parse!
|
8
|
-
raise "#{@config_file} is not a valid file" unless @config_file.file?
|
9
|
-
@config = YAML.load_file(@config_file.to_s)
|
10
|
-
validate!
|
11
|
-
end
|
12
|
-
|
13
|
-
def [](key)
|
14
|
-
@config[key]
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def validate!
|
20
|
-
raise "Bad configuration for Litle plugin. Config is #{@config.inspect}" if @config.blank? || !@config[:litle] || !@config[:litle][:merchant_id] || !@config[:litle][:password]
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
data/lib/litle/litle/gateway.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
module Killbill::Litle
|
2
|
-
class Gateway
|
3
|
-
def self.from_config(config)
|
4
|
-
if config[:test]
|
5
|
-
ActiveMerchant::Billing::Base.mode = :test
|
6
|
-
end
|
7
|
-
|
8
|
-
if config[:log_file]
|
9
|
-
ActiveMerchant::Billing::LitleGateway.wiredump_device = File.open(config[:log_file], 'w')
|
10
|
-
ActiveMerchant::Billing::LitleGateway.wiredump_device.sync = true
|
11
|
-
end
|
12
|
-
|
13
|
-
gateways = {}
|
14
|
-
config[:merchant_id].each do |currency, mid|
|
15
|
-
gateways[currency.upcase.to_sym] = Gateway.new(currency, config[:username], config[:password], mid)
|
16
|
-
end
|
17
|
-
gateways
|
18
|
-
end
|
19
|
-
|
20
|
-
def initialize(currency, user, password, merchant_id)
|
21
|
-
@currency = currency
|
22
|
-
@gateway = ActiveMerchant::Billing::LitleGateway.new({:user => user,
|
23
|
-
:password => password,
|
24
|
-
:merchant_id => merchant_id
|
25
|
-
})
|
26
|
-
end
|
27
|
-
|
28
|
-
def method_missing(m, *args, &block)
|
29
|
-
@gateway.send(m, *args, &block)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
@@ -1,167 +0,0 @@
|
|
1
|
-
module Killbill::Litle
|
2
|
-
class LitlePaymentMethod < ActiveRecord::Base
|
3
|
-
attr_accessible :kb_account_id,
|
4
|
-
:kb_payment_method_id,
|
5
|
-
:litle_token,
|
6
|
-
:cc_first_name,
|
7
|
-
:cc_last_name,
|
8
|
-
:cc_type,
|
9
|
-
:cc_exp_month,
|
10
|
-
:cc_exp_year,
|
11
|
-
:cc_last_4,
|
12
|
-
:address1,
|
13
|
-
:address2,
|
14
|
-
:city,
|
15
|
-
:state,
|
16
|
-
:zip,
|
17
|
-
:country
|
18
|
-
|
19
|
-
alias_attribute :external_payment_method_id, :litle_token
|
20
|
-
|
21
|
-
def self.from_kb_account_id(kb_account_id)
|
22
|
-
find_all_by_kb_account_id_and_is_deleted(kb_account_id, false)
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.from_kb_payment_method_id(kb_payment_method_id)
|
26
|
-
payment_methods = find_all_by_kb_payment_method_id_and_is_deleted(kb_payment_method_id, false)
|
27
|
-
raise "No payment method found for payment method #{kb_payment_method_id}" if payment_methods.empty?
|
28
|
-
raise "Killbill payment method mapping to multiple active Litle tokens for payment method #{kb_payment_method_id}" if payment_methods.size > 1
|
29
|
-
payment_methods[0]
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.mark_as_deleted!(kb_payment_method_id)
|
33
|
-
payment_method = from_kb_payment_method_id(kb_payment_method_id)
|
34
|
-
payment_method.is_deleted = true
|
35
|
-
payment_method.save!
|
36
|
-
end
|
37
|
-
|
38
|
-
# VisibleForTesting
|
39
|
-
def self.search_query(search_key, offset = nil, limit = nil)
|
40
|
-
t = self.arel_table
|
41
|
-
|
42
|
-
# Exact match for litle_token, cc_type, cc_exp_month, cc_exp_year, cc_last_4, state and zip, partial match for the reset
|
43
|
-
where_clause = t[:litle_token].eq(search_key)
|
44
|
-
.or(t[:cc_type].eq(search_key))
|
45
|
-
.or(t[:state].eq(search_key))
|
46
|
-
.or(t[:zip].eq(search_key))
|
47
|
-
.or(t[:cc_first_name].matches("%#{search_key}%"))
|
48
|
-
.or(t[:cc_last_name].matches("%#{search_key}%"))
|
49
|
-
.or(t[:address1].matches("%#{search_key}%"))
|
50
|
-
.or(t[:address2].matches("%#{search_key}%"))
|
51
|
-
.or(t[:city].matches("%#{search_key}%"))
|
52
|
-
.or(t[:country].matches("%#{search_key}%"))
|
53
|
-
|
54
|
-
# Coming from Kill Bill, search_key will always be a String. Check to see if it represents a numeric for numeric-only fields
|
55
|
-
if search_key.is_a?(Numeric) or search_key.to_s =~ /\A[-+]?[0-9]*\.?[0-9]+\Z/
|
56
|
-
where_clause = where_clause.or(t[:cc_exp_month].eq(search_key))
|
57
|
-
.or(t[:cc_exp_year].eq(search_key))
|
58
|
-
.or(t[:cc_last_4].eq(search_key))
|
59
|
-
end
|
60
|
-
|
61
|
-
query = t.where(where_clause)
|
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)
|
78
|
-
pagination = Killbill::Plugin::Model::Pagination.new
|
79
|
-
pagination.current_offset = offset
|
80
|
-
pagination.total_nb_records = self.count_by_sql(self.search_query(search_key))
|
81
|
-
pagination.max_nb_records = self.count
|
82
|
-
pagination.next_offset = (!pagination.total_nb_records.nil? && offset + limit >= pagination.total_nb_records) ? nil : offset + limit
|
83
|
-
# Reduce the limit if the specified value is larger than the number of records
|
84
|
-
actual_limit = [pagination.max_nb_records, limit].min
|
85
|
-
pagination.iterator = StreamyResultSet.new(actual_limit) do |offset,limit|
|
86
|
-
self.find_by_sql(self.search_query(search_key, offset, limit))
|
87
|
-
.map(&:to_payment_method_response)
|
88
|
-
end
|
89
|
-
pagination
|
90
|
-
end
|
91
|
-
|
92
|
-
def to_payment_method_response
|
93
|
-
properties = []
|
94
|
-
properties << create_pm_kv_info('token', external_payment_method_id)
|
95
|
-
properties << create_pm_kv_info('ccName', cc_name)
|
96
|
-
properties << create_pm_kv_info('ccType', cc_type)
|
97
|
-
properties << create_pm_kv_info('ccExpirationMonth', cc_exp_month)
|
98
|
-
properties << create_pm_kv_info('ccExpirationYear', cc_exp_year)
|
99
|
-
properties << create_pm_kv_info('ccLast4', cc_last_4)
|
100
|
-
properties << create_pm_kv_info('address1', address1)
|
101
|
-
properties << create_pm_kv_info('address2', address2)
|
102
|
-
properties << create_pm_kv_info('city', city)
|
103
|
-
properties << create_pm_kv_info('state', state)
|
104
|
-
properties << create_pm_kv_info('zip', zip)
|
105
|
-
properties << create_pm_kv_info('country', country)
|
106
|
-
|
107
|
-
pm_plugin = Killbill::Plugin::Model::PaymentMethodPlugin.new
|
108
|
-
pm_plugin.kb_payment_method_id = kb_payment_method_id
|
109
|
-
pm_plugin.external_payment_method_id = external_payment_method_id
|
110
|
-
pm_plugin.is_default_payment_method = is_default
|
111
|
-
pm_plugin.properties = properties
|
112
|
-
pm_plugin.type = 'CreditCard'
|
113
|
-
pm_plugin.cc_name = cc_name
|
114
|
-
pm_plugin.cc_type = cc_type
|
115
|
-
pm_plugin.cc_expiration_month = cc_exp_month
|
116
|
-
pm_plugin.cc_expiration_year = cc_exp_year
|
117
|
-
pm_plugin.cc_last4 = cc_last_4
|
118
|
-
pm_plugin.address1 = address1
|
119
|
-
pm_plugin.address2 = address2
|
120
|
-
pm_plugin.city = city
|
121
|
-
pm_plugin.state = state
|
122
|
-
pm_plugin.zip = zip
|
123
|
-
pm_plugin.country = country
|
124
|
-
|
125
|
-
pm_plugin
|
126
|
-
end
|
127
|
-
|
128
|
-
def to_payment_method_info_response
|
129
|
-
pm_info_plugin = Killbill::Plugin::Model::PaymentMethodInfoPlugin.new
|
130
|
-
pm_info_plugin.account_id = kb_account_id
|
131
|
-
pm_info_plugin.payment_method_id = kb_payment_method_id
|
132
|
-
pm_info_plugin.is_default = is_default
|
133
|
-
pm_info_plugin.external_payment_method_id = external_payment_method_id
|
134
|
-
pm_info_plugin
|
135
|
-
end
|
136
|
-
|
137
|
-
def is_default
|
138
|
-
# No concept of default payment method in Litle
|
139
|
-
false
|
140
|
-
end
|
141
|
-
|
142
|
-
def cc_name
|
143
|
-
if cc_first_name and cc_last_name
|
144
|
-
"#{cc_first_name} #{cc_last_name}"
|
145
|
-
elsif cc_first_name
|
146
|
-
cc_first_name
|
147
|
-
elsif cc_last_name
|
148
|
-
cc_last_name
|
149
|
-
else
|
150
|
-
nil
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
def to_litle_card_token
|
155
|
-
ActiveMerchant::Billing::LitleGateway::LitleCardToken.new(:token => litle_token, :month => cc_exp_month, :year => cc_exp_year)
|
156
|
-
end
|
157
|
-
|
158
|
-
private
|
159
|
-
|
160
|
-
def create_pm_kv_info(key, value)
|
161
|
-
prop = Killbill::Plugin::Model::PaymentMethodKVInfo.new
|
162
|
-
prop.key = key
|
163
|
-
prop.value = value
|
164
|
-
prop
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
@@ -1,199 +0,0 @@
|
|
1
|
-
module Killbill::Litle
|
2
|
-
class LitleResponse < ActiveRecord::Base
|
3
|
-
has_one :litle_transaction
|
4
|
-
attr_accessible :api_call,
|
5
|
-
:kb_payment_id,
|
6
|
-
:message,
|
7
|
-
# Either litleToken (registerToken call) or litleTxnId
|
8
|
-
:authorization,
|
9
|
-
:fraud_review,
|
10
|
-
:test,
|
11
|
-
:params_litleonelineresponse_message,
|
12
|
-
:params_litleonelineresponse_response,
|
13
|
-
:params_litleonelineresponse_version,
|
14
|
-
:params_litleonelineresponse_xmlns,
|
15
|
-
:params_litleonelineresponse_saleresponse_customer_id,
|
16
|
-
:params_litleonelineresponse_saleresponse_id,
|
17
|
-
:params_litleonelineresponse_saleresponse_report_group,
|
18
|
-
:params_litleonelineresponse_saleresponse_litle_txn_id,
|
19
|
-
:params_litleonelineresponse_saleresponse_order_id,
|
20
|
-
:params_litleonelineresponse_saleresponse_response,
|
21
|
-
:params_litleonelineresponse_saleresponse_response_time,
|
22
|
-
:params_litleonelineresponse_saleresponse_message,
|
23
|
-
:params_litleonelineresponse_saleresponse_auth_code,
|
24
|
-
:avs_result_code,
|
25
|
-
:avs_result_message,
|
26
|
-
:avs_result_street_match,
|
27
|
-
:avs_result_postal_match,
|
28
|
-
:cvv_result_code,
|
29
|
-
:cvv_result_message,
|
30
|
-
:success
|
31
|
-
|
32
|
-
def litle_token
|
33
|
-
authorization
|
34
|
-
end
|
35
|
-
|
36
|
-
def litle_txn_id
|
37
|
-
potential_litle_txn_id = params_litleonelineresponse_saleresponse_litle_txn_id || authorization
|
38
|
-
if potential_litle_txn_id.blank?
|
39
|
-
nil
|
40
|
-
else
|
41
|
-
# Litle seems to return the precision sometimes along with the txnId (e.g. 053499651324799+19)
|
42
|
-
# And sometimes it adds a ;credit
|
43
|
-
# TODO Figure out WTF is going on here
|
44
|
-
potential_litle_txn_id.to_s.split(';')[0].split('+')[0]
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def self.from_response(api_call, kb_payment_id, response)
|
49
|
-
LitleResponse.new({
|
50
|
-
:api_call => api_call,
|
51
|
-
:kb_payment_id => kb_payment_id,
|
52
|
-
:message => response.message,
|
53
|
-
:authorization => response.authorization,
|
54
|
-
:fraud_review => response.fraud_review?,
|
55
|
-
:test => response.test?,
|
56
|
-
:params_litleonelineresponse_message => extract(response, "litleOnlineResponse", "message"),
|
57
|
-
:params_litleonelineresponse_response => extract(response, "litleOnlineResponse", "response"),
|
58
|
-
:params_litleonelineresponse_version => extract(response, "litleOnlineResponse", "version"),
|
59
|
-
:params_litleonelineresponse_xmlns => extract(response, "litleOnlineResponse", "xmlns"),
|
60
|
-
:params_litleonelineresponse_saleresponse_customer_id => extract(response, "litleOnlineResponse", "saleResponse", "customerId"),
|
61
|
-
:params_litleonelineresponse_saleresponse_id => extract(response, "litleOnlineResponse", "saleResponse", "id"),
|
62
|
-
:params_litleonelineresponse_saleresponse_report_group => extract(response, "litleOnlineResponse", "saleResponse", "reportGroup"),
|
63
|
-
:params_litleonelineresponse_saleresponse_litle_txn_id => extract(response, "litleOnlineResponse", "saleResponse", "litleTxnId"),
|
64
|
-
:params_litleonelineresponse_saleresponse_order_id => extract(response, "litleOnlineResponse", "saleResponse", "orderId"),
|
65
|
-
:params_litleonelineresponse_saleresponse_response => extract(response, "litleOnlineResponse", "saleResponse", "response"),
|
66
|
-
:params_litleonelineresponse_saleresponse_response_time => extract(response, "litleOnlineResponse", "saleResponse", "responseTime"),
|
67
|
-
:params_litleonelineresponse_saleresponse_message => extract(response, "litleOnlineResponse", "saleResponse", "message"),
|
68
|
-
:params_litleonelineresponse_saleresponse_auth_code => extract(response, "litleOnlineResponse", "saleResponse", "authCode"),
|
69
|
-
:avs_result_code => response.avs_result.kind_of?(ActiveMerchant::Billing::AVSResult) ? response.avs_result.code : response.avs_result['code'],
|
70
|
-
:avs_result_message => response.avs_result.kind_of?(ActiveMerchant::Billing::AVSResult) ? response.avs_result.message : response.avs_result['message'],
|
71
|
-
:avs_result_street_match => response.avs_result.kind_of?(ActiveMerchant::Billing::AVSResult) ? response.avs_result.street_match : response.avs_result['street_match'],
|
72
|
-
:avs_result_postal_match => response.avs_result.kind_of?(ActiveMerchant::Billing::AVSResult) ? response.avs_result.postal_match : response.avs_result['postal_match'],
|
73
|
-
:cvv_result_code => response.cvv_result.kind_of?(ActiveMerchant::Billing::CVVResult) ? response.cvv_result.code : response.cvv_result['code'],
|
74
|
-
:cvv_result_message => response.cvv_result.kind_of?(ActiveMerchant::Billing::CVVResult) ? response.cvv_result.message : response.cvv_result['message'],
|
75
|
-
:success => response.success?
|
76
|
-
})
|
77
|
-
end
|
78
|
-
|
79
|
-
def to_payment_response
|
80
|
-
to_killbill_response :payment
|
81
|
-
end
|
82
|
-
|
83
|
-
def to_refund_response
|
84
|
-
to_killbill_response :refund
|
85
|
-
end
|
86
|
-
|
87
|
-
# VisibleForTesting
|
88
|
-
def self.search_query(api_call, search_key, offset = nil, limit = nil)
|
89
|
-
t = self.arel_table
|
90
|
-
|
91
|
-
# Exact matches only
|
92
|
-
where_clause = t[:params_litleonelineresponse_saleresponse_id].eq(search_key)
|
93
|
-
.or(t[:params_litleonelineresponse_saleresponse_litle_txn_id].eq(search_key))
|
94
|
-
.or(t[:params_litleonelineresponse_saleresponse_order_id].eq(search_key))
|
95
|
-
.or(t[:params_litleonelineresponse_saleresponse_auth_code].eq(search_key))
|
96
|
-
|
97
|
-
# Only search successful payments and refunds
|
98
|
-
where_clause = where_clause.and(t[:api_call].eq(api_call))
|
99
|
-
.and(t[:success].eq(true))
|
100
|
-
|
101
|
-
query = t.where(where_clause)
|
102
|
-
.order(t[:id])
|
103
|
-
|
104
|
-
if offset.blank? and limit.blank?
|
105
|
-
# true is for count distinct
|
106
|
-
query.project(t[:id].count(true))
|
107
|
-
else
|
108
|
-
query.skip(offset) unless offset.blank?
|
109
|
-
query.take(limit) unless limit.blank?
|
110
|
-
query.project(t[Arel.star])
|
111
|
-
# Not chainable
|
112
|
-
query.distinct
|
113
|
-
end
|
114
|
-
query
|
115
|
-
end
|
116
|
-
|
117
|
-
def self.search(search_key, offset = 0, limit = 100, type = :payment)
|
118
|
-
api_call = type == :payment ? 'charge' : 'refund'
|
119
|
-
pagination = Killbill::Plugin::Model::Pagination.new
|
120
|
-
pagination.current_offset = offset
|
121
|
-
pagination.total_nb_records = self.count_by_sql(self.search_query(api_call, search_key))
|
122
|
-
pagination.max_nb_records = self.where(:api_call => api_call, :success => true).count
|
123
|
-
pagination.next_offset = (!pagination.total_nb_records.nil? && offset + limit >= pagination.total_nb_records) ? nil : offset + limit
|
124
|
-
# Reduce the limit if the specified value is larger than the number of records
|
125
|
-
actual_limit = [pagination.max_nb_records, limit].min
|
126
|
-
pagination.iterator = StreamyResultSet.new(actual_limit) do |offset,limit|
|
127
|
-
self.find_by_sql(self.search_query(api_call, search_key, offset, limit))
|
128
|
-
.map { |x| type == :payment ? x.to_payment_response : x.to_refund_response }
|
129
|
-
end
|
130
|
-
pagination
|
131
|
-
end
|
132
|
-
|
133
|
-
private
|
134
|
-
|
135
|
-
def to_killbill_response(type)
|
136
|
-
if litle_transaction.nil?
|
137
|
-
amount_in_cents = nil
|
138
|
-
currency = nil
|
139
|
-
created_date = created_at
|
140
|
-
first_payment_reference_id = nil
|
141
|
-
second_payment_reference_id = nil
|
142
|
-
else
|
143
|
-
amount_in_cents = litle_transaction.amount_in_cents
|
144
|
-
currency = litle_transaction.currency
|
145
|
-
created_date = litle_transaction.created_at
|
146
|
-
first_reference_id = params_litleonelineresponse_saleresponse_id
|
147
|
-
second_reference_id = litle_transaction.litle_txn_id
|
148
|
-
end
|
149
|
-
|
150
|
-
effective_date = params_litleonelineresponse_saleresponse_response_time || created_date
|
151
|
-
gateway_error = message || params_litleonelineresponse_saleresponse_message
|
152
|
-
gateway_error_code = params_litleonelineresponse_saleresponse_response
|
153
|
-
|
154
|
-
if type == :payment
|
155
|
-
p_info_plugin = Killbill::Plugin::Model::PaymentInfoPlugin.new
|
156
|
-
p_info_plugin.kb_payment_id = kb_payment_id
|
157
|
-
p_info_plugin.amount = Money.new(amount_in_cents, currency).to_d if currency
|
158
|
-
p_info_plugin.currency = currency
|
159
|
-
p_info_plugin.created_date = created_date
|
160
|
-
p_info_plugin.effective_date = effective_date
|
161
|
-
p_info_plugin.status = (success ? :PROCESSED : :ERROR)
|
162
|
-
p_info_plugin.gateway_error = gateway_error
|
163
|
-
p_info_plugin.gateway_error_code = gateway_error_code
|
164
|
-
p_info_plugin.first_payment_reference_id = first_reference_id
|
165
|
-
p_info_plugin.second_payment_reference_id = second_reference_id
|
166
|
-
p_info_plugin
|
167
|
-
else
|
168
|
-
r_info_plugin = Killbill::Plugin::Model::RefundInfoPlugin.new
|
169
|
-
r_info_plugin.kb_payment_id = kb_payment_id
|
170
|
-
r_info_plugin.amount = Money.new(amount_in_cents, currency).to_d if currency
|
171
|
-
r_info_plugin.currency = currency
|
172
|
-
r_info_plugin.created_date = created_date
|
173
|
-
r_info_plugin.effective_date = effective_date
|
174
|
-
r_info_plugin.status = (success ? :PROCESSED : :ERROR)
|
175
|
-
r_info_plugin.gateway_error = gateway_error
|
176
|
-
r_info_plugin.gateway_error_code = gateway_error_code
|
177
|
-
r_info_plugin.first_refund_reference_id = first_reference_id
|
178
|
-
r_info_plugin.second_refund_reference_id = second_reference_id
|
179
|
-
r_info_plugin
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
def self.extract(response, key1, key2=nil, key3=nil)
|
184
|
-
return nil if response.nil? || response.params.nil?
|
185
|
-
level1 = response.params[key1]
|
186
|
-
|
187
|
-
if level1.nil? or (key2.nil? and key3.nil?)
|
188
|
-
return level1
|
189
|
-
end
|
190
|
-
level2 = level1[key2]
|
191
|
-
|
192
|
-
if level2.nil? or key3.nil?
|
193
|
-
return level2
|
194
|
-
else
|
195
|
-
return level2[key3]
|
196
|
-
end
|
197
|
-
end
|
198
|
-
end
|
199
|
-
end
|