sisow 0.9.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.
- 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
|