activemerchant_banklink 0.0.1

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 ADDED
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in activemerchant_banklink.gemspec
4
+ gemspec
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2005-2010 Tobias Luetke
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.rdoc ADDED
@@ -0,0 +1,32 @@
1
+ = Active Merchant Banklink
2
+
3
+ WARNING: this is an early release. THINGS WILL CHANGE.
4
+
5
+ This library adds Banklink payment integration support to {ActiveMerchant}[http://activemerchant.org].
6
+
7
+ Gem is originally based on ActiveMerchant {fork}[https://github.com/indrekj/active_merchant] by Indrek Juhkam.
8
+
9
+ == Installation
10
+
11
+ === From Ruby Gems
12
+
13
+ Installation from RubyGems
14
+
15
+ > gem install activemerchant_banklink
16
+
17
+ === From Git
18
+
19
+ You can check out the latest source from git:
20
+
21
+ > git pull git://github.com/laurynas/activemerchant_banklink.git
22
+
23
+ == Testing
24
+
25
+ You can run the tests from this gem with (inside the activemerchant_banklink directory):
26
+
27
+ > rake test
28
+
29
+ == Maintainer
30
+
31
+ This gem is maintained by {Laurynas Butkus}[mailto:laurynas.butkus@gmail.com]
32
+
data/Rakefile ADDED
@@ -0,0 +1,26 @@
1
+ require 'bundler'
2
+ require 'rake/testtask'
3
+
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ desc "Run the unit test suite"
7
+ task :default => 'test:units'
8
+
9
+ namespace :test do
10
+
11
+ Rake::TestTask.new(:units) do |t|
12
+ t.pattern = 'test/unit/**/*_test.rb'
13
+ t.ruby_opts << '-rubygems'
14
+ t.libs << 'test'
15
+ t.verbose = true
16
+ end
17
+
18
+ Rake::TestTask.new(:remote) do |t|
19
+ t.pattern = 'test/remote/**/*_test.rb'
20
+ t.ruby_opts << '-rubygems'
21
+ t.libs << 'test'
22
+ t.verbose = true
23
+ end
24
+
25
+ end
26
+
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "activemerchant_banklink/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "activemerchant_banklink"
7
+ s.version = ActivemerchantBanklink::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Indrek Juhkam", "Laurynas Butkus"]
10
+ s.email = ["laurynas.butkus@gmail.com"]
11
+ s.homepage = "http://github.com/laurynas/activemerchant_banklink"
12
+ s.summary = %q{ActiveMerchant Banklink add-on (alpha version)}
13
+ s.description = %q{Adds Banklink support to ActiveMerchant library. Banklink is provided by major banks in the Baltic states.}
14
+
15
+ s.rubyforge_project = "activemerchant_banklink"
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
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'activemerchant_banklink'
@@ -0,0 +1,117 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Integrations #:nodoc:
4
+ module Pizza #:nodoc:
5
+ module Helper #:nodoc:
6
+
7
+ def self.included(base)
8
+ base.class_eval do
9
+ mapping :account, 'VK_SND_ID'
10
+ # Amount paid, for example, "33.00"
11
+ mapping :amount, 'VK_AMOUNT'
12
+ # Unique order id
13
+ mapping :order, 'VK_STAMP'
14
+ # Currency used, 3-letter ISO 4217 code
15
+ mapping :currency, 'VK_CURR'
16
+ mapping :notify_url, 'VK_RETURN'
17
+ mapping :return_url, 'VK_RETURN'
18
+ mapping :cancel_return_url, 'VK_CANCEL'
19
+
20
+ mapping :reference, 'VK_REF'
21
+ mapping :description, 'VK_MSG'
22
+ end
23
+ end
24
+
25
+ def initialize(order, account, options = {})
26
+ old_valid_keys = [:amount, :currency, :test]
27
+ new_valid_keys = [:description, :reference]
28
+ valid_keys = (old_valid_keys + new_valid_keys + Pizza.required_service_params.values << :service_msg_number).uniq
29
+ options.assert_valid_keys(valid_keys)
30
+
31
+ @options = options
32
+ @fields = {}
33
+ self.order = order
34
+ self.account = account
35
+ self.amount = options[:amount]
36
+ self.currency = options[:currency]
37
+ self.description = options[:description]
38
+ self.reference = options[:reference]
39
+
40
+ if options[:service_msg_number]
41
+ @service_msg_number = options.delete(:service_msg_number)
42
+ else
43
+ @service_msg_number = default_service_msg_number
44
+ end
45
+
46
+ add_required_params
47
+ add_charset_field
48
+ add_vk_mac
49
+ end
50
+
51
+ # Amount can be supplied with a optional dot separator for cents.
52
+ def amount=(amount)
53
+ # TODO check this, sooner or later someone will get a wrong amount.
54
+
55
+ # If a string is passed to us, don't do anything.
56
+ # If a Money object is passed to us, don't do anything.
57
+ # Otherwise delegate the handling to the money object
58
+ # and free ourself from the responsibility, yay.
59
+ if amount.is_a?(String) || amount.is_a?(Money)
60
+ add_field('VK_AMOUNT', amount)
61
+ else
62
+ add_field('VK_AMOUNT', Money.new(amount).to_s)
63
+ end
64
+ end
65
+
66
+ def add_vk_mac
67
+ # Signature used to validate previous parameters
68
+ add_field('VK_MAC', generate_mac(@service_msg_number, form_fields))
69
+ end
70
+
71
+ def add_charset_field
72
+ add_field vk_charset_param, vk_charset
73
+ end
74
+
75
+ def add_required_params
76
+ required_params = Pizza.required_service_params[@service_msg_number]
77
+ required_params.each do |param|
78
+ param_value = (@options.delete(param) || send(param.to_s.downcase)).to_s
79
+ add_field param, iconv.iconv(param_value)
80
+ end
81
+ end
82
+
83
+ # Default parameters
84
+ def vk_charset
85
+ 'ISO-8859-1'
86
+ end
87
+
88
+ def vk_charset_param
89
+ 'VK_CHARSET'
90
+ end
91
+
92
+ def vk_service
93
+ @service_msg_number
94
+ end
95
+
96
+ def vk_version
97
+ '008'
98
+ end
99
+
100
+ # Default service message number.
101
+ # Use '1002' because it requires the least amount of parameters.
102
+ def default_service_msg_number
103
+ 1002
104
+ end
105
+
106
+ private
107
+ # Iconv converter to convert from utf8 to
108
+ # the charset the bank api expects.
109
+ def iconv
110
+ @iconv ||= Iconv.new(vk_charset, 'UTF-8')
111
+ end
112
+
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,101 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Integrations #:nodoc:
4
+ module Pizza
5
+ module Notification
6
+
7
+ # A helper method to parse the raw post of the request & return
8
+ # the right Notification subclass based on the sender id.
9
+ def self.get_notification(http_raw_data)
10
+ params = ActiveMerchant::Billing::Integrations::Notification.new(http_raw_data).params
11
+ Pizza.get_class(params['VK_SND_ID'])::Notification.new(params)
12
+ end
13
+
14
+ def bank_signature_valid?(bank_signature, service_msg_number, sigparams)
15
+ self.class.parent.get_bank_public_key.verify(OpenSSL::Digest::SHA1.new, bank_signature, generate_data_string(service_msg_number, sigparams))
16
+ end
17
+
18
+ def complete?
19
+ params['VK_SERVICE'] == '1101'
20
+ end
21
+
22
+ def currency
23
+ params['VK_CURR']
24
+ end
25
+
26
+ # The order id we passed to the form helper.
27
+ def item_id
28
+ params['VK_STAMP']
29
+ end
30
+
31
+ def transaction_id
32
+ params['VK_T_NO']
33
+ end
34
+
35
+ # When was this payment received by the client.
36
+ # We're expecting a dd.mm.yyyy format.
37
+ def received_at
38
+ date = params['VK_T_DATE']
39
+ return nil unless date
40
+ day, month, year = *date.split('.').map(&:to_i)
41
+ Date.civil(year, month, day)
42
+ end
43
+
44
+ def signature
45
+ Base64.decode64(params['VK_MAC'])
46
+ end
47
+
48
+ # The money amount we received, string.
49
+ def gross
50
+ params['VK_AMOUNT']
51
+ end
52
+
53
+ # Was this a test transaction?
54
+ def test?
55
+ params['VK_REC_ID'] == 'testvpos'
56
+ end
57
+
58
+ # TODO what should be here?
59
+ def status
60
+ complete? ? 'Completed' : 'Failed'
61
+ end
62
+
63
+ # If our request was sent automatically by the bank (true) or manually
64
+ # by the user triggering the callback by pressing a "return" button (false).
65
+ def automatic?
66
+ params['VK_AUTO'].upcase == 'Y'
67
+ end
68
+
69
+ def success?
70
+ acknowledge && complete?
71
+ end
72
+
73
+ # We don't actually acknowledge the notification by making another request ourself,
74
+ # instead, we check the notification by checking the signature that came with the notification.
75
+ # This method has to be called when handling the notification & deciding whether to process the order.
76
+ # Example:
77
+ #
78
+ # def notify
79
+ # notify = Notification.new(params)
80
+ #
81
+ # if notify.acknowledge
82
+ # ... process order ... if notify.complete?
83
+ # else
84
+ # ... log possible hacking attempt ...
85
+ # end
86
+ def acknowledge
87
+ bank_signature_valid?(signature, params['VK_SERVICE'], params)
88
+ end
89
+
90
+ private
91
+ # Take the posted data and move the relevant data into a hash
92
+ # No parsing since we're already expecting a hash.
93
+ def parse(params)
94
+ raise(ArgumentError, 'Need a hash') unless params.is_a?(Hash)
95
+ @params = params
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,116 @@
1
+ require 'active_merchant/billing/integrations/pizza/helper.rb'
2
+ require 'active_merchant/billing/integrations/pizza/notification.rb'
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ module Integrations #:nodoc:
6
+ module Pizza
7
+
8
+ # Define sender id (VK_SND_ID) to bank module mappings.
9
+ def self.get_class(vk_snd_id)
10
+ case vk_snd_id
11
+ when 'EYP' then SebEst
12
+ when 'SAMPOPANK' then SampoEst
13
+ when 'HP' then SwedbankEst
14
+ else raise(ArgumentError, "unknown sender id: #{vk_snd_id}")
15
+ end
16
+ end
17
+
18
+ # Define required fields for each service message.
19
+ # We need to know this in order to calculate VK_MAC
20
+ # from a given hash of parameters.
21
+ # Order of the parameters is important.
22
+ mattr_accessor :required_service_params
23
+ self.required_service_params = {
24
+ 1001 => [
25
+ 'VK_SERVICE',
26
+ 'VK_VERSION',
27
+ 'VK_SND_ID',
28
+ 'VK_STAMP',
29
+ 'VK_AMOUNT',
30
+ 'VK_CURR',
31
+ 'VK_ACC',
32
+ 'VK_NAME',
33
+ 'VK_REF',
34
+ 'VK_MSG'],
35
+ 1002 => [
36
+ 'VK_SERVICE',
37
+ 'VK_VERSION',
38
+ 'VK_SND_ID',
39
+ 'VK_STAMP',
40
+ 'VK_AMOUNT',
41
+ 'VK_CURR',
42
+ 'VK_REF',
43
+ 'VK_MSG' ],
44
+ 1101 => [
45
+ 'VK_SERVICE',
46
+ 'VK_VERSION',
47
+ 'VK_SND_ID',
48
+ 'VK_REC_ID',
49
+ 'VK_STAMP',
50
+ 'VK_T_NO',
51
+ 'VK_AMOUNT',
52
+ 'VK_CURR',
53
+ 'VK_REC_ACC',
54
+ 'VK_REC_NAME',
55
+ 'VK_SND_ACC',
56
+ 'VK_SND_NAME',
57
+ 'VK_REF',
58
+ 'VK_MSG',
59
+ 'VK_T_DATE'],
60
+ 1901 => [
61
+ 'VK_SERVICE',
62
+ 'VK_VERSION',
63
+ 'VK_SND_ID',
64
+ 'VK_REC_ID',
65
+ 'VK_STAMP',
66
+ 'VK_REF',
67
+ 'VK_MSG']
68
+ }
69
+
70
+ # Calculation using method VK_VERSION=008:
71
+ # VK_MAC is RSA signature of the request fields coded into BASE64.
72
+ # VK_MAC will be calculated using secret key of the sender using RSA. Signature will
73
+ # be calculated for string that consists of all field lengths and contents in the query. Also
74
+ # empty fields are used in calculation – lenght “000”. Unnumbered (optional) fields are
75
+ # not used in calculation.
76
+ # MAC(x1,x2,...,xn) := RSA( SHA-1(p(x1 )|| x1|| p(x2 )|| x2 || ... ||p( xn )||xn),d,n)
77
+ # where:
78
+ # || is string concatenation mark
79
+ # x1, x2, ..., xn are parameters of the query
80
+ # p(x) is length of the field x represented by three digits
81
+ # d is RSA secret exponent
82
+ # n is RSA modulus
83
+ module Common
84
+ # p(x) is length of the field x represented by three digits
85
+ def func_p(val)
86
+ sprintf("%03i", val.size)
87
+ end
88
+
89
+ # Generate a string to be signed out of service message parameters.
90
+ # p(x1 )|| x1|| p(x2 )|| x2 || ... ||p( xn )||xn
91
+ # || is string concatenation mark
92
+ # p(x) is length of the field x represented by three digits
93
+ # Parameters val1, val2, value3 would be turned into:
94
+ # '003val1003val2006value3'
95
+ def generate_data_string(service_msg_number, sigparams)
96
+ str = ''
97
+ Pizza.required_service_params[Integer(service_msg_number)].each do |param|
98
+ val = sigparams[param].to_s # nil goes to ''
99
+ str << func_p(val) << val
100
+ end
101
+ str
102
+ end
103
+
104
+ def generate_signature(service_msg_number, sigparams)
105
+ privkey = self.class.parent.get_private_key
106
+ privkey.sign(OpenSSL::Digest::SHA1.new, generate_data_string(service_msg_number, sigparams))
107
+ end
108
+
109
+ def generate_mac(service_msg_number, sigparams)
110
+ Base64.encode64(generate_signature(service_msg_number, sigparams)).gsub(/\n/,'')
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,17 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Integrations #:nodoc:
4
+ module SampoEst #:nodoc:
5
+ class Helper < ActiveMerchant::Billing::Integrations::Helper #:nodoc:
6
+ include Pizza::Common
7
+ include Pizza::Helper
8
+
9
+ def vk_charset
10
+ 'ISO-8859-4'
11
+ end
12
+
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,12 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Integrations #:nodoc:
4
+ module SampoEst #:nodoc:
5
+ class Notification < ActiveMerchant::Billing::Integrations::Notification #:nodoc:
6
+ include Pizza::Common
7
+ include Pizza::Notification
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,101 @@
1
+ require File.dirname(__FILE__) + '/sampo_est/helper.rb'
2
+ require File.dirname(__FILE__) + '/sampo_est/notification.rb'
3
+
4
+ module ActiveMerchant #:nodoc:
5
+ module Billing #:nodoc:
6
+ module Integrations #:nodoc:
7
+
8
+ # This module implements bank payments through
9
+ # AS Sampo Pank (http://www.sampopank.ee/en/index.html) using
10
+ # their bank link service (see http://www.sampopank.ee/en/25672.html).
11
+ #
12
+ # Configuration:
13
+ # ActiveMerchant::Billing::Integrations::SampoEst.bank_certificate = File.read('cert')
14
+ # ActiveMerchant::Billing::Integrations::SampoEst.test_bank_certificate = File.read('cert')
15
+ # ActiveMerchant::Billing::Integrations::SampoEst.private_key = File.read('keyfile')
16
+ # ActiveMerchant::Billing::Integrations::SampoEst.test_private_key = File.read('keyfile')
17
+ # ActiveMerchant::Billing::Integrations::SampoEst.test_url = 'https://test-gateway.tld/gw'
18
+ # ActiveMerchant::Billing::Integrations::SampoEst.production_url = 'https://production-gateway.tld/gw/'
19
+ #
20
+ # The syntax of the helper is as follows:
21
+ # <% payment_service_for order_id, account_id,
22
+ # :amount => 50.00,
23
+ # :service => :sampo_est do |service| %>
24
+ #
25
+ # <% service.notify_url url_for(:action => 'notify', :only_path => false) %>
26
+ # <% service.cancel_return_url 'http://mystore.com' %>
27
+ # <% end %>
28
+ #
29
+ # The order_id parameter is a random id referencing the transaction (VK_STAMP)
30
+ # The account_id parameter is a id given to you from the bank (VK_SND_ID)
31
+ # The notify_url is the URL that the bank will send its responses.
32
+ #
33
+ # You can handle the notification in
34
+ # your controller action as follows:
35
+ #
36
+ # class NotificationController < ApplicationController
37
+ # include ActiveMerchant::Billing::Integrations
38
+ #
39
+ # def notify
40
+ # # Notification class is automatically fetched based on the request parameters.
41
+ # notify = Pizza::Notification.get_notification(params)
42
+ #
43
+ # if notify.acknowledge
44
+ # ... process order ... if notify.complete?
45
+ # else
46
+ # ... log possible hacking attempt ...
47
+ # end
48
+ # end
49
+ # end
50
+
51
+ module SampoEst
52
+
53
+ # Raw X509 certificate of the bank, string format.
54
+ mattr_accessor :bank_certificate
55
+ mattr_accessor :test_bank_certificate
56
+ # RSA public key of the bank, taken from the X509 certificate of the bank. OpenSSL container.
57
+ def self.get_bank_public_key
58
+ if ActiveMerchant::Billing::Base.integration_mode == :production
59
+ cert = self.bank_certificate
60
+ else
61
+ cert = self.test_bank_certificate
62
+ end
63
+ OpenSSL::X509::Certificate.new(cert.gsub(/ /, '')).public_key
64
+ end
65
+
66
+ # Our raw RSA private key, string format.
67
+ mattr_accessor :private_key
68
+ mattr_accessor :test_private_key
69
+ # Our RSA private key. OpenSSL container.
70
+ def self.get_private_key
71
+ if ActiveMerchant::Billing::Base.integration_mode == :production
72
+ private_key = self.private_key
73
+ else
74
+ private_key = self.test_private_key
75
+ end
76
+ OpenSSL::PKey::RSA.new(private_key.gsub(/ /, ''))
77
+ end
78
+
79
+ # Bank gateway
80
+ mattr_accessor :test_url
81
+ mattr_accessor :production_url
82
+ def self.service_url
83
+ mode = ActiveMerchant::Billing::Base.integration_mode
84
+ case mode
85
+ when :production
86
+ self.production_url
87
+ when :test
88
+ self.test_url
89
+ else
90
+ raise StandardError, "Integration mode set to an invalid value: #{mode}"
91
+ end
92
+ end
93
+
94
+ def self.notification(post)
95
+ Notification.new(post)
96
+ end
97
+
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,16 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Integrations #:nodoc:
4
+ module SebEst #:nodoc:
5
+ class Helper < ActiveMerchant::Billing::Integrations::Helper #:nodoc:
6
+ include Pizza::Common
7
+ include Pizza::Helper
8
+
9
+ def vk_charset
10
+ 'UTF-8'
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Integrations #:nodoc:
4
+ module SebEst #:nodoc:
5
+ class Notification < ActiveMerchant::Billing::Integrations::Notification #:nodoc:
6
+ include Pizza::Common
7
+ include Pizza::Notification
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,100 @@
1
+ require File.dirname(__FILE__) + '/seb_est/helper.rb'
2
+ require File.dirname(__FILE__) + '/seb_est/notification.rb'
3
+
4
+ module ActiveMerchant #:nodoc:
5
+ module Billing #:nodoc:
6
+ module Integrations #:nodoc:
7
+
8
+ # This module implements bank payments through
9
+ # SEB Eesti Ühispank (http://www.seb.ee/index/1305) using
10
+ # their bank link service (see http://www.seb.ee/page/130212050205).
11
+ #
12
+ # Configuration:
13
+ # ActiveMerchant::Billing::Integrations::SebEst.bank_certificate = File.read('cert')
14
+ # ActiveMerchant::Billing::Integrations::SebEst.test_bank_certificate = File.read('cert')
15
+ # ActiveMerchant::Billing::Integrations::SebEst.private_key = File.read('keyfile')
16
+ # ActiveMerchant::Billing::Integrations::SebEst.test_private_key = File.read('keyfile')
17
+ # ActiveMerchant::Billing::Integrations::SebEst.test_url = 'https://test-gateway.tld/gw'
18
+ # ActiveMerchant::Billing::Integrations::SebEst.production_url = 'https://production-gateway.tld/gw/'
19
+ #
20
+ # The syntax of the helper is as follows:
21
+ # <% payment_service_for order_id, account_id,
22
+ # :amount => 50.00,
23
+ # :service => :seb_est do |service| %>
24
+ #
25
+ # <% service.notify_url url_for(:action => 'notify', :only_path => false) %>
26
+ # <% service.cancel_return_url 'http://mystore.com' %>
27
+ # <% end %>
28
+ #
29
+ # The order_id parameter is a random id referencing the transaction (VK_STAMP)
30
+ # The account_id parameter is a id given to you from the bank (VK_SND_ID)
31
+ # The notify_url is the URL that the bank will send its responses.
32
+ #
33
+ # You can handle the notification in
34
+ # your controller action as follows:
35
+ #
36
+ # class NotificationController < ApplicationController
37
+ # include ActiveMerchant::Billing::Integrations
38
+ #
39
+ # def notify
40
+ # # Notification class is automatically fetched based on the request parameters.
41
+ # notify = Pizza::Notification.get_notification(params)
42
+ #
43
+ # if notify.acknowledge
44
+ # ... process order ... if notify.complete?
45
+ # else
46
+ # ... log possible hacking attempt ...
47
+ # end
48
+ # end
49
+ # end
50
+
51
+ module SebEst
52
+
53
+ # Raw X509 certificate of the bank, string format.
54
+ mattr_accessor :bank_certificate
55
+ mattr_accessor :test_bank_certificate
56
+ # RSA public key of the bank, taken from the X509 certificate of the bank. OpenSSL container.
57
+ def self.get_bank_public_key
58
+ if ActiveMerchant::Billing::Base.integration_mode == :production
59
+ cert = self.bank_certificate
60
+ else
61
+ cert = self.test_bank_certificate
62
+ end
63
+ OpenSSL::X509::Certificate.new(cert.gsub(/ /, '')).public_key
64
+ end
65
+
66
+ # Our raw RSA private key, string format.
67
+ mattr_accessor :private_key
68
+ mattr_accessor :test_private_key
69
+ # Our RSA private key. OpenSSL container.
70
+ def self.get_private_key
71
+ if ActiveMerchant::Billing::Base.integration_mode == :production
72
+ private_key = self.private_key
73
+ else
74
+ private_key = self.test_private_key
75
+ end
76
+ OpenSSL::PKey::RSA.new(private_key.gsub(/ /, ''))
77
+ end
78
+
79
+ mattr_accessor :test_url
80
+ mattr_accessor :production_url
81
+ def self.service_url
82
+ mode = ActiveMerchant::Billing::Base.integration_mode
83
+ case mode
84
+ when :production
85
+ self.production_url
86
+ when :test
87
+ self.test_url
88
+ else
89
+ raise StandardError, "Integration mode set to an invalid value: #{mode}"
90
+ end
91
+ end
92
+
93
+ def self.notification(post)
94
+ Notification.new(post)
95
+ end
96
+
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,20 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Integrations #:nodoc:
4
+ module SwedbankEst #:nodoc:
5
+ class Helper < ActiveMerchant::Billing::Integrations::Helper #:nodoc:
6
+ include Pizza::Common
7
+ include Pizza::Helper
8
+
9
+ def vk_charset
10
+ 'ISO-8859-1'
11
+ end
12
+
13
+ def vk_charset_param
14
+ 'VK_ENCODING'
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,12 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Integrations #:nodoc:
4
+ module SwedbankEst #:nodoc:
5
+ class Notification < ActiveMerchant::Billing::Integrations::Notification #:nodoc:
6
+ include Pizza::Common
7
+ include Pizza::Notification
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,99 @@
1
+ require File.dirname(__FILE__) + '/swedbank_est/helper.rb'
2
+ require File.dirname(__FILE__) + '/swedbank_est/notification.rb'
3
+
4
+ module ActiveMerchant #:nodoc:
5
+ module Billing #:nodoc:
6
+ module Integrations #:nodoc:
7
+
8
+ # This module implements bank payments through
9
+ # Aktsiaselts Hansapank using their bank link service
10
+ # (http://w.hansa.ee/eng/arikliendile_teenusedkaupmehele_makselahendusedinternetis_tehnilinekirjeldus.html).
11
+ #
12
+ # Configuration:
13
+ # ActiveMerchant::Billing::Integrations::SwedbankEst.bank_certificate = File.read('cert')
14
+ # ActiveMerchant::Billing::Integrations::SwedbankEst.test_bank_certificate = File.read('cert')
15
+ # ActiveMerchant::Billing::Integrations::SwedbankEst.private_key = File.read('keyfile')
16
+ # ActiveMerchant::Billing::Integrations::SwedbankEst.test_private_key = File.read('keyfile')
17
+ # ActiveMerchant::Billing::Integrations::SwedbankEst.production_url = 'https://production-gateway.tld/gw/'
18
+ #
19
+ #
20
+ # The syntax of the helper is as follows:
21
+ # <% payment_service_for order_id, account_id,
22
+ # :amount => 50.00,
23
+ # :service => :swedbank_est do |service| %>
24
+ #
25
+ # <% service.notify_url url_for(:action => 'notify', :only_path => false) %>
26
+ # <% service.cancel_return_url 'http://mystore.com' %>
27
+ # <% end %>
28
+ #
29
+ # The order_id parameter is a random id referencing the transaction (VK_STAMP)
30
+ # The account_id parameter is a id given to you from the bank (VK_SND_ID)
31
+ # The notify_url is the URL that the bank will send its responses.
32
+ #
33
+ # You can handle the notification in
34
+ # your controller action as follows:
35
+ #
36
+ # class NotificationController < ApplicationController
37
+ # include ActiveMerchant::Billing::Integrations
38
+ #
39
+ # def notify
40
+ # # Notification class is automatically fetched based on the request parameters.
41
+ # notify = Pizza::Notification.get_notification(params)
42
+ #
43
+ # if notify.acknowledge
44
+ # ... process order ... if notify.complete?
45
+ # else
46
+ # ... log possible hacking attempt ...
47
+ # end
48
+ # end
49
+ # end
50
+
51
+ module SwedbankEst
52
+
53
+ # Raw X509 certificate of the bank, string format.
54
+ mattr_accessor :bank_certificate
55
+ mattr_accessor :test_bank_certificate
56
+ # RSA public key of the bank, taken from the X509 certificate of the bank. OpenSSL container.
57
+ def self.get_bank_public_key
58
+ if ActiveMerchant::Billing::Base.integration_mode == :production
59
+ cert = self.bank_certificate
60
+ else
61
+ cert = self.test_bank_certificate
62
+ end
63
+ OpenSSL::X509::Certificate.new(cert.gsub(/ /, '')).public_key
64
+ end
65
+
66
+ mattr_accessor :private_key
67
+ mattr_accessor :test_private_key
68
+ # Our RSA private key. OpenSSL container.
69
+ def self.get_private_key
70
+ if ActiveMerchant::Billing::Base.integration_mode == :production
71
+ private_key = self.private_key
72
+ else
73
+ private_key = self.test_private_key
74
+ end
75
+ OpenSSL::PKey::RSA.new(private_key.gsub(/ /, ''))
76
+ end
77
+
78
+ mattr_accessor :test_url
79
+ mattr_accessor :production_url
80
+ def self.service_url
81
+ mode = ActiveMerchant::Billing::Base.integration_mode
82
+ case mode
83
+ when :production
84
+ self.production_url
85
+ when :test
86
+ self.test_url
87
+ else
88
+ raise StandardError, "Integration mode set to an invalid value: #{mode}"
89
+ end
90
+ end
91
+
92
+ def self.notification(post)
93
+ Notification.new(post)
94
+ end
95
+
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,3 @@
1
+ module ActivemerchantBanklink
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,5 @@
1
+ require 'active_merchant'
2
+ require 'active_merchant/billing/integrations/pizza'
3
+ require 'active_merchant/billing/integrations/swedbank_est'
4
+ require 'active_merchant/billing/integrations/seb_est'
5
+ require 'active_merchant/billing/integrations/sampo_est'
@@ -0,0 +1,182 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
3
+
4
+ require 'activemerchant_banklink'
5
+ require 'rubygems'
6
+ require 'money'
7
+ require 'test/unit'
8
+ require 'mocha'
9
+ require 'yaml'
10
+
11
+ begin
12
+ gem 'actionpack'
13
+ rescue LoadError
14
+ raise StandardError, "The view tests need ActionPack installed as gem to run"
15
+ end
16
+
17
+ require 'action_controller'
18
+ require 'action_controller/test_process'
19
+ require 'active_merchant/billing/integrations/action_view_helper'
20
+
21
+ ActiveMerchant::Billing::Base.mode = :test
22
+
23
+ # Test gateways
24
+ class SimpleTestGateway < ActiveMerchant::Billing::Gateway
25
+ end
26
+
27
+ class SubclassGateway < SimpleTestGateway
28
+ end
29
+
30
+
31
+ module ActiveMerchant
32
+ module Assertions
33
+ def assert_field(field, value)
34
+ clean_backtrace do
35
+ assert_equal value, @helper.fields[field]
36
+ end
37
+ end
38
+
39
+ # Allows the testing of you to check for negative assertions:
40
+ #
41
+ # # Instead of
42
+ # assert !something_that_is_false
43
+ #
44
+ # # Do this
45
+ # assert_false something_that_should_be_false
46
+ #
47
+ # An optional +msg+ parameter is available to help you debug.
48
+ def assert_false(boolean, message = nil)
49
+ message = build_message message, '<?> is not false or nil.', boolean
50
+
51
+ clean_backtrace do
52
+ assert_block message do
53
+ not boolean
54
+ end
55
+ end
56
+ end
57
+
58
+ # A handy little assertion to check for a successful response:
59
+ #
60
+ # # Instead of
61
+ # assert_success response
62
+ #
63
+ # # DRY that up with
64
+ # assert_success response
65
+ #
66
+ # A message will automatically show the inspection of the response
67
+ # object if things go afoul.
68
+ def assert_success(response)
69
+ clean_backtrace do
70
+ assert response.success?, "Response failed: #{response.inspect}"
71
+ end
72
+ end
73
+
74
+ # The negative of +assert_success+
75
+ def assert_failure(response)
76
+ clean_backtrace do
77
+ assert_false response.success?, "Response expected to fail: #{response.inspect}"
78
+ end
79
+ end
80
+
81
+ def assert_valid(validateable)
82
+ clean_backtrace do
83
+ assert validateable.valid?, "Expected to be valid"
84
+ end
85
+ end
86
+
87
+ def assert_not_valid(validateable)
88
+ clean_backtrace do
89
+ assert_false validateable.valid?, "Expected to not be valid"
90
+ end
91
+ end
92
+
93
+ private
94
+ def clean_backtrace(&block)
95
+ yield
96
+ rescue Test::Unit::AssertionFailedError => e
97
+ path = File.expand_path(__FILE__)
98
+ raise Test::Unit::AssertionFailedError, e.message, e.backtrace.reject { |line| File.expand_path(line) =~ /#{path}/ }
99
+ end
100
+ end
101
+
102
+ module Fixtures
103
+ HOME_DIR = RUBY_PLATFORM =~ /mswin32/ ? ENV['HOMEPATH'] : ENV['HOME'] unless defined?(HOME_DIR)
104
+ LOCAL_CREDENTIALS = File.join(HOME_DIR.to_s, '.active_merchant/fixtures.yml') unless defined?(LOCAL_CREDENTIALS)
105
+ DEFAULT_CREDENTIALS = File.join(File.dirname(__FILE__), 'fixtures.yml') unless defined?(DEFAULT_CREDENTIALS)
106
+
107
+ private
108
+ def credit_card(number = '4242424242424242', options = {})
109
+ defaults = {
110
+ :number => number,
111
+ :month => 9,
112
+ :year => Time.now.year + 1,
113
+ :first_name => 'Longbob',
114
+ :last_name => 'Longsen',
115
+ :verification_value => '123',
116
+ :type => 'visa'
117
+ }.update(options)
118
+
119
+ Billing::CreditCard.new(defaults)
120
+ end
121
+
122
+ def check(options = {})
123
+ defaults = {
124
+ :name => 'Jim Smith',
125
+ :routing_number => '244183602',
126
+ :account_number => '15378535',
127
+ :account_holder_type => 'personal',
128
+ :account_type => 'checking',
129
+ :number => '1'
130
+ }.update(options)
131
+
132
+ Billing::Check.new(defaults)
133
+ end
134
+
135
+ def address(options = {})
136
+ {
137
+ :name => 'Jim Smith',
138
+ :address1 => '1234 My Street',
139
+ :address2 => 'Apt 1',
140
+ :company => 'Widgets Inc',
141
+ :city => 'Ottawa',
142
+ :state => 'ON',
143
+ :zip => 'K1C2N6',
144
+ :country => 'CA',
145
+ :phone => '(555)555-5555',
146
+ :fax => '(555)555-6666'
147
+ }.update(options)
148
+ end
149
+
150
+ def all_fixtures
151
+ @@fixtures ||= load_fixtures
152
+ end
153
+
154
+ def fixtures(key)
155
+ data = all_fixtures[key] || raise(StandardError, "No fixture data was found for '#{key}'")
156
+
157
+ data.dup
158
+ end
159
+
160
+ def load_fixtures
161
+ file = File.exists?(LOCAL_CREDENTIALS) ? LOCAL_CREDENTIALS : DEFAULT_CREDENTIALS
162
+ yaml_data = YAML.load(File.read(file))
163
+ symbolize_keys(yaml_data)
164
+
165
+ yaml_data
166
+ end
167
+
168
+ def symbolize_keys(hash)
169
+ return unless hash.is_a?(Hash)
170
+
171
+ hash.symbolize_keys!
172
+ hash.each{|k,v| symbolize_keys(v)}
173
+ end
174
+ end
175
+ end
176
+
177
+ Test::Unit::TestCase.class_eval do
178
+ include ActiveMerchant::Billing
179
+ include ActiveMerchant::Assertions
180
+ include ActiveMerchant::Utils
181
+ include ActiveMerchant::Fixtures
182
+ end
@@ -0,0 +1,87 @@
1
+ require File.dirname(__FILE__) + '/../../../test_helper'
2
+
3
+ # setup test rsa private key
4
+ ActiveMerchant::Billing::Integrations::SebEst.test_private_key = <<EOF
5
+ -----BEGIN RSA PRIVATE KEY-----
6
+ MIICXAIBAAKBgQC+AROlXiRvi1T7Q9fAh0Lw73szAn26mqfKDqd6Bdplq3v+gVWC
7
+ 3v0+bgtfNakRE/UVYOxEA0z0viqRpKzPuNy8OstTMe8fFKs19NW8lBYik6NzJ4Bk
8
+ +B6VmovOm0nJLQJytXKiJyuHP9DqPOVmP8S+azzX7Uqzov1nxo9fvH7y2QIDAQAB
9
+ AoGAFhbD9O6r57fYCloJxB01gBMnTHfWrBH8vbXUbJAvorA7+wuIKG3KHS7n7Yqs
10
+ fArI7FJXRVTo5m8RPdtaJ9ADAT9rjAi3A17TaEueyJl+B/hjHYhsd8MeFhTb2fh0
11
+ rY3F6diL8U/YDbiAIegnKO0zcc6ynJrsQZvzb6DlY/CLPe0CQQD3KXJzw1ZfJ1ts
12
+ c370b/ZC1YrRURw41Q0I8ljYJ8EJw/ngVxrnCIsd43bRnOVp9guJrjTQRkhDC3Gn
13
+ J2Y0+42LAkEAxMxmh7QY4nItBTS0fe1KCat4VDxhyxYEhZKlGDhxW75vNROrripB
14
+ 1ZfBsq5xkY2MM9R7WKmL7SpStrUPIvEVqwJBAOXA4ISd61cupbytrDEbNscv7Afh
15
+ pyNpYOGVLmNYqQgj5c7WCcsD1RYmkRgPCe8y6czFZJDLFHdGVxLz+/16bTsCQC9J
16
+ Ob2TnYMTkhO1JUU4tdh69e+vjoPgp3d80+Rs83fq2wey0UaI6saqryUC21Dw5OYz
17
+ QOv92RxEVhmGibuIl/8CQCiYrzwlZJDlsKrWPZT0E8rzNmLZkhNHzYJP9S7x+FKk
18
+ m3gFeXEBgzGn9UOd6xIAp0p7A1XVBN8XzDMa09gSOks=
19
+ -----END RSA PRIVATE KEY-----
20
+ EOF
21
+
22
+ # setup bank public certificate, used for checking response params
23
+ ActiveMerchant::Billing::Integrations::SebEst.test_bank_certificate = <<EOF
24
+ -----BEGIN CERTIFICATE-----
25
+ MIIDRTCCAq6gAwIBAgIBADANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJFRTEO
26
+ MAwGA1UECBMFSGFyanUxEDAOBgNVBAcTB1RhbGxpbm4xDDAKBgNVBAoTA0VZUDEL
27
+ MAkGA1UECxMCSVQxDDAKBgNVBAMTA2EuYTEhMB8GCSqGSIb3DQEJARYSYWxsYXIu
28
+ YWxsYXNAZXlwLmVlMB4XDTk5MTExNTA4MTAzM1oXDTk5MTIxNTA4MTAzM1owezEL
29
+ MAkGA1UEBhMCRUUxDjAMBgNVBAgTBUhhcmp1MRAwDgYDVQQHEwdUYWxsaW5uMQww
30
+ CgYDVQQKEwNFWVAxCzAJBgNVBAsTAklUMQwwCgYDVQQDEwNhLmExITAfBgkqhkiG
31
+ 9w0BCQEWEmFsbGFyLmFsbGFzQGV5cC5lZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
32
+ gYkCgYEAvgETpV4kb4tU+0PXwIdC8O97MwJ9upqnyg6negXaZat7/oFVgt79Pm4L
33
+ XzWpERP1FWDsRANM9L4qkaSsz7jcvDrLUzHvHxSrNfTVvJQWIpOjcyeAZPgelZqL
34
+ zptJyS0CcrVyoicrhz/Q6jzlZj/Evms81+1Ks6L9Z8aPX7x+8tkCAwEAAaOB2DCB
35
+ 1TAdBgNVHQ4EFgQUFivCzZNmegEoOxYtg20YMMRB98gwgaUGA1UdIwSBnTCBmoAU
36
+ FivCzZNmegEoOxYtg20YMMRB98ihf6R9MHsxCzAJBgNVBAYTAkVFMQ4wDAYDVQQI
37
+ EwVIYXJqdTEQMA4GA1UEBxMHVGFsbGlubjEMMAoGA1UEChMDRVlQMQswCQYDVQQL
38
+ EwJJVDEMMAoGA1UEAxMDYS5hMSEwHwYJKoZIhvcNAQkBFhJhbGxhci5hbGxhc0Bl
39
+ eXAuZWWCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQBfkayuot+e
40
+ fwW8QmPwpWF5AY3oMT/fTncjCljDBOg39IQv4PjnpTdDfwwl3lUIZHHTLM2i0L/c
41
+ eD4D1UFM1qdp2VZzhBd1eeMjxYjCP8qL2v2MfLkCYcP30Sl6ISSkFjFc5qbGXZOc
42
+ C82uR/wUZJDw9kj+R1O46/byG8yA+S9FVw==
43
+ -----END CERTIFICATE-----
44
+ EOF
45
+
46
+ class SebEstNotificationTest < Test::Unit::TestCase
47
+ include ActiveMerchant::Billing::Integrations
48
+
49
+ def setup
50
+ @seb_est = Pizza::Notification.get_notification(http_raw_data)
51
+ end
52
+
53
+ def test_get_notification_class_from_pizza
54
+ notify_class = Pizza::Notification.get_notification(http_raw_data)
55
+ assert notify_class.is_a?(ActiveMerchant::Billing::Integrations::SebEst::Notification)
56
+ end
57
+
58
+ def test_accessors
59
+ assert_equal true, @seb_est.complete?
60
+ assert_equal 'Completed', @seb_est.status
61
+ assert_equal "88", @seb_est.item_id
62
+ assert_equal "2774", @seb_est.transaction_id
63
+ assert_equal '33', @seb_est.gross
64
+ assert_equal "EEK", @seb_est.currency
65
+ assert_equal '26.11.2007', @seb_est.received_at.strftime("%d.%m.%Y")
66
+ assert_equal true, @seb_est.test?
67
+ end
68
+
69
+ def test_compositions
70
+ assert_equal Money.new(3300, 'EEK'), @seb_est.amount
71
+ end
72
+
73
+ def test_acknowledgement
74
+ assert_equal true, @seb_est.acknowledge
75
+ end
76
+
77
+ def test_acknowledgement_fail_with_params_changed
78
+ @seb_est_wrong = Pizza::Notification.get_notification(http_raw_data.gsub('VK_AMOUNT=33', 'VK_AMOUNT=100'))
79
+ assert_equal false, @seb_est_wrong.acknowledge
80
+ end
81
+
82
+ private
83
+
84
+ def http_raw_data
85
+ "VK_SERVICE=1101&VK_VERSION=008&VK_SND_ID=EYP&VK_REC_ID=testvpos&VK_STAMP=88&VK_T_NO=2774&VK_AMOUNT=33&VK_CURR=EEK&VK_REC_ACC=10002050618003&VK_REC_NAME=ALLAS+ALLAR&VK_SND_ACC=10010046155012&VK_SND_NAME=t%C3%B5%C3%B5ger+%2C+Le%C3%B5p%C3%A4%C3%B6ld%C5%BE%C5%BD%C5%A1%C5%A0&VK_REF=123&VK_MSG=Porgandid&VK_T_DATE=26.11.2007&VK_MAC=LyCZRncu%2F%2BOi5nwzOkI6C9UMFohN6tSl3tLFyIJyNp2lGKBrDKZ2H8b%2BadU3XalzS7MwnAj8r%2FRhLpbsGNE5ysNyM4CKkSrsVzxoXbt9%2BB1foH9Rlp9LCeoR2H774f8UcMe9RVsE%2B%2BZfrEZzzXYyR1PXDCVOShQOAxlD9pbh8nk%3D&VK_LANG=EST&VK_RETURN=http%3A%2F%2F90.190.110.154%2Fseb_est%2Fnotify&VK_AUTO=N&VK_CHARSET=UTF-8&keel=EST&appname=UN3MIN&act=UPOSTEST2"
86
+ end
87
+ end
@@ -0,0 +1,9 @@
1
+ require File.dirname(__FILE__) + '/../../test_helper'
2
+
3
+ class SampoEstModuleTest < Test::Unit::TestCase
4
+ include ActiveMerchant::Billing::Integrations
5
+
6
+ def test_notification_method
7
+ assert_instance_of SampoEst::Notification, SampoEst.notification({'name' => 'cody'})
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require File.dirname(__FILE__) + '/../../test_helper'
2
+
3
+ class SebEstModuleTest < Test::Unit::TestCase
4
+ include ActiveMerchant::Billing::Integrations
5
+
6
+ def test_notification_method
7
+ assert_instance_of SebEst::Notification, SebEst.notification({'name' => 'cody'})
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require File.dirname(__FILE__) + '/../../test_helper'
2
+
3
+ class SwedbankEstModuleTest < Test::Unit::TestCase
4
+ include ActiveMerchant::Billing::Integrations
5
+
6
+ def test_notification_method
7
+ assert_instance_of SwedbankEst::Notification, SwedbankEst.notification({'name' => 'cody'})
8
+ end
9
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activemerchant_banklink
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Indrek Juhkam
14
+ - Laurynas Butkus
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2011-01-29 00:00:00 +02:00
20
+ default_executable:
21
+ dependencies: []
22
+
23
+ description: Adds Banklink support to ActiveMerchant library. Banklink is provided by major banks in the Baltic states.
24
+ email:
25
+ - laurynas.butkus@gmail.com
26
+ executables: []
27
+
28
+ extensions: []
29
+
30
+ extra_rdoc_files: []
31
+
32
+ files:
33
+ - .gitignore
34
+ - Gemfile
35
+ - MIT-LICENSE
36
+ - README.rdoc
37
+ - Rakefile
38
+ - activemerchant_banklink.gemspec
39
+ - init.rb
40
+ - lib/active_merchant/billing/integrations/pizza.rb
41
+ - lib/active_merchant/billing/integrations/pizza/helper.rb
42
+ - lib/active_merchant/billing/integrations/pizza/notification.rb
43
+ - lib/active_merchant/billing/integrations/sampo_est.rb
44
+ - lib/active_merchant/billing/integrations/sampo_est/helper.rb
45
+ - lib/active_merchant/billing/integrations/sampo_est/notification.rb
46
+ - lib/active_merchant/billing/integrations/seb_est.rb
47
+ - lib/active_merchant/billing/integrations/seb_est/helper.rb
48
+ - lib/active_merchant/billing/integrations/seb_est/notification.rb
49
+ - lib/active_merchant/billing/integrations/swedbank_est.rb
50
+ - lib/active_merchant/billing/integrations/swedbank_est/helper.rb
51
+ - lib/active_merchant/billing/integrations/swedbank_est/notification.rb
52
+ - lib/activemerchant_banklink.rb
53
+ - lib/activemerchant_banklink/version.rb
54
+ - test/test_helper.rb
55
+ - test/unit/integrations/notifications/seb_est_notification_test.rb
56
+ - test/unit/integrations/sampo_est_module_test.rb
57
+ - test/unit/integrations/seb_est_module_test.rb
58
+ - test/unit/integrations/swedbank_est_module_test.rb
59
+ has_rdoc: true
60
+ homepage: http://github.com/laurynas/activemerchant_banklink
61
+ licenses: []
62
+
63
+ post_install_message:
64
+ rdoc_options: []
65
+
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ hash: 3
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ hash: 3
83
+ segments:
84
+ - 0
85
+ version: "0"
86
+ requirements: []
87
+
88
+ rubyforge_project: activemerchant_banklink
89
+ rubygems_version: 1.3.7
90
+ signing_key:
91
+ specification_version: 3
92
+ summary: ActiveMerchant Banklink add-on (alpha version)
93
+ test_files: []
94
+