wirecard 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.travis.yml +15 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +33 -0
- data/Rakefile +8 -0
- data/lib/wirecard.rb +37 -0
- data/lib/wirecard/base.rb +51 -0
- data/lib/wirecard/callback.rb +57 -0
- data/lib/wirecard/configuration.rb +38 -0
- data/lib/wirecard/data_storage/base.rb +13 -0
- data/lib/wirecard/data_storage/init.rb +19 -0
- data/lib/wirecard/data_storage/read.rb +10 -0
- data/lib/wirecard/fingerprint/base.rb +42 -0
- data/lib/wirecard/fingerprint/sha_512.rb +9 -0
- data/lib/wirecard/payment_process/init.rb +21 -0
- data/lib/wirecard/request.rb +59 -0
- data/lib/wirecard/response.rb +27 -0
- data/lib/wirecard/version.rb +3 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/unit_tests/base_shared.rb +34 -0
- data/spec/unit_tests/data_storage/init_spec.rb +37 -0
- data/spec/unit_tests/support/shared_examples.rb +35 -0
- data/spec/wirecard_spec.rb +133 -0
- data/wirecard.gemspec +25 -0
- metadata +133 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 33a010befa5f036f4cab9eb4655b23b71e8c5a20
|
4
|
+
data.tar.gz: 52c073c41d4b78d7712160fcd1648f10fdb89810
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2da2e6633594d1b33d9a27ef9c942a35c8913d51a5257f7aaee49fb5eafee492d2efbbd24ef95cab0f30f80f74e3fa418130106573828ce969ea17c9ec6a7ba2
|
7
|
+
data.tar.gz: 67dff048e38eae1222cbfd83b842d265fd120ad652770a9c8fb162b397fe438a4e7ca1dff0f2d1780c3b553e1a17c17cfadb2157a6054dd53698dd31aaf8ba48
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Dominic Breuker
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# Wirecard
|
2
|
+
|
3
|
+
[![Code Climate](https://codeclimate.com/github/DominicBreuker/wirecard/badges/gpa.svg)](https://codeclimate.com/github/DominicBreuker/wirecard)
|
4
|
+
|
5
|
+
Implements wirecard API
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'wirecard'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install wirecard
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
TODO: Write usage instructions here
|
26
|
+
|
27
|
+
## Contributing
|
28
|
+
|
29
|
+
1. Fork it ( https://github.com/[my-github-username]/wirecard/fork )
|
30
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
31
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
32
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
33
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/lib/wirecard.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'wirecard/version'
|
2
|
+
require 'wirecard/base'
|
3
|
+
require 'wirecard/configuration'
|
4
|
+
require 'wirecard/request'
|
5
|
+
require 'wirecard/response'
|
6
|
+
require 'wirecard/callback'
|
7
|
+
require 'wirecard/data_storage/base'
|
8
|
+
require 'wirecard/data_storage/init'
|
9
|
+
require 'wirecard/data_storage/read'
|
10
|
+
require 'wirecard/fingerprint/base'
|
11
|
+
require 'wirecard/fingerprint/sha_512'
|
12
|
+
require 'wirecard/payment_process/init'
|
13
|
+
|
14
|
+
module Wirecard
|
15
|
+
autoload :Base, 'wirecard/base'
|
16
|
+
autoload :Request, 'wirecard/request'
|
17
|
+
autoload :Response, 'wirecard/response'
|
18
|
+
autoload :Callback, 'wirecard/callback'
|
19
|
+
autoload :Base, 'wirecard/data_storage/base'
|
20
|
+
autoload :Init, 'wirecard/data_storage/init'
|
21
|
+
autoload :Read, 'wirecard/data_storage/read'
|
22
|
+
autoload :Base, 'wirecard/fingerprint/base'
|
23
|
+
autoload :Sha512, 'wirecard/fingerprint/sha_512'
|
24
|
+
autoload :Init, 'wirecard/payment_process/init'
|
25
|
+
|
26
|
+
class << self
|
27
|
+
def configure
|
28
|
+
yield configuration
|
29
|
+
end
|
30
|
+
|
31
|
+
def configuration
|
32
|
+
@configuration ||= Configuration.new
|
33
|
+
end
|
34
|
+
|
35
|
+
alias :config :configuration
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Wirecard
|
2
|
+
class Base
|
3
|
+
|
4
|
+
attr_reader :request
|
5
|
+
|
6
|
+
def defaults
|
7
|
+
@defaults ||= {
|
8
|
+
customer_id: Wirecard.config.customer_id,
|
9
|
+
shop_id: Wirecard.config.shop_id
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(params = {})
|
14
|
+
@request = Wirecard::Request.new(
|
15
|
+
params: defaults.merge(params),
|
16
|
+
implicit_fingerprint_order: implicit_fingerprint_order,
|
17
|
+
uri: uri
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
### ------------------------------------------ ###
|
22
|
+
### -------------- API request --------------- ###
|
23
|
+
### ------------------------------------------ ###
|
24
|
+
|
25
|
+
def post
|
26
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
27
|
+
http.use_ssl = true
|
28
|
+
|
29
|
+
Wirecard::Response.new(http.request(request.to_post)).to_hash
|
30
|
+
end
|
31
|
+
|
32
|
+
### ------------------------------------------ ###
|
33
|
+
### ---------------- Helpers ----------------- ###
|
34
|
+
### ------------------------------------------ ###
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def uri
|
39
|
+
@uri ||= URI.parse(url)
|
40
|
+
end
|
41
|
+
|
42
|
+
def implicit_fingerprint_order
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
|
46
|
+
def url
|
47
|
+
raise NotImplementedError, 'A URL must be given to make a call'
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Wirecard
|
2
|
+
class Callback
|
3
|
+
|
4
|
+
attr_reader :params
|
5
|
+
|
6
|
+
def initialize(params)
|
7
|
+
@params = params
|
8
|
+
|
9
|
+
raise ArgumentError, 'fingerprint order and fingerprint must both be set' unless response_fingerprint && response_fingerprint_order
|
10
|
+
raise ArgumentError, 'parameter hash contain parameters not covered in the fingerprint: ' + unfingerprinted_params.join(',') if unfingerprinted_params.size > 0
|
11
|
+
|
12
|
+
truncate_params!
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_hash
|
16
|
+
fingerprint_valid? ? params_to_ruby : nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def fingerprint_valid?
|
20
|
+
computed_fingerprint == response_fingerprint
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def response_fingerprint
|
26
|
+
@response_fingerprint ||= params['responseFingerprint']
|
27
|
+
end
|
28
|
+
|
29
|
+
def response_fingerprint_order
|
30
|
+
@response_fingerprint_order ||= params['responseFingerprintOrder']
|
31
|
+
end
|
32
|
+
|
33
|
+
def fingerprinted_params
|
34
|
+
@fingerprinted_params ||= response_fingerprint_order.split(',')
|
35
|
+
end
|
36
|
+
|
37
|
+
def unfingerprinted_params
|
38
|
+
@unfingerprinted_params ||= params.keys - fingerprinted_params - ['responseFingerprint']
|
39
|
+
end
|
40
|
+
|
41
|
+
def truncate_params!
|
42
|
+
params.keys.each{ |key| params.delete(key) unless fingerprinted_params.include?(key) || key == 'responseFingerprint' }
|
43
|
+
end
|
44
|
+
|
45
|
+
def underscore(s)
|
46
|
+
s.gsub(/([A-Z])/) { |e| '_' + $1.downcase }
|
47
|
+
end
|
48
|
+
|
49
|
+
def params_to_ruby
|
50
|
+
@ruby_params ||= Hash[params.map{ |key, value| [underscore(key).to_sym, value] }]
|
51
|
+
end
|
52
|
+
|
53
|
+
def computed_fingerprint
|
54
|
+
@computed_fingerprint ||= Wirecard::Fingerprint::Sha512.new(params).fingerprint
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Wirecard
|
2
|
+
class Configuration
|
3
|
+
|
4
|
+
attr_accessor :customer_id
|
5
|
+
|
6
|
+
attr_accessor :shop_id
|
7
|
+
|
8
|
+
attr_accessor :host
|
9
|
+
|
10
|
+
attr_accessor :user_agent
|
11
|
+
|
12
|
+
attr_accessor :endpoint
|
13
|
+
|
14
|
+
attr_accessor :secret
|
15
|
+
|
16
|
+
attr_accessor :language
|
17
|
+
|
18
|
+
attr_accessor :currency
|
19
|
+
|
20
|
+
attr_accessor :success_url
|
21
|
+
|
22
|
+
attr_accessor :failure_url
|
23
|
+
|
24
|
+
attr_accessor :cancel_url
|
25
|
+
|
26
|
+
attr_accessor :service_url
|
27
|
+
|
28
|
+
attr_accessor :confirm_url
|
29
|
+
|
30
|
+
attr_accessor :return_url
|
31
|
+
|
32
|
+
def initialize
|
33
|
+
@user_agent = '### User Agent ###'
|
34
|
+
@endpoint = 'https://checkout.wirecard.com/seamless'
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Wirecard
|
2
|
+
module DataStorage
|
3
|
+
class Base < Wirecard::Base
|
4
|
+
def url
|
5
|
+
@url ||= [Wirecard.config.endpoint, :dataStorage, self.class.to_s.split('::').last.downcase].join('/')
|
6
|
+
end
|
7
|
+
|
8
|
+
def implicit_fingerprint_order
|
9
|
+
@implicit_fingerprint_order ||= [:customer_id, :shop_id]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Wirecard
|
2
|
+
module DataStorage
|
3
|
+
class Init < Base
|
4
|
+
def implicit_fingerprint_order
|
5
|
+
@implicit_fingerprint_order ||= super + [:order_ident, :return_url, :language, :javascript_script_version, :secret]
|
6
|
+
end
|
7
|
+
|
8
|
+
def defaults
|
9
|
+
super.merge(
|
10
|
+
javascript_script_version: 'pci3',
|
11
|
+
language: Wirecard.config.language,
|
12
|
+
return_url: Wirecard.config.return_url,
|
13
|
+
# don't forget to add custom styles for the iFrame
|
14
|
+
# post_params['iframeCssUrl'] ActionController::Base.helpers.asset_url('credit_card_form.css')
|
15
|
+
)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Wirecard
|
2
|
+
module Fingerprint
|
3
|
+
class Base
|
4
|
+
|
5
|
+
attr_reader :params, :implicit_fingerprint_order
|
6
|
+
|
7
|
+
def initialize(params, implicit_fingerprint_order = nil)
|
8
|
+
@params = params
|
9
|
+
@implicit_fingerprint_order = implicit_fingerprint_order
|
10
|
+
end
|
11
|
+
|
12
|
+
def fingerprinted_params
|
13
|
+
set_request_fingerprint_order! unless implicit_fingerprint_order
|
14
|
+
set_request_fingerprint!
|
15
|
+
@params
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def set_request_fingerprint_order!
|
21
|
+
@params.merge!('requestFingerprintOrder' => request_fingerprint_order)
|
22
|
+
end
|
23
|
+
|
24
|
+
def request_fingerprint_order
|
25
|
+
params.keys.select { |key| params[key] != nil }.join(',').concat(',requestFingerprintOrder,secret')
|
26
|
+
end
|
27
|
+
|
28
|
+
def set_request_fingerprint!
|
29
|
+
@params.merge!('requestFingerprint' => fingerprint)
|
30
|
+
end
|
31
|
+
|
32
|
+
def fingerprint_string
|
33
|
+
keys = implicit_fingerprint_order || (params['requestFingerprintOrder'] || params['responseFingerprintOrder']).split(',')
|
34
|
+
keys.map{ |key| key == 'secret' ? Wirecard.config.secret : params[key] }.compact.join
|
35
|
+
end
|
36
|
+
|
37
|
+
def fingerprint
|
38
|
+
raise NotImplementedError, 'Choose a subclass that specifies the method for digest (MD5/SHA512)'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Wirecard
|
2
|
+
module PaymentProcess
|
3
|
+
class Init < Wirecard::Base
|
4
|
+
def url
|
5
|
+
@url ||= [Wirecard.config.endpoint, :frontend, :init].join('/')
|
6
|
+
end
|
7
|
+
|
8
|
+
def defaults
|
9
|
+
super.merge(
|
10
|
+
language: Wirecard.config.language,
|
11
|
+
currency: Wirecard.config.currency,
|
12
|
+
success_url: Wirecard.config.success_url,
|
13
|
+
failure_url: Wirecard.config.failure_url,
|
14
|
+
cancel_url: Wirecard.config.cancel_url,
|
15
|
+
service_url: Wirecard.config.service_url,
|
16
|
+
confirm_url: Wirecard.config.confirm_url
|
17
|
+
)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Wirecard
|
2
|
+
class Request
|
3
|
+
attr_reader :params, :implicit_fingerprint_order, :uri
|
4
|
+
|
5
|
+
def defaults
|
6
|
+
@defaults ||= {
|
7
|
+
params: nil,
|
8
|
+
implicit_fingerprint_order: nil,
|
9
|
+
uri: nil
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(options)
|
14
|
+
options = defaults.merge(options)
|
15
|
+
raise ArgumentError 'Options must contain parameters: {params: <parameters hash>' unless options[:params]
|
16
|
+
raise ArgumentError 'Options must contain uri: {uri: <wirecard API uri>' unless options[:uri]
|
17
|
+
|
18
|
+
@params = params_to_wirecard(options[:params])
|
19
|
+
@implicit_fingerprint_order = keys_to_wirecard(options[:implicit_fingerprint_order])
|
20
|
+
@uri = options[:uri]
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_post
|
24
|
+
post = Net::HTTP::Post.new(uri.request_uri)
|
25
|
+
|
26
|
+
post.set_form_data(fingerprinted_params)
|
27
|
+
|
28
|
+
post["Host"] = Wirecard.config.host
|
29
|
+
post["User-Agent"] = Wirecard.config.user_agent
|
30
|
+
post["Content-Type"] = 'application/x-www-form-urlencoded'
|
31
|
+
post["Content-Length"] = post.body.bytesize.to_s
|
32
|
+
post["Connection"] = 'close'
|
33
|
+
|
34
|
+
post
|
35
|
+
end
|
36
|
+
|
37
|
+
### ------------------------------------------ ###
|
38
|
+
### ---------------- Helpers ----------------- ###
|
39
|
+
### ------------------------------------------ ###
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def params_to_wirecard(params)
|
44
|
+
Hash[params.keys.map{ |key| [camelize(key), params[key]] }]
|
45
|
+
end
|
46
|
+
|
47
|
+
def keys_to_wirecard(keys)
|
48
|
+
keys.map{ |key| camelize(key) } if keys
|
49
|
+
end
|
50
|
+
|
51
|
+
def camelize(key)
|
52
|
+
key.to_s.gsub(/_(.)/) { |e| $1.upcase }
|
53
|
+
end
|
54
|
+
|
55
|
+
def fingerprinted_params
|
56
|
+
@fingerprinted_params ||= Wirecard::Fingerprint::Sha512.new(params, implicit_fingerprint_order).fingerprinted_params
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Wirecard
|
2
|
+
class Response
|
3
|
+
attr_reader :body
|
4
|
+
|
5
|
+
def initialize(http_response)
|
6
|
+
@body = http_response.body
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_hash
|
10
|
+
Hash[CGI.parse(body).map{ |param| extract_key_value(param) }]
|
11
|
+
end
|
12
|
+
|
13
|
+
### ------------------------------------------ ###
|
14
|
+
### ---------------- Helpers ----------------- ###
|
15
|
+
### ------------------------------------------ ###
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def underscore(s)
|
20
|
+
s.gsub(/([A-Z])/) { |e| '_' + $1.downcase }
|
21
|
+
end
|
22
|
+
|
23
|
+
def extract_key_value(param)
|
24
|
+
[underscore(param[0]).to_sym, param[1].join(',')]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.shared_examples 'Wirecard::Base#defaults' do
|
4
|
+
it { expect(subject[:customer_id]).to eq(config[:customer_id]) }
|
5
|
+
it { expect(subject[:shop_id]).to eq(config[:shop_id]) }
|
6
|
+
end
|
7
|
+
|
8
|
+
RSpec.shared_examples 'Wirecard::Base' do
|
9
|
+
|
10
|
+
let(:base) { Wirecard::Base.new }
|
11
|
+
let(:customer_id) { 'customer1' }
|
12
|
+
let(:shop_id) { 'shop1' }
|
13
|
+
let(:url) { 'http://example.com' }
|
14
|
+
|
15
|
+
before do
|
16
|
+
allow_any_instance_of(Wirecard::Base).to receive(:url).and_return(url) # set dummy url
|
17
|
+
Wirecard::Base.config = { customer_id: customer_id, shop_id: shop_id }
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#defaults' do
|
21
|
+
subject { base.defaults }
|
22
|
+
|
23
|
+
it { expect(subject[:customer_id]).to eq customer_id }
|
24
|
+
it { expect(subject[:shop_id]).to eq shop_id }
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#uri' do
|
28
|
+
subject { base.send(:uri) }
|
29
|
+
|
30
|
+
it { is_expected.to be_a_kind_of(URI::HTTP) }
|
31
|
+
it { expect(subject.to_s).to eq(url) }
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Wirecard::DataStorage::Init do
|
4
|
+
|
5
|
+
let(:init) { Wirecard::DataStorage::Init.new(options) }
|
6
|
+
let(:options) { Hash.new }
|
7
|
+
|
8
|
+
include_examples 'configuration'
|
9
|
+
|
10
|
+
it { is_expected.to be_a_kind_of(Wirecard::DataStorage::Init) }
|
11
|
+
|
12
|
+
it { binding.pry }
|
13
|
+
|
14
|
+
# describe '#implicit_fingerprint_order' do
|
15
|
+
# subject { init.implicit_fingerprint_order }
|
16
|
+
#
|
17
|
+
# it { is_expected.to eq([:customer_id, :shop_id, :order_ident, :return_url, :language, :javascript_script_version, :secret]) }
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# describe '#defaults' do
|
21
|
+
# subject { init.defaults }
|
22
|
+
#
|
23
|
+
# include_examples 'Wirecard::Base#defaults'
|
24
|
+
# it { expect(subject[:javascript_script_version]).to eq('pci3') }
|
25
|
+
#
|
26
|
+
# context 'when defaults are overwritten' do
|
27
|
+
# let(:options) { { customer_id: 'special_customer_id', shop_id: 'special_shop_id' } }
|
28
|
+
#
|
29
|
+
# it { expect(subject[:customer_id]).to eq(options[:customer_id]) }
|
30
|
+
# it { expect(subject[:customer_id]).not_to eq(config[:customer_id]) }
|
31
|
+
#
|
32
|
+
# it { expect(subject[:shop_id]).to eq(options[:shop_id]) }
|
33
|
+
# it { expect(subject[:shop_id]).not_to eq(config[:shop_id]) }
|
34
|
+
# end
|
35
|
+
# end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
RSpec.shared_examples 'configuration' do
|
2
|
+
let(:default_config) { {
|
3
|
+
host: 'checkout.wirecard.com',
|
4
|
+
endpoint: 'https://checkout.wirecard.com/seamless',
|
5
|
+
customer_id: 'D200001',
|
6
|
+
shop_id: 'qmore',
|
7
|
+
secret: 'B8AKTPWBRMNBV455FG6M2DANE99WU2',
|
8
|
+
success_url: 'http://localhost.success.url',
|
9
|
+
failure_url: 'http://localhost.failure.url',
|
10
|
+
cancel_url: 'http://localhost.cancel.url',
|
11
|
+
service_url: 'http://localhost.service.url',
|
12
|
+
confirm_url: 'http://localhost.confirm.url',
|
13
|
+
return_url: 'http://localhost.return.url',
|
14
|
+
language: 'en'
|
15
|
+
} }
|
16
|
+
|
17
|
+
before do
|
18
|
+
Wirecard.configure do |config|
|
19
|
+
binding.pry
|
20
|
+
config.host = config[:host]
|
21
|
+
config.endpoint = config[:endpoint]
|
22
|
+
config.customer_id = config[:customer_id]
|
23
|
+
config.shop_id = config[:shop_id]
|
24
|
+
config.secret = config[:secret]
|
25
|
+
config.success_url = config[:success_url]
|
26
|
+
config.failure_url = config[:failure_url]
|
27
|
+
config.cancel_url = config[:cancel_url]
|
28
|
+
config.service_url = config[:service_url]
|
29
|
+
config.confirm_url = config[:confirm_url]
|
30
|
+
config.return_url = config[:return_url]
|
31
|
+
config.language = config[:language]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Wirecard do
|
4
|
+
|
5
|
+
before do
|
6
|
+
Wirecard.configure do |config|
|
7
|
+
config.host = 'checkout.wirecard.com'
|
8
|
+
config.endpoint = 'https://checkout.wirecard.com/seamless'
|
9
|
+
config.customer_id = 'D200001'
|
10
|
+
config.shop_id = 'qmore'
|
11
|
+
config.secret = 'B8AKTPWBRMNBV455FG6M2DANE99WU2'
|
12
|
+
config.success_url = 'http://localhost.success.url'
|
13
|
+
config.failure_url = 'http://localhost.failure.url'
|
14
|
+
config.cancel_url = 'http://localhost.cancel.url'
|
15
|
+
config.service_url = 'http://localhost.service.url'
|
16
|
+
config.confirm_url = 'http://localhost.confirm.url'
|
17
|
+
config.return_url = 'http://localhost.return.url'
|
18
|
+
config.language = 'en'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'data storage' do
|
23
|
+
let(:storage_id) { 'd738d62b67ea9719f80530e5097beada' }
|
24
|
+
|
25
|
+
describe 'init' do
|
26
|
+
subject { Wirecard::DataStorage::Init.new(order_ident: '123').post }
|
27
|
+
|
28
|
+
#it { is_expected.to eq(storage_id: storage_id, javascript_url: 'https://checkout.wirecard.com/seamless/dataStorage/js/D200001/qmore/d738d62b67ea9719f80530e5097beada/dataStorage.js') }
|
29
|
+
end
|
30
|
+
|
31
|
+
describe 'read' do
|
32
|
+
subject { Wirecard::DataStorage::Read.new(storage_id: storage_id).post }
|
33
|
+
|
34
|
+
#it { is_expected.to eq({storage_id: storage_id, payment_informations: '0' }) }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe 'payment process' do
|
39
|
+
let(:params) { {
|
40
|
+
payment_type: 'CCARD',
|
41
|
+
amount: '1000',
|
42
|
+
consumer_ip_address: '127.0.0.1',
|
43
|
+
consumer_user_agent: 'some agent',
|
44
|
+
currency: 'EUR',
|
45
|
+
language: 'de',
|
46
|
+
order_description: 'sdfdg'
|
47
|
+
} }
|
48
|
+
|
49
|
+
describe 'init' do
|
50
|
+
subject { Wirecard::PaymentProcess::Init.new(params).post }
|
51
|
+
|
52
|
+
#it { expect(subject.keys).to include(:redirect_url) }
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'callback' do
|
56
|
+
subject { Wirecard::Callback.new(response_params).to_hash }
|
57
|
+
|
58
|
+
let(:response_params) do
|
59
|
+
{
|
60
|
+
"amount" => "1000",
|
61
|
+
"currency" => "EUR",
|
62
|
+
"paymentType" => "CCARD",
|
63
|
+
"financialInstitution" => "Visa",
|
64
|
+
"language" => "de",
|
65
|
+
"orderNumber" => "5028575",
|
66
|
+
"paymentState" => "SUCCESS",
|
67
|
+
"authenticated" => "No",
|
68
|
+
"anonymousPan" => "0004",
|
69
|
+
"expiry" => "03/2018",
|
70
|
+
"cardholder" => "sdg",
|
71
|
+
"maskedPan" => "940000******0004",
|
72
|
+
"gatewayReferenceNumber" => "DGW_5028575_RN",
|
73
|
+
"gatewayContractNumber" => "DemoContractNumber123",
|
74
|
+
"avsResponseCode" => "X",
|
75
|
+
"avsResponseMessage" => "Demo AVS ResultMessage",
|
76
|
+
"avsProviderResultCode" => "X",
|
77
|
+
"avsProviderResultMessage" => "Demo AVS ProviderResultMessage",
|
78
|
+
"responseFingerprintOrder" => "amount,currency,paymentType,financialInstitution,language,orderNumber,paymentState,authenticated,anonymousPan,expiry,cardholder,maskedPan,gatewayReferenceNumber,gatewayContractNumber,avsResponseCode,avsResponseMessage,avsProviderResultCode,avsProviderResultMessage,secret,responseFingerprintOrder",
|
79
|
+
"responseFingerprint" => response_fingerprint
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'when response fingerprint is valid' do
|
84
|
+
let(:response_fingerprint) { "42c937f7712b69210839c8d149bb17a352e04761eb08d67d28b2319b4a254c923b55cd6270c5d03f32cc9613dc53924c52e7a0dd7ad2139a5334a15cb4763e97" }
|
85
|
+
|
86
|
+
context 'when response contains only fingerprinted params' do
|
87
|
+
let(:parsed_response_params) do
|
88
|
+
{
|
89
|
+
amount: "1000",
|
90
|
+
currency: "EUR",
|
91
|
+
payment_type: "CCARD",
|
92
|
+
financial_institution: "Visa",
|
93
|
+
language: "de",
|
94
|
+
order_number: "5028575",
|
95
|
+
payment_state: "SUCCESS",
|
96
|
+
authenticated: "No",
|
97
|
+
anonymous_pan: "0004",
|
98
|
+
expiry: "03/2018",
|
99
|
+
cardholder: "sdg",
|
100
|
+
masked_pan: "940000******0004",
|
101
|
+
gateway_reference_number: "DGW_5028575_RN",
|
102
|
+
gateway_contract_number: "DemoContractNumber123",
|
103
|
+
avs_response_code: "X",
|
104
|
+
avs_response_message: "Demo AVS ResultMessage",
|
105
|
+
avs_provider_result_code: "X",
|
106
|
+
avs_provider_result_message: "Demo AVS ProviderResultMessage",
|
107
|
+
response_fingerprint_order: "amount,currency,paymentType,financialInstitution,language,orderNumber,paymentState,authenticated,anonymousPan,expiry,cardholder,maskedPan,gatewayReferenceNumber,gatewayContractNumber,avsResponseCode,avsResponseMessage,avsProviderResultCode,avsProviderResultMessage,secret,responseFingerprintOrder",
|
108
|
+
response_fingerprint: response_fingerprint
|
109
|
+
}
|
110
|
+
end
|
111
|
+
|
112
|
+
#it { is_expected.to eq(parsed_response_params) }
|
113
|
+
end
|
114
|
+
|
115
|
+
context 'when response contains unfingerprinted params' do
|
116
|
+
subject { Wirecard::Callback.new(response_params.merge(other_params)).to_hash }
|
117
|
+
let(:other_params) { {
|
118
|
+
"parameter_key" => "parameter_value"
|
119
|
+
} }
|
120
|
+
|
121
|
+
#it { is_expected.to raise_error(ArgumentError) } TODO: get this to work...
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'when response fingerprint is invalid' do
|
126
|
+
let(:response_fingerprint) { "invalid fingerprint" }
|
127
|
+
|
128
|
+
#it { is_expected.to be nil }
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
data/wirecard.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'wirecard/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "wirecard"
|
8
|
+
spec.version = Wirecard::VERSION
|
9
|
+
spec.authors = ["Dominic Breuker", "Michael Rüffer"]
|
10
|
+
spec.email = ["dominic.breuker@gmail.com", "mr@hitfoxgroup.com"]
|
11
|
+
spec.summary = "Wirecard API wrapper"
|
12
|
+
spec.description = "Implements the Wirecard API for payment services. Currently supports only seamless mode."
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
spec.add_development_dependency "pry"
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wirecard
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dominic Breuker
|
8
|
+
- Michael Rüffer
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2015-07-28 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ~>
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.7'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.7'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rake
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ~>
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '10.0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '10.0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rspec
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - '>='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: pry
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
description: Implements the Wirecard API for payment services. Currently supports
|
71
|
+
only seamless mode.
|
72
|
+
email:
|
73
|
+
- dominic.breuker@gmail.com
|
74
|
+
- mr@hitfoxgroup.com
|
75
|
+
executables: []
|
76
|
+
extensions: []
|
77
|
+
extra_rdoc_files: []
|
78
|
+
files:
|
79
|
+
- .gitignore
|
80
|
+
- .travis.yml
|
81
|
+
- Gemfile
|
82
|
+
- LICENSE.txt
|
83
|
+
- README.md
|
84
|
+
- Rakefile
|
85
|
+
- lib/wirecard.rb
|
86
|
+
- lib/wirecard/base.rb
|
87
|
+
- lib/wirecard/callback.rb
|
88
|
+
- lib/wirecard/configuration.rb
|
89
|
+
- lib/wirecard/data_storage/base.rb
|
90
|
+
- lib/wirecard/data_storage/init.rb
|
91
|
+
- lib/wirecard/data_storage/read.rb
|
92
|
+
- lib/wirecard/fingerprint/base.rb
|
93
|
+
- lib/wirecard/fingerprint/sha_512.rb
|
94
|
+
- lib/wirecard/payment_process/init.rb
|
95
|
+
- lib/wirecard/request.rb
|
96
|
+
- lib/wirecard/response.rb
|
97
|
+
- lib/wirecard/version.rb
|
98
|
+
- spec/spec_helper.rb
|
99
|
+
- spec/unit_tests/base_shared.rb
|
100
|
+
- spec/unit_tests/data_storage/init_spec.rb
|
101
|
+
- spec/unit_tests/support/shared_examples.rb
|
102
|
+
- spec/wirecard_spec.rb
|
103
|
+
- wirecard.gemspec
|
104
|
+
homepage: ''
|
105
|
+
licenses:
|
106
|
+
- MIT
|
107
|
+
metadata: {}
|
108
|
+
post_install_message:
|
109
|
+
rdoc_options: []
|
110
|
+
require_paths:
|
111
|
+
- lib
|
112
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - '>='
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - '>='
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
requirements: []
|
123
|
+
rubyforge_project:
|
124
|
+
rubygems_version: 2.4.5
|
125
|
+
signing_key:
|
126
|
+
specification_version: 4
|
127
|
+
summary: Wirecard API wrapper
|
128
|
+
test_files:
|
129
|
+
- spec/spec_helper.rb
|
130
|
+
- spec/unit_tests/base_shared.rb
|
131
|
+
- spec/unit_tests/data_storage/init_spec.rb
|
132
|
+
- spec/unit_tests/support/shared_examples.rb
|
133
|
+
- spec/wirecard_spec.rb
|