buckaroo 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.
- checksums.yaml +7 -0
- data/.gitignore +37 -0
- data/.travis.yml +19 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +59 -0
- data/LICENSE +21 -0
- data/README.md +43 -0
- data/Vagrantfile +35 -0
- data/buckaroo.gemspec +30 -0
- data/init.rb +1 -0
- data/lib/buckaroo.rb +10 -0
- data/lib/buckaroo/gateway.rb +161 -0
- data/lib/buckaroo/response.rb +97 -0
- data/lib/buckaroo/urls.rb +8 -0
- data/lib/buckaroo/version.rb +5 -0
- data/provision.sh +24 -0
- data/spec/remote_spec.rb +122 -0
- data/spec/spec.rb +100 -0
- metadata +106 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e3320da151ff6d333b962aa93cda3da4de6c4570
|
4
|
+
data.tar.gz: 95ac59d4e5a7de13cba03eb23e0c7bbc57f93bd9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5bbad8f54ef8c041f082faa7f1621fbe052a62e9d2ffa5963a8ce8a205f41c288d6a807dc283e27debdd4afe9d9aedbbecd62948b02105ce91b5a80bfa18fd2a
|
7
|
+
data.tar.gz: e5ef546ed866e46493324491b5cc9b0f57e725b69fc9ac356154db04f38e9e5e190d2c6d294cce58feac9555c160321dd86c4b6f7fc7c3ea03666db1565cb773
|
data/.gitignore
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
/.config
|
4
|
+
/coverage/
|
5
|
+
/InstalledFiles
|
6
|
+
/pkg/
|
7
|
+
/spec/reports/
|
8
|
+
/test/tmp/
|
9
|
+
/test/version_tmp/
|
10
|
+
/tmp/
|
11
|
+
|
12
|
+
## Specific to RubyMotion:
|
13
|
+
.dat*
|
14
|
+
.repl_history
|
15
|
+
build/
|
16
|
+
|
17
|
+
## Documentation cache and generated files:
|
18
|
+
/.yardoc/
|
19
|
+
/_yardoc/
|
20
|
+
/doc/
|
21
|
+
/rdoc/
|
22
|
+
|
23
|
+
## Environment normalisation:
|
24
|
+
/.bundle/
|
25
|
+
/lib/bundler/man/
|
26
|
+
|
27
|
+
# for a library or gem, you might want to ignore these files since the code is
|
28
|
+
# intended to run in multiple environments; otherwise, check them in:
|
29
|
+
# Gemfile.lock
|
30
|
+
# .ruby-version
|
31
|
+
# .ruby-gemset
|
32
|
+
|
33
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
34
|
+
.rvmrc
|
35
|
+
|
36
|
+
.vagrant/
|
37
|
+
env.source
|
data/.travis.yml
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
language: ruby
|
2
|
+
cache: bundler
|
3
|
+
rvm:
|
4
|
+
- 2.1.2
|
5
|
+
- 2.1.0
|
6
|
+
- 2.0.0
|
7
|
+
script: bundle exec rspec spec/spec.rb spec/remote_spec.rb
|
8
|
+
notifications:
|
9
|
+
email: false
|
10
|
+
hipchat:
|
11
|
+
rooms:
|
12
|
+
secure: IiZp/qFD7GtkXm2OYVdzr+sPo/myu79rFEKhO/Dg5d5dkruERZz1pfZ8xUrGz3JNEEl+wviMUx/FwY3n9odX2uCzFbqytjX87AMqx9F0kUNi5ze0pLdShnh5xQC5oq5g489rH+0W4AXRUD0dLM+At01AbVnTkzKaYq3/oPHJUYM=
|
13
|
+
template:
|
14
|
+
- '%{repository}#%{build_number} (%{branch} - %{commit} - %{commit_message} : %{author}): %{message}'
|
15
|
+
env:
|
16
|
+
global:
|
17
|
+
- secure: XLpikaYlecYiZUUPjedPpgItraL5auslJwyhJn5Fzrfz3whlcqg4r9ZHZrWay4pVc75RyevZ33f1gzQ8KS6B943OvbePQTTNnq61dj+KIyt+tdv/RPrN7JJTn86XqUuPJlp1RWHwCCfSHjQjhSKabPUpBaUOght8H+tTaSs6e8s=
|
18
|
+
- secure: fAG930g2TUvNnb570xpplp8FFL6M/G3MubiVziG0b0Zz0N9+0sR/oNQu6xYrbxvgeuCJvCzWalxVxE9uSJVMr/L6NhpIRoNyrdVmy4NWblfsL9yjoDnJU1ZiVGmF9lskm7WaG/ZVOJO+aAV1RHvZRVCOXetmkeYftDNIv0/+B3g=
|
19
|
+
- secure: VK8oZxOhAlmVNtXCQ3tOWqJxQMRB2ILTf0egpyIzRheFZpBNI7Qzn85MNB6FgLvm7o4kA76OzuqDMc7xvlaSaQ0if5F5Ts8HVK89Ak7Oydl0Xo9m3Xf2xuxHJfl93dtGljvoz8VVXdqN73ampr19dM7n56H+IZnQMlW57fSJGUQ=
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
buckaroo (1.0.0)
|
5
|
+
addressable
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
addressable (2.3.6)
|
11
|
+
coveralls (0.7.1)
|
12
|
+
multi_json (~> 1.3)
|
13
|
+
rest-client
|
14
|
+
simplecov (>= 0.7)
|
15
|
+
term-ansicolor
|
16
|
+
thor
|
17
|
+
diff-lcs (1.2.5)
|
18
|
+
docile (1.1.5)
|
19
|
+
metaclass (0.0.4)
|
20
|
+
mime-types (2.3)
|
21
|
+
mocha (1.1.0)
|
22
|
+
metaclass (~> 0.0.1)
|
23
|
+
multi_json (1.10.1)
|
24
|
+
netrc (0.7.7)
|
25
|
+
rake (10.3.2)
|
26
|
+
rest-client (1.7.2)
|
27
|
+
mime-types (>= 1.16, < 3.0)
|
28
|
+
netrc (~> 0.7)
|
29
|
+
rspec (3.0.0)
|
30
|
+
rspec-core (~> 3.0.0)
|
31
|
+
rspec-expectations (~> 3.0.0)
|
32
|
+
rspec-mocks (~> 3.0.0)
|
33
|
+
rspec-core (3.0.4)
|
34
|
+
rspec-support (~> 3.0.0)
|
35
|
+
rspec-expectations (3.0.4)
|
36
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
37
|
+
rspec-support (~> 3.0.0)
|
38
|
+
rspec-mocks (3.0.4)
|
39
|
+
rspec-support (~> 3.0.0)
|
40
|
+
rspec-support (3.0.4)
|
41
|
+
simplecov (0.9.0)
|
42
|
+
docile (~> 1.1.0)
|
43
|
+
multi_json
|
44
|
+
simplecov-html (~> 0.8.0)
|
45
|
+
simplecov-html (0.8.0)
|
46
|
+
term-ansicolor (1.3.0)
|
47
|
+
tins (~> 1.0)
|
48
|
+
thor (0.19.1)
|
49
|
+
tins (1.3.2)
|
50
|
+
|
51
|
+
PLATFORMS
|
52
|
+
ruby
|
53
|
+
|
54
|
+
DEPENDENCIES
|
55
|
+
buckaroo!
|
56
|
+
coveralls
|
57
|
+
mocha
|
58
|
+
rake
|
59
|
+
rspec
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 inventid
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
[](http://opensource.inventid.nl)
|
2
|
+
|
3
|
+
# Buckaroo
|
4
|
+
| Branch | Build status | Code coverage |
|
5
|
+
|---|---|---|
|
6
|
+
| Master |[](https://travis-ci.org/inventid/buckaroo)|[](https://coveralls.io/r/inventid/buckaroo?branch=master)|
|
7
|
+
| Develop |[](https://travis-ci.org/inventid/buckaroo)|[](https://coveralls.io/r/inventid/buckaroo?branch=develop)|
|
8
|
+
|
9
|
+
## What is it?
|
10
|
+
|
11
|
+
Buckaroo is a simple Ruby 2.1 compliant gateway to contact the Buckaroo Payment Service Provider.
|
12
|
+
Since there was no decent one available, we decided to develop our own.
|
13
|
+
And now you can use it too!
|
14
|
+
|
15
|
+
## How to use it?
|
16
|
+
|
17
|
+
Using it is quite simple, you can simply clone the code and then require it (_we plan to release a gem later_).
|
18
|
+
|
19
|
+
## How to suggest improvements?
|
20
|
+
|
21
|
+
We are still actively developing Buckaroo for our internal use, but we would already love to hear your feedback. In case you have some great ideas, you may just [open an issue](https://github.com/inventid/buckaroo/issues/new). Be sure to check beforehand whether the same issue does not already exist.
|
22
|
+
|
23
|
+
## How can I contribute?
|
24
|
+
|
25
|
+
We feel contributions from the community are extremely worthwhile. If you use Buckaroo in production and make some modification, please share it back to the community. You can simply [fork the repository](https://github.com/inventid/buckaroo/fork), commit your changes to your code and create a pull request back to this repository.
|
26
|
+
|
27
|
+
If there are any issues related to your changes, be sure to reference to those. Additionally we use the `develop` branch, so create a pull request to that branch and not to `master`.
|
28
|
+
|
29
|
+
Additionally we always use [vagrant](http://www.vagrantup.com) for our development. To do the same, you can do the following:
|
30
|
+
|
31
|
+
1. Make sure to have [vagrant](http://www.vagrantup.com) installed.
|
32
|
+
1. Clone the repository
|
33
|
+
1. Open a terminal / shell script and nagivate to the place where you cloned the repository
|
34
|
+
1. Simply enter `vagrant up`
|
35
|
+
1. Provisioning takes around 5 minutes on my PC. If you want it to be faster you can use the `userConfig.json` file in the root and override the specific settings for memory and CPU.
|
36
|
+
1. The Vagrant machine provisions and you can easily work with us. Enter `vagrant ssh` to get shell access to the machine. In case you are done with it, simply enter `vagrant destroy`. You won't lose any changes to your git repository when this happens.
|
37
|
+
|
38
|
+
## Collaborators
|
39
|
+
|
40
|
+
We would like to thank the developers which contributed to Buckaroo, both big and small.
|
41
|
+
|
42
|
+
- [rogierslag](https://github.com/rogierslag) (Lead developer of Buckaroo @ [inventid](https://www.inventid.nl))
|
43
|
+
- [joostverdoorn](https://github.com/joostverdoorn) (Developer of Buckaroo @ [inventid](https://www.inventid.nl))
|
data/Vagrantfile
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- mode: ruby -*-
|
2
|
+
# vi: set ft=ruby :
|
3
|
+
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
|
7
|
+
VAGRANTFILE_API_VERSION = "2"
|
8
|
+
|
9
|
+
vagrantConfigFile = "vagrantConfig.json"
|
10
|
+
|
11
|
+
if File.exists?(vagrantConfigFile)
|
12
|
+
userConfig = JSON.parse(File.read(vagrantConfigFile))
|
13
|
+
else
|
14
|
+
userConfig = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
18
|
+
config.vm.box = "trusty64"
|
19
|
+
config.vm.box_url = "https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box"
|
20
|
+
config.vm.provider :virtualbox do |vb|
|
21
|
+
vb.name = "buckaroo-local.inventid.net"
|
22
|
+
end
|
23
|
+
|
24
|
+
memory = userConfig["memory"] || 1024
|
25
|
+
cpus = userConfig["cpus"] || 1
|
26
|
+
|
27
|
+
config.vm.provider :virtualbox do |vb|
|
28
|
+
vb.customize ["modifyvm", :id, "--memory", memory, "--cpus", cpus]
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
config.vm.hostname = "buckaroo-local.inventid.net"
|
33
|
+
config.vm.provision :shell, :path => "provision.sh"
|
34
|
+
|
35
|
+
end
|
data/buckaroo.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "buckaroo/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = %q{buckaroo}
|
7
|
+
s.version = Buckaroo::VERSION
|
8
|
+
s.authors = ["Rogier Slag"]
|
9
|
+
s.description = %q{Buckaroo payment gateway (see http://www.buckaroo.nl)}
|
10
|
+
s.summary = %q{Buckaroo payment gateway}
|
11
|
+
s.email = %q{rogier@inventid.nl}
|
12
|
+
s.licenses = ['MIT']
|
13
|
+
s.homepage = %q{http://opensource.inventid.nl/buckaroo}
|
14
|
+
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.md"
|
18
|
+
]
|
19
|
+
|
20
|
+
s.files = `git ls-files`.split("\n")
|
21
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
22
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
23
|
+
s.require_paths = ["lib"]
|
24
|
+
|
25
|
+
s.add_dependency "addressable"
|
26
|
+
|
27
|
+
s.add_development_dependency "rspec"
|
28
|
+
s.add_development_dependency "mocha"
|
29
|
+
|
30
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'buckaroo'
|
data/lib/buckaroo.rb
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'net/https'
|
4
|
+
require 'digest/sha2'
|
5
|
+
require 'addressable/uri'
|
6
|
+
require 'base64'
|
7
|
+
require 'openssl'
|
8
|
+
require 'buckaroo/urls'
|
9
|
+
|
10
|
+
|
11
|
+
module Buckaroo
|
12
|
+
class Gateway
|
13
|
+
LANGUAGE = 'nl'
|
14
|
+
CURRENCY = 'EUR'
|
15
|
+
|
16
|
+
class << self
|
17
|
+
# Holds the environment in which the run (default is test)
|
18
|
+
attr_accessor :environment
|
19
|
+
|
20
|
+
# Holds the global iDEAL merchant id. Make sure to use a string with
|
21
|
+
# leading zeroes if needed.
|
22
|
+
attr_accessor :website_key
|
23
|
+
|
24
|
+
# Holds the secret that should be used for the website key.
|
25
|
+
attr_accessor :secret
|
26
|
+
|
27
|
+
# Holds the users locale
|
28
|
+
attr_accessor :locale
|
29
|
+
end
|
30
|
+
|
31
|
+
# Environment defaults to test
|
32
|
+
self.environment = :test
|
33
|
+
|
34
|
+
# Returns whether we're in test mode or not.
|
35
|
+
def self.test?
|
36
|
+
if self.environment.nil?
|
37
|
+
self.environment = :test
|
38
|
+
end
|
39
|
+
self.environment == :test
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns the endpoint for the request.
|
43
|
+
#
|
44
|
+
# Automatically uses test or live URLs based on the configuration.
|
45
|
+
def request_url(operation)
|
46
|
+
if self.class.test?
|
47
|
+
url = URLS[:test_url]
|
48
|
+
else
|
49
|
+
url = URLS[:live_url]
|
50
|
+
end
|
51
|
+
return url if operation.nil?
|
52
|
+
url + '?op=' + operation
|
53
|
+
end
|
54
|
+
|
55
|
+
# TODO: Add comment here
|
56
|
+
def setup_purchase(money, options)
|
57
|
+
config_complete!
|
58
|
+
requires!(options, :order_id, :return_url, :description, :method)
|
59
|
+
|
60
|
+
req = build_transaction_request(money, options)
|
61
|
+
post_data request_url('transactionrequest'), req, TransactionResponse
|
62
|
+
end
|
63
|
+
|
64
|
+
# Sends a status request for the specified +transaction_id+ and
|
65
|
+
# returns an StatusResponse.
|
66
|
+
#
|
67
|
+
# It is _your_ responsibility as the merchant to check if the payment has
|
68
|
+
# been made until you receive a response with a finished status like:
|
69
|
+
# `Success', `Cancelled', `Expired', everything else equals `Open'.
|
70
|
+
#
|
71
|
+
# === Example
|
72
|
+
#
|
73
|
+
# capture_response = gateway.capture(@purchase.transaction_id)
|
74
|
+
# if capture_response.success?
|
75
|
+
# @purchase.update_attributes!(:paid => true)
|
76
|
+
# flash[:notice] = "Congratulations, you are now the proud owner of a Dutch windmill!"
|
77
|
+
# end
|
78
|
+
#
|
79
|
+
# See the Gateway class description for a more elaborate example.
|
80
|
+
def capture(transaction_id)
|
81
|
+
config_complete!
|
82
|
+
|
83
|
+
a = build_status_request(transaction_id)
|
84
|
+
post_data request_url('transactionstatus'), a, StatusResponse
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def ssl_post(url, params)
|
90
|
+
log('URL', url)
|
91
|
+
log('Request', params)
|
92
|
+
response = Net::HTTP.post_form(URI.parse(url), params)
|
93
|
+
log('Response', response.body)
|
94
|
+
response
|
95
|
+
end
|
96
|
+
|
97
|
+
def post_data(gateway_url, data, response_klass)
|
98
|
+
response_klass.new(ssl_post(gateway_url, data))
|
99
|
+
end
|
100
|
+
|
101
|
+
def requires!(options, *keys)
|
102
|
+
missing = keys - options.keys
|
103
|
+
unless missing.empty?
|
104
|
+
raise ArgumentError, "Missing required options: #{missing.map { |m| m.to_s }.join(', ')}"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def build_status_request(transaction_id)
|
109
|
+
data = {
|
110
|
+
brq_websitekey: self.class.website_key,
|
111
|
+
brq_transaction: transaction_id,
|
112
|
+
brq_test: self.class.test?
|
113
|
+
}
|
114
|
+
|
115
|
+
sign!(data)
|
116
|
+
end
|
117
|
+
|
118
|
+
def build_transaction_request(amount, options)
|
119
|
+
data = {
|
120
|
+
brq_payment_method: options[:method],
|
121
|
+
brq_websitekey: self.class.website_key,
|
122
|
+
brq_culture: self.class.locale,
|
123
|
+
brq_currency: CURRENCY,
|
124
|
+
brq_amount: amount,
|
125
|
+
brq_invoicenumber: options[:order_id],
|
126
|
+
brq_ordernumber: options[:order_id],
|
127
|
+
brq_description: options[:description],
|
128
|
+
brq_return: options[:return_url],
|
129
|
+
brq_returncancel: '',
|
130
|
+
brq_returnerror: '',
|
131
|
+
brq_returnreject: '',
|
132
|
+
brq_continue_on_incomplete: 'RedirectToHTML',
|
133
|
+
brq_test: self.class.test?
|
134
|
+
}
|
135
|
+
extra = 'brq_service_'+options[:method]+'_action'
|
136
|
+
data[extra] = 'Pay'
|
137
|
+
|
138
|
+
sign!(data)
|
139
|
+
end
|
140
|
+
|
141
|
+
def sign!(input)
|
142
|
+
sorted_data = input.sort_by { |key, _| key.to_s }
|
143
|
+
|
144
|
+
to_hash = ''
|
145
|
+
sorted_data.each { |key, value| to_hash << key.to_s+'='+value.to_s }
|
146
|
+
to_hash << self.class.secret
|
147
|
+
input['brq_signature'] = Digest::SHA512.hexdigest(to_hash)
|
148
|
+
input
|
149
|
+
end
|
150
|
+
|
151
|
+
def config_complete!
|
152
|
+
if self.class.website_key.to_s.empty? || self.class.secret.to_s.empty? || self.class.locale.to_s.empty?
|
153
|
+
raise ArgumentError, "Required config is not done"
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def log(thing, contents)
|
158
|
+
$stderr.write("\n#{thing}:\n\n#{contents}\n") if $DEBUG
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'addressable/uri'
|
4
|
+
require 'digest/sha2'
|
5
|
+
|
6
|
+
module Buckaroo
|
7
|
+
|
8
|
+
class Response
|
9
|
+
attr_accessor :status_code
|
10
|
+
|
11
|
+
def initialize(response, options = {})
|
12
|
+
body = response.body
|
13
|
+
@response = Hash[Addressable::URI.form_unencode(body)]
|
14
|
+
@status_code = @response['BRQ_STATUSCODE'].to_i
|
15
|
+
@success = !error_occurred?
|
16
|
+
@test = @response['BRQ_TEST'].downcase == 'true' ? true : false
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns whether we're running in test mode
|
20
|
+
def test?
|
21
|
+
@test
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns whether the request was a success
|
25
|
+
def success?
|
26
|
+
@success
|
27
|
+
end
|
28
|
+
|
29
|
+
def verified?
|
30
|
+
input = @response.dup
|
31
|
+
given_hash = input['BRQ_SIGNATURE']
|
32
|
+
input.delete('BRQ_SIGNATURE')
|
33
|
+
# This might actually need some explanation why we are converting do lowercase here
|
34
|
+
# Buckaroo specifies to sort these parameters, although the exact matter of sorting
|
35
|
+
# is quite ambigious. So after quite a while of debugging, I discovered that by
|
36
|
+
# sorting they do not use the ASCII based sorting Ruby uses. In fact, the sorting
|
37
|
+
# is specified to place symbols first (which ASCII does, except for the underscore (_)
|
38
|
+
# which is located between the capitals and lowercase letters (jeej ASCII!).
|
39
|
+
# So in this case, by converting everything to lowercase before comparing, we ensure
|
40
|
+
# that all symbols are in the table before the letters.
|
41
|
+
#
|
42
|
+
# Actual case where it went wrong: keys BRQ_TRANSACTIONS and BRQ_TRANSACTION_CANCELABLE
|
43
|
+
# Ruby would sort these in this exact order, whereas Buckaroo would reverse them. And
|
44
|
+
# since for hashing the reversal generates a totally different sequence, that would
|
45
|
+
# break message validation.
|
46
|
+
#
|
47
|
+
# TLDR; Leave it with a downcase
|
48
|
+
sorted_data = input.sort_by { |key, _| key.to_s.downcase }
|
49
|
+
|
50
|
+
to_hash = ''
|
51
|
+
sorted_data.each { |key, value| to_hash << key.to_s+'='+value.to_s }
|
52
|
+
to_hash << Buckaroo::Gateway.secret
|
53
|
+
|
54
|
+
Digest::SHA512.hexdigest(to_hash) == given_hash
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def error_occurred?
|
60
|
+
!verified? || @status_code == 491 || @status_code == 492
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
class TransactionResponse < Response
|
66
|
+
def redirect_url
|
67
|
+
@response['BRQ_REDIRECTURL']
|
68
|
+
end
|
69
|
+
|
70
|
+
def transaction_id
|
71
|
+
@response['BRQ_TRANSACTIONS']
|
72
|
+
end
|
73
|
+
|
74
|
+
def order_id
|
75
|
+
@response['BRQ_ORDERNUMBER']
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
class StatusResponse < Response
|
81
|
+
def status
|
82
|
+
case @status_code
|
83
|
+
when 190 then
|
84
|
+
'success'
|
85
|
+
when 490..690 then
|
86
|
+
'failure'
|
87
|
+
when 790..793 then
|
88
|
+
'open'
|
89
|
+
when 890..891 then
|
90
|
+
'cancelled'
|
91
|
+
else
|
92
|
+
raise(Exception)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
data/provision.sh
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
# This improves performance since the Google DNS is much quicker than the local Vagrant Virtualbox combination
|
4
|
+
printf "nameserver 8.8.8.8\nnameserver 8.8.4.4" > /etc/resolv.conf
|
5
|
+
|
6
|
+
echo "Updating the Operating System..."
|
7
|
+
sudo apt-get update >> /tmp/provision.log 2>&1
|
8
|
+
sudo apt-get upgrade -y >> /tmp/provision.log 2>&1
|
9
|
+
|
10
|
+
echo "Installing extra packages..."
|
11
|
+
sudo apt-get install curl wget git g++ libreadline6-dev zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 autoconf libgdbm-dev libncurses5-dev automake libtool bison pkg-config libffi-dev -y >> /tmp/provision.log 2>&1
|
12
|
+
|
13
|
+
echo "Installing rvm..."
|
14
|
+
curl -sSL https://get.rvm.io | bash -s stable --ruby >> /tmp/provision.log 2>&1
|
15
|
+
source /usr/local/rvm/scripts/rvm
|
16
|
+
|
17
|
+
echo "Installing Ruby-2.1.2..."
|
18
|
+
rvm install ruby-2.1.2 >> /tmp/provision.log 2>&1
|
19
|
+
rvm use ruby-2.1.2 --default >> /tmp/provision.log 2>&1
|
20
|
+
|
21
|
+
cd /vagrant && bundle install >> /tmp/provision.log 2>&1
|
22
|
+
|
23
|
+
echo ""
|
24
|
+
echo "And we are done! Check /tmp/provision.log for a full log file \`vagrant ssh -c \"cat /tmp/provision.log\"\`"
|
data/spec/remote_spec.rb
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'coveralls'
|
3
|
+
|
4
|
+
Coveralls.wear!
|
5
|
+
|
6
|
+
require 'buckaroo'
|
7
|
+
require 'mocha'
|
8
|
+
|
9
|
+
def set_vars_from_env
|
10
|
+
Buckaroo::Gateway.environment = :test
|
11
|
+
Buckaroo::Gateway.website_key = ENV['website_key']
|
12
|
+
Buckaroo::Gateway.secret = ENV['secret']
|
13
|
+
Buckaroo::Gateway.locale = ENV['locale']
|
14
|
+
end
|
15
|
+
|
16
|
+
VALID_OPTIONS = {
|
17
|
+
order_id: 1,
|
18
|
+
return_url: 'http://www.inventid.nl',
|
19
|
+
description: 'test',
|
20
|
+
method: 'bancontactmrcash'
|
21
|
+
}
|
22
|
+
|
23
|
+
module Buckaroo
|
24
|
+
|
25
|
+
class InvalidParameters
|
26
|
+
|
27
|
+
describe Buckaroo do
|
28
|
+
|
29
|
+
before(:each) do
|
30
|
+
Buckaroo::Gateway.website_key = nil
|
31
|
+
Buckaroo::Gateway.environment = nil
|
32
|
+
Buckaroo::Gateway.locale = nil
|
33
|
+
Buckaroo::Gateway.secret = nil
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should fail on negative numbers' do
|
38
|
+
set_vars_from_env
|
39
|
+
gateway = Buckaroo::Gateway.new
|
40
|
+
response = gateway.setup_purchase('-1', VALID_OPTIONS)
|
41
|
+
expect(response.verified?).to be true
|
42
|
+
expect(response.success?).to be false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class CaptureTransaction
|
48
|
+
|
49
|
+
describe 'Buckaroo' do
|
50
|
+
|
51
|
+
|
52
|
+
it 'should create an valid request if remainder is ok' do
|
53
|
+
set_vars_from_env
|
54
|
+
gateway = Buckaroo::Gateway.new
|
55
|
+
response = gateway.setup_purchase('1.00', VALID_OPTIONS)
|
56
|
+
expect(response.verified?).to be true
|
57
|
+
expect(response.success?).to be true
|
58
|
+
expect(response.order_id).to eq(VALID_OPTIONS[:order_id].to_s)
|
59
|
+
expect(response).to be_a TransactionResponse
|
60
|
+
end
|
61
|
+
|
62
|
+
describe 'capture' do
|
63
|
+
it 'should create an valid status request if remainder is ok' do
|
64
|
+
set_vars_from_env
|
65
|
+
#Buckaroo::Gateway.environment = :live
|
66
|
+
gateway = Buckaroo::Gateway.new
|
67
|
+
response = gateway.setup_purchase('1.00', VALID_OPTIONS)
|
68
|
+
expect(response.verified?).to be true
|
69
|
+
expect(response.success?).to be true
|
70
|
+
expect(response.order_id).to eq(VALID_OPTIONS[:order_id].to_s)
|
71
|
+
expect(response.redirect_url).to match(/buckaroo/)
|
72
|
+
expect(response).to be_a TransactionResponse
|
73
|
+
|
74
|
+
transaction_id = response.transaction_id
|
75
|
+
result = gateway.capture(transaction_id)
|
76
|
+
expect(result.verified?).to be true
|
77
|
+
expect(result.status).to eq('open')
|
78
|
+
expect(result).to be_a StatusResponse
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should return failure if a payment was failed' do
|
82
|
+
set_vars_from_env
|
83
|
+
gateway = Buckaroo::Gateway.new
|
84
|
+
transaction_id = 'F7B5BD0D19B24A6DB2A9BAE45919B5DB'
|
85
|
+
result = gateway.capture(transaction_id)
|
86
|
+
expect(result.status).to eq('failure')
|
87
|
+
expect(result.verified?).to be true
|
88
|
+
expect(result.test?).to be true
|
89
|
+
expect(result).to be_a StatusResponse
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'should return cancelled if the customer cancelled' do
|
93
|
+
set_vars_from_env
|
94
|
+
gateway = Buckaroo::Gateway.new
|
95
|
+
transaction_id = 'EC99E0BD08CB4D06B17C6670F4FFDDAA'
|
96
|
+
result = gateway.capture(transaction_id)
|
97
|
+
expect(result.status).to eq('cancelled')
|
98
|
+
expect(result.verified?).to be true
|
99
|
+
expect(result.test?).to be true
|
100
|
+
expect(result).to be_a StatusResponse
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'should return success if the payment was OK' do
|
104
|
+
set_vars_from_env
|
105
|
+
gateway = Buckaroo::Gateway.new
|
106
|
+
|
107
|
+
PAYPAL_OPTIONS = VALID_OPTIONS.dup
|
108
|
+
PAYPAL_OPTIONS[:method] = 'paypal'
|
109
|
+
response = gateway.setup_purchase('1.00', PAYPAL_OPTIONS)
|
110
|
+
|
111
|
+
expect(response).to be_a TransactionResponse
|
112
|
+
|
113
|
+
#transaction_id = 'EC99E0BD08CB4D06B17C6670F4FFDDAA'
|
114
|
+
#result = gateway.capture(transaction_id)
|
115
|
+
#expect(result.status).to eq('cancelled')
|
116
|
+
#expect(result.verified?).to be true
|
117
|
+
#expect(result.test?).to be true
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
data/spec/spec.rb
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'coveralls'
|
3
|
+
|
4
|
+
Coveralls.wear!
|
5
|
+
|
6
|
+
require 'buckaroo'
|
7
|
+
require 'mocha'
|
8
|
+
|
9
|
+
module Buckaroo
|
10
|
+
|
11
|
+
class RequestGeneration
|
12
|
+
|
13
|
+
describe Buckaroo do
|
14
|
+
|
15
|
+
VALID_OPTIONS = {
|
16
|
+
order_id: 1,
|
17
|
+
return_url: 'http://www.inventid.nl',
|
18
|
+
description: 'test',
|
19
|
+
method: 'bancontactmrcash'
|
20
|
+
}
|
21
|
+
|
22
|
+
before(:each) do
|
23
|
+
Buckaroo::Gateway.website_key = nil
|
24
|
+
Buckaroo::Gateway.environment = nil
|
25
|
+
Buckaroo::Gateway.locale = nil
|
26
|
+
Buckaroo::Gateway.secret = nil
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#test?' do
|
31
|
+
it 'should return true by default since we are using the test environment' do
|
32
|
+
expect(Buckaroo::Gateway.test?).to be true
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should return false it we override to the live environment' do
|
36
|
+
Buckaroo::Gateway.environment = :live
|
37
|
+
expect(Buckaroo::Gateway.test?).to be false
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe 'request_url' do
|
42
|
+
it 'should return the test url in the setup test environment' do
|
43
|
+
Buckaroo::Gateway.environment = :test
|
44
|
+
gateway = Buckaroo::Gateway.new
|
45
|
+
expect(gateway.request_url(nil)).to eq(URLS[:test_url])
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should return the test url in the setup test environment' do
|
49
|
+
Buckaroo::Gateway.environment = :live
|
50
|
+
gateway = Buckaroo::Gateway.new
|
51
|
+
expect(gateway.request_url(nil)).to eq(URLS[:live_url])
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'setup_purchase' do
|
56
|
+
it 'should throw an error about missing parameters' do
|
57
|
+
Buckaroo::Gateway.environment = :test
|
58
|
+
gateway = Buckaroo::Gateway.new
|
59
|
+
Buckaroo::Gateway.website_key = 'test'
|
60
|
+
Buckaroo::Gateway.secret = 'test'
|
61
|
+
Buckaroo::Gateway.locale = 'test'
|
62
|
+
expect { gateway.setup_purchase('10.00', {return_url: 'http://example.com', description: 'test', method: 'paypal'}) }.to raise_error(ArgumentError)
|
63
|
+
expect { gateway.setup_purchase('10.00', {order_id: 4, description: 'test', method: 'paypal'}) }.to raise_error(ArgumentError)
|
64
|
+
expect { gateway.setup_purchase('10.00', {return_url: 'http://example.com', order_id: 'test', method: 'paypal'}) }.to raise_error(ArgumentError)
|
65
|
+
expect { gateway.setup_purchase('10.00', {return_url: 'http://example.com', description: 'test', method: 'paypal'}) }.to raise_error(ArgumentError)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should fail because of missing config' do
|
69
|
+
Buckaroo::Gateway.environment = :test
|
70
|
+
gateway = Buckaroo::Gateway.new
|
71
|
+
expect { gateway.setup_purchase('10.00', VALID_OPTIONS) }.to raise_error(ArgumentError)
|
72
|
+
Buckaroo::Gateway.website_key = ENV['website_key']
|
73
|
+
expect { gateway.setup_purchase('10.00', VALID_OPTIONS) }.to raise_error(ArgumentError)
|
74
|
+
Buckaroo::Gateway.secret = ENV['secret']
|
75
|
+
expect { gateway.setup_purchase('10.00', VALID_OPTIONS) }.to raise_error(ArgumentError)
|
76
|
+
Buckaroo::Gateway.locale = ENV['locale']
|
77
|
+
Buckaroo::Gateway.locale = nil
|
78
|
+
expect { gateway.setup_purchase('10.00', VALID_OPTIONS) }.to raise_error(ArgumentError)
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
describe 'capture' do
|
84
|
+
it 'should fail because of missing config' do
|
85
|
+
Buckaroo::Gateway.environment = :test
|
86
|
+
gateway = Buckaroo::Gateway.new
|
87
|
+
expect { gateway.capture('1234') }.to raise_error(ArgumentError)
|
88
|
+
Buckaroo::Gateway.website_key = ENV['website_key']
|
89
|
+
expect { gateway.capture('1234') }.to raise_error(ArgumentError)
|
90
|
+
Buckaroo::Gateway.secret = ENV['secret']
|
91
|
+
expect { gateway.capture('1234') }.to raise_error(ArgumentError)
|
92
|
+
Buckaroo::Gateway.locale = ENV['locale']
|
93
|
+
Buckaroo::Gateway.locale = nil
|
94
|
+
expect { gateway.capture('1234') }.to raise_error(ArgumentError)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
metadata
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: buckaroo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Rogier Slag
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-09-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: addressable
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: mocha
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Buckaroo payment gateway (see http://www.buckaroo.nl)
|
56
|
+
email: rogier@inventid.nl
|
57
|
+
executables: []
|
58
|
+
extensions: []
|
59
|
+
extra_rdoc_files:
|
60
|
+
- LICENSE
|
61
|
+
- README.md
|
62
|
+
files:
|
63
|
+
- ".gitignore"
|
64
|
+
- ".travis.yml"
|
65
|
+
- Gemfile
|
66
|
+
- Gemfile.lock
|
67
|
+
- LICENSE
|
68
|
+
- README.md
|
69
|
+
- Vagrantfile
|
70
|
+
- buckaroo.gemspec
|
71
|
+
- init.rb
|
72
|
+
- lib/buckaroo.rb
|
73
|
+
- lib/buckaroo/gateway.rb
|
74
|
+
- lib/buckaroo/response.rb
|
75
|
+
- lib/buckaroo/urls.rb
|
76
|
+
- lib/buckaroo/version.rb
|
77
|
+
- provision.sh
|
78
|
+
- spec/remote_spec.rb
|
79
|
+
- spec/spec.rb
|
80
|
+
homepage: http://opensource.inventid.nl/buckaroo
|
81
|
+
licenses:
|
82
|
+
- MIT
|
83
|
+
metadata: {}
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
requirements: []
|
99
|
+
rubyforge_project:
|
100
|
+
rubygems_version: 2.2.2
|
101
|
+
signing_key:
|
102
|
+
specification_version: 4
|
103
|
+
summary: Buckaroo payment gateway
|
104
|
+
test_files:
|
105
|
+
- spec/remote_spec.rb
|
106
|
+
- spec/spec.rb
|