sisow 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/Gemfile +4 -0
- data/README.rdoc +116 -0
- data/Rakefile +2 -0
- data/lib/sisow.rb +40 -0
- data/lib/sisow/api/callback.rb +51 -0
- data/lib/sisow/api/request.rb +67 -0
- data/lib/sisow/api/request/check_merchant_request.rb +40 -0
- data/lib/sisow/api/request/directory_request.rb +25 -0
- data/lib/sisow/api/request/ping_request.rb +25 -0
- data/lib/sisow/api/request/transaction_request.rb +86 -0
- data/lib/sisow/configuration.rb +33 -0
- data/lib/sisow/error_response.rb +14 -0
- data/lib/sisow/exception.rb +4 -0
- data/lib/sisow/issuer.rb +24 -0
- data/lib/sisow/merchant.rb +10 -0
- data/lib/sisow/payment.rb +40 -0
- data/lib/sisow/payment/bancontact_payment.rb +9 -0
- data/lib/sisow/payment/ideal_payment.rb +9 -0
- data/lib/sisow/payment/sofort_payment.rb +9 -0
- data/lib/sisow/ping.rb +9 -0
- data/lib/sisow/version.rb +3 -0
- data/sisow.gemspec +29 -0
- data/spec/models/bancontact_payment_spec.rb +29 -0
- data/spec/models/callback_spec.rb +72 -0
- data/spec/models/configuration_spec.rb +25 -0
- data/spec/models/error_response_spec.rb +15 -0
- data/spec/models/ideal_payment_spec.rb +29 -0
- data/spec/models/issuer_spec.rb +14 -0
- data/spec/models/merchant_spec.rb +11 -0
- data/spec/models/payment_spec.rb +57 -0
- data/spec/models/ping_spec.rb +11 -0
- data/spec/models/request_spec.rb +40 -0
- data/spec/models/sisow_spec.rb +28 -0
- data/spec/models/sofort_payment_spec.rb +29 -0
- data/spec/models/transaction_request_spec.rb +24 -0
- data/spec/sisow.yml +2 -0
- data/spec/sisow.yml.example +2 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/vcr_setup.rb +6 -0
- metadata +177 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
module Sisow
|
2
|
+
class Configuration
|
3
|
+
|
4
|
+
attr_accessor :merchant_id, :merchant_key, :test_mode, :debug_mode, :shop_id
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@debug_mode = false
|
8
|
+
@test_mode = false
|
9
|
+
@merchant_key = nil
|
10
|
+
@merchant_id = nil
|
11
|
+
@shop_id = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_mode_enabled?
|
15
|
+
@test_mode == true
|
16
|
+
end
|
17
|
+
|
18
|
+
def debug_mode=(boolean)
|
19
|
+
@debug_mode = boolean
|
20
|
+
|
21
|
+
if boolean == true
|
22
|
+
Sisow::Api::Request.debug_output $stderr
|
23
|
+
else
|
24
|
+
Sisow::Api::Request.debug_output nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def debug_mode_enabled?
|
29
|
+
@debug_mode == true
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Sisow
|
2
|
+
class ErrorResponse
|
3
|
+
attr_accessor :code, :message
|
4
|
+
|
5
|
+
def initialize(response)
|
6
|
+
@code = response.errorresponse.error.errorcode
|
7
|
+
@message = response.errorresponse.error.errormessage
|
8
|
+
end
|
9
|
+
|
10
|
+
def message
|
11
|
+
"An error occurred: #{@code}. #{@message}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/sisow/issuer.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
module Sisow
|
2
|
+
class Issuer
|
3
|
+
attr_accessor :id, :name
|
4
|
+
|
5
|
+
def self.list
|
6
|
+
hash = Sisow::Api::DirectoryRequest.perform
|
7
|
+
|
8
|
+
hash.issuer = [ hash.issuer ] unless hash.issuer.is_a?(Array)
|
9
|
+
|
10
|
+
hash.issuer.map do |issuer|
|
11
|
+
new(
|
12
|
+
:id => issuer.issuerid,
|
13
|
+
:name => issuer.issuername
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(attributes = {})
|
19
|
+
@id = attributes[:id]
|
20
|
+
@name = attributes[:name]
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Sisow
|
2
|
+
class Payment
|
3
|
+
|
4
|
+
attr_accessor :purchase_id,
|
5
|
+
:issuer_id,
|
6
|
+
:description,
|
7
|
+
:amount,
|
8
|
+
:entrance_code,
|
9
|
+
:return_url,
|
10
|
+
:cancel_url,
|
11
|
+
:callback_url,
|
12
|
+
:notify_url
|
13
|
+
|
14
|
+
def initialize(attributes = {})
|
15
|
+
attributes.each do |k,v|
|
16
|
+
send("#{k}=", v)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def payment_url
|
21
|
+
request = Sisow::Api::TransactionRequest.new(self)
|
22
|
+
response = request.perform
|
23
|
+
|
24
|
+
CGI::unescape(response.issuerurl) if response.issuerurl?
|
25
|
+
end
|
26
|
+
|
27
|
+
def shop_id
|
28
|
+
Sisow.configuration.shop_id
|
29
|
+
end
|
30
|
+
|
31
|
+
def valid?
|
32
|
+
entrance_code.index(/-|_/).nil? &&
|
33
|
+
purchase_id.index(/\#|_/).nil? &&
|
34
|
+
(!amount.nil? && amount != '')
|
35
|
+
end
|
36
|
+
|
37
|
+
def payment_method; raise 'Implement me in a subclass'; end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
data/lib/sisow/ping.rb
ADDED
data/sisow.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "sisow/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "sisow"
|
7
|
+
s.version = Sisow::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Marcel de Graaf"]
|
10
|
+
s.email = ["mail@marceldegraaf.net"]
|
11
|
+
s.homepage = "http://github.com/marceldegraaf/sisow"
|
12
|
+
s.summary = %q{Rails gem for payments through Sisow.}
|
13
|
+
s.description = %q{This gem implements the REST API of the Sisow payment provider.}
|
14
|
+
|
15
|
+
s.rubyforge_project = "sisow"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_dependency 'httparty'
|
23
|
+
s.add_dependency 'hashie'
|
24
|
+
|
25
|
+
s.add_development_dependency 'rspec'
|
26
|
+
s.add_development_dependency 'vcr'
|
27
|
+
s.add_development_dependency 'fakeweb'
|
28
|
+
s.add_development_dependency 'simplecov'
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sisow::BancontactPayment do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
@payment = Sisow::BancontactPayment.new(
|
7
|
+
:purchase_id => 'purchase-123',
|
8
|
+
:issuer_id => '99',
|
9
|
+
:description => 'Payment description',
|
10
|
+
:entrance_code => 'entrancecode',
|
11
|
+
:return_url => 'http://example.com/return',
|
12
|
+
:cancel_url => 'http://example.com/cancel',
|
13
|
+
:callback_url => 'http://example.com/callback',
|
14
|
+
:notify_url => 'http://example.com/notify',
|
15
|
+
:amount => 1299
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should have the 'mistercash' payment method" do
|
20
|
+
@payment.payment_method.should == 'mistercash'
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should request a payment URL with the Sisow API" do
|
24
|
+
VCR.use_cassette("bancontact_payment") do
|
25
|
+
@payment.payment_url.should =~ /https:\/\/www\.sisow\.nl\/Sisow\/iDeal\/Simulator\.aspx/
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sisow::Api::Callback do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
@transaction_id = 'trx-123'
|
7
|
+
@entrance_code = 'entrancecode'
|
8
|
+
@status = 'Success'
|
9
|
+
@sha1 = Digest::SHA1.hexdigest(
|
10
|
+
[
|
11
|
+
@transaction_id,
|
12
|
+
@entrance_code,
|
13
|
+
@status,
|
14
|
+
Sisow.configuration.merchant_id,
|
15
|
+
Sisow.configuration.merchant_key
|
16
|
+
].join
|
17
|
+
)
|
18
|
+
|
19
|
+
@callback = Sisow::Api::Callback.new(
|
20
|
+
:transaction_id => @transaction_id,
|
21
|
+
:entrance_code => @entrance_code,
|
22
|
+
:status => @status,
|
23
|
+
:sha1 => @sha1
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should be valid" do
|
28
|
+
@callback = Sisow::Api::Callback.new(
|
29
|
+
:transaction_id => @transaction_id,
|
30
|
+
:entrance_code => @entrance_code,
|
31
|
+
:status => @status,
|
32
|
+
:sha1 => @sha1
|
33
|
+
)
|
34
|
+
|
35
|
+
@callback.valid?.should == true
|
36
|
+
lambda { @callback.validate! }.should_not raise_error
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should raise an error when invalid" do
|
40
|
+
@callback = Sisow::Api::Callback.new(
|
41
|
+
:transaction_id => @transaction_id,
|
42
|
+
:entrance_code => @entrance_code,
|
43
|
+
:status => @status,
|
44
|
+
:sha1 => 'fake-hash'
|
45
|
+
)
|
46
|
+
|
47
|
+
@callback.valid?.should == false
|
48
|
+
lambda { @callback.validate! }.should raise_error(Sisow::Exception, "This callback is forged")
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "transaction status" do
|
52
|
+
it "should be success" do
|
53
|
+
@callback.success?.should == true
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should be expired" do
|
57
|
+
@callback.status = 'Expired'
|
58
|
+
@callback.expired?.should == true
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should be cancelled" do
|
62
|
+
@callback.status = 'Cancelled'
|
63
|
+
@callback.cancelled?.should == true
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should be failure" do
|
67
|
+
@callback.status = 'Failure'
|
68
|
+
@callback.failure?.should == true
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sisow::Configuration do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
@configuration = Sisow::Configuration.new
|
7
|
+
@configuration.merchant_id = '123'
|
8
|
+
@configuration.merchant_key = 'abc'
|
9
|
+
@configuration.shop_id = '999'
|
10
|
+
@configuration.debug_mode = false
|
11
|
+
@configuration.test_mode = false
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should tell wether test mode is enabled" do
|
15
|
+
@configuration.test_mode = true
|
16
|
+
@configuration.test_mode_enabled?.should == true
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should tell wether debug mode is enabled" do
|
20
|
+
@configuration.debug_mode = true
|
21
|
+
@configuration.debug_mode_enabled?.should == true
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sisow::ErrorResponse do
|
4
|
+
|
5
|
+
before :all do
|
6
|
+
response = Hashie::Mash.new
|
7
|
+
response.errorresponse = {:error => {:errorcode => "TA123", :errormessage => "Foo bar"}}
|
8
|
+
@error_response = Sisow::ErrorResponse.new(response)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should display a message, given a response" do
|
12
|
+
@error_response.message.should == "An error occurred: TA123. Foo bar"
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sisow::IdealPayment do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
@payment = Sisow::IdealPayment.new(
|
7
|
+
:purchase_id => 'Order 123',
|
8
|
+
:issuer_id => '99',
|
9
|
+
:description => 'Payment description',
|
10
|
+
:entrance_code => 'entrancecode',
|
11
|
+
:return_url => 'http://example.com/return',
|
12
|
+
:cancel_url => 'http://example.com/cancel',
|
13
|
+
:callback_url => 'http://example.com/callback',
|
14
|
+
:notify_url => 'http://example.com/notify',
|
15
|
+
:amount => 1299
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should have the 'ideal' payment method" do
|
20
|
+
@payment.payment_method.should == 'ideal'
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should request a payment URL with the Sisow API" do
|
24
|
+
VCR.use_cassette("ideal_payment") do
|
25
|
+
@payment.payment_url.should =~ /https:\/\/www\.sisow\.nl\/Sisow\/iDeal\/Simulator\.aspx/
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sisow::Issuer do
|
4
|
+
|
5
|
+
it "should list all available issuers" do
|
6
|
+
VCR.use_cassette('issuer') do
|
7
|
+
list = Sisow::Issuer.list
|
8
|
+
list.size.should == 1
|
9
|
+
list.first.name.should =~ /Sisow Bank/
|
10
|
+
list.first.id.should_not be_nil
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sisow::Payment do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
@payment = Sisow::Payment.new(
|
7
|
+
:purchase_id => 'Order 123',
|
8
|
+
:issuer_id => '99',
|
9
|
+
:description => 'Payment description',
|
10
|
+
:entrance_code => 'entrancecode',
|
11
|
+
:return_url => 'http://example.com/return',
|
12
|
+
:cancel_url => 'http://example.com/cancel',
|
13
|
+
:callback_url => 'http://example.com/callback',
|
14
|
+
:notify_url => 'http://example.com/notify',
|
15
|
+
:amount => 1299
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "validation" do
|
20
|
+
|
21
|
+
it "should be valid" do
|
22
|
+
@payment.valid?.should == true
|
23
|
+
end
|
24
|
+
|
25
|
+
it "entrance code should not contain - or _" do
|
26
|
+
@payment.entrance_code = 'foo_bar'
|
27
|
+
@payment.valid?.should == false
|
28
|
+
@payment.entrance_code = 'foo-bar'
|
29
|
+
@payment.valid?.should == false
|
30
|
+
end
|
31
|
+
|
32
|
+
it "purchase ID should not contain # or _" do
|
33
|
+
@payment.purchase_id = 'Foo #123'
|
34
|
+
@payment.valid?.should == false
|
35
|
+
@payment.purchase_id = 'Foo_123'
|
36
|
+
@payment.valid?.should == false
|
37
|
+
end
|
38
|
+
|
39
|
+
it "amount should not be nil or empty" do
|
40
|
+
@payment.amount = nil
|
41
|
+
@payment.valid?.should == false
|
42
|
+
@payment.amount = ''
|
43
|
+
@payment.valid?.should == false
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should raise an error when calling payment_method" do
|
49
|
+
lambda{ @payment.payment_method }.should raise_error
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should raise an error if amount is missing" do
|
53
|
+
@payment.amount = nil
|
54
|
+
lambda{ @payment.payment_url }.should raise_error(Sisow::Exception, "One of your payment parameters is missing or invalid")
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|