lolita-first-data 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +2 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +140 -0
- data/LICENSE.txt +20 -0
- data/README.md +89 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/app/controllers/lolita/first_data/common_controller.rb +25 -0
- data/app/controllers/lolita/first_data/test_controller.rb +78 -0
- data/app/controllers/lolita/first_data/transaction_controller.rb +49 -0
- data/app/models/lolita/first_data/transaction.rb +55 -0
- data/config/locales/en.yml +109 -0
- data/config/locales/lv.yml +109 -0
- data/config/routes.rb +5 -0
- data/lib/generators/lolita_first_data/install_generator.rb +14 -0
- data/lib/generators/lolita_first_data/templates/migration.rb +21 -0
- data/lib/lolita-first-data.rb +6 -0
- data/lib/lolita-first-data/billing.rb +37 -0
- data/lib/lolita-first-data/custom_logger.rb +10 -0
- data/lib/lolita-first-data/gateway.rb +160 -0
- data/lib/lolita-first-data/rails.rb +6 -0
- data/lib/tasks/first_data_tasks.rake +78 -0
- data/lolita-first-data.gemspec +95 -0
- data/spec/cert.pem +63 -0
- data/spec/fabricators/reservation_fabricator.rb +4 -0
- data/spec/fabricators/transaction_fabricator.rb +7 -0
- data/spec/first_data_spec.rb +67 -0
- data/spec/spec_helper.rb +101 -0
- data/spec/support/rails.rb +16 -0
- metadata +189 -0
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
namespace :first_data do
|
4
|
+
desc "Generate certificates"
|
5
|
+
task :generate_certificate do
|
6
|
+
fdcg = FirstDataCertGenerator.new
|
7
|
+
fdcg.start
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class FirstDataCertGenerator
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@cert_type = prompt(%^\nCertificate type?
|
15
|
+
1. test
|
16
|
+
2. production^) == '2' ? 'production' : 'test'
|
17
|
+
@destination = File.join(Rails.root, "config", "first-data", @cert_type)
|
18
|
+
FileUtils.mkdir_p(@destination) unless File.exists?(@destination)
|
19
|
+
@domain = prompt("Your domain:")
|
20
|
+
@merchantId = prompt("Your merchantId:")
|
21
|
+
end
|
22
|
+
|
23
|
+
def start
|
24
|
+
unless File.exists?("#{@destination}/ECOMM.pem")
|
25
|
+
gen_cert
|
26
|
+
end
|
27
|
+
sign_cert
|
28
|
+
end
|
29
|
+
|
30
|
+
def gen_cert
|
31
|
+
`openssl req -newkey rsa:1024 -keyout #{@destination}/#{@merchantId}_key.pem -out #{@destination}/#{@merchantId}_req.pem -subj "/C=lv/O=#{@domain}/CN=#{@merchantId}" -outform PEM`
|
32
|
+
if @cert_type == 'test'
|
33
|
+
puts "Open https://secureshop-test.firstdata.lv/report/keystore_.do and enter your email address and copy this into \"Cert Request (PEM)\""
|
34
|
+
puts File.open("#{@destination}/#{@merchantId}_req.pem", 'r').read.split("\n").collect{|line| line unless line =~ /^-/}.join("\n")
|
35
|
+
else
|
36
|
+
puts "Send \"#{@destination}/#{@merchantId}_req.pem\" to FirstData support email."
|
37
|
+
end
|
38
|
+
puts "\nAfter receiving email, download all attachments into #{@destination}"
|
39
|
+
prompt("To continue press [return]")
|
40
|
+
end
|
41
|
+
|
42
|
+
def sign_cert
|
43
|
+
puts "For PEM pass enter the same as in the first step, for import and export pass type new password."
|
44
|
+
`openssl pkcs12 -export -in #{@destination}/#{@merchantId}.pem -out #{@destination}/#{@merchantId}_keystore.p12 -certfile #{@destination}/ECOMM.pem -inkey #{@destination}/#{@merchantId}_key.pem`
|
45
|
+
`openssl pkcs12 -in #{@destination}/#{@merchantId}_keystore.p12 > #{@destination}/cert.pem`
|
46
|
+
puts "\nNow update your environment configuration files with constants:"
|
47
|
+
puts "\nFD_PEM = File.join(Rails.root, \"config\", \"first-data\", \"#{@cert_type}\", \"cert.pem\")"
|
48
|
+
puts "FD_PASS = '<Enter PEM pass phrase>'"
|
49
|
+
if @cert_type == 'test'
|
50
|
+
puts "\nAnd change mode to :test"
|
51
|
+
puts %^
|
52
|
+
config.after_initialize do
|
53
|
+
ActiveMerchant::Billing::Base.mode = :test
|
54
|
+
end
|
55
|
+
|
56
|
+
IMPORTANT
|
57
|
+
|
58
|
+
After you have test certificate you should run all FirstData tests https://secureshop-test.firstdata.lv/report/common/testplan/test.jsp
|
59
|
+
To do sou you need to update your merchant information https://secureshop-test.firstdata.lv/report/merchantlist.do
|
60
|
+
- change IP to your current IP
|
61
|
+
- change returnOkUrl and returnFailUrl to http://localhost:3000/first_data_test/test
|
62
|
+
- save
|
63
|
+
|
64
|
+
Now run server and start testing http://localhost:3000/first_data_test/test?nr=1
|
65
|
+
In transaction details you specify all data from response and amount as 1.00 LVL.
|
66
|
+
^
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def prompt q
|
73
|
+
puts "#{q}"
|
74
|
+
$stdout.flush
|
75
|
+
$stdin.gets.strip
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "lolita-first-data"
|
8
|
+
s.version = "1.0.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["ITHouse, Gatis Tomsons"]
|
12
|
+
s.date = "2011-09-07"
|
13
|
+
s.description = "FirstData Payment plugin for Lolita using ActiveMerchant"
|
14
|
+
s.email = "gatis@ithouse.cc"
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.md"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".rspec",
|
21
|
+
"Gemfile",
|
22
|
+
"Gemfile.lock",
|
23
|
+
"LICENSE.txt",
|
24
|
+
"README.md",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"app/controllers/lolita/first_data/common_controller.rb",
|
28
|
+
"app/controllers/lolita/first_data/test_controller.rb",
|
29
|
+
"app/controllers/lolita/first_data/transaction_controller.rb",
|
30
|
+
"app/models/lolita/first_data/transaction.rb",
|
31
|
+
"config/locales/en.yml",
|
32
|
+
"config/locales/lv.yml",
|
33
|
+
"config/routes.rb",
|
34
|
+
"lib/generators/lolita_first_data/install_generator.rb",
|
35
|
+
"lib/generators/lolita_first_data/templates/migration.rb",
|
36
|
+
"lib/lolita-first-data.rb",
|
37
|
+
"lib/lolita-first-data/billing.rb",
|
38
|
+
"lib/lolita-first-data/custom_logger.rb",
|
39
|
+
"lib/lolita-first-data/gateway.rb",
|
40
|
+
"lib/lolita-first-data/rails.rb",
|
41
|
+
"lib/tasks/first_data_tasks.rake",
|
42
|
+
"lolita-first-data.gemspec",
|
43
|
+
"spec/cert.pem",
|
44
|
+
"spec/fabricators/reservation_fabricator.rb",
|
45
|
+
"spec/fabricators/transaction_fabricator.rb",
|
46
|
+
"spec/first_data_spec.rb",
|
47
|
+
"spec/spec_helper.rb",
|
48
|
+
"spec/support/rails.rb"
|
49
|
+
]
|
50
|
+
s.homepage = "http://github.com/ithouse/lolita-first-data"
|
51
|
+
s.licenses = ["MIT"]
|
52
|
+
s.require_paths = ["lib"]
|
53
|
+
s.rubygems_version = "1.8.10"
|
54
|
+
s.summary = "FirstData Payment plugin for Lolita"
|
55
|
+
|
56
|
+
if s.respond_to? :specification_version then
|
57
|
+
s.specification_version = 3
|
58
|
+
|
59
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
60
|
+
s.add_runtime_dependency(%q<rails>, [">= 3.0.0"])
|
61
|
+
s.add_runtime_dependency(%q<activemerchant>, ["~> 1.17.0"])
|
62
|
+
s.add_development_dependency(%q<sqlite3>, ["~> 1.3.4"])
|
63
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.6.0"])
|
64
|
+
s.add_development_dependency(%q<webmock>, ["~> 1.7.6"])
|
65
|
+
s.add_development_dependency(%q<ruby-debug19>, ["~> 0.11.6"])
|
66
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
67
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
68
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
69
|
+
s.add_development_dependency(%q<fabrication>, ["~> 1.1.0"])
|
70
|
+
else
|
71
|
+
s.add_dependency(%q<rails>, [">= 3.0.0"])
|
72
|
+
s.add_dependency(%q<activemerchant>, ["~> 1.17.0"])
|
73
|
+
s.add_dependency(%q<sqlite3>, ["~> 1.3.4"])
|
74
|
+
s.add_dependency(%q<rspec>, ["~> 2.6.0"])
|
75
|
+
s.add_dependency(%q<webmock>, ["~> 1.7.6"])
|
76
|
+
s.add_dependency(%q<ruby-debug19>, ["~> 0.11.6"])
|
77
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
78
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
79
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
80
|
+
s.add_dependency(%q<fabrication>, ["~> 1.1.0"])
|
81
|
+
end
|
82
|
+
else
|
83
|
+
s.add_dependency(%q<rails>, [">= 3.0.0"])
|
84
|
+
s.add_dependency(%q<activemerchant>, ["~> 1.17.0"])
|
85
|
+
s.add_dependency(%q<sqlite3>, ["~> 1.3.4"])
|
86
|
+
s.add_dependency(%q<rspec>, ["~> 2.6.0"])
|
87
|
+
s.add_dependency(%q<webmock>, ["~> 1.7.6"])
|
88
|
+
s.add_dependency(%q<ruby-debug19>, ["~> 0.11.6"])
|
89
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
90
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
91
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
92
|
+
s.add_dependency(%q<fabrication>, ["~> 1.1.0"])
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
data/spec/cert.pem
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
Bag Attributes
|
2
|
+
localKeyID: 43 9C BD D3 7A E2 0F AF 0B CD FE 3C DC 0D 1C F2 7B 31 01 3C
|
3
|
+
subject=/C=lv/O=rentmama.com/CN=1205715
|
4
|
+
issuer=/C=LV/ST=Riga/L=Riga/O=BSC/OU=BSC/CN=ECOMM/emailAddress=gatisa@bsc.lv
|
5
|
+
-----BEGIN CERTIFICATE-----
|
6
|
+
MIICaDCCAdGgAwIBAgIGASx+2FQ/MA0GCSqGSIb3DQEBBQUAMHUxCzAJBgNVBAYT
|
7
|
+
AkxWMQ0wCwYDVQQIEwRSaWdhMQ0wCwYDVQQHEwRSaWdhMQwwCgYDVQQKEwNCU0Mx
|
8
|
+
DDAKBgNVBAsTA0JTQzEOMAwGA1UEAxMFRUNPTU0xHDAaBgkqhkiG9w0BCQEWDWdh
|
9
|
+
dGlzYUBic2MubHYwHhcNMTAxMTI0MTcwNDU1WhcNMTExMTI0MTcwNDU1WjA2MQsw
|
10
|
+
CQYDVQQGEwJsdjEVMBMGA1UEChMMcmVudG1hbWEuY29tMRAwDgYDVQQDEwcxMjA1
|
11
|
+
NzE1MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDD1qUrW+wQWirKgO8TEmNY
|
12
|
+
0HQVMsX7KI7dnYDxZbmRrVJnphtfsPkSlG94mnJVVhfPMHZarR1jjBGegEyfvmND
|
13
|
+
A/gkqP+jb7Ab4F/YiD4mcBQPlraLFNH/SR1I6LT/s5lIzwHeAAeGcdm589MvPB5w
|
14
|
+
SRrwrtk8uaCBI2qB6h2qaQIDAQABo0IwQDAdBgNVHQ4EFgQUkYZ8CFxL1omXWfjs
|
15
|
+
Qi1R2mIhEsswHwYDVR0jBBgwFoAUeMx7hKHipDRx8VQVqW3Zd/Q/iu0wDQYJKoZI
|
16
|
+
hvcNAQEFBQADgYEAER2D3mDAAObaaxMLlFCexyasCAx3XlZslQ9Im1BDM6Do1rIW
|
17
|
+
OQJi8mmmGLqmFHNA1Swnw0g5gDjHb0e+uvFJoMQOp9AL/dhshDimShBklu3O476D
|
18
|
+
ehuGv2rS8ERB01fYrz1UT6jIGMpLPR6ewxZUtLwjPERVNDYXg/gIdc7LwmA=
|
19
|
+
-----END CERTIFICATE-----
|
20
|
+
Bag Attributes: <No Attributes>
|
21
|
+
subject=/C=LV/ST=Riga/L=Riga/O=BSC/OU=BSC/CN=ECOMM/emailAddress=gatisa@bsc.lv
|
22
|
+
issuer=/C=LV/ST=Riga/L=Riga/O=BSC/OU=BSC/CN=ECOMM/emailAddress=gatisa@bsc.lv
|
23
|
+
-----BEGIN CERTIFICATE-----
|
24
|
+
MIIDMzCCApygAwIBAgIBADANBgkqhkiG9w0BAQQFADB1MQswCQYDVQQGEwJMVjEN
|
25
|
+
MAsGA1UECBMEUmlnYTENMAsGA1UEBxMEUmlnYTEMMAoGA1UEChMDQlNDMQwwCgYD
|
26
|
+
VQQLEwNCU0MxDjAMBgNVBAMTBUVDT01NMRwwGgYJKoZIhvcNAQkBFg1nYXRpc2FA
|
27
|
+
YnNjLmx2MB4XDTA0MDQwODAxMzcwOFoXDTE0MDQwNjAxMzcwOFowdTELMAkGA1UE
|
28
|
+
BhMCTFYxDTALBgNVBAgTBFJpZ2ExDTALBgNVBAcTBFJpZ2ExDDAKBgNVBAoTA0JT
|
29
|
+
QzEMMAoGA1UECxMDQlNDMQ4wDAYDVQQDEwVFQ09NTTEcMBoGCSqGSIb3DQEJARYN
|
30
|
+
Z2F0aXNhQGJzYy5sdjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzuhGdZxj
|
31
|
+
+SisIrvbbCbqE9zYFKzzm9EpYD1RB95FuKHTXDJvFzZ4BPigxHVKeFK+I6ok/pdw
|
32
|
+
0RC1v6SVQWCrFYhD4YaBnyZP/QhXvCsiWuqqYf+MTW+1qrTSiW18e+bVqZIVwEYi
|
33
|
+
7UF7Eo45ldqq1F5Sqja0rtYhuvqesaCF7H8CAwEAAaOB0jCBzzAdBgNVHQ4EFgQU
|
34
|
+
eMx7hKHipDRx8VQVqW3Zd/Q/iu0wgZ8GA1UdIwSBlzCBlIAUeMx7hKHipDRx8VQV
|
35
|
+
qW3Zd/Q/iu2heaR3MHUxCzAJBgNVBAYTAkxWMQ0wCwYDVQQIEwRSaWdhMQ0wCwYD
|
36
|
+
VQQHEwRSaWdhMQwwCgYDVQQKEwNCU0MxDDAKBgNVBAsTA0JTQzEOMAwGA1UEAxMF
|
37
|
+
RUNPTU0xHDAaBgkqhkiG9w0BCQEWDWdhdGlzYUBic2MubHaCAQAwDAYDVR0TBAUw
|
38
|
+
AwEB/zANBgkqhkiG9w0BAQQFAAOBgQCz+f3UFP3qHde5nXC5az0ypDJJbCbpo3p1
|
39
|
+
T82Zu1Gz0DEF4EOj1oPyt7RnIid3FLWQ42xCBmIcSYXwdfg6eUDLYbW8W4FWsTmP
|
40
|
+
h2WYdD7LSF6yZb4OmsfQdY1ITDwoQu4LDflA34zW3yEd2cA+OZp5DllVbpu2CUaG
|
41
|
+
M2Pi8ijiEA==
|
42
|
+
-----END CERTIFICATE-----
|
43
|
+
Bag Attributes
|
44
|
+
localKeyID: 43 9C BD D3 7A E2 0F AF 0B CD FE 3C DC 0D 1C F2 7B 31 01 3C
|
45
|
+
Key Attributes: <No Attributes>
|
46
|
+
-----BEGIN RSA PRIVATE KEY-----
|
47
|
+
Proc-Type: 4,ENCRYPTED
|
48
|
+
DEK-Info: DES-EDE3-CBC,4BFFF89B175212F9
|
49
|
+
|
50
|
+
Kj6qk3u2SqeowQUZEKY4HePMfbTUsvcHpACMUPuXLGMSMlHsGkd6L3tZU/qCtx8G
|
51
|
+
lBdF+eRHzrirYOAfawjbe4P6B7zcH4zsg1vFm3jKARgsG6PYFwhIyrjjHCFkiSM1
|
52
|
+
0fwIjCVu55EyVhEZQtjYIvfXQiI8kimF6sB6Ayru3ZTyA1U2P3FuHb24whocdAPn
|
53
|
+
l2LiRezYO0dx9PjvZDSRFszbImJiHgEUtMx0FeQsP1xBtH86X4OgmygOXtAnqOeU
|
54
|
+
CAvXJiB5wf8x7EEsFNf2mlRofQ0nDFfs2WV1GN+xxoBE6wKFuTpYZBGPwJyonDci
|
55
|
+
7s+51NYZoGXBImk+7zptr3NEEXSRDP2AeRaKXe6JfhvZuCSgvM4Q+wR1uYTixozp
|
56
|
+
kPMjQHDyneZDRfqL3x+dpcxjbBhXIjjGm3Pt1zUqhcUmCXwe7CLc67mxNNMc89Vh
|
57
|
+
4RJagkG14JT9Qphgko2X6+OtBRKFfxC6g/aVxcuaxiYnB6m5UPp36hmnb0iaqoQi
|
58
|
+
FFRDEHJmgZUVMQBM6x94h6CSvrNxeMCRD2s3XKS9b+Jy/GAiHv8+w/TJF4OL52fG
|
59
|
+
FiFkCob5/1gyn7pjXk2QelPg7v625ppO1reQQKj472wG79C3cNF8zBo72R8NXiTM
|
60
|
+
/zo6mxAv2r8kfJ9vSPjBjxLxrVsJcjclaPAzADnCWhXbec/K0nb9jszTRFqpWI8x
|
61
|
+
3NiXipaV7M96slcz7MiOkdm5DvgfBbjtFxyirRnQUC6HoGm4BKjwxB3BoOQZh2MW
|
62
|
+
nKQju6pJxleyABQpmEwrtRdy1hf3XUrcu2v3ucTaFmA7MpAv0987uA==
|
63
|
+
-----END RSA PRIVATE KEY-----
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
3
|
+
|
4
|
+
describe Lolita::FirstData::Transaction do
|
5
|
+
|
6
|
+
let(:trx){ Fabricate(:transaction) }
|
7
|
+
let(:gateway) {
|
8
|
+
ActiveMerchant::Billing::FirstDataGateway.new(
|
9
|
+
:pem => File.open(FD_PEM).read,
|
10
|
+
:pem_password => FD_PASS,
|
11
|
+
:payment => trx.paymentable
|
12
|
+
)
|
13
|
+
}
|
14
|
+
|
15
|
+
it "should create transaction" do
|
16
|
+
trx.transaction_id.should == "D6zNpp/BJnC1y2wZntm4D8XrB2g="
|
17
|
+
trx.status.should == 'processing'
|
18
|
+
trx.paymentable.full_price.should == 250
|
19
|
+
trx.ip.should == "100.100.100.100"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should process answer and save transaction" do
|
23
|
+
rs = gateway.get_trans_result("127.0.0.1", trx.transaction_id)
|
24
|
+
request = double('request')
|
25
|
+
request.stub(:env).and_return({})
|
26
|
+
trx.process_answer(rs, gateway, request).should be_true
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should process completed payment" do
|
30
|
+
stub_request(:post, "https://secureshop.firstdata.lv:8443/ecomm/MerchantHandler").
|
31
|
+
with(:body => {"client_ip_addr"=>"127.0.0.1", "command"=>"c", "trans_id"=>"D6zNpp/BJnC1y2wZntm4D8XrB2g="},
|
32
|
+
:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/x-www-form-urlencoded', 'User-Agent'=>'Ruby'}).
|
33
|
+
to_return(:status => 200, :body => "RESULT: OK RESULT_CODE: 000", :headers => {})
|
34
|
+
|
35
|
+
rs = gateway.get_trans_result("127.0.0.1", trx.transaction_id)
|
36
|
+
request = double('request')
|
37
|
+
request.stub(:env).and_return({})
|
38
|
+
trx.process_answer(rs, gateway, request).should be_true
|
39
|
+
trx.status.should == 'completed'
|
40
|
+
trx.paymentable.status.should == 'completed'
|
41
|
+
trx.paymentable.paid?.should be_true
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should process rejected payment" do
|
45
|
+
stub_request(:post, "https://secureshop.firstdata.lv:8443/ecomm/MerchantHandler").
|
46
|
+
with(:body => {"client_ip_addr"=>"127.0.0.1", "command"=>"c", "trans_id"=>"D6zNpp/BJnC1y2wZntm4D8XrB2g="},
|
47
|
+
:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/x-www-form-urlencoded', 'User-Agent'=>'Ruby'}).
|
48
|
+
to_return(:status => 200, :body => "RESULT: FAILED RESULT_CODE: 102", :headers => {})
|
49
|
+
|
50
|
+
rs = gateway.get_trans_result("127.0.0.1", trx.transaction_id)
|
51
|
+
request = double('request')
|
52
|
+
request.stub(:env).and_return({})
|
53
|
+
trx.process_answer(rs, gateway, request).should be_true
|
54
|
+
trx.status.should == 'rejected'
|
55
|
+
trx.transaction_code.should == "102"
|
56
|
+
trx.paymentable.status.should == 'rejected'
|
57
|
+
trx.paymentable.fd_error_message.should == "Rejected, possible fraud detected"
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should process close day" do
|
61
|
+
stub_request(:post, "https://secureshop.firstdata.lv:8443/ecomm/MerchantHandler").
|
62
|
+
with(:body => {"command"=>"b"},:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/x-www-form-urlencoded', 'User-Agent'=>'Ruby'}).
|
63
|
+
to_return(:status => 200, :body => "RESULT: OK", :headers => {})
|
64
|
+
|
65
|
+
Reservation.close_business_day.should be_true
|
66
|
+
end
|
67
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'active_record'
|
12
|
+
require 'rspec'
|
13
|
+
require 'webmock/rspec'
|
14
|
+
require 'fabrication'
|
15
|
+
require 'logger'
|
16
|
+
require 'ruby-debug'
|
17
|
+
require 'lolita-first-data'
|
18
|
+
require 'support/rails'
|
19
|
+
|
20
|
+
FD_PEM = File.dirname(__FILE__) + "/cert.pem"
|
21
|
+
FD_PASS = "1234"
|
22
|
+
|
23
|
+
# load transaction module
|
24
|
+
require File.dirname(__FILE__)+'/../app/models/lolita/first_data/transaction.rb'
|
25
|
+
|
26
|
+
ActiveRecord::Base.logger = Logger.new(File.open("#{File.dirname(__FILE__)}/database.log", 'w+'))
|
27
|
+
ActiveRecord::Base.establish_connection({ :database => ":memory:", :adapter => 'sqlite3', :timeout => 500 })
|
28
|
+
|
29
|
+
# setup I18n
|
30
|
+
I18n.load_path += Dir[File.join(File.dirname(__FILE__), '..', 'config', 'locales', '*.{rb,yml}').to_s]
|
31
|
+
I18n.available_locales = [:en,:lv]
|
32
|
+
I18n.default_locale = :en
|
33
|
+
I18n.locale = :en
|
34
|
+
|
35
|
+
# load transaction module
|
36
|
+
require File.dirname(__FILE__)+'/../app/models/lolita/first_data/transaction.rb'
|
37
|
+
|
38
|
+
# Add models
|
39
|
+
ActiveRecord::Schema.define do
|
40
|
+
create_table :first_data_transactions do |t|
|
41
|
+
t.string :transaction_id, :length => 28
|
42
|
+
t.string :transaction_code, :length => 3
|
43
|
+
t.string :status, :default => 'processing'
|
44
|
+
t.references :paymentable, :polymorphic => true
|
45
|
+
t.string :ip, :length => 10
|
46
|
+
|
47
|
+
t.timestamps
|
48
|
+
end
|
49
|
+
|
50
|
+
create_table :reservations do |t|
|
51
|
+
t.integer :full_price
|
52
|
+
t.string :status
|
53
|
+
|
54
|
+
t.timestamps
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class Reservation < ActiveRecord::Base
|
59
|
+
include Lolita::FirstData::Billing
|
60
|
+
|
61
|
+
# Methods for FirstData
|
62
|
+
#-----------------------
|
63
|
+
def price
|
64
|
+
full_price
|
65
|
+
end
|
66
|
+
|
67
|
+
# string up to 125 symbols
|
68
|
+
def description
|
69
|
+
"testing"
|
70
|
+
end
|
71
|
+
|
72
|
+
# returns 3 digit string according to http://en.wikipedia.org/wiki/ISO_4217
|
73
|
+
def currency
|
74
|
+
"840"
|
75
|
+
end
|
76
|
+
|
77
|
+
# this is called when FirstData merchant is taking some actions
|
78
|
+
# there you can save the log message other than the default log file
|
79
|
+
def log severity, message
|
80
|
+
end
|
81
|
+
|
82
|
+
def fd_trx_saved trx
|
83
|
+
case trx.status
|
84
|
+
when 'processing'
|
85
|
+
update_attribute(:status, 'payment')
|
86
|
+
when 'completed'
|
87
|
+
update_attribute(:status, 'completed')
|
88
|
+
when 'rejected'
|
89
|
+
update_attribute(:status, 'rejected')
|
90
|
+
end
|
91
|
+
end
|
92
|
+
#-----------------------
|
93
|
+
end
|
94
|
+
|
95
|
+
RSpec.configure do |config|
|
96
|
+
config.mock_with :rspec
|
97
|
+
config.before(:each) do
|
98
|
+
ActiveRecord::Base.connection.execute "DELETE from first_data_transactions"
|
99
|
+
ActiveRecord::Base.connection.execute "DELETE from reservations"
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'active_support/core_ext/object/to_param'
|
2
|
+
|
3
|
+
class Object
|
4
|
+
# Converts an object into a string suitable for use as a URL query string, using the given <tt>key</tt> as the
|
5
|
+
# param name.
|
6
|
+
#
|
7
|
+
# Note: This method is defined as a default implementation for all Objects for Hash#to_query to work.
|
8
|
+
def to_query(key)
|
9
|
+
require 'cgi' unless defined?(CGI) && defined?(CGI::escape)
|
10
|
+
"#{CGI.escape(key.to_s)}=#{CGI.escape(to_param.to_s)}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Hash
|
15
|
+
alias_method :to_query, :to_param
|
16
|
+
end
|