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
 
    
        data/.gitignore
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    
    
        data/README.rdoc
    ADDED
    
    | 
         @@ -0,0 +1,116 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            = Sisow
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            *NOTE* This gem is work in progress. I'm planning to have it ready somewhere in March.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            This gem provides an interface to interact with the Sisow payment provider. Sisow offers payments through the iDeal (Dutch),
         
     | 
| 
      
 6 
     | 
    
         
            +
            Bancontact/Mister Cash (Belgian) and Sofort (German) online payment systems.
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            To use this gem, you'll need a payment account at Sisow (you'll need your <tt>merchant key</tt> and <tt>merchant id</tt>).
         
     | 
| 
      
 9 
     | 
    
         
            +
            The gem is aimed at Rails 3.2 but it should work on older Rails versions as well as in non-Rails apps.
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            == Installation
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            To install this gem, simply do <tt>gem install sisow</tt> or add it to your Gemfile:
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              gem 'sisow'
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            And update your bundle with <tt>bundle install</tt>
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            == Usage
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            === Configuration
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            To be able to use the gem, you must first configure it. If you're on Rails, insert the following code in <tt>config/initializers/sisow.rb</tt>:
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              Sisow.setup do |config|
         
     | 
| 
      
 26 
     | 
    
         
            +
                config.merchant_key = 'your-merchant-key'
         
     | 
| 
      
 27 
     | 
    
         
            +
                config.merchant_id  = 'your-merchant-id'
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                #
         
     | 
| 
      
 30 
     | 
    
         
            +
                # The following settings are optional
         
     | 
| 
      
 31 
     | 
    
         
            +
                #
         
     | 
| 
      
 32 
     | 
    
         
            +
                config.test_mode    = false   # default: false
         
     | 
| 
      
 33 
     | 
    
         
            +
                config.debug_mode   = false   # default: false
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            That's it. Once you restart your Rails application (or open a Rails console) you should be able to communicate with
         
     | 
| 
      
 37 
     | 
    
         
            +
            the Sisow API.
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            === Getting a list of issuers
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            To set up a payment, your user needs to choose an issuer (a bank) that will fulfill the payment. To fetch a list of Issuers, use the following command:
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
              Sisow::Issuer.list
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
            This will return a list of <tt>Sisow::Issuer</tt> objects that have an <tt>id</tt> and a <tt>name</tt>. The <tt>id</tt> is needed
         
     | 
| 
      
 46 
     | 
    
         
            +
            to set up the payment in the following step.
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            === Setting up a payment
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            After choosing an issuer, your user must be redirected to the payment page for that issuer. For that to happen, you'll have to
         
     | 
| 
      
 51 
     | 
    
         
            +
            set up a payment through the Sisow API, after which you'll be given a URL to redirect your user to.
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            Setting up a payment looks like this:
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
              payment_attributes = {
         
     | 
| 
      
 56 
     | 
    
         
            +
                :purchase_id    => '2012-01-28-33558',      # for your own reference
         
     | 
| 
      
 57 
     | 
    
         
            +
                :issuer_id      => '99',                    # the issuer id from the previous step
         
     | 
| 
      
 58 
     | 
    
         
            +
                :description    => 'Acme Inc. payment',     # description of this payment
         
     | 
| 
      
 59 
     | 
    
         
            +
                :amount         => 1299,                    # amount in Euro in cents
         
     | 
| 
      
 60 
     | 
    
         
            +
                :entrance_code  => 'foobar-foxtrot',        # a verification code you can choose. Cannot contain spaces
         
     | 
| 
      
 61 
     | 
    
         
            +
                :return_url     => 'http://example.com',    # where the user is sent after the payment
         
     | 
| 
      
 62 
     | 
    
         
            +
                :cancel_url     => 'http://example.com',    # where the user is sent when he cancels the payment
         
     | 
| 
      
 63 
     | 
    
         
            +
                :callback_url   => 'http://example.com',    # where a failed (not cancelled) payment will be reported
         
     | 
| 
      
 64 
     | 
    
         
            +
                :notify_url     => 'http://example.com',    # where the payment status will be reported
         
     | 
| 
      
 65 
     | 
    
         
            +
              }
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
              payment = Sisow::IdealPayment.new(payment_attributes)
         
     | 
| 
      
 68 
     | 
    
         
            +
              redirect_url = payment.payment_url
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
            === Supported payment methods
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
            This gem supports payments through iDeal, Bancontact/Mister Cash and Sofort. Each of these payment methods have their own class. Payment attributes are the same for each payment method, so in the example above you should only need to switch <tt>Sisow::IdealPayment</tt> for one of the other classes. These are the available class names:
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
              Sisow::IdealPayment       # for iDeal payments
         
     | 
| 
      
 75 
     | 
    
         
            +
              Sisow::BancontactPayment  # for Bancontact/Mister Cash payments
         
     | 
| 
      
 76 
     | 
    
         
            +
              Sisow::SofortPayment      # for Sofort payments
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
            === Validity checks
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
            The Sisow API has a few safety measures built in, to prevent malicious users from tampering with your payments. These checks are documented in the Sisow API documentation and are implemented in the gem.
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
            === Callbacks
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
            As documented in the Sisow API documentation, four callbacks are available. When setting up your payment, each of these callbacks can be assigned a URL. These are: <tt>return_url</tt>, <tt>cancel_url</tt>, <tt>callback_url</tt> and <tt>notify_url</tt>. After a successful or failed payment, or when the payment timeout has been reached, the Sisow API will attempt to perform a GET request on the URL's you defined.
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
            The <tt>Sisow::Api::Callback</tt> can handle these callbacks for you. To initialize such an instance you should provide the following query parameters (which are given by Sisow in the request):
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
              callback = Sisow::Api::Callback.new(
         
     | 
| 
      
 89 
     | 
    
         
            +
                :transaction_id => params[:trxid],
         
     | 
| 
      
 90 
     | 
    
         
            +
                :entrance_code  => params[:ec],
         
     | 
| 
      
 91 
     | 
    
         
            +
                :status         => params[:status],
         
     | 
| 
      
 92 
     | 
    
         
            +
                :sha1           => params[:sha1]
         
     | 
| 
      
 93 
     | 
    
         
            +
              )
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
            After initializing a <tt>Sisow::Api::Callback</tt> instance, you can check the validity of the callback and check the transaction status:
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
              callback.validate!  # Will raise a Sisow::Exception unless the callback is valid
         
     | 
| 
      
 98 
     | 
    
         
            +
              callback.valid?     # Will return a boolean to indicate the validity of the callback
         
     | 
| 
      
 99 
     | 
    
         
            +
              callback.success?   # True if the transaction was successful
         
     | 
| 
      
 100 
     | 
    
         
            +
              callback.expired?   # True if the transaction has expired
         
     | 
| 
      
 101 
     | 
    
         
            +
              callback.cancelled? # True if the transaction was cancelled
         
     | 
| 
      
 102 
     | 
    
         
            +
              callback.failure?   # True if the transaction has failed
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
            == Development
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
            Your contributions are more than welcome. To contribute to this gem, follow these steps:
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
            1. Fork the repository from Github
         
     | 
| 
      
 109 
     | 
    
         
            +
            2. Clone your fork on your development machine
         
     | 
| 
      
 110 
     | 
    
         
            +
            3. Install the dependencies with <tt>bundle install</tt>
         
     | 
| 
      
 111 
     | 
    
         
            +
            4. Copy <tt>spec/sisow.yml.example</tt> to <tt>spec/sisow.yml</tt> and enter your own Sisow credentials
         
     | 
| 
      
 112 
     | 
    
         
            +
            5. Verify your clone is working by running <tt>rspec</tt>
         
     | 
| 
      
 113 
     | 
    
         
            +
            6. Hack away
         
     | 
| 
      
 114 
     | 
    
         
            +
            7. Run the specs with <tt>rspec</tt>
         
     | 
| 
      
 115 
     | 
    
         
            +
            8. Verify spec coverage by opening <tt>coverage/index.html</tt>
         
     | 
| 
      
 116 
     | 
    
         
            +
            9. If all is good: send me a pull request
         
     | 
    
        data/Rakefile
    ADDED
    
    
    
        data/lib/sisow.rb
    ADDED
    
    | 
         @@ -0,0 +1,40 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rubygems'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'httparty'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'hashie'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            require 'sisow/configuration'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'sisow/error_response'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'sisow/exception'
         
     | 
| 
      
 8 
     | 
    
         
            +
            require 'sisow/issuer'
         
     | 
| 
      
 9 
     | 
    
         
            +
            require 'sisow/ping'
         
     | 
| 
      
 10 
     | 
    
         
            +
            require 'sisow/payment'
         
     | 
| 
      
 11 
     | 
    
         
            +
            require 'sisow/payment/ideal_payment'
         
     | 
| 
      
 12 
     | 
    
         
            +
            require 'sisow/payment/bancontact_payment'
         
     | 
| 
      
 13 
     | 
    
         
            +
            require 'sisow/payment/sofort_payment'
         
     | 
| 
      
 14 
     | 
    
         
            +
            require 'sisow/merchant'
         
     | 
| 
      
 15 
     | 
    
         
            +
            require 'sisow/api/request'
         
     | 
| 
      
 16 
     | 
    
         
            +
            require 'sisow/api/request/directory_request'
         
     | 
| 
      
 17 
     | 
    
         
            +
            require 'sisow/api/request/ping_request'
         
     | 
| 
      
 18 
     | 
    
         
            +
            require 'sisow/api/request/transaction_request'
         
     | 
| 
      
 19 
     | 
    
         
            +
            require 'sisow/api/request/check_merchant_request'
         
     | 
| 
      
 20 
     | 
    
         
            +
            require 'sisow/api/callback'
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            module Sisow
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
              class << self
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                def service_reachable?
         
     | 
| 
      
 27 
     | 
    
         
            +
                  ping = Sisow::Ping.send
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                def configure
         
     | 
| 
      
 31 
     | 
    
         
            +
                  yield configuration
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                def configuration
         
     | 
| 
      
 35 
     | 
    
         
            +
                  @configuration ||= Configuration.new
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,51 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Sisow
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Api
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Callback
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                  attr_accessor :transaction_id,
         
     | 
| 
      
 6 
     | 
    
         
            +
                                :entrance_code,
         
     | 
| 
      
 7 
     | 
    
         
            +
                                :status,
         
     | 
| 
      
 8 
     | 
    
         
            +
                                :sha1
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  def initialize(attributes = {})
         
     | 
| 
      
 11 
     | 
    
         
            +
                    attributes.each do |k,v|
         
     | 
| 
      
 12 
     | 
    
         
            +
                      send("#{k}=", v)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    end
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  def valid?
         
     | 
| 
      
 17 
     | 
    
         
            +
                    valid_callback == true
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  def validate!
         
     | 
| 
      
 21 
     | 
    
         
            +
                    raise Sisow::Exception, "This callback is forged" and return if valid_callback == false
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  def success?
         
     | 
| 
      
 25 
     | 
    
         
            +
                    @status == 'Success'
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                  def expired?
         
     | 
| 
      
 29 
     | 
    
         
            +
                    @status == 'Expired'
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  def cancelled?
         
     | 
| 
      
 33 
     | 
    
         
            +
                    @status == 'Cancelled'
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  def failure?
         
     | 
| 
      
 37 
     | 
    
         
            +
                    @status == 'Failure'
         
     | 
| 
      
 38 
     | 
    
         
            +
                  end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  private
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                    def valid_callback
         
     | 
| 
      
 43 
     | 
    
         
            +
                      string = [ @transaction_id, @entrance_code, @status, Sisow.configuration.merchant_id, Sisow.configuration.merchant_key ].join
         
     | 
| 
      
 44 
     | 
    
         
            +
                      calculated_sha1 = Digest::SHA1.hexdigest(string)
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                      calculated_sha1 == @sha1
         
     | 
| 
      
 47 
     | 
    
         
            +
                    end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                end
         
     | 
| 
      
 50 
     | 
    
         
            +
              end
         
     | 
| 
      
 51 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,67 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Sisow
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Api
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Request
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                  include HTTParty
         
     | 
| 
      
 6 
     | 
    
         
            +
                  base_uri "http://www.sisow.nl/Sisow/iDeal/RestHandler.ashx/"
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  def self.perform
         
     | 
| 
      
 9 
     | 
    
         
            +
                    new.perform
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  def perform
         
     | 
| 
      
 13 
     | 
    
         
            +
                    raise Sisow::Exception, 'Your merchant_id or merchant_key are not set' unless can_perform?
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                    validate!
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                    response = self.class.get(uri)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    response = Hashie::Mash.new(response)
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                    error!(response) if response.errorresponse?
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                    clean(response)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  def default_params
         
     | 
| 
      
 26 
     | 
    
         
            +
                    {
         
     | 
| 
      
 27 
     | 
    
         
            +
                      :merchantid  => Sisow.configuration.merchant_id,
         
     | 
| 
      
 28 
     | 
    
         
            +
                      :merchantkey => Sisow.configuration.merchant_key,
         
     | 
| 
      
 29 
     | 
    
         
            +
                      :test        => Sisow.configuration.test_mode_enabled?? test_mode_param : nil
         
     | 
| 
      
 30 
     | 
    
         
            +
                    }
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  def params;     raise 'Implement me in a subclass'; end
         
     | 
| 
      
 34 
     | 
    
         
            +
                  def method;     raise 'Implement me in a subclass'; end
         
     | 
| 
      
 35 
     | 
    
         
            +
                  def clean;      raise 'Implement me in a subclass'; end
         
     | 
| 
      
 36 
     | 
    
         
            +
                  def validate!;  raise 'Implement me in a subclass'; end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  private
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                    def can_perform?
         
     | 
| 
      
 41 
     | 
    
         
            +
                      !Sisow.configuration.merchant_id.empty? && !Sisow.configuration.merchant_key.empty?
         
     | 
| 
      
 42 
     | 
    
         
            +
                    end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                    def uri
         
     | 
| 
      
 45 
     | 
    
         
            +
                      [ '/', method, '?', encoded_params ].join
         
     | 
| 
      
 46 
     | 
    
         
            +
                    end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                    def params_string
         
     | 
| 
      
 49 
     | 
    
         
            +
                      params.map { |k,v| [ k, '=', v ].join }.join('&')
         
     | 
| 
      
 50 
     | 
    
         
            +
                    end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                    def encoded_params
         
     | 
| 
      
 53 
     | 
    
         
            +
                      URI.encode(params_string)
         
     | 
| 
      
 54 
     | 
    
         
            +
                    end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                    def test_mode_param
         
     | 
| 
      
 57 
     | 
    
         
            +
                      'true'
         
     | 
| 
      
 58 
     | 
    
         
            +
                    end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                    def error!(response)
         
     | 
| 
      
 61 
     | 
    
         
            +
                      error_response = Sisow::ErrorResponse.new(response)
         
     | 
| 
      
 62 
     | 
    
         
            +
                      raise Sisow::Exception, error_response.message and return
         
     | 
| 
      
 63 
     | 
    
         
            +
                    end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                end
         
     | 
| 
      
 66 
     | 
    
         
            +
              end
         
     | 
| 
      
 67 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,40 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Sisow
         
     | 
| 
      
 2 
     | 
    
         
            +
              class CheckMerchantRequest < Sisow::Api::Request
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                def method
         
     | 
| 
      
 5 
     | 
    
         
            +
                  'CheckMerchantRequest'
         
     | 
| 
      
 6 
     | 
    
         
            +
                end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                def params
         
     | 
| 
      
 9 
     | 
    
         
            +
                  default_params.merge!(merchant_params)
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                def clean(response)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  if response.checkmerchantresponse? && response.checkmerchantresponse.merchant?
         
     | 
| 
      
 14 
     | 
    
         
            +
                    response.checkmerchantresponse.merchant.payments
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                def validate!
         
     | 
| 
      
 19 
     | 
    
         
            +
                  true
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                private
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  def merchant_params
         
     | 
| 
      
 25 
     | 
    
         
            +
                    {
         
     | 
| 
      
 26 
     | 
    
         
            +
                      :sha1 => sha1
         
     | 
| 
      
 27 
     | 
    
         
            +
                    }
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  def sha1
         
     | 
| 
      
 31 
     | 
    
         
            +
                    string = [
         
     | 
| 
      
 32 
     | 
    
         
            +
                      Sisow.configuration.merchant_id,
         
     | 
| 
      
 33 
     | 
    
         
            +
                      Sisow.configuration.merchant_key
         
     | 
| 
      
 34 
     | 
    
         
            +
                    ].join
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                    Digest::SHA1.hexdigest(string)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
              end
         
     | 
| 
      
 40 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,25 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Sisow
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Api
         
     | 
| 
      
 3 
     | 
    
         
            +
                class DirectoryRequest < Request
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                  def method
         
     | 
| 
      
 6 
     | 
    
         
            +
                    'DirectoryRequest'
         
     | 
| 
      
 7 
     | 
    
         
            +
                  end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  def params
         
     | 
| 
      
 10 
     | 
    
         
            +
                    default_params
         
     | 
| 
      
 11 
     | 
    
         
            +
                  end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  def clean(response)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    if response.directoryresponse? && response.directoryresponse.directory?
         
     | 
| 
      
 15 
     | 
    
         
            +
                      response.directoryresponse.directory
         
     | 
| 
      
 16 
     | 
    
         
            +
                    end
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  def validate!
         
     | 
| 
      
 20 
     | 
    
         
            +
                    true
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,25 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Sisow
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Api
         
     | 
| 
      
 3 
     | 
    
         
            +
                class PingRequest < Request
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                  def method
         
     | 
| 
      
 6 
     | 
    
         
            +
                    'PingRequest'
         
     | 
| 
      
 7 
     | 
    
         
            +
                  end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  def params
         
     | 
| 
      
 10 
     | 
    
         
            +
                    default_params
         
     | 
| 
      
 11 
     | 
    
         
            +
                  end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  def clean(response)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    if response.pingresponse? && response.pingresponse.timestamp?
         
     | 
| 
      
 15 
     | 
    
         
            +
                      response.pingresponse.timestamp
         
     | 
| 
      
 16 
     | 
    
         
            +
                    end
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  def validate!
         
     | 
| 
      
 20 
     | 
    
         
            +
                    true
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,86 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Sisow
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Api
         
     | 
| 
      
 3 
     | 
    
         
            +
                class TransactionRequest < Request
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                  attr_accessor :purchase_id,
         
     | 
| 
      
 6 
     | 
    
         
            +
                                :issuer_id,
         
     | 
| 
      
 7 
     | 
    
         
            +
                                :description,
         
     | 
| 
      
 8 
     | 
    
         
            +
                                :amount,
         
     | 
| 
      
 9 
     | 
    
         
            +
                                :payment
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  def initialize(payment)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @payment = payment
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  def method
         
     | 
| 
      
 16 
     | 
    
         
            +
                    'TransactionRequest'
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  def params
         
     | 
| 
      
 20 
     | 
    
         
            +
                    default_params.merge!(transaction_params)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                  def clean(response)
         
     | 
| 
      
 24 
     | 
    
         
            +
                    check_validity!(response)
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                    if response.transactionrequest? && response.transactionrequest.transaction?
         
     | 
| 
      
 27 
     | 
    
         
            +
                      response.transactionrequest.transaction
         
     | 
| 
      
 28 
     | 
    
         
            +
                    end
         
     | 
| 
      
 29 
     | 
    
         
            +
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  def validate!
         
     | 
| 
      
 32 
     | 
    
         
            +
                    raise Sisow::Exception, 'One of your payment parameters is missing or invalid' unless @payment.valid?
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  def sha1
         
     | 
| 
      
 36 
     | 
    
         
            +
                    string = [
         
     | 
| 
      
 37 
     | 
    
         
            +
                      payment.purchase_id,
         
     | 
| 
      
 38 
     | 
    
         
            +
                      payment.entrance_code,
         
     | 
| 
      
 39 
     | 
    
         
            +
                      payment.amount,
         
     | 
| 
      
 40 
     | 
    
         
            +
                      Sisow.configuration.merchant_id,
         
     | 
| 
      
 41 
     | 
    
         
            +
                      Sisow.configuration.merchant_key
         
     | 
| 
      
 42 
     | 
    
         
            +
                    ].join
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                    Digest::SHA1.hexdigest(string)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                  private
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                    def transaction_params
         
     | 
| 
      
 50 
     | 
    
         
            +
                      {
         
     | 
| 
      
 51 
     | 
    
         
            +
                        :payment      => payment.payment_method,
         
     | 
| 
      
 52 
     | 
    
         
            +
                        :purchaseid   => payment.purchase_id,
         
     | 
| 
      
 53 
     | 
    
         
            +
                        :amount       => payment.amount,
         
     | 
| 
      
 54 
     | 
    
         
            +
                        :issuerid     => payment.issuer_id,
         
     | 
| 
      
 55 
     | 
    
         
            +
                        :description  => payment.description,
         
     | 
| 
      
 56 
     | 
    
         
            +
                        :entrancecode => payment.entrance_code,
         
     | 
| 
      
 57 
     | 
    
         
            +
                        :returnurl    => payment.return_url,
         
     | 
| 
      
 58 
     | 
    
         
            +
                        :cancelurl    => payment.cancel_url,
         
     | 
| 
      
 59 
     | 
    
         
            +
                        :callbackurl  => payment.callback_url,
         
     | 
| 
      
 60 
     | 
    
         
            +
                        :notifyurl    => payment.notify_url,
         
     | 
| 
      
 61 
     | 
    
         
            +
                        :shop_id      => payment.shop_id,
         
     | 
| 
      
 62 
     | 
    
         
            +
                        :sha1         => sha1
         
     | 
| 
      
 63 
     | 
    
         
            +
                      }
         
     | 
| 
      
 64 
     | 
    
         
            +
                    end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                    def payment
         
     | 
| 
      
 67 
     | 
    
         
            +
                      @payment
         
     | 
| 
      
 68 
     | 
    
         
            +
                    end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                    def check_validity!(response)
         
     | 
| 
      
 71 
     | 
    
         
            +
                      string = [
         
     | 
| 
      
 72 
     | 
    
         
            +
                        response.transactionrequest.transaction.trxid,
         
     | 
| 
      
 73 
     | 
    
         
            +
                        response.transactionrequest.transaction.issuerurl,
         
     | 
| 
      
 74 
     | 
    
         
            +
                        Sisow.configuration.merchant_id,
         
     | 
| 
      
 75 
     | 
    
         
            +
                        Sisow.configuration.merchant_key
         
     | 
| 
      
 76 
     | 
    
         
            +
                      ].join
         
     | 
| 
      
 77 
     | 
    
         
            +
                      calculated_sha1 = Digest::SHA1.hexdigest(string)
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                      if calculated_sha1 != response.transactionrequest.signature.sha1
         
     | 
| 
      
 80 
     | 
    
         
            +
                        raise Sisow::Exception, "This response has been forged" and return
         
     | 
| 
      
 81 
     | 
    
         
            +
                      end
         
     | 
| 
      
 82 
     | 
    
         
            +
                    end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                end
         
     | 
| 
      
 85 
     | 
    
         
            +
              end
         
     | 
| 
      
 86 
     | 
    
         
            +
            end
         
     |