sisow 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/.gitignore +7 -0
  2. data/Gemfile +4 -0
  3. data/README.rdoc +116 -0
  4. data/Rakefile +2 -0
  5. data/lib/sisow.rb +40 -0
  6. data/lib/sisow/api/callback.rb +51 -0
  7. data/lib/sisow/api/request.rb +67 -0
  8. data/lib/sisow/api/request/check_merchant_request.rb +40 -0
  9. data/lib/sisow/api/request/directory_request.rb +25 -0
  10. data/lib/sisow/api/request/ping_request.rb +25 -0
  11. data/lib/sisow/api/request/transaction_request.rb +86 -0
  12. data/lib/sisow/configuration.rb +33 -0
  13. data/lib/sisow/error_response.rb +14 -0
  14. data/lib/sisow/exception.rb +4 -0
  15. data/lib/sisow/issuer.rb +24 -0
  16. data/lib/sisow/merchant.rb +10 -0
  17. data/lib/sisow/payment.rb +40 -0
  18. data/lib/sisow/payment/bancontact_payment.rb +9 -0
  19. data/lib/sisow/payment/ideal_payment.rb +9 -0
  20. data/lib/sisow/payment/sofort_payment.rb +9 -0
  21. data/lib/sisow/ping.rb +9 -0
  22. data/lib/sisow/version.rb +3 -0
  23. data/sisow.gemspec +29 -0
  24. data/spec/models/bancontact_payment_spec.rb +29 -0
  25. data/spec/models/callback_spec.rb +72 -0
  26. data/spec/models/configuration_spec.rb +25 -0
  27. data/spec/models/error_response_spec.rb +15 -0
  28. data/spec/models/ideal_payment_spec.rb +29 -0
  29. data/spec/models/issuer_spec.rb +14 -0
  30. data/spec/models/merchant_spec.rb +11 -0
  31. data/spec/models/payment_spec.rb +57 -0
  32. data/spec/models/ping_spec.rb +11 -0
  33. data/spec/models/request_spec.rb +40 -0
  34. data/spec/models/sisow_spec.rb +28 -0
  35. data/spec/models/sofort_payment_spec.rb +29 -0
  36. data/spec/models/transaction_request_spec.rb +24 -0
  37. data/spec/sisow.yml +2 -0
  38. data/spec/sisow.yml.example +2 -0
  39. data/spec/spec_helper.rb +26 -0
  40. data/spec/vcr_setup.rb +6 -0
  41. 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
@@ -0,0 +1,4 @@
1
+ module Sisow
2
+ class Exception < StandardError
3
+ end
4
+ end
@@ -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,10 @@
1
+ module Sisow
2
+ class Merchant
3
+
4
+ def self.payment_methods
5
+ payments = Sisow::CheckMerchantRequest.perform
6
+ [payments].flatten.map(&:payment)
7
+ end
8
+
9
+ end
10
+ 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
@@ -0,0 +1,9 @@
1
+ module Sisow
2
+ class BancontactPayment < Sisow::Payment
3
+
4
+ def payment_method
5
+ 'mistercash'
6
+ end
7
+
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Sisow
2
+ class IdealPayment < Sisow::Payment
3
+
4
+ def payment_method
5
+ 'ideal'
6
+ end
7
+
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Sisow
2
+ class SofortPayment < Sisow::Payment
3
+
4
+ def payment_method
5
+ 'sofort'
6
+ end
7
+
8
+ end
9
+ end
data/lib/sisow/ping.rb ADDED
@@ -0,0 +1,9 @@
1
+ module Sisow
2
+ class Ping
3
+
4
+ def self.send
5
+ Sisow::Api::PingRequest.perform
6
+ end
7
+
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module Sisow
2
+ VERSION = "0.9.0"
3
+ end
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,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe Sisow::Merchant do
4
+
5
+ it "should retrieve payment methods" do
6
+ VCR.use_cassette('merchant') do
7
+ Sisow::Merchant.payment_methods.should == %w(ideal)
8
+ end
9
+ end
10
+
11
+ 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