omni_kassa 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,70 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
+
5
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
6
+ <head>
7
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
8
+
9
+ <title>File: test_helper.rb [RDoc Documentation]</title>
10
+
11
+ <link type="text/css" media="screen" href="../../../rdoc.css" rel="stylesheet" />
12
+
13
+ <script src="../../../js/jquery.js" type="text/javascript"
14
+ charset="utf-8"></script>
15
+ <script src="../../../js/thickbox-compressed.js" type="text/javascript"
16
+ charset="utf-8"></script>
17
+ <script src="../../../js/quicksearch.js" type="text/javascript"
18
+ charset="utf-8"></script>
19
+ <script src="../../../js/darkfish.js" type="text/javascript"
20
+ charset="utf-8"></script>
21
+ </head>
22
+
23
+ <body class="file file-popup">
24
+ <div id="metadata">
25
+ <dl>
26
+ <dt class="modified-date">Last Modified</dt>
27
+ <dd class="modified-date">2012-12-02 15:11:58 +0100</dd>
28
+
29
+
30
+ <dt class="requires">Requires</dt>
31
+ <dd class="requires">
32
+ <ul>
33
+
34
+ <li>rubygems</li>
35
+
36
+ <li>bundler/setup</li>
37
+
38
+ <li>omni_kassa</li>
39
+
40
+ <li>minitest/unit</li>
41
+
42
+ <li>capybara</li>
43
+
44
+ <li>capybara/dsl</li>
45
+
46
+ <li>rack/test</li>
47
+
48
+ <li>sinatra</li>
49
+
50
+ <li>./app</li>
51
+
52
+ </ul>
53
+ </dd>
54
+
55
+
56
+
57
+ </dl>
58
+ </div>
59
+
60
+ <div id="documentation">
61
+
62
+ <div class="description">
63
+ <h2>Description</h2>
64
+
65
+ </div>
66
+
67
+ </div>
68
+ </body>
69
+ </html>
70
+
@@ -0,0 +1,54 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
+
5
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
6
+ <head>
7
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
8
+
9
+ <title>File: omni_kassa_test.rb [RDoc Documentation]</title>
10
+
11
+ <link type="text/css" media="screen" href="../rdoc.css" rel="stylesheet" />
12
+
13
+ <script src="../js/jquery.js" type="text/javascript"
14
+ charset="utf-8"></script>
15
+ <script src="../js/thickbox-compressed.js" type="text/javascript"
16
+ charset="utf-8"></script>
17
+ <script src="../js/quicksearch.js" type="text/javascript"
18
+ charset="utf-8"></script>
19
+ <script src="../js/darkfish.js" type="text/javascript"
20
+ charset="utf-8"></script>
21
+ </head>
22
+
23
+ <body class="file file-popup">
24
+ <div id="metadata">
25
+ <dl>
26
+ <dt class="modified-date">Last Modified</dt>
27
+ <dd class="modified-date">2012-12-02 15:11:46 +0100</dd>
28
+
29
+
30
+ <dt class="requires">Requires</dt>
31
+ <dd class="requires">
32
+ <ul>
33
+
34
+ <li>omni_kassa/test_helper</li>
35
+
36
+ </ul>
37
+ </dd>
38
+
39
+
40
+
41
+ </dl>
42
+ </div>
43
+
44
+ <div id="documentation">
45
+
46
+ <div class="description">
47
+ <h2>Description</h2>
48
+
49
+ </div>
50
+
51
+ </div>
52
+ </body>
53
+ </html>
54
+
@@ -0,0 +1,52 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
+
5
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
6
+ <head>
7
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
8
+
9
+ <title>File: test_settings.rb [RDoc Documentation]</title>
10
+
11
+ <link type="text/css" media="screen" href="./rdoc.css" rel="stylesheet" />
12
+
13
+ <script src="./js/jquery.js" type="text/javascript"
14
+ charset="utf-8"></script>
15
+ <script src="./js/thickbox-compressed.js" type="text/javascript"
16
+ charset="utf-8"></script>
17
+ <script src="./js/quicksearch.js" type="text/javascript"
18
+ charset="utf-8"></script>
19
+ <script src="./js/darkfish.js" type="text/javascript"
20
+ charset="utf-8"></script>
21
+ </head>
22
+
23
+ <body class="file file-popup">
24
+ <div id="metadata">
25
+ <dl>
26
+ <dt class="modified-date">Last Modified</dt>
27
+ <dd class="modified-date">2012-12-02 14:52:08 +0100</dd>
28
+
29
+
30
+ <dt class="requires">Requires</dt>
31
+ <dd class="requires">
32
+ <ul>
33
+
34
+ </ul>
35
+ </dd>
36
+
37
+
38
+
39
+ </dl>
40
+ </div>
41
+
42
+ <div id="documentation">
43
+
44
+ <div class="description">
45
+ <h2>Description</h2>
46
+
47
+ </div>
48
+
49
+ </div>
50
+ </body>
51
+ </html>
52
+
@@ -0,0 +1,69 @@
1
+ module OmniKassa
2
+ class Request
3
+ # OmniKassa requirement, doesn't do anything
4
+ KEY_VERSION = 1
5
+
6
+ # OmniKassa requirement, doesn't do anything
7
+ INTERFACE_VERSION = 'HP_1.0'
8
+
9
+ REQUIRED = :merchant_id, :currency_code, :transaction_reference,
10
+ :order_id, :amount, :normal_return_url, :key_version
11
+
12
+ attr_accessor :merchant_id, :currency_code, :transaction_reference,
13
+ :order_id, :amount, :normal_return_url, :key_version,
14
+ :automatic_return_url
15
+
16
+ def initialize
17
+ self.key_version = KEY_VERSION
18
+
19
+ # Load default settings into the request
20
+ OmniKassa.request_settings.each do |key, value|
21
+ send key.to_s + '=', value
22
+ end
23
+ end
24
+
25
+ def valid?
26
+ REQUIRED.map do |attr|
27
+ value = send attr
28
+ return false if value.nil?
29
+ end
30
+ end
31
+
32
+ def perform
33
+ HTTParty.post(OmniKassa.url, query: query, ssl_version: :SSLv3).body
34
+ end
35
+
36
+ def transaction_reference
37
+ @transaction_reference.call(order_id)
38
+ end
39
+
40
+ protected
41
+ def query
42
+ {
43
+ InterfaceVersion: INTERFACE_VERSION,
44
+ Data: data,
45
+ Seal: seal
46
+ }
47
+ end
48
+
49
+ def data
50
+ data_hash.to_a.map {|a| a.join('=') }.join('|')
51
+ end
52
+
53
+ def data_hash
54
+ REQUIRED.map do |attr|
55
+ value = send attr
56
+ raise RequestError, "attribute '#{attr}' missing" if value.nil?
57
+
58
+ [attr.to_s.camelcase(:lower), value]
59
+ end
60
+ end
61
+
62
+ def seal
63
+ Digest::SHA2.new.update data + OmniKassa.secret_key
64
+ end
65
+
66
+ class RequestError < OmniKassaError; end
67
+ end
68
+ end
69
+
@@ -0,0 +1,57 @@
1
+ module OmniKassa
2
+ class Response
3
+ RESPONSE_CODES = {
4
+ 0 => :success,
5
+ 17 => :user_cancellation,
6
+ 97 => :request_timeout
7
+ }
8
+
9
+ attr_accessor :data, :seal, :order_id, :response_code, :amount
10
+
11
+ def initialize(params)
12
+ self.data = params[:Data]
13
+ self.seal = params[:Seal]
14
+
15
+ verify_seal!
16
+ end
17
+
18
+ def successful?
19
+ response == :success
20
+ end
21
+
22
+ def response
23
+ RESPONSE_CODES[response_code] or :unknown_failure
24
+ end
25
+
26
+ def data=(data)
27
+ @data = data
28
+ parse_data_hash
29
+ end
30
+
31
+ def response_code=(response_code)
32
+ raise ResponseCodeError if response_code.to_s.scan(/\D/).present?
33
+ @response_code = response_code.to_i
34
+ end
35
+
36
+ protected
37
+ def verify_seal!
38
+ seal = Digest::SHA2.new.update(data + OmniKassa.secret_key)
39
+ raise SealMismatchError if seal != self.seal
40
+ end
41
+
42
+ def parse_data_hash
43
+ data_hash.each do |key, value|
44
+ key = key.underscore + '='
45
+ send key, value if respond_to? key
46
+ end
47
+ end
48
+
49
+ def data_hash
50
+ Hash[data.split('|').map {|a| a.split('=') }]
51
+ end
52
+
53
+ class SealMismatchError < OmniKassaError; end
54
+ class ResponseCodeError < OmniKassaError; end
55
+ end
56
+ end
57
+
data/lib/omni_kassa.rb ADDED
@@ -0,0 +1,42 @@
1
+ require 'httparty'
2
+ require 'active_support/core_ext/string'
3
+
4
+ module OmniKassa
5
+ REQUEST_SETTINGS = :merchant_id, :currency_code, :transaction_reference
6
+ SETTINGS = REQUEST_SETTINGS + [:secret_key, :url]
7
+
8
+ def self.config(settings)
9
+ for setting in SETTINGS
10
+ value = settings[setting.to_sym]
11
+ raise ConfigError, "config setting '#{setting}' missing" if value.nil?
12
+
13
+ class_variable_set '@@' + setting.to_s, value
14
+ end
15
+ end
16
+
17
+ def self.request_settings
18
+ Hash[REQUEST_SETTINGS.map do |setting|
19
+ [setting.to_s, class_variable_get('@@' + setting.to_s)]
20
+ end]
21
+ end
22
+
23
+ def self.secret_key
24
+ @@secret_key
25
+ end
26
+
27
+ def self.url
28
+ @@url
29
+ end
30
+
31
+ # The common base class for all exceptions raised by OmniKassa
32
+ class OmniKassaError < StandardError
33
+ end
34
+
35
+ # Raised if something is wrong with the configuration parameters
36
+ class ConfigError < OmniKassaError
37
+ end
38
+ end
39
+
40
+ require 'omni_kassa/request'
41
+ require 'omni_kassa/response'
42
+
@@ -0,0 +1,21 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'omni_kassa'
3
+ s.version = '1.0.0'
4
+ s.author = 'Pepijn Looije'
5
+ s.email = 'pepijn@plict.nl'
6
+ s.summary = 'Easier Rabobank OmniKassa payments'
7
+
8
+ s.required_ruby_version = '>= 1.9'
9
+
10
+ s.add_dependency 'httparty'
11
+ s.add_dependency 'activesupport'
12
+
13
+ s.add_development_dependency 'rake'
14
+ s.add_development_dependency 'rack-test'
15
+ s.add_development_dependency 'minitest'
16
+ s.add_development_dependency 'sinatra'
17
+ #s.add_development_dependency 'capybara'
18
+
19
+ s.files = Dir["#{File.dirname(__FILE__)}/**/*"]
20
+ end
21
+
data/test/capybara.rb ADDED
@@ -0,0 +1,26 @@
1
+ require 'omni_kassa/test_helper'
2
+
3
+ class AcceptanceTest < MiniTest::Unit::TestCase
4
+ include Capybara::DSL
5
+
6
+ Capybara.default_driver = :selenium
7
+
8
+ def setup
9
+ Capybara.app = Sinatra::Application.new
10
+ end
11
+
12
+ def test_amount_1337
13
+ visit '/1337'
14
+ assert page.has_content? "13,37"
15
+ find(:xpath, '//div[@class="availablePaymentMeans"]/div[2]/a').click
16
+ select 'Issuer Simulation 0 : Short', from: 'issuerComponent'
17
+ click_on 'Akkoord'
18
+ click_on 'Confirm Transaction'
19
+ click_on 'Verder'
20
+ click_on 'Continue'
21
+
22
+ # FIXME: Annoying Firefox security warning
23
+ assert page.has_content? 'success'
24
+ end
25
+ end
26
+
@@ -0,0 +1,16 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'omni_kassa'
4
+
5
+ require 'minitest/unit'
6
+ require 'rack/test'
7
+
8
+ require './test_settings'
9
+
10
+ #require 'capybara'
11
+ #require 'capybara/dsl'
12
+ #require 'sinatra'
13
+ #require './app'
14
+
15
+ MiniTest::Unit.autorun
16
+
@@ -0,0 +1,50 @@
1
+ require 'omni_kassa/test_helper'
2
+
3
+ ORDER_ID = rand(10000)
4
+ AMOUNT = rand(10000)
5
+
6
+ class RequestTest < MiniTest::Unit::TestCase
7
+ def setup
8
+ @request = OmniKassa::Request.new
9
+ @request.order_id = ORDER_ID
10
+ @request.amount = AMOUNT
11
+ @request.normal_return_url = 'https://google.com'
12
+ end
13
+
14
+ def test_attributes
15
+ assert_equal 1, @request.key_version
16
+ assert_equal "002020000000001", @request.merchant_id
17
+ assert_equal 978, @request.currency_code
18
+ assert_equal "omnikassatest#{Time.now.to_i}",
19
+ @request.transaction_reference
20
+
21
+ assert_equal ORDER_ID, @request.order_id
22
+ assert_equal AMOUNT, @request.amount
23
+ assert_equal 'https://google.com',
24
+ @request.normal_return_url
25
+ end
26
+
27
+ def test_invalid_without_order_id
28
+ @request.order_id = nil
29
+ refute @request.valid?
30
+ end
31
+
32
+ def test_invalid_without_amount
33
+ @request.amount = nil
34
+ refute @request.valid?
35
+ end
36
+
37
+ def test_invalid_without_normal_return_url
38
+ @request.normal_return_url = nil
39
+ refute @request.valid?
40
+ end
41
+
42
+ def test_perform_invalid
43
+ @request.amount = 0
44
+ assert_match /ERROR/, @request.perform
45
+ end
46
+
47
+ def test_perform_valid
48
+ refute_match /ERROR/, @request.perform
49
+ end
50
+ end
@@ -0,0 +1,46 @@
1
+ require 'omni_kassa/test_helper'
2
+
3
+ class ResponseTest < MiniTest::Unit::TestCase
4
+ def setup
5
+ @params = {
6
+ Data: "amount=1337|captureDay=0|captureMode=AUTHOR_CAPTURE|currencyCode=978|merchantId=002020000000001|orderId=527|transactionDateTime=2012-12-02T21:41:01+01:00|transactionReference=omnikassatest1354480861|keyVersion=1|authorisationId=0020000006791167|paymentMeanBrand=IDEAL|paymentMeanType=CREDIT_TRANSFER|responseCode=00",
7
+ InterfaceVersion: "HP_1.0",
8
+ Encode: '',
9
+ Seal: '46204f0e97394293c9270b6313e78524027acba1f83d4ce9682848e1f5927ab3'
10
+ }
11
+
12
+ @response = OmniKassa::Response.new(@params)
13
+ end
14
+
15
+ def test_attributes
16
+ assert_equal "527", @response.order_id
17
+ assert_equal "1337", @response.amount
18
+ end
19
+
20
+ def test_responses
21
+ assert_equal :success, @response.response
22
+
23
+ @response.response_code = 17
24
+ assert_equal :user_cancellation, @response.response
25
+
26
+ @response.response_code = 97
27
+ assert_equal :request_timeout, @response.response
28
+
29
+ @response.response_code = 1 # not 0
30
+ assert_equal :unknown_failure, @response.response
31
+ end
32
+
33
+ def test_invalid_seal
34
+ @params[:Seal] = 'haxx0r'
35
+ assert_raises OmniKassa::Response::SealMismatchError do
36
+ OmniKassa::Response.new(@params)
37
+ end
38
+ end
39
+
40
+ def test_invalid_response_code
41
+ assert_raises OmniKassa::Response::ResponseCodeError do
42
+ @response.response_code = '1337x'
43
+ end
44
+ end
45
+ end
46
+
data/test_settings.rb ADDED
@@ -0,0 +1,8 @@
1
+ OmniKassa.config(
2
+ secret_key: '002020000000001_KEY1',
3
+ merchant_id: '002020000000001',
4
+ currency_code: 978,
5
+ transaction_reference: lambda {|order_id| "omnikassatest#{Time.now.to_i}" },
6
+ url: 'https://payment-webinit.simu.omnikassa.rabobank.nl/paymentServlet'
7
+ )
8
+
metadata ADDED
@@ -0,0 +1,176 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: omni_kassa
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Pepijn Looije
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: httparty
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: activesupport
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rack-test
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: minitest
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: sinatra
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ description:
111
+ email: pepijn@plict.nl
112
+ executables: []
113
+ extensions: []
114
+ extra_rdoc_files: []
115
+ files:
116
+ - ./app.rb
117
+ - ./config.ru
118
+ - ./doc/app_rb.html
119
+ - ./doc/created.rid
120
+ - ./doc/Gemfile.html
121
+ - ./doc/HelloWorldTest.html
122
+ - ./doc/index.html
123
+ - ./doc/lib/omni_kassa/request_rb.html
124
+ - ./doc/lib/omni_kassa/response_rb.html
125
+ - ./doc/lib/omni_kassa_rb.html
126
+ - ./doc/OmniKassa/ConfigError.html
127
+ - ./doc/OmniKassa/OmniKassaError.html
128
+ - ./doc/OmniKassa/Request/RequestError.html
129
+ - ./doc/OmniKassa/Request.html
130
+ - ./doc/OmniKassa/Response/ResponseCodeError.html
131
+ - ./doc/OmniKassa/Response/SealMismatchError.html
132
+ - ./doc/OmniKassa/Response.html
133
+ - ./doc/OmniKassa.html
134
+ - ./doc/Rakefile.html
135
+ - ./doc/rdoc.css
136
+ - ./doc/test/lib/omni_kassa/test_helper_rb.html
137
+ - ./doc/test/omni_kassa_test_rb.html
138
+ - ./doc/test_settings_rb.html
139
+ - ./Gemfile
140
+ - ./Gemfile.lock
141
+ - ./lib/omni_kassa/request.rb
142
+ - ./lib/omni_kassa/response.rb
143
+ - ./lib/omni_kassa.rb
144
+ - ./omni_kassa.gemspec
145
+ - ./Rakefile
146
+ - ./README.md
147
+ - ./test/capybara.rb
148
+ - ./test/lib/omni_kassa/test_helper.rb
149
+ - ./test/request_test.rb
150
+ - ./test/response_test.rb
151
+ - ./test_settings.rb
152
+ homepage:
153
+ licenses: []
154
+ post_install_message:
155
+ rdoc_options: []
156
+ require_paths:
157
+ - lib
158
+ required_ruby_version: !ruby/object:Gem::Requirement
159
+ none: false
160
+ requirements:
161
+ - - ! '>='
162
+ - !ruby/object:Gem::Version
163
+ version: '1.9'
164
+ required_rubygems_version: !ruby/object:Gem::Requirement
165
+ none: false
166
+ requirements:
167
+ - - ! '>='
168
+ - !ruby/object:Gem::Version
169
+ version: '0'
170
+ requirements: []
171
+ rubyforge_project:
172
+ rubygems_version: 1.8.23
173
+ signing_key:
174
+ specification_version: 3
175
+ summary: Easier Rabobank OmniKassa payments
176
+ test_files: []