ideal-mollie 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/.rspec +2 -0
- data/.yardopts +3 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile +4 -0
- data/LICENSE.md +20 -0
- data/README.md +52 -0
- data/Rakefile +8 -0
- data/ideal-mollie.gemspec +32 -0
- data/lib/ideal-mollie.rb +172 -0
- data/lib/ideal-mollie/config.rb +32 -0
- data/lib/ideal-mollie/engine.rb +15 -0
- data/lib/ideal-mollie/ideal_exception.rb +17 -0
- data/lib/ideal-mollie/version.rb +4 -0
- data/spec/config_spec.rb +35 -0
- data/spec/ideal_exception_spec.rb +38 -0
- data/spec/ideal_mollie_spec.rb +66 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/vcr_cassettes/banks.yml +33 -0
- data/spec/vcr_cassettes/check_payment.yml +82 -0
- data/spec/vcr_cassettes/new_payment.yml +54 -0
- data/spec/vcr_cassettes/request_payment.yml +32 -0
- metadata +196 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.yardopts
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Manuel van Rijn, http://manuel.manuelles.nl/
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
|
2
|
+
# Ideal Mollie (ideal-mollie)
|
3
|
+
|
4
|
+
A simple Ruby implementation for handling iDeal transactions with the [Mollie API](https://www.mollie.nl/support/documentatie/betaaldiensten/ideal/).
|
5
|
+
|
6
|
+
Here you can find the [Documentation](http://rubydoc.info/github/manuelvanrijn/ideal-mollie/master/frames)
|
7
|
+
|
8
|
+
## Getting started
|
9
|
+
|
10
|
+
### Install
|
11
|
+
|
12
|
+
To install the gem you could execute
|
13
|
+
|
14
|
+
```
|
15
|
+
sudo gem install ideal-mollie
|
16
|
+
```
|
17
|
+
|
18
|
+
Or you could add the gem into your `Gemfile`.
|
19
|
+
|
20
|
+
```
|
21
|
+
gem 'ideal-mollie'
|
22
|
+
```
|
23
|
+
|
24
|
+
Finally, if you don’t dig any of that gemming that’s so popular nowadays, you can install it as a plugin;
|
25
|
+
|
26
|
+
```
|
27
|
+
cd vendor/plugins
|
28
|
+
git clone --depth 1 git://github.com/manuelvanrijn/ideal-mollie.git ideal-mollie
|
29
|
+
```
|
30
|
+
|
31
|
+
### Configuration
|
32
|
+
|
33
|
+
Add the following config parameters to your environment config file
|
34
|
+
|
35
|
+
```
|
36
|
+
config.ideal_mollie.partner_id = 123456
|
37
|
+
config.ideal_mollie.report_url = "http://example.org/report"
|
38
|
+
config.ideal_mollie.return_url = "http://example.org/return"
|
39
|
+
config.ideal_mollie.test_mode = false
|
40
|
+
```
|
41
|
+
|
42
|
+
### Example Controller
|
43
|
+
|
44
|
+
TODO
|
45
|
+
|
46
|
+
## Changelog
|
47
|
+
|
48
|
+
A details overview could be found in the [CHANGELOG](https://github.com/manuelvanrijn/ideal-mollie/blob/master/CHANGELOG.md).
|
49
|
+
|
50
|
+
## Copyright
|
51
|
+
|
52
|
+
Copyright © 2012 Manuel van Rijn. See [LICENSE](https://github.com/manuelvanrijn/ideal-mollie/blob/master/LICENSE.md) for further details.
|
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "ideal-mollie/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "ideal-mollie"
|
7
|
+
s.version = IdealMollie::VERSION
|
8
|
+
s.authors = ["Manuel van Rijn"]
|
9
|
+
s.email = ["manuel@manuelles.nl"]
|
10
|
+
s.homepage = "https://github.com/manuelvanrijn/ideal-mollie"
|
11
|
+
s.summary = %q{Make iDeal Mollie payments without the pain}
|
12
|
+
s.description = %q{A simple Ruby implementation for handeling iDeal transactions with the Mollie API}
|
13
|
+
|
14
|
+
s.rubyforge_project = "ideal-mollie"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
s.add_development_dependency "rspec"
|
21
|
+
s.add_development_dependency "vcr"
|
22
|
+
s.add_development_dependency "fakeweb"
|
23
|
+
s.add_development_dependency "yard"
|
24
|
+
s.add_development_dependency "redcarpet"
|
25
|
+
s.add_development_dependency "simplecov"
|
26
|
+
|
27
|
+
s.add_dependency "rake", "~> 0.9.0"
|
28
|
+
s.add_dependency "faraday", "~> 0.5.7"
|
29
|
+
s.add_dependency "faraday_middleware", "~> 0.3.2"
|
30
|
+
s.add_dependency "multi_xml", "~> 0.2.2"
|
31
|
+
s.add_dependency "nokogiri", "~> 1.4.1"
|
32
|
+
end
|
data/lib/ideal-mollie.rb
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
# Gems
|
2
|
+
require "faraday"
|
3
|
+
require "faraday_middleware"
|
4
|
+
require "multi_xml"
|
5
|
+
|
6
|
+
# Files
|
7
|
+
require "ideal-mollie/config"
|
8
|
+
require "ideal-mollie/ideal_exception"
|
9
|
+
require "ideal-mollie/engine" if defined?(Rails) && Rails::VERSION::MAJOR == 3
|
10
|
+
|
11
|
+
#
|
12
|
+
# IdealMollie Module
|
13
|
+
#
|
14
|
+
module IdealMollie
|
15
|
+
#
|
16
|
+
# List of supported banks.
|
17
|
+
#
|
18
|
+
# @visibility public
|
19
|
+
#
|
20
|
+
# @example
|
21
|
+
# IdealMollie.banks
|
22
|
+
# # => [{:id=>"9999", :name=>"TBM Bank"}, ...]
|
23
|
+
#
|
24
|
+
# @return [Array] list of supported banks.
|
25
|
+
def self.banks
|
26
|
+
response = IdealMollie.request("banklist")
|
27
|
+
|
28
|
+
banks = response["bank"]
|
29
|
+
banks = [banks] unless banks.is_a?Array # to array if it isn't already
|
30
|
+
|
31
|
+
banks.map do |bank|
|
32
|
+
{:id => bank["bank_id"], :name => bank["bank_name"]}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Create a new payment
|
38
|
+
#
|
39
|
+
# @visibility public
|
40
|
+
#
|
41
|
+
# @param [int] amount The amount of money to transfer (defined in cents).
|
42
|
+
# @param [String] description The description of the payment on the bank transfer.
|
43
|
+
# @param [String] bank_id The id of the bank selected from one of the supported banks.
|
44
|
+
#
|
45
|
+
# @example
|
46
|
+
#
|
47
|
+
# IdealMollie.new_payment(1000, "Ordernumber #123: new gadget", "0031")
|
48
|
+
# # => {
|
49
|
+
# # :transaction_id=>"72457c865d4b800eb8b0f3ba928ff495",
|
50
|
+
# # :amount=>1000,
|
51
|
+
# # :currency=>"EUR",
|
52
|
+
# # :URL=>"http://www.mollie.nl/partners/ideal-test-bank?order_nr=M738907M05885973&transaction_id=72457c865d4b800eb8b0f3ba928ff495&trxid=0073890705885973",
|
53
|
+
# # :message=>"Your iDEAL-payment has successfully been setup. Your customer should visit the given URL to make the payment"
|
54
|
+
# # }
|
55
|
+
#
|
56
|
+
# @return [Hash] the transaction object
|
57
|
+
def self.new_payment(amount, description, bank_id)
|
58
|
+
response = IdealMollie.request("fetch", {
|
59
|
+
:partnerid => Config.partner_id,
|
60
|
+
:reporturl => Config.report_url,
|
61
|
+
:returnurl => Config.return_url,
|
62
|
+
:description => description,
|
63
|
+
:amount => amount,
|
64
|
+
:bank_id => bank_id
|
65
|
+
})
|
66
|
+
order = response["order"]
|
67
|
+
|
68
|
+
result = {
|
69
|
+
:transaction_id => order["transaction_id"],
|
70
|
+
:amount => order["amount"].to_i,
|
71
|
+
:currency => order["currency"],
|
72
|
+
:url => order["URL"],
|
73
|
+
:message => order["message"]
|
74
|
+
}
|
75
|
+
result
|
76
|
+
end
|
77
|
+
|
78
|
+
#
|
79
|
+
# Check the status of a transaction.
|
80
|
+
#
|
81
|
+
# @visibility public
|
82
|
+
#
|
83
|
+
# @param [String] transaction_id the transaction to verify.
|
84
|
+
#
|
85
|
+
# @example
|
86
|
+
# IdealMollie.check_payment("4b99662febb42ce6f889d9c57f5cf3fa")
|
87
|
+
# # => {
|
88
|
+
# # :transaction_id => '4b99662febb42ce6f889d9c57f5cf3fa',
|
89
|
+
# # :amount => 1465,
|
90
|
+
# # :currency => "EUR",
|
91
|
+
# # :payed => true,
|
92
|
+
# # :consumer => {
|
93
|
+
# # :name => "Hr J Janssen",
|
94
|
+
# # :account => "P001234567",
|
95
|
+
# # :city => "Amsterdam"
|
96
|
+
# # },
|
97
|
+
# # :message => "This iDEAL-order has successfuly been payed for,
|
98
|
+
# # and this is the first time you check it.",
|
99
|
+
# # :status => "Expired"
|
100
|
+
# # }
|
101
|
+
#
|
102
|
+
# @note Once a transaction is payed, only the next time you verify the
|
103
|
+
# transaction will the value of 'payed' be 'true'.
|
104
|
+
# Else it will be 'false'.
|
105
|
+
#
|
106
|
+
# @return [Hash] the status of the transaction.
|
107
|
+
def self.check_payment(transaction_id)
|
108
|
+
response = IdealMollie.request("check", {
|
109
|
+
:partnerid => Config.partner_id,
|
110
|
+
:transaction_id => transaction_id
|
111
|
+
})
|
112
|
+
order = response["order"]
|
113
|
+
|
114
|
+
result = {
|
115
|
+
:transaction_id => order["transaction_id"],
|
116
|
+
:amount => order["amount"].to_i,
|
117
|
+
:currency => order["currency"],
|
118
|
+
:payed => order["payed"] == "true" ? true : false,
|
119
|
+
:message => order["message"],
|
120
|
+
:status => order["status"]
|
121
|
+
}
|
122
|
+
if order.has_key?("consumer")
|
123
|
+
consumer = order["consumer"]
|
124
|
+
result.merge!(:consumer => {
|
125
|
+
:name => consumer["consumerName"],
|
126
|
+
:account => consumer["consumerAccount"],
|
127
|
+
:city => consumer["consumerCity"]
|
128
|
+
})
|
129
|
+
end
|
130
|
+
result
|
131
|
+
end
|
132
|
+
|
133
|
+
class << self
|
134
|
+
MultiXml.parser = :nokogiri
|
135
|
+
|
136
|
+
#
|
137
|
+
# Perform a request to the https xlm server of mollie and return the responded xml
|
138
|
+
# which is converted to an hash
|
139
|
+
#
|
140
|
+
# @param [String] action The action to perform.
|
141
|
+
# @param [Hash] params Additional parameters to send like partner_id
|
142
|
+
#
|
143
|
+
# @raise [IdealMollie::IdealException] When a error is returned by Mollie
|
144
|
+
#
|
145
|
+
# @return [Hash] the returned XML as a Hash
|
146
|
+
def request(action, params={})
|
147
|
+
params.merge!(:a => action)
|
148
|
+
params.merge!(:testmode => Config.test_mode)
|
149
|
+
request = connection.post do |req|
|
150
|
+
req.url("", params)
|
151
|
+
end
|
152
|
+
response = request.body["response"]
|
153
|
+
|
154
|
+
if response.has_key?("item")
|
155
|
+
error = response["item"]
|
156
|
+
raise IdealMollie::IdealException.new(error["errorcode"], error["message"], error["type"])
|
157
|
+
end
|
158
|
+
response
|
159
|
+
end
|
160
|
+
|
161
|
+
private
|
162
|
+
|
163
|
+
def connection
|
164
|
+
@connection ||= Faraday::Connection.new(:url => "https://secure.mollie.nl/xml/ideal",
|
165
|
+
:headers => {:user_agent => "Ruby-IdealMollie"},
|
166
|
+
:ssl => {:verify => false}) do |builder|
|
167
|
+
builder.adapter Faraday.default_adapter
|
168
|
+
builder.use Faraday::Response::ParseXml
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#
|
2
|
+
# Configuration object for storing some parameters required for making transactions
|
3
|
+
#
|
4
|
+
module IdealMollie::Config
|
5
|
+
class << self
|
6
|
+
attr_accessor :partner_id, :report_url, :return_url, :test_mode
|
7
|
+
|
8
|
+
# Set's the default value's to nil and false
|
9
|
+
def init!
|
10
|
+
@defaults = {
|
11
|
+
:@partner_id => nil,
|
12
|
+
:@report_url => nil,
|
13
|
+
:@return_url => nil,
|
14
|
+
:@test_mode => false
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
# Resets the value's to there previous value (instance_variable)
|
19
|
+
def reset!
|
20
|
+
@defaults.each { |key, value| instance_variable_set(key, value) }
|
21
|
+
end
|
22
|
+
|
23
|
+
# Set's the new value's as instance variables
|
24
|
+
def update!
|
25
|
+
@defaults.each do |key, value|
|
26
|
+
instance_variable_set(key, value) unless instance_variable_defined?(key)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
init!
|
31
|
+
reset!
|
32
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module IdealMollie
|
2
|
+
#
|
3
|
+
# Simpel extend on the Rails::Engine to add support for a new config section within the environment configs
|
4
|
+
#
|
5
|
+
# @example
|
6
|
+
# # /config/environments/development.rb
|
7
|
+
# config.ideal_mollie.partner_id = 123456
|
8
|
+
# config.ideal_mollie.report_url = "http://example.org/report"
|
9
|
+
# config.ideal_mollie.return_url = "http://example.org/return"
|
10
|
+
# config.ideal_mollie.test_mode = false
|
11
|
+
#
|
12
|
+
class Engine < Rails::Engine
|
13
|
+
config.ideal_mollie = IdealMollie::Config
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module IdealMollie
|
2
|
+
#
|
3
|
+
# Exception class specific for the IdealMollie error that might occur
|
4
|
+
#
|
5
|
+
class IdealException < Exception
|
6
|
+
attr_accessor :errorcode, :message, :type
|
7
|
+
|
8
|
+
# @param [String] errorcode The errorcode
|
9
|
+
# @param [String] message The error description
|
10
|
+
# @param [String] type The error type
|
11
|
+
def initialize(errorcode, message, type)
|
12
|
+
self.errorcode = errorcode
|
13
|
+
self.message = message
|
14
|
+
self.type = type
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe IdealMollie::Config do
|
4
|
+
before(:each) do
|
5
|
+
@config = IdealMollie::Config
|
6
|
+
@config.test_mode = true
|
7
|
+
@config.partner_id = 123456
|
8
|
+
@config.report_url = "http://example.org/report"
|
9
|
+
@config.return_url = "http://example.org/return"
|
10
|
+
end
|
11
|
+
describe "#reset!" do
|
12
|
+
it "should reset the values" do
|
13
|
+
@config.reset!
|
14
|
+
@config.test_mode.should be_false
|
15
|
+
@config.partner_id.should be_nil
|
16
|
+
@config.report_url.should be_nil
|
17
|
+
@config.return_url.should be_nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
describe "#update!" do
|
21
|
+
it "should update" do
|
22
|
+
@config.test_mode = false
|
23
|
+
@config.partner_id = 987654
|
24
|
+
@config.report_url = "report"
|
25
|
+
@config.return_url = "return"
|
26
|
+
@config.update!
|
27
|
+
|
28
|
+
config = IdealMollie::Config
|
29
|
+
config.test_mode.should be_false
|
30
|
+
config.partner_id.should eq 987654
|
31
|
+
config.report_url.should eq "report"
|
32
|
+
config.return_url.should eq "return"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe IdealMollie::IdealException do
|
4
|
+
context "#new_payment" do
|
5
|
+
it "should throw exception when no config is set" do
|
6
|
+
VCR.use_cassette("new_payment") do
|
7
|
+
expect { IdealMollie.new_payment(1234, "exception test", "0031") }.
|
8
|
+
to raise_error(IdealMollie::IdealException, /This account does not exist or is suspended./)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
it "should throw an exception when a unknown account is specified" do
|
12
|
+
config = IdealMollie::Config
|
13
|
+
config.test_mode = false
|
14
|
+
config.partner_id = 123456
|
15
|
+
config.report_url = "http://example.org/report"
|
16
|
+
config.return_url = "http://example.org/return"
|
17
|
+
|
18
|
+
VCR.use_cassette("new_payment") do
|
19
|
+
expect { IdealMollie.new_payment(1234, "exception test", "0031") }.
|
20
|
+
to raise_error(IdealMollie::IdealException, /This account does not exist or is suspended./)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
context "#check_payment" do
|
25
|
+
it "should raise an exception when a invalid transaction_id is asked" do
|
26
|
+
config = IdealMollie::Config
|
27
|
+
config.test_mode = false
|
28
|
+
config.partner_id = 738907
|
29
|
+
config.report_url = "http://example.org/report"
|
30
|
+
config.return_url = "http://example.org/return"
|
31
|
+
|
32
|
+
VCR.use_cassette("check_payment") do
|
33
|
+
expect { IdealMollie.check_payment("482d599bbcc7795727650330ad65fe9b") }.
|
34
|
+
to raise_error(IdealMollie::IdealException, /This is an unknown order./)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe IdealMollie do
|
4
|
+
before(:each) do
|
5
|
+
config = IdealMollie::Config
|
6
|
+
config.test_mode = false
|
7
|
+
config.partner_id = 123456
|
8
|
+
config.report_url = "http://example.org/report"
|
9
|
+
config.return_url = "http://example.org/return"
|
10
|
+
end
|
11
|
+
|
12
|
+
context "#banks" do
|
13
|
+
it "returns an array with banks" do
|
14
|
+
VCR.use_cassette("banks") do
|
15
|
+
banks = IdealMollie.banks
|
16
|
+
banks.class.is_a?Array.should be_true
|
17
|
+
banks.count > 0
|
18
|
+
|
19
|
+
bank = banks.first
|
20
|
+
bank[:id].should eq "0031"
|
21
|
+
bank[:name].should eq "ABN AMRO"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "#new_payment" do
|
27
|
+
it "should return a transaction hash with the correct values" do
|
28
|
+
VCR.use_cassette("new_payment") do
|
29
|
+
payment = IdealMollie.new_payment(1000, "test", "0031")
|
30
|
+
payment[:transaction_id].should eq "c9f93e5c2bd6c1e7c5bee5c5580c6f83"
|
31
|
+
payment[:amount].should eq 1000
|
32
|
+
payment[:currency].should eq "EUR"
|
33
|
+
payment[:url].should eq "https://www.abnamro.nl/nl/ideal/identification.do?randomizedstring=8433910909&trxid=30000217841224"
|
34
|
+
payment[:message].should eq "Your iDEAL-payment has successfully been setup. Your customer should visit the given URL to make the payment"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "#check_payment" do
|
40
|
+
it "should return a payment response with the correct values" do
|
41
|
+
VCR.use_cassette("check_payment") do
|
42
|
+
payment = IdealMollie.check_payment("c9f93e5c2bd6c1e7c5bee5c5580c6f83")
|
43
|
+
payment[:transaction_id].should eq "c9f93e5c2bd6c1e7c5bee5c5580c6f83"
|
44
|
+
payment[:amount].should eq 1000
|
45
|
+
payment[:currency].should eq "EUR"
|
46
|
+
payment[:payed].should eq false
|
47
|
+
payment[:message].should eq "This iDEAL-order wasn't payed for, or was already checked by you. (We give payed=true only once, for your protection)"
|
48
|
+
payment[:status].should eq "CheckedBefore"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
it "should mark the transaction as payed and contain the consumer information when called by mollie" do
|
52
|
+
VCR.use_cassette("check_payment") do
|
53
|
+
payment = IdealMollie.check_payment("482d599bbcc7795727650330ad65fe9b")
|
54
|
+
payment[:transaction_id].should eq "482d599bbcc7795727650330ad65fe9b"
|
55
|
+
payment[:amount].should eq 1000
|
56
|
+
payment[:currency].should eq "EUR"
|
57
|
+
payment[:payed].should eq true
|
58
|
+
payment[:message].should eq "This iDEAL-order has successfuly been payed for, and this is the first time you check it."
|
59
|
+
consumer = payment[:consumer]
|
60
|
+
consumer[:name].should eq "Hr J Janssen"
|
61
|
+
consumer[:account].should eq "P001234567"
|
62
|
+
consumer[:city].should eq "Amsterdam"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
SimpleCov.start
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'bundler/setup'
|
6
|
+
require 'vcr'
|
7
|
+
require 'ideal-mollie'
|
8
|
+
|
9
|
+
VCR.config do |c|
|
10
|
+
c.cassette_library_dir = 'spec/vcr_cassettes'
|
11
|
+
c.stub_with :fakeweb
|
12
|
+
end
|
13
|
+
|
14
|
+
RSpec.configure do |config|
|
15
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
---
|
2
|
+
- !ruby/struct:VCR::HTTPInteraction
|
3
|
+
request: !ruby/struct:VCR::Request
|
4
|
+
method: :post
|
5
|
+
uri: https://secure.mollie.nl:443/xml/ideal/?a=banklist&testmode=false
|
6
|
+
body:
|
7
|
+
headers:
|
8
|
+
user-agent:
|
9
|
+
- Ruby-IdealMollie
|
10
|
+
response: !ruby/struct:VCR::Response
|
11
|
+
status: !ruby/struct:VCR::ResponseStatus
|
12
|
+
code: 200
|
13
|
+
message: OK
|
14
|
+
headers:
|
15
|
+
server:
|
16
|
+
- nginx/0.7.67
|
17
|
+
date:
|
18
|
+
- Tue, 24 Jan 2012 12:44:39 GMT
|
19
|
+
content-type:
|
20
|
+
- text/xml
|
21
|
+
x-powered-by:
|
22
|
+
- PHP/5.2.6-1+lenny13
|
23
|
+
content-length:
|
24
|
+
- '854'
|
25
|
+
body: ! "<?xml version=\"1.0\" ?>\n<response>\n\t<bank>\n\t\t<bank_id>0031</bank_id>\n\t\t<bank_name>ABN
|
26
|
+
AMRO</bank_name>\n\t</bank>\n\t<bank>\n\t\t<bank_id>0761</bank_id>\n\t\t<bank_name>ASN
|
27
|
+
Bank</bank_name>\n\t</bank>\n\t<bank>\n\t\t<bank_id>0091</bank_id>\n\t\t<bank_name>Friesland
|
28
|
+
Bank</bank_name>\n\t</bank>\n\t<bank>\n\t\t<bank_id>0721</bank_id>\n\t\t<bank_name>ING</bank_name>\n\t</bank>\n\t<bank>\n\t\t<bank_id>0021</bank_id>\n\t\t<bank_name>Rabobank</bank_name>\n\t</bank>\n\t<bank>\n\t\t<bank_id>0771</bank_id>\n\t\t<bank_name>RegioBank</bank_name>\n\t</bank>\n\t<bank>\n\t\t<bank_id>0751</bank_id>\n\t\t<bank_name>SNS
|
29
|
+
Bank</bank_name>\n\t</bank>\n\t<bank>\n\t\t<bank_id>0511</bank_id>\n\t\t<bank_name>Triodos
|
30
|
+
Bank</bank_name>\n\t</bank>\n\t<bank>\n\t\t<bank_id>0161</bank_id>\n\t\t<bank_name>van
|
31
|
+
Lanschot</bank_name>\n\t</bank>\n<message>This is the current list of banks
|
32
|
+
and their ID's that currently support iDEAL-payments</message>\n</response>"
|
33
|
+
http_version: '1.1'
|
@@ -0,0 +1,82 @@
|
|
1
|
+
---
|
2
|
+
- !ruby/struct:VCR::HTTPInteraction
|
3
|
+
request: !ruby/struct:VCR::Request
|
4
|
+
method: :post
|
5
|
+
uri: https://secure.mollie.nl:443/xml/ideal/?partnerid=123456&transaction_id=c9f93e5c2bd6c1e7c5bee5c5580c6f83&a=check&testmode=false
|
6
|
+
body:
|
7
|
+
headers:
|
8
|
+
user-agent:
|
9
|
+
- Ruby-IdealMollie
|
10
|
+
response: !ruby/struct:VCR::Response
|
11
|
+
status: !ruby/struct:VCR::ResponseStatus
|
12
|
+
code: 200
|
13
|
+
message: OK
|
14
|
+
headers:
|
15
|
+
server:
|
16
|
+
- nginx/0.7.67
|
17
|
+
date:
|
18
|
+
- Tue, 24 Jan 2012 13:02:18 GMT
|
19
|
+
content-type:
|
20
|
+
- text/xml
|
21
|
+
x-powered-by:
|
22
|
+
- PHP/5.2.6-1+lenny13
|
23
|
+
content-length:
|
24
|
+
- '151'
|
25
|
+
body: ! "<?xml version=\"1.0\" ?>\n<response>\n\t<order>\n\t\t<transaction_id>c9f93e5c2bd6c1e7c5bee5c5580c6f83</transaction_id>\n\t\t<amount>1000</amount>\n\t\t<currency>EUR</currency>\n\t\t<payed>false</payed>\n\t\t<message>This
|
26
|
+
iDEAL-order wasn't payed for, or was already checked by you. (We give payed=true
|
27
|
+
only once, for your protection)</message>\n\t\t<status>CheckedBefore</status>\n\t</order>\n\n</response>"
|
28
|
+
http_version: '1.1'
|
29
|
+
- !ruby/struct:VCR::HTTPInteraction
|
30
|
+
request: !ruby/struct:VCR::Request
|
31
|
+
method: :post
|
32
|
+
uri: https://secure.mollie.nl:443/xml/ideal/?partnerid=123456&transaction_id=482d599bbcc7795727650330ad65fe9b&a=check&testmode=false
|
33
|
+
body:
|
34
|
+
headers:
|
35
|
+
user-agent:
|
36
|
+
- Ruby-IdealMollie
|
37
|
+
response: !ruby/struct:VCR::Response
|
38
|
+
status: !ruby/struct:VCR::ResponseStatus
|
39
|
+
code: 200
|
40
|
+
message: OK
|
41
|
+
headers:
|
42
|
+
server:
|
43
|
+
- nginx/0.7.67
|
44
|
+
date:
|
45
|
+
- Tue, 24 Jan 2012 13:02:18 GMT
|
46
|
+
content-type:
|
47
|
+
- text/xml
|
48
|
+
x-powered-by:
|
49
|
+
- PHP/5.2.6-1+lenny13
|
50
|
+
content-length:
|
51
|
+
- '151'
|
52
|
+
body: ! "<?xml version=\"1.0\" ?>\n<response>\n\t<order>\n\t\t<transaction_id>482d599bbcc7795727650330ad65fe9b</transaction_id>\n\t\t<amount>1000</amount>\n\t\t<currency>EUR</currency>\n\t\t<payed>true</payed>\n\t\t<consumer>\n\t\t\t<consumerName>Hr
|
53
|
+
J Janssen</consumerName>\n\t\t\t<consumerAccount>P001234567</consumerAccount>\n\t\t\t<consumerCity>Amsterdam</consumerCity>\n\t\t</consumer>\n\t\t<message>This
|
54
|
+
iDEAL-order has successfuly been payed for, and this is the first time you check
|
55
|
+
it.</message>\n\t</order>\n\n</response>"
|
56
|
+
http_version: '1.1'
|
57
|
+
- !ruby/struct:VCR::HTTPInteraction
|
58
|
+
request: !ruby/struct:VCR::Request
|
59
|
+
method: :post
|
60
|
+
uri: https://secure.mollie.nl:443/xml/ideal/?partnerid=738907&transaction_id=482d599bbcc7795727650330ad65fe9b&a=check&testmode=false
|
61
|
+
body:
|
62
|
+
headers:
|
63
|
+
user-agent:
|
64
|
+
- Ruby-IdealMollie
|
65
|
+
response: !ruby/struct:VCR::Response
|
66
|
+
status: !ruby/struct:VCR::ResponseStatus
|
67
|
+
code: 200
|
68
|
+
message: OK
|
69
|
+
headers:
|
70
|
+
server:
|
71
|
+
- nginx/0.7.67
|
72
|
+
date:
|
73
|
+
- Tue, 24 Jan 2012 13:26:15 GMT
|
74
|
+
content-type:
|
75
|
+
- text/xml
|
76
|
+
x-powered-by:
|
77
|
+
- PHP/5.2.6-1+lenny13
|
78
|
+
content-length:
|
79
|
+
- '151'
|
80
|
+
body: ! "<?xml version=\"1.0\" ?>\n<response>\n\t<item type=\"error\">\n\t\t<errorcode>-10</errorcode>\n\t\t<message>This
|
81
|
+
is an unknown order.</message>\n\t</item>\n</response>"
|
82
|
+
http_version: '1.1'
|
@@ -0,0 +1,54 @@
|
|
1
|
+
---
|
2
|
+
- !ruby/struct:VCR::HTTPInteraction
|
3
|
+
request: !ruby/struct:VCR::Request
|
4
|
+
method: :post
|
5
|
+
uri: https://secure.mollie.nl:443/xml/ideal/?partnerid=123456&reporturl=http%3A%2F%2Fexample.org%2Freport&returnurl=http%3A%2F%2Fexample.org%2Freturn&description=test&amount=1000&bank_id=0031&a=fetch&testmode=false
|
6
|
+
body:
|
7
|
+
headers:
|
8
|
+
user-agent:
|
9
|
+
- Ruby-IdealMollie
|
10
|
+
response: !ruby/struct:VCR::Response
|
11
|
+
status: !ruby/struct:VCR::ResponseStatus
|
12
|
+
code: 200
|
13
|
+
message: OK
|
14
|
+
headers:
|
15
|
+
server:
|
16
|
+
- nginx/0.7.67
|
17
|
+
date:
|
18
|
+
- Tue, 24 Jan 2012 12:52:31 GMT
|
19
|
+
content-type:
|
20
|
+
- text/xml
|
21
|
+
x-powered-by:
|
22
|
+
- PHP/5.2.6-1+lenny13
|
23
|
+
content-length:
|
24
|
+
- '212'
|
25
|
+
body: ! "<?xml version=\"1.0\" ?>\n<response>\n\t<order>\n\t\t<transaction_id>c9f93e5c2bd6c1e7c5bee5c5580c6f83</transaction_id>\n\t\t<amount>1000</amount>\n\t\t<currency>EUR</currency>\n\t\t<URL>https://www.abnamro.nl/nl/ideal/identification.do?randomizedstring=8433910909&trxid=30000217841224</URL>\n\t\t<message>Your
|
26
|
+
iDEAL-payment has successfully been setup. Your customer should visit the given
|
27
|
+
URL to make the payment</message>\n\t</order>\n</response>"
|
28
|
+
http_version: '1.1'
|
29
|
+
- !ruby/struct:VCR::HTTPInteraction
|
30
|
+
request: !ruby/struct:VCR::Request
|
31
|
+
method: :post
|
32
|
+
uri: https://secure.mollie.nl:443/xml/ideal/?partnerid=123456&reporturl=http%3A%2F%2Fexample.org%2Freport&returnurl=http%3A%2F%2Fexample.org%2Freturn&description=exception%20test&amount=1234&bank_id=0031&a=fetch&testmode=false
|
33
|
+
body:
|
34
|
+
headers:
|
35
|
+
user-agent:
|
36
|
+
- Ruby-IdealMollie
|
37
|
+
response: !ruby/struct:VCR::Response
|
38
|
+
status: !ruby/struct:VCR::ResponseStatus
|
39
|
+
code: 200
|
40
|
+
message: OK
|
41
|
+
headers:
|
42
|
+
server:
|
43
|
+
- nginx/0.7.67
|
44
|
+
date:
|
45
|
+
- Tue, 24 Jan 2012 13:18:45 GMT
|
46
|
+
content-type:
|
47
|
+
- text/xml
|
48
|
+
x-powered-by:
|
49
|
+
- PHP/5.2.6-1+lenny13
|
50
|
+
content-length:
|
51
|
+
- '169'
|
52
|
+
body: ! "<?xml version=\"1.0\" ?>\n<response>\n\t<item type=\"error\">\n\t\t<errorcode>-2</errorcode>\n\t\t<message>This
|
53
|
+
account does not exist or is suspended.</message>\n\t</item>\n</response>"
|
54
|
+
http_version: '1.1'
|
@@ -0,0 +1,32 @@
|
|
1
|
+
---
|
2
|
+
- !ruby/struct:VCR::HTTPInteraction
|
3
|
+
request: !ruby/struct:VCR::Request
|
4
|
+
method: :get
|
5
|
+
uri: https://secure.mollie.nl:443/xml/ideal?a=fetch&partnerid=123456&description=description&reporturl=http%3A%2F%2Fexample.org%2Ftransactions%2Freport_payment&returnurl=http%3A%2F%2Fexample.org%2Ftransactions%2Ffinish&amount=1000&bank_id=0031&testmode=false
|
6
|
+
body:
|
7
|
+
headers:
|
8
|
+
response: !ruby/struct:VCR::Response
|
9
|
+
status: !ruby/struct:VCR::ResponseStatus
|
10
|
+
code: 200
|
11
|
+
message: OK
|
12
|
+
headers:
|
13
|
+
server:
|
14
|
+
- nginx/0.7.67
|
15
|
+
date:
|
16
|
+
- Fri, 20 Jan 2012 13:39:15 GMT
|
17
|
+
content-type:
|
18
|
+
- text/xml
|
19
|
+
content-location:
|
20
|
+
- ideal.php
|
21
|
+
vary:
|
22
|
+
- negotiate
|
23
|
+
tcn:
|
24
|
+
- choice
|
25
|
+
x-powered-by:
|
26
|
+
- PHP/5.2.6-1+lenny13
|
27
|
+
content-length:
|
28
|
+
- '429'
|
29
|
+
body: ! "<?xml version=\"1.0\" ?>\n<response>\n\t<order>\n\t\t<transaction_id>c9f93e5c2bd6c1e7c5bee5c5580c6f83</transaction_id>\n\t\t<amount>1000</amount>\n\t\t<currency>EUR</currency>\n\t\t<URL>https://www.abnamro.nl/nl/ideal/identification.do?randomizedstring=8433910909&trxid=30000217841224</URL>\n\t\t<message>Your
|
30
|
+
iDEAL-payment has successfully been setup. Your customer should visit the given
|
31
|
+
URL to make the payment</message>\n\t</order>\n</response>"
|
32
|
+
http_version: '1.1'
|
metadata
ADDED
@@ -0,0 +1,196 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ideal-mollie
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Manuel van Rijn
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-01-25 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: &16337200 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *16337200
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: vcr
|
27
|
+
requirement: &16336640 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *16336640
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: fakeweb
|
38
|
+
requirement: &16335860 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *16335860
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: yard
|
49
|
+
requirement: &16335260 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *16335260
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: redcarpet
|
60
|
+
requirement: &16334340 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *16334340
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: &16333000 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *16333000
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: rake
|
82
|
+
requirement: &16332260 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ~>
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: 0.9.0
|
88
|
+
type: :runtime
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *16332260
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: faraday
|
93
|
+
requirement: &16346260 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ~>
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: 0.5.7
|
99
|
+
type: :runtime
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *16346260
|
102
|
+
- !ruby/object:Gem::Dependency
|
103
|
+
name: faraday_middleware
|
104
|
+
requirement: &16344600 !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 0.3.2
|
110
|
+
type: :runtime
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: *16344600
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
name: multi_xml
|
115
|
+
requirement: &16343320 !ruby/object:Gem::Requirement
|
116
|
+
none: false
|
117
|
+
requirements:
|
118
|
+
- - ~>
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: 0.2.2
|
121
|
+
type: :runtime
|
122
|
+
prerelease: false
|
123
|
+
version_requirements: *16343320
|
124
|
+
- !ruby/object:Gem::Dependency
|
125
|
+
name: nokogiri
|
126
|
+
requirement: &16342380 !ruby/object:Gem::Requirement
|
127
|
+
none: false
|
128
|
+
requirements:
|
129
|
+
- - ~>
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 1.4.1
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: *16342380
|
135
|
+
description: A simple Ruby implementation for handeling iDeal transactions with the
|
136
|
+
Mollie API
|
137
|
+
email:
|
138
|
+
- manuel@manuelles.nl
|
139
|
+
executables: []
|
140
|
+
extensions: []
|
141
|
+
extra_rdoc_files: []
|
142
|
+
files:
|
143
|
+
- .gitignore
|
144
|
+
- .rspec
|
145
|
+
- .yardopts
|
146
|
+
- CHANGELOG.md
|
147
|
+
- Gemfile
|
148
|
+
- LICENSE.md
|
149
|
+
- README.md
|
150
|
+
- Rakefile
|
151
|
+
- ideal-mollie.gemspec
|
152
|
+
- lib/ideal-mollie.rb
|
153
|
+
- lib/ideal-mollie/config.rb
|
154
|
+
- lib/ideal-mollie/engine.rb
|
155
|
+
- lib/ideal-mollie/ideal_exception.rb
|
156
|
+
- lib/ideal-mollie/version.rb
|
157
|
+
- spec/config_spec.rb
|
158
|
+
- spec/ideal_exception_spec.rb
|
159
|
+
- spec/ideal_mollie_spec.rb
|
160
|
+
- spec/spec_helper.rb
|
161
|
+
- spec/vcr_cassettes/banks.yml
|
162
|
+
- spec/vcr_cassettes/check_payment.yml
|
163
|
+
- spec/vcr_cassettes/new_payment.yml
|
164
|
+
- spec/vcr_cassettes/request_payment.yml
|
165
|
+
homepage: https://github.com/manuelvanrijn/ideal-mollie
|
166
|
+
licenses: []
|
167
|
+
post_install_message:
|
168
|
+
rdoc_options: []
|
169
|
+
require_paths:
|
170
|
+
- lib
|
171
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
172
|
+
none: false
|
173
|
+
requirements:
|
174
|
+
- - ! '>='
|
175
|
+
- !ruby/object:Gem::Version
|
176
|
+
version: '0'
|
177
|
+
segments:
|
178
|
+
- 0
|
179
|
+
hash: 3389092229287419673
|
180
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
181
|
+
none: false
|
182
|
+
requirements:
|
183
|
+
- - ! '>='
|
184
|
+
- !ruby/object:Gem::Version
|
185
|
+
version: '0'
|
186
|
+
segments:
|
187
|
+
- 0
|
188
|
+
hash: 3389092229287419673
|
189
|
+
requirements: []
|
190
|
+
rubyforge_project: ideal-mollie
|
191
|
+
rubygems_version: 1.8.11
|
192
|
+
signing_key:
|
193
|
+
specification_version: 3
|
194
|
+
summary: Make iDeal Mollie payments without the pain
|
195
|
+
test_files: []
|
196
|
+
has_rdoc:
|