lolita-first-data 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,6 @@
1
+ if defined?(Rails)
2
+ module LolitaFirstData
3
+ class Engine < Rails::Engine
4
+ end
5
+ end
6
+ end
@@ -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
+
@@ -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,4 @@
1
+ Fabricator(:reservation) do
2
+ full_price 250
3
+ status 'processing'
4
+ end
@@ -0,0 +1,7 @@
1
+ Fabricator(:transaction, class_name: "Lolita::FirstData::Transaction") do
2
+ transaction_id "D6zNpp/BJnC1y2wZntm4D8XrB2g="
3
+ transaction_code ""
4
+ status 'processing'
5
+ paymentable! :fabricator => :reservation
6
+ ip "100.100.100.100"
7
+ end
@@ -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
@@ -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