lolita-first-data 1.0.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 +7 -0
- data/{LICENSE.txt → MIT-LICENSE} +1 -1
- data/README.md +8 -89
- data/Rakefile +22 -45
- data/app/controllers/lolita_first_data/application_controller.rb +23 -0
- data/app/controllers/lolita_first_data/test_controller.rb +73 -0
- data/app/controllers/lolita_first_data/transactions_controller.rb +63 -0
- data/app/models/lolita_first_data/transaction.rb +45 -0
- data/config/locales/en.yml +109 -109
- data/config/locales/lv.yml +109 -109
- data/config/routes.rb +5 -5
- data/lib/generators/lolita_first_data/install_generator.rb +13 -14
- data/lib/generators/lolita_first_data/templates/migration.rb +21 -21
- data/lib/lolita-first-data.rb +25 -6
- data/lib/lolita_first_data/billing.rb +82 -0
- data/lib/lolita_first_data/custom_logger.rb +8 -0
- data/lib/lolita_first_data/engine.rb +5 -0
- data/lib/lolita_first_data/version.rb +3 -0
- data/lib/tasks/lolita_first_data_tasks.rake +4 -0
- metadata +100 -102
- data/.rspec +0 -2
- data/Gemfile +0 -15
- data/Gemfile.lock +0 -140
- data/VERSION +0 -1
- data/app/controllers/lolita/first_data/common_controller.rb +0 -25
- data/app/controllers/lolita/first_data/test_controller.rb +0 -78
- data/app/controllers/lolita/first_data/transaction_controller.rb +0 -49
- data/app/models/lolita/first_data/transaction.rb +0 -55
- data/lib/lolita-first-data/billing.rb +0 -37
- data/lib/lolita-first-data/custom_logger.rb +0 -10
- data/lib/lolita-first-data/gateway.rb +0 -160
- data/lib/lolita-first-data/rails.rb +0 -6
- data/lib/tasks/first_data_tasks.rake +0 -78
- data/lolita-first-data.gemspec +0 -95
- data/spec/cert.pem +0 -63
- data/spec/fabricators/reservation_fabricator.rb +0 -4
- data/spec/fabricators/transaction_fabricator.rb +0 -7
- data/spec/first_data_spec.rb +0 -67
- data/spec/spec_helper.rb +0 -101
- data/spec/support/rails.rb +0 -16
data/.rspec
DELETED
data/Gemfile
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
source "http://rubygems.org"
|
2
|
-
|
3
|
-
gem 'rails', '>= 3.0.0'
|
4
|
-
gem "activemerchant", "~> 1.17.0"
|
5
|
-
|
6
|
-
group :development do
|
7
|
-
gem 'sqlite3', '~> 1.3.4'
|
8
|
-
gem 'rspec', '~> 2.6.0'
|
9
|
-
gem 'webmock', '~> 1.7.6'
|
10
|
-
gem 'ruby-debug19', '~> 0.11.6'
|
11
|
-
gem "bundler", "~> 1.0.0"
|
12
|
-
gem "jeweler", "~> 1.6.4"
|
13
|
-
gem "rcov", ">= 0"
|
14
|
-
gem 'fabrication', "~> 1.1.0"
|
15
|
-
end
|
data/Gemfile.lock
DELETED
@@ -1,140 +0,0 @@
|
|
1
|
-
GEM
|
2
|
-
remote: http://rubygems.org/
|
3
|
-
specs:
|
4
|
-
actionmailer (3.1.0)
|
5
|
-
actionpack (= 3.1.0)
|
6
|
-
mail (~> 2.3.0)
|
7
|
-
actionpack (3.1.0)
|
8
|
-
activemodel (= 3.1.0)
|
9
|
-
activesupport (= 3.1.0)
|
10
|
-
builder (~> 3.0.0)
|
11
|
-
erubis (~> 2.7.0)
|
12
|
-
i18n (~> 0.6)
|
13
|
-
rack (~> 1.3.2)
|
14
|
-
rack-cache (~> 1.0.3)
|
15
|
-
rack-mount (~> 0.8.2)
|
16
|
-
rack-test (~> 0.6.1)
|
17
|
-
sprockets (~> 2.0.0)
|
18
|
-
activemerchant (1.17.0)
|
19
|
-
activesupport (>= 2.3.11)
|
20
|
-
braintree (>= 2.0.0)
|
21
|
-
builder (>= 2.0.0)
|
22
|
-
json (>= 1.5.1)
|
23
|
-
activemodel (3.1.0)
|
24
|
-
activesupport (= 3.1.0)
|
25
|
-
bcrypt-ruby (~> 3.0.0)
|
26
|
-
builder (~> 3.0.0)
|
27
|
-
i18n (~> 0.6)
|
28
|
-
activerecord (3.1.0)
|
29
|
-
activemodel (= 3.1.0)
|
30
|
-
activesupport (= 3.1.0)
|
31
|
-
arel (~> 2.2.1)
|
32
|
-
tzinfo (~> 0.3.29)
|
33
|
-
activeresource (3.1.0)
|
34
|
-
activemodel (= 3.1.0)
|
35
|
-
activesupport (= 3.1.0)
|
36
|
-
activesupport (3.1.0)
|
37
|
-
multi_json (~> 1.0)
|
38
|
-
addressable (2.2.6)
|
39
|
-
archive-tar-minitar (0.5.2)
|
40
|
-
arel (2.2.1)
|
41
|
-
bcrypt-ruby (3.0.0)
|
42
|
-
braintree (2.11.0)
|
43
|
-
builder (>= 2.0.0)
|
44
|
-
builder (3.0.0)
|
45
|
-
columnize (0.3.4)
|
46
|
-
crack (0.1.8)
|
47
|
-
diff-lcs (1.1.3)
|
48
|
-
erubis (2.7.0)
|
49
|
-
fabrication (1.1.0)
|
50
|
-
git (1.2.5)
|
51
|
-
hike (1.2.1)
|
52
|
-
i18n (0.6.0)
|
53
|
-
jeweler (1.6.4)
|
54
|
-
bundler (~> 1.0)
|
55
|
-
git (>= 1.2.5)
|
56
|
-
rake
|
57
|
-
json (1.5.4)
|
58
|
-
linecache19 (0.5.12)
|
59
|
-
ruby_core_source (>= 0.1.4)
|
60
|
-
mail (2.3.0)
|
61
|
-
i18n (>= 0.4.0)
|
62
|
-
mime-types (~> 1.16)
|
63
|
-
treetop (~> 1.4.8)
|
64
|
-
mime-types (1.16)
|
65
|
-
multi_json (1.0.3)
|
66
|
-
polyglot (0.3.2)
|
67
|
-
rack (1.3.2)
|
68
|
-
rack-cache (1.0.3)
|
69
|
-
rack (>= 0.4)
|
70
|
-
rack-mount (0.8.3)
|
71
|
-
rack (>= 1.0.0)
|
72
|
-
rack-ssl (1.3.2)
|
73
|
-
rack
|
74
|
-
rack-test (0.6.1)
|
75
|
-
rack (>= 1.0)
|
76
|
-
rails (3.1.0)
|
77
|
-
actionmailer (= 3.1.0)
|
78
|
-
actionpack (= 3.1.0)
|
79
|
-
activerecord (= 3.1.0)
|
80
|
-
activeresource (= 3.1.0)
|
81
|
-
activesupport (= 3.1.0)
|
82
|
-
bundler (~> 1.0)
|
83
|
-
railties (= 3.1.0)
|
84
|
-
railties (3.1.0)
|
85
|
-
actionpack (= 3.1.0)
|
86
|
-
activesupport (= 3.1.0)
|
87
|
-
rack-ssl (~> 1.3.2)
|
88
|
-
rake (>= 0.8.7)
|
89
|
-
rdoc (~> 3.4)
|
90
|
-
thor (~> 0.14.6)
|
91
|
-
rake (0.9.2)
|
92
|
-
rcov (0.9.10)
|
93
|
-
rdoc (3.9.4)
|
94
|
-
rspec (2.6.0)
|
95
|
-
rspec-core (~> 2.6.0)
|
96
|
-
rspec-expectations (~> 2.6.0)
|
97
|
-
rspec-mocks (~> 2.6.0)
|
98
|
-
rspec-core (2.6.4)
|
99
|
-
rspec-expectations (2.6.0)
|
100
|
-
diff-lcs (~> 1.1.2)
|
101
|
-
rspec-mocks (2.6.0)
|
102
|
-
ruby-debug-base19 (0.11.25)
|
103
|
-
columnize (>= 0.3.1)
|
104
|
-
linecache19 (>= 0.5.11)
|
105
|
-
ruby_core_source (>= 0.1.4)
|
106
|
-
ruby-debug19 (0.11.6)
|
107
|
-
columnize (>= 0.3.1)
|
108
|
-
linecache19 (>= 0.5.11)
|
109
|
-
ruby-debug-base19 (>= 0.11.19)
|
110
|
-
ruby_core_source (0.1.5)
|
111
|
-
archive-tar-minitar (>= 0.5.2)
|
112
|
-
sprockets (2.0.0)
|
113
|
-
hike (~> 1.2)
|
114
|
-
rack (~> 1.0)
|
115
|
-
tilt (!= 1.3.0, ~> 1.1)
|
116
|
-
sqlite3 (1.3.4)
|
117
|
-
thor (0.14.6)
|
118
|
-
tilt (1.3.3)
|
119
|
-
treetop (1.4.10)
|
120
|
-
polyglot
|
121
|
-
polyglot (>= 0.3.1)
|
122
|
-
tzinfo (0.3.29)
|
123
|
-
webmock (1.7.6)
|
124
|
-
addressable (> 2.2.5, ~> 2.2)
|
125
|
-
crack (>= 0.1.7)
|
126
|
-
|
127
|
-
PLATFORMS
|
128
|
-
ruby
|
129
|
-
|
130
|
-
DEPENDENCIES
|
131
|
-
activemerchant (~> 1.17.0)
|
132
|
-
bundler (~> 1.0.0)
|
133
|
-
fabrication (~> 1.1.0)
|
134
|
-
jeweler (~> 1.6.4)
|
135
|
-
rails (>= 3.0.0)
|
136
|
-
rcov
|
137
|
-
rspec (~> 2.6.0)
|
138
|
-
ruby-debug19 (~> 0.11.6)
|
139
|
-
sqlite3 (~> 1.3.4)
|
140
|
-
webmock (~> 1.7.6)
|
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
1.0.0
|
@@ -1,25 +0,0 @@
|
|
1
|
-
module Lolita::FirstData
|
2
|
-
class CommonController < ApplicationController
|
3
|
-
include ActiveMerchant::Billing
|
4
|
-
before_filter :set_gateway
|
5
|
-
skip_before_filter :verify_authenticity_token
|
6
|
-
|
7
|
-
private
|
8
|
-
|
9
|
-
def set_gateway
|
10
|
-
@gateway ||= ActiveMerchant::Billing::FirstDataGateway.new(
|
11
|
-
:pem => File.open(FD_PEM).read,
|
12
|
-
:pem_password => FD_PASS,
|
13
|
-
:payment => set_active_payment
|
14
|
-
)
|
15
|
-
end
|
16
|
-
|
17
|
-
# returns current payment instance from session
|
18
|
-
def set_active_payment
|
19
|
-
if session && session[:first_data] && params[:controller] == 'Lolita::FirstData::Transaction'
|
20
|
-
@payment ||= session[:first_data][:billing_class].constantize.find(session[:first_data][:billing_id])
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
end
|
@@ -1,78 +0,0 @@
|
|
1
|
-
module Lolita::FirstData
|
2
|
-
class TestController < Lolita::FirstData::CommonController
|
3
|
-
before_filter :render_nothing
|
4
|
-
|
5
|
-
# renders nothing if not in development environment
|
6
|
-
def render_nothing
|
7
|
-
render :nothing => true unless Rails.env == 'development'
|
8
|
-
end
|
9
|
-
|
10
|
-
#FIXME: refactor
|
11
|
-
# There are all 12 FirstData tests
|
12
|
-
# you should pass them to get production certificates
|
13
|
-
# use: http://localhost:3000/first_data_test/test?nr=1
|
14
|
-
# then increment the "nr" until done
|
15
|
-
def test
|
16
|
-
ip = params[:nr] == '9' ? '192.168.1.2' : request.remote_ip
|
17
|
-
# REQUEST
|
18
|
-
case params[:nr]
|
19
|
-
when /^(1|2|5|6|7|8|10)$/
|
20
|
-
session[:first_data] = {}
|
21
|
-
session[:first_data][:test] = params[:nr]
|
22
|
-
rs = @gateway.purchase(100,428,ip,'tests')
|
23
|
-
if rs.success?
|
24
|
-
session[:first_data][:trans_id] = rs.params['TRANSACTION_ID']
|
25
|
-
return redirect_to(@gateway.go_out)
|
26
|
-
else
|
27
|
-
return render(:text => "<pre>#{rs.message}</pre>", :satus => 400)
|
28
|
-
end
|
29
|
-
when /^(3|4|9|11)$/
|
30
|
-
session[:first_data] = {}
|
31
|
-
session[:first_data][:test] = params[:nr]
|
32
|
-
rs = @gateway.authorize(100,428,ip,'tests')
|
33
|
-
if rs.success?
|
34
|
-
session[:first_data][:trans_id] = rs.params['TRANSACTION_ID']
|
35
|
-
return redirect_to(@gateway.go_out)
|
36
|
-
else
|
37
|
-
return render(:text => "<pre>#{rs.message}</pre>", :satus => 400)
|
38
|
-
end
|
39
|
-
when /^(12)$/
|
40
|
-
session[:first_data] = {}
|
41
|
-
session[:first_data][:test] = params[:nr]
|
42
|
-
rs = @gateway.close_day
|
43
|
-
return render(:text => "<pre>#{rs.message}</pre>")
|
44
|
-
end
|
45
|
-
|
46
|
-
# RESPONSE
|
47
|
-
case session[:first_data][:test]
|
48
|
-
when /^(1|2|5|6|7|8)$/
|
49
|
-
rs = @gateway.get_trans_result(ip,session[:first_data][:trans_id])
|
50
|
-
msg = %^
|
51
|
-
trans_id: #{session[:first_data][:trans_id]} <br />
|
52
|
-
<pre>#{rs.message}</pre>
|
53
|
-
^
|
54
|
-
return render(:text => msg)
|
55
|
-
when /^3|4|9$/
|
56
|
-
rs = @gateway.complete(session[:first_data][:trans_id],100,428,ip,'tests')
|
57
|
-
msg = %^
|
58
|
-
trans_id: #{session[:first_data][:trans_id]} <br />
|
59
|
-
<pre>#{rs.message}</pre>
|
60
|
-
^
|
61
|
-
return render(:text => msg)
|
62
|
-
when /^(10|11)$/
|
63
|
-
if session[:first_data][:test] == '11'
|
64
|
-
@gateway.complete(session[:first_data][:trans_id],100,428,ip,'tests')
|
65
|
-
@gateway.close_day
|
66
|
-
end
|
67
|
-
rs = @gateway.reverse(session[:first_data][:trans_id],100)
|
68
|
-
msg = %^
|
69
|
-
trans_id: #{session[:first_data][:trans_id]} <br />
|
70
|
-
<pre>#{rs.message}</pre>
|
71
|
-
^
|
72
|
-
return render(:text => msg)
|
73
|
-
end if session[:first_data]
|
74
|
-
render :text => "WRONG REQUEST", :status => 400
|
75
|
-
end
|
76
|
-
|
77
|
-
end
|
78
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
module Lolita::FirstData
|
2
|
-
class TransactionController < Lolita::FirstData::CommonController
|
3
|
-
before_filter :is_ssl_required
|
4
|
-
|
5
|
-
# should exist
|
6
|
-
# session[:first_data][:billing_class]
|
7
|
-
# session[:first_data]:billing_id]
|
8
|
-
# Class should respond to these methods:
|
9
|
-
# => :price - cents
|
10
|
-
# => :currency - according to http://en.wikipedia.org/wiki/ISO_4217
|
11
|
-
# => :description - string that will show up in payment details
|
12
|
-
def checkout
|
13
|
-
if @payment && !@payment.paid?
|
14
|
-
rs = @gateway.purchase(@payment.price,@payment.currency,request.remote_ip,@payment.description)
|
15
|
-
if rs.success?
|
16
|
-
Lolita::FirstData::Transaction.add(@payment, request, rs)
|
17
|
-
redirect_to(@gateway.go_out)
|
18
|
-
else
|
19
|
-
if request.xhr? || !request.referer
|
20
|
-
render :text => I18n.t('fd.purchase_failed'), :status => 400
|
21
|
-
else
|
22
|
-
redirect_to :back
|
23
|
-
end
|
24
|
-
end
|
25
|
-
else
|
26
|
-
render :text => I18n.t('fd.wrong_request'), :status => 400
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
# there we land after returning from FirstData server
|
31
|
-
# then we get transactions result and redirect to your given "finish" path
|
32
|
-
def answer
|
33
|
-
if trx = Lolita::FirstData::Transaction.where(transaction_id: params[:trans_id]).first
|
34
|
-
rs = @gateway.get_trans_result(request.remote_ip,params[:trans_id])
|
35
|
-
trx.process_answer(rs, @gateway, request)
|
36
|
-
redirect_to "#{session[:first_data][:finish_path]}?merchant=fd&trans_id=#{CGI::escape(params[:trans_id])}"
|
37
|
-
else
|
38
|
-
render :text => "wrong transaction ID", :status => 400
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
private
|
43
|
-
|
44
|
-
# forces SSL in production mode if available
|
45
|
-
def is_ssl_required
|
46
|
-
ssl_required(:answer, :checkout) if defined?(ssl_required) && (Rails.env == 'production' || Rails.env == 'staging')
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
@@ -1,55 +0,0 @@
|
|
1
|
-
module Lolita::FirstData
|
2
|
-
class Transaction < ActiveRecord::Base
|
3
|
-
set_table_name :first_data_transactions
|
4
|
-
belongs_to :paymentable, :polymorphic => true
|
5
|
-
after_save :touch_paymentable
|
6
|
-
|
7
|
-
def ip
|
8
|
-
IPAddr.new(self[:ip], Socket::AF_INET).to_s
|
9
|
-
end
|
10
|
-
|
11
|
-
def ip=(x)
|
12
|
-
self[:ip] = IPAddr.new(x).to_i
|
13
|
-
end
|
14
|
-
|
15
|
-
def process_answer rs, gateway, request
|
16
|
-
self.status = (rs.success?) ? 'completed' : 'rejected'
|
17
|
-
self.transaction_code = rs.params['RESULT_CODE']
|
18
|
-
begin
|
19
|
-
self.save!
|
20
|
-
rescue Exception => e
|
21
|
-
fdp_error = "#{e.to_s}\n\n#{$@.join("\n")}"
|
22
|
-
if rs.success?
|
23
|
-
begin
|
24
|
-
gateway.reverse(fdp.transaction_id,fdp.paymentable.price)
|
25
|
-
rescue Exception => reverse_exception
|
26
|
-
reverse_error = "#{reverse_exception.to_s}\n\n#{$@.join("\n")}"
|
27
|
-
ExceptionNotifier::Notifier.exception_notification(request.env, reverse_exception).deliver if defined?(ExceptionNotifier)
|
28
|
-
gateway.log :error, reverse_error
|
29
|
-
end
|
30
|
-
end
|
31
|
-
ExceptionNotifier::Notifier.exception_notification(request.env, e).deliver if defined?(ExceptionNotifier)
|
32
|
-
gateway.log :error, fdp_error
|
33
|
-
false
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
# add new transaction in Checkout
|
38
|
-
def self.add payment, request, rs
|
39
|
-
Lolita::FirstData::Transaction.create!(
|
40
|
-
:transaction_id => rs.params['TRANSACTION_ID'],
|
41
|
-
:status => 'processing',
|
42
|
-
:paymentable_id => payment.id,
|
43
|
-
:paymentable_type => payment.class.to_s,
|
44
|
-
:ip => request.remote_ip
|
45
|
-
)
|
46
|
-
end
|
47
|
-
|
48
|
-
private
|
49
|
-
|
50
|
-
# trigger "fd_trx_saved" on our paymentable model
|
51
|
-
def touch_paymentable
|
52
|
-
paymentable.fd_trx_saved(self) if paymentable
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
module Lolita
|
2
|
-
module FirstData
|
3
|
-
module Billing
|
4
|
-
def self.included(base)
|
5
|
-
base.has_many :fd_transactions, :as => :paymentable, :class_name => "Lolita::FirstData::Transaction", :dependent => :destroy
|
6
|
-
base.extend ClassMethods
|
7
|
-
base.class_eval do
|
8
|
-
# returns true if exists transaction with status 'completed'
|
9
|
-
# and updates status if needed
|
10
|
-
def paid?
|
11
|
-
self.fd_transactions.count(:conditions => {:status => 'completed', :transaction_code => '000'}) >= 1
|
12
|
-
end
|
13
|
-
|
14
|
-
def fd_error_message
|
15
|
-
if !fd_transactions.empty? && fd_transactions.last.transaction_code
|
16
|
-
I18n.t("fd.response.code_#{fd_transactions.last.transaction_code}", :default => I18n.t('fd.unknown_error'))
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
module ClassMethods
|
23
|
-
# Closes business day
|
24
|
-
# should be executed every day ~midnight
|
25
|
-
# Like "ruby script/runner <YourBillingModel>.close_business_day"
|
26
|
-
def close_business_day
|
27
|
-
gw = ActiveMerchant::Billing::FirstDataGateway.new(
|
28
|
-
:pem => File.open(FD_PEM).read,
|
29
|
-
:pem_password => FD_PASS
|
30
|
-
)
|
31
|
-
rs =gw.close_day
|
32
|
-
rs.success? or raise("FirstData close day: #{rs.message}")
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,10 +0,0 @@
|
|
1
|
-
module Lolita
|
2
|
-
module FirstData
|
3
|
-
# custom log formatter for FirstData gateway
|
4
|
-
class LogFormatter < Logger::Formatter
|
5
|
-
def call(severity, time, program_name, message)
|
6
|
-
"%5s [%s] (%s) %s :: %s\n" % [severity,I18n.l(time), $$, program_name, message]
|
7
|
-
end
|
8
|
-
end
|
9
|
-
end
|
10
|
-
end
|
@@ -1,160 +0,0 @@
|
|
1
|
-
module ActiveMerchant #:nodoc:
|
2
|
-
module Billing #:nodoc:
|
3
|
-
class FirstDataGateway < Gateway
|
4
|
-
TEST_DOMAIN = 'https://secureshop-test.firstdata.lv'
|
5
|
-
LIVE_DOMAIN = 'https://secureshop.firstdata.lv'
|
6
|
-
|
7
|
-
# The homepage URL of the gateway
|
8
|
-
self.homepage_url = 'http://www.firstdata.lv/'
|
9
|
-
|
10
|
-
# The name of the gateway
|
11
|
-
self.display_name = 'FirstData'
|
12
|
-
|
13
|
-
def initialize(options = {})
|
14
|
-
requires!(options, :pem, :pem_password)
|
15
|
-
@options = options
|
16
|
-
@logger = Logger.new(defined?(Rails) ? "#{Rails.root}/log/first_data.log" : "/tmp/fd.log", 2, 1024**2)
|
17
|
-
@logger.formatter = Lolita::FirstData::LogFormatter.new
|
18
|
-
super
|
19
|
-
end
|
20
|
-
|
21
|
-
def authorize(money, currency ,ip, description)
|
22
|
-
commit('authorize',{
|
23
|
-
'command' => 'a',
|
24
|
-
'msg_type' => 'DMS',
|
25
|
-
'amount' => money,
|
26
|
-
'currency' => currency,
|
27
|
-
'client_ip_addr'=> ip,
|
28
|
-
'description' => description[0,125],
|
29
|
-
'language' => language
|
30
|
-
})
|
31
|
-
end
|
32
|
-
|
33
|
-
def complete(trans_id,amount,currency,ip,description)
|
34
|
-
commit('complete',{
|
35
|
-
'command' => 't',
|
36
|
-
'msg_type' => 'DMS',
|
37
|
-
'trans_id' => trans_id,
|
38
|
-
'amount' => amount,
|
39
|
-
'currency' => currency,
|
40
|
-
'client_ip_addr'=> ip,
|
41
|
-
'description' => description[0,125]
|
42
|
-
})
|
43
|
-
end
|
44
|
-
|
45
|
-
def purchase(money, currency ,ip, description)
|
46
|
-
commit('purchase',{
|
47
|
-
'command' => 'v',
|
48
|
-
'amount' => money,
|
49
|
-
'currency' => currency,
|
50
|
-
'client_ip_addr'=> ip,
|
51
|
-
'description' => description[0,125],
|
52
|
-
'language' => language
|
53
|
-
})
|
54
|
-
end
|
55
|
-
|
56
|
-
def get_trans_result(ip,trans_id)
|
57
|
-
commit('result',{
|
58
|
-
'command' => 'c',
|
59
|
-
'trans_id' => trans_id,
|
60
|
-
'client_ip_addr'=> ip
|
61
|
-
})
|
62
|
-
end
|
63
|
-
|
64
|
-
def reverse(trans_id, amount)
|
65
|
-
commit('reverse',{
|
66
|
-
'command' => 'r',
|
67
|
-
'trans_id' => trans_id,
|
68
|
-
'amount' => amount
|
69
|
-
})
|
70
|
-
end
|
71
|
-
|
72
|
-
def close_day
|
73
|
-
commit('close',{
|
74
|
-
'command' => 'b'
|
75
|
-
})
|
76
|
-
end
|
77
|
-
|
78
|
-
def go_out
|
79
|
-
raise I18n.t('fd.no_trans_id') unless @trans_id
|
80
|
-
url = get_domain + "/ecomm/ClientHandler?trans_id=#{CGI.escape @trans_id}"
|
81
|
-
url
|
82
|
-
end
|
83
|
-
|
84
|
-
# log to default logger and if possible to payment logger
|
85
|
-
def log severity, message
|
86
|
-
@logger.send(severity,message)
|
87
|
-
@options[:payment].log(severity,message) if @options[:payment].respond_to?(:log)
|
88
|
-
end
|
89
|
-
|
90
|
-
private
|
91
|
-
|
92
|
-
def language
|
93
|
-
I18n.locale.to_s.sub('-','_').downcase
|
94
|
-
end
|
95
|
-
|
96
|
-
def test?
|
97
|
-
ActiveMerchant::Billing::Base.mode == :test
|
98
|
-
end
|
99
|
-
|
100
|
-
def get_domain
|
101
|
-
test? ? TEST_DOMAIN : LIVE_DOMAIN
|
102
|
-
end
|
103
|
-
|
104
|
-
def parse(body)
|
105
|
-
body.to_s.strip
|
106
|
-
end
|
107
|
-
|
108
|
-
# Return Response object
|
109
|
-
# Use the response:
|
110
|
-
# rs.success? - returns true|false
|
111
|
-
# rs.message - returns String with message
|
112
|
-
# rs.params - returns Hash with {'TRANSACTION_ID': 'jl2j4l2j423423=3-3423-4'} or {'RESULT_CODE' => '000'} ...
|
113
|
-
def commit(action,parameters)
|
114
|
-
url = get_domain + ":8443/ecomm/MerchantHandler"
|
115
|
-
data = post_data(action, parameters)
|
116
|
-
log :info, "#{url} + #{data}"
|
117
|
-
rs = parse(post(url, data))
|
118
|
-
log :info, rs
|
119
|
-
data = {}
|
120
|
-
rs.scan(/[0-9A-Z_]+:\s[^\s]+/){|item|
|
121
|
-
item =~ /([0-9A-Z_]+):\s(.+)/
|
122
|
-
data[$1] = $2
|
123
|
-
}
|
124
|
-
case action
|
125
|
-
when /purchase|authorize/
|
126
|
-
@trans_id = data['TRANSACTION_ID']
|
127
|
-
Response.new(data['TRANSACTION_ID'],rs,data)
|
128
|
-
when /result|reverse|complete|close/
|
129
|
-
Response.new(data['RESULT'] == "OK",rs,data)
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
# this posts data to FirstData server
|
134
|
-
def post url, data, headers = {}
|
135
|
-
begin
|
136
|
-
ssl_post(url, data, headers)
|
137
|
-
rescue Exception => e
|
138
|
-
log :error, "#{e.to_s}\n\n#{$@.join("\n")}"
|
139
|
-
"ERROR POSTING DATA"
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
def pem_password
|
144
|
-
@options[:pem_password]
|
145
|
-
end
|
146
|
-
|
147
|
-
def ssl_strict
|
148
|
-
false
|
149
|
-
end
|
150
|
-
|
151
|
-
def post_data(action, parameters = {})
|
152
|
-
parameters.to_query
|
153
|
-
end
|
154
|
-
|
155
|
-
def self.get_code_msg k
|
156
|
-
I18n.t("fd.code._#{k}", :default => I18n.t('fd.unknown_error'))
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|