banklink_lv 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -1
- data/Gemfile.lock +92 -0
- data/README +69 -69
- data/README.rdoc +69 -69
- data/Rakefile +3 -38
- data/banklink_lv.gemspec +27 -20
- data/lib/banklink_lv/banklink.rb +134 -134
- data/lib/banklink_lv/base.rb +8 -8
- data/lib/banklink_lv/helper.rb +112 -110
- data/lib/banklink_lv/notification.rb +166 -166
- data/lib/banklink_lv/swedbank.rb +48 -48
- data/lib/banklink_lv/version.rb +2 -2
- data/lib/banklink_lv.rb +5 -9
- data/pkg/banklink_lv-0.0.3.gem +0 -0
- data/test/banklink_common_test.rb +15 -13
- data/test/banklink_helper_test.rb +22 -20
- data/test/banklink_notification_test.rb +42 -40
- data/test/database.yml +2 -2
- data/test/debug.log +6 -6
- data/test/schema.rb +1 -1
- data/test/string_utf8_test.rb +9 -0
- data/test/test_helper.rb +4 -2
- metadata +88 -50
- data/banklink_lv-1.0.1.gem +0 -0
- data/install.rb +0 -1
- data/lib/app/helpers/banklink_helper.rb +0 -26
- data/lib/banklink_lv/core_ext.rb +0 -730
- data/test/banklink_view_helper_test.rb +0 -17
- data/test/core_ext_test.rb +0 -7
- data/uninstall.rb +0 -1
data/lib/banklink_lv/banklink.rb
CHANGED
@@ -1,135 +1,135 @@
|
|
1
|
-
module Banklink
|
2
|
-
|
3
|
-
# Detect bank module from params
|
4
|
-
#def self.get_class(params)
|
5
|
-
# case params['VK_SND_ID']
|
6
|
-
# when 'EYP' then SebEst
|
7
|
-
# when 'SAMPOPANK' then SampoEst
|
8
|
-
# when 'HP' then SwedbankEst
|
9
|
-
|
10
|
-
# Swedbank uses same sender id for different countries, currently can't detect Lithuanian
|
11
|
-
# use:
|
12
|
-
# notify = SwedbankLtu::Notification.new(params)
|
13
|
-
#when 'HP' then SwedbankLtu
|
14
|
-
|
15
|
-
#when '70440' then SebLtu
|
16
|
-
#when 'SMPOLT22' then DanskeLtu
|
17
|
-
#when 'SNORLT22' then SnorasLtu
|
18
|
-
#when '112029720' then DnbnordLtu
|
19
|
-
#when '70100' then UbLtu
|
20
|
-
|
21
|
-
# else raise(ArgumentError, "unknown sender id: #{params['VK_SND_ID']}")
|
22
|
-
# end
|
23
|
-
#end
|
24
|
-
|
25
|
-
# Define required fields for each service message.
|
26
|
-
# We need to know this in order to calculate VK_MAC
|
27
|
-
# from a given hash of parameters.
|
28
|
-
# Order of the parameters is important.
|
29
|
-
mattr_accessor :required_service_params
|
30
|
-
self.required_service_params = {
|
31
|
-
1001 => [
|
32
|
-
'VK_SERVICE',
|
33
|
-
'VK_VERSION',
|
34
|
-
'VK_SND_ID',
|
35
|
-
'VK_STAMP',
|
36
|
-
'VK_AMOUNT',
|
37
|
-
'VK_CURR',
|
38
|
-
'VK_ACC',
|
39
|
-
'VK_NAME',
|
40
|
-
'VK_REF',
|
41
|
-
'VK_MSG'],
|
42
|
-
1002 => [
|
43
|
-
'VK_SERVICE',
|
44
|
-
'VK_VERSION',
|
45
|
-
'VK_SND_ID',
|
46
|
-
'VK_STAMP',
|
47
|
-
'VK_AMOUNT',
|
48
|
-
'VK_CURR',
|
49
|
-
'VK_REF',
|
50
|
-
'VK_MSG' ],
|
51
|
-
1101 => [
|
52
|
-
'VK_SERVICE',
|
53
|
-
'VK_VERSION',
|
54
|
-
'VK_SND_ID',
|
55
|
-
'VK_REC_ID',
|
56
|
-
'VK_STAMP',
|
57
|
-
'VK_T_NO',
|
58
|
-
'VK_AMOUNT',
|
59
|
-
'VK_CURR',
|
60
|
-
'VK_REC_ACC',
|
61
|
-
'VK_REC_NAME',
|
62
|
-
'VK_SND_ACC',
|
63
|
-
'VK_SND_NAME',
|
64
|
-
'VK_REF',
|
65
|
-
'VK_MSG',
|
66
|
-
'VK_T_DATE'],
|
67
|
-
1201 => [
|
68
|
-
'VK_SERVICE',
|
69
|
-
'VK_VERSION',
|
70
|
-
'VK_SND_ID',
|
71
|
-
'VK_REC_ID',
|
72
|
-
'VK_STAMP',
|
73
|
-
'VK_AMOUNT',
|
74
|
-
'VK_CURR',
|
75
|
-
'VK_REC_ACC',
|
76
|
-
'VK_REC_NAME',
|
77
|
-
'VK_SND_ACC',
|
78
|
-
'VK_SND_NAME',
|
79
|
-
'VK_REF',
|
80
|
-
'VK_MSG'],
|
81
|
-
1901 => [
|
82
|
-
'VK_SERVICE',
|
83
|
-
'VK_VERSION',
|
84
|
-
'VK_SND_ID',
|
85
|
-
'VK_REC_ID',
|
86
|
-
'VK_STAMP',
|
87
|
-
'VK_REF',
|
88
|
-
'VK_MSG']
|
89
|
-
}
|
90
|
-
|
91
|
-
# Calculation using method VK_VERSION=008:
|
92
|
-
# VK_MAC is RSA signature of the request fields coded into BASE64.
|
93
|
-
# VK_MAC will be calculated using secret key of the sender using RSA. Signature will
|
94
|
-
# be calculated for string that consists of all field lengths and contents in the query. Also
|
95
|
-
# empty fields are used in calculation – lenght “000”. Unnumbered (optional) fields are
|
96
|
-
# not used in calculation.
|
97
|
-
# MAC(x1,x2,...,xn) := RSA( SHA-1(p(x1 )|| x1|| p(x2 )|| x2 || ... ||p( xn )||xn),d,n)
|
98
|
-
# where:
|
99
|
-
# || is string concatenation mark
|
100
|
-
# x1, x2, ..., xn are parameters of the query
|
101
|
-
# p(x) is length of the field x represented by three digits
|
102
|
-
# d is RSA secret exponent
|
103
|
-
# n is RSA modulus
|
104
|
-
module Common
|
105
|
-
# p(x) is length of the field x represented by three digits
|
106
|
-
def func_p(val)
|
107
|
-
sprintf("%03i", val.
|
108
|
-
end
|
109
|
-
|
110
|
-
# Generate a string to be signed out of service message parameters.
|
111
|
-
# p(x1 )|| x1|| p(x2 )|| x2 || ... ||p( xn )||xn
|
112
|
-
# || is string concatenation mark
|
113
|
-
# p(x) is length of the field x represented by three digits
|
114
|
-
# Parameters val1, val2, value3 would be turned into:
|
115
|
-
# '003val1003val2006value3'
|
116
|
-
def generate_data_string(service_msg_number, sigparams)
|
117
|
-
str = ''
|
118
|
-
Banklink.required_service_params[Integer(service_msg_number)].each do |param|
|
119
|
-
val = sigparams[param].to_s # nil goes to ''
|
120
|
-
str << func_p(val) << val
|
121
|
-
end
|
122
|
-
str
|
123
|
-
end
|
124
|
-
|
125
|
-
def generate_signature(service_msg_number, sigparams)
|
126
|
-
# privkey = self.class.parent.get_private_key
|
127
|
-
privkey = SwedbankLv.get_private_key
|
128
|
-
privkey.sign(OpenSSL::Digest::SHA1.new, generate_data_string(service_msg_number, sigparams))
|
129
|
-
end
|
130
|
-
|
131
|
-
def generate_mac(service_msg_number, sigparams)
|
132
|
-
Base64.encode64(generate_signature(service_msg_number, sigparams)).gsub(/\n/,'')
|
133
|
-
end
|
134
|
-
end
|
1
|
+
module Banklink
|
2
|
+
|
3
|
+
# Detect bank module from params
|
4
|
+
#def self.get_class(params)
|
5
|
+
# case params['VK_SND_ID']
|
6
|
+
# when 'EYP' then SebEst
|
7
|
+
# when 'SAMPOPANK' then SampoEst
|
8
|
+
# when 'HP' then SwedbankEst
|
9
|
+
|
10
|
+
# Swedbank uses same sender id for different countries, currently can't detect Lithuanian
|
11
|
+
# use:
|
12
|
+
# notify = SwedbankLtu::Notification.new(params)
|
13
|
+
#when 'HP' then SwedbankLtu
|
14
|
+
|
15
|
+
#when '70440' then SebLtu
|
16
|
+
#when 'SMPOLT22' then DanskeLtu
|
17
|
+
#when 'SNORLT22' then SnorasLtu
|
18
|
+
#when '112029720' then DnbnordLtu
|
19
|
+
#when '70100' then UbLtu
|
20
|
+
|
21
|
+
# else raise(ArgumentError, "unknown sender id: #{params['VK_SND_ID']}")
|
22
|
+
# end
|
23
|
+
#end
|
24
|
+
|
25
|
+
# Define required fields for each service message.
|
26
|
+
# We need to know this in order to calculate VK_MAC
|
27
|
+
# from a given hash of parameters.
|
28
|
+
# Order of the parameters is important.
|
29
|
+
mattr_accessor :required_service_params
|
30
|
+
self.required_service_params = {
|
31
|
+
1001 => [
|
32
|
+
'VK_SERVICE',
|
33
|
+
'VK_VERSION',
|
34
|
+
'VK_SND_ID',
|
35
|
+
'VK_STAMP',
|
36
|
+
'VK_AMOUNT',
|
37
|
+
'VK_CURR',
|
38
|
+
'VK_ACC',
|
39
|
+
'VK_NAME',
|
40
|
+
'VK_REF',
|
41
|
+
'VK_MSG'],
|
42
|
+
1002 => [
|
43
|
+
'VK_SERVICE',
|
44
|
+
'VK_VERSION',
|
45
|
+
'VK_SND_ID',
|
46
|
+
'VK_STAMP',
|
47
|
+
'VK_AMOUNT',
|
48
|
+
'VK_CURR',
|
49
|
+
'VK_REF',
|
50
|
+
'VK_MSG' ],
|
51
|
+
1101 => [
|
52
|
+
'VK_SERVICE',
|
53
|
+
'VK_VERSION',
|
54
|
+
'VK_SND_ID',
|
55
|
+
'VK_REC_ID',
|
56
|
+
'VK_STAMP',
|
57
|
+
'VK_T_NO',
|
58
|
+
'VK_AMOUNT',
|
59
|
+
'VK_CURR',
|
60
|
+
'VK_REC_ACC',
|
61
|
+
'VK_REC_NAME',
|
62
|
+
'VK_SND_ACC',
|
63
|
+
'VK_SND_NAME',
|
64
|
+
'VK_REF',
|
65
|
+
'VK_MSG',
|
66
|
+
'VK_T_DATE'],
|
67
|
+
1201 => [
|
68
|
+
'VK_SERVICE',
|
69
|
+
'VK_VERSION',
|
70
|
+
'VK_SND_ID',
|
71
|
+
'VK_REC_ID',
|
72
|
+
'VK_STAMP',
|
73
|
+
'VK_AMOUNT',
|
74
|
+
'VK_CURR',
|
75
|
+
'VK_REC_ACC',
|
76
|
+
'VK_REC_NAME',
|
77
|
+
'VK_SND_ACC',
|
78
|
+
'VK_SND_NAME',
|
79
|
+
'VK_REF',
|
80
|
+
'VK_MSG'],
|
81
|
+
1901 => [
|
82
|
+
'VK_SERVICE',
|
83
|
+
'VK_VERSION',
|
84
|
+
'VK_SND_ID',
|
85
|
+
'VK_REC_ID',
|
86
|
+
'VK_STAMP',
|
87
|
+
'VK_REF',
|
88
|
+
'VK_MSG']
|
89
|
+
}
|
90
|
+
|
91
|
+
# Calculation using method VK_VERSION=008:
|
92
|
+
# VK_MAC is RSA signature of the request fields coded into BASE64.
|
93
|
+
# VK_MAC will be calculated using secret key of the sender using RSA. Signature will
|
94
|
+
# be calculated for string that consists of all field lengths and contents in the query. Also
|
95
|
+
# empty fields are used in calculation – lenght “000”. Unnumbered (optional) fields are
|
96
|
+
# not used in calculation.
|
97
|
+
# MAC(x1,x2,...,xn) := RSA( SHA-1(p(x1 )|| x1|| p(x2 )|| x2 || ... ||p( xn )||xn),d,n)
|
98
|
+
# where:
|
99
|
+
# || is string concatenation mark
|
100
|
+
# x1, x2, ..., xn are parameters of the query
|
101
|
+
# p(x) is length of the field x represented by three digits
|
102
|
+
# d is RSA secret exponent
|
103
|
+
# n is RSA modulus
|
104
|
+
module Common
|
105
|
+
# p(x) is length of the field x represented by three digits
|
106
|
+
def func_p(val)
|
107
|
+
sprintf("%03i", val.length)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Generate a string to be signed out of service message parameters.
|
111
|
+
# p(x1 )|| x1|| p(x2 )|| x2 || ... ||p( xn )||xn
|
112
|
+
# || is string concatenation mark
|
113
|
+
# p(x) is length of the field x represented by three digits
|
114
|
+
# Parameters val1, val2, value3 would be turned into:
|
115
|
+
# '003val1003val2006value3'
|
116
|
+
def generate_data_string(service_msg_number, sigparams)
|
117
|
+
str = ''
|
118
|
+
Banklink.required_service_params[Integer(service_msg_number)].each do |param|
|
119
|
+
val = sigparams[param].to_s # nil goes to ''
|
120
|
+
str << func_p(val) << val
|
121
|
+
end
|
122
|
+
str
|
123
|
+
end
|
124
|
+
|
125
|
+
def generate_signature(service_msg_number, sigparams)
|
126
|
+
# privkey = self.class.parent.get_private_key
|
127
|
+
privkey = SwedbankLv.get_private_key
|
128
|
+
privkey.sign(OpenSSL::Digest::SHA1.new, generate_data_string(service_msg_number, sigparams))
|
129
|
+
end
|
130
|
+
|
131
|
+
def generate_mac(service_msg_number, sigparams)
|
132
|
+
Base64.encode64(generate_signature(service_msg_number, sigparams)).gsub(/\n/,'')
|
133
|
+
end
|
134
|
+
end
|
135
135
|
end
|
data/lib/banklink_lv/base.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
class Hash
|
2
|
-
def to_params
|
3
|
-
map{ |k, v| URI.escape("#{k}=#{v}") }.join("&")
|
4
|
-
end
|
5
|
-
end
|
6
|
-
|
7
|
-
module BanklinkLv
|
8
|
-
|
1
|
+
class Hash
|
2
|
+
def to_params
|
3
|
+
map{ |k, v| URI.escape("#{k}=#{v}") }.join("&")
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
module BanklinkLv
|
8
|
+
|
9
9
|
end
|
data/lib/banklink_lv/helper.rb
CHANGED
@@ -1,111 +1,113 @@
|
|
1
|
-
module Banklink #:nodoc:
|
2
|
-
class Helper
|
3
|
-
attr_reader :fields
|
4
|
-
include Banklink::Common
|
5
|
-
|
6
|
-
def initialize(order, account, options = {})
|
7
|
-
|
8
|
-
@options = options
|
9
|
-
@fields = {}
|
10
|
-
|
11
|
-
@options['VK_SND_ID'] = account
|
12
|
-
@options['VK_STAMP'] = order
|
13
|
-
@options['VK_AMOUNT'] = options[:amount]
|
14
|
-
@options['VK_CURR'] = options[:currency]
|
15
|
-
@options['VK_RETURN'] = options[:return]
|
16
|
-
@options['VK_REF'] = options[:reference]
|
17
|
-
@options['VK_MSG'] = options[:message]
|
18
|
-
|
19
|
-
if options[:service_msg_number]
|
20
|
-
@service_msg_number = options.delete(:service_msg_number)
|
21
|
-
else
|
22
|
-
@service_msg_number = default_service_msg_number
|
23
|
-
end
|
24
|
-
|
25
|
-
add_required_params
|
26
|
-
add_vk_mac
|
27
|
-
add_charset_field
|
28
|
-
add_return_url_field
|
29
|
-
add_lang_field
|
30
|
-
end
|
31
|
-
|
32
|
-
|
33
|
-
def form_fields
|
34
|
-
@fields
|
35
|
-
end
|
36
|
-
|
37
|
-
def self.mapping(attribute, options = {})
|
38
|
-
self.mappings ||= {}
|
39
|
-
self.mappings[attribute] = options
|
40
|
-
end
|
41
|
-
|
42
|
-
def add_field(name, value)
|
43
|
-
return if name.blank? || value.blank?
|
44
|
-
@fields[name.to_s] = value.to_s
|
45
|
-
end
|
46
|
-
|
47
|
-
def add_vk_mac
|
48
|
-
# Signature used to validate previous parameters
|
49
|
-
add_field('VK_MAC', generate_mac(@service_msg_number, form_fields))
|
50
|
-
end
|
51
|
-
|
52
|
-
def add_return_url_field
|
53
|
-
add_field('VK_RETURN', @options['VK_RETURN'])
|
54
|
-
end
|
55
|
-
|
56
|
-
def add_lang_field
|
57
|
-
add_field vk_lang_param, vk_lang
|
58
|
-
end
|
59
|
-
|
60
|
-
def add_charset_field
|
61
|
-
add_field vk_charset_param, vk_charset
|
62
|
-
end
|
63
|
-
|
64
|
-
def add_required_params
|
65
|
-
required_params = Banklink.required_service_params[@service_msg_number]
|
66
|
-
required_params.each do |param|
|
67
|
-
param_value = (@options.delete(param) || send(param.to_s.downcase)).to_s
|
68
|
-
add_field param,
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
# Default parameters
|
73
|
-
def vk_charset
|
74
|
-
'UTF-8'
|
75
|
-
end
|
76
|
-
|
77
|
-
def vk_charset_param
|
78
|
-
'VK_ENCODING'
|
79
|
-
end
|
80
|
-
|
81
|
-
# Default parameters
|
82
|
-
def vk_lang
|
83
|
-
'LAT'
|
84
|
-
end
|
85
|
-
|
86
|
-
def vk_lang_param
|
87
|
-
'VK_LANG'
|
88
|
-
end
|
89
|
-
|
90
|
-
def vk_service
|
91
|
-
@service_msg_number
|
92
|
-
end
|
93
|
-
|
94
|
-
def vk_version
|
95
|
-
'008'
|
96
|
-
end
|
97
|
-
|
98
|
-
# Default service message number.
|
99
|
-
# Use '1002' because it requires the least amount of parameters.
|
100
|
-
def default_service_msg_number
|
101
|
-
1002
|
102
|
-
end
|
103
|
-
|
104
|
-
private
|
105
|
-
# Iconv converter to convert from utf8 to
|
106
|
-
# the charset the bank api expects.
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
1
|
+
module Banklink #:nodoc:
|
2
|
+
class Helper
|
3
|
+
attr_reader :fields
|
4
|
+
include Banklink::Common
|
5
|
+
|
6
|
+
def initialize(order, account, options = {})
|
7
|
+
|
8
|
+
@options = options
|
9
|
+
@fields = {}
|
10
|
+
|
11
|
+
@options['VK_SND_ID'] = account
|
12
|
+
@options['VK_STAMP'] = order
|
13
|
+
@options['VK_AMOUNT'] = options[:amount]
|
14
|
+
@options['VK_CURR'] = options[:currency]
|
15
|
+
@options['VK_RETURN'] = options[:return]
|
16
|
+
@options['VK_REF'] = options[:reference]
|
17
|
+
@options['VK_MSG'] = options[:message]
|
18
|
+
|
19
|
+
if options[:service_msg_number]
|
20
|
+
@service_msg_number = options.delete(:service_msg_number)
|
21
|
+
else
|
22
|
+
@service_msg_number = default_service_msg_number
|
23
|
+
end
|
24
|
+
|
25
|
+
add_required_params
|
26
|
+
add_vk_mac
|
27
|
+
add_charset_field
|
28
|
+
add_return_url_field
|
29
|
+
add_lang_field
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def form_fields
|
34
|
+
@fields
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.mapping(attribute, options = {})
|
38
|
+
self.mappings ||= {}
|
39
|
+
self.mappings[attribute] = options
|
40
|
+
end
|
41
|
+
|
42
|
+
def add_field(name, value)
|
43
|
+
return if name.blank? || value.blank?
|
44
|
+
@fields[name.to_s] = value.to_s
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_vk_mac
|
48
|
+
# Signature used to validate previous parameters
|
49
|
+
add_field('VK_MAC', generate_mac(@service_msg_number, form_fields))
|
50
|
+
end
|
51
|
+
|
52
|
+
def add_return_url_field
|
53
|
+
add_field('VK_RETURN', @options['VK_RETURN'])
|
54
|
+
end
|
55
|
+
|
56
|
+
def add_lang_field
|
57
|
+
add_field vk_lang_param, vk_lang
|
58
|
+
end
|
59
|
+
|
60
|
+
def add_charset_field
|
61
|
+
add_field vk_charset_param, vk_charset
|
62
|
+
end
|
63
|
+
|
64
|
+
def add_required_params
|
65
|
+
required_params = Banklink.required_service_params[@service_msg_number]
|
66
|
+
required_params.each do |param|
|
67
|
+
param_value = (@options.delete(param) || send(param.to_s.downcase)).to_s
|
68
|
+
add_field param, encode_to_utf8(param_value)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Default parameters
|
73
|
+
def vk_charset
|
74
|
+
'UTF-8'
|
75
|
+
end
|
76
|
+
|
77
|
+
def vk_charset_param
|
78
|
+
'VK_ENCODING'
|
79
|
+
end
|
80
|
+
|
81
|
+
# Default parameters
|
82
|
+
def vk_lang
|
83
|
+
'LAT'
|
84
|
+
end
|
85
|
+
|
86
|
+
def vk_lang_param
|
87
|
+
'VK_LANG'
|
88
|
+
end
|
89
|
+
|
90
|
+
def vk_service
|
91
|
+
@service_msg_number
|
92
|
+
end
|
93
|
+
|
94
|
+
def vk_version
|
95
|
+
'008'
|
96
|
+
end
|
97
|
+
|
98
|
+
# Default service message number.
|
99
|
+
# Use '1002' because it requires the least amount of parameters.
|
100
|
+
def default_service_msg_number
|
101
|
+
1002
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
# Iconv converter to convert from utf8 to
|
106
|
+
# the charset the bank api expects.
|
107
|
+
|
108
|
+
def encode_to_utf8 string
|
109
|
+
string.encode('UTF-8', :invalid => :replace, :replace => '').encode('UTF-8')
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
111
113
|
end
|