adyen 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/adyen.gemspec +1 -1
- data/lib/adyen/form.rb +73 -39
- data/spec/form_spec.rb +13 -13
- metadata +1 -1
data/adyen.gemspec
CHANGED
data/lib/adyen/form.rb
CHANGED
@@ -5,11 +5,15 @@ module Adyen
|
|
5
5
|
|
6
6
|
extend ActionView::Helpers::TagHelper
|
7
7
|
|
8
|
+
######################################################
|
9
|
+
# SKINS
|
10
|
+
######################################################
|
11
|
+
|
8
12
|
def self.skins
|
9
13
|
@skins ||= {}
|
10
14
|
end
|
11
15
|
|
12
|
-
def self.
|
16
|
+
def self.register_skin(name, skin_code, shared_secret)
|
13
17
|
self.skins[name] = {:name => name, :skin_code => skin_code, :shared_secret => shared_secret }
|
14
18
|
end
|
15
19
|
|
@@ -20,6 +24,26 @@ module Adyen
|
|
20
24
|
def self.skin_by_code(skin_code)
|
21
25
|
self.skins.detect { |(name, skin)| skin[:skin_code] == skin_code }.last rescue nil
|
22
26
|
end
|
27
|
+
|
28
|
+
def self.lookup_shared_secret(skin_code)
|
29
|
+
skin = skin_by_code(skin_code)[:shared_secret] rescue nil
|
30
|
+
end
|
31
|
+
|
32
|
+
######################################################
|
33
|
+
# DEFAULT FORM / REDIRECT PARAMETERS
|
34
|
+
######################################################
|
35
|
+
|
36
|
+
def self.default_parameters
|
37
|
+
@default_arguments ||= {}
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.default_parameters=(hash)
|
41
|
+
@default_arguments = hash
|
42
|
+
end
|
43
|
+
|
44
|
+
######################################################
|
45
|
+
# ADYEN FORM URL
|
46
|
+
######################################################
|
23
47
|
|
24
48
|
ACTION_URL = "https://%s.adyen.com/hpp/select.shtml"
|
25
49
|
|
@@ -28,65 +52,75 @@ module Adyen
|
|
28
52
|
Adyen::Form::ACTION_URL % environment.to_s
|
29
53
|
end
|
30
54
|
|
31
|
-
def self.calculate_signature_string(attributes)
|
32
|
-
merchant_sig_string = ""
|
33
|
-
merchant_sig_string << attributes[:payment_amount].to_s << attributes[:currency_code].to_s <<
|
34
|
-
attributes[:ship_before_date].to_s << attributes[:merchant_reference].to_s <<
|
35
|
-
attributes[:skin_code].to_s << attributes[:merchant_account].to_s <<
|
36
|
-
attributes[:session_validity].to_s << attributes[:shopper_email].to_s <<
|
37
|
-
attributes[:shopper_reference].to_s << attributes[:recurring_contract].to_s <<
|
38
|
-
attributes[:allowed_methods].to_s << attributes[:blocked_methods].to_s <<
|
39
|
-
attributes[:shopper_statement].to_s << attributes[:billing_address_type].to_s
|
40
|
-
end
|
41
55
|
|
42
|
-
|
43
|
-
|
44
|
-
|
56
|
+
######################################################
|
57
|
+
# POSTING/REDIRECTING TO ADYEN
|
58
|
+
######################################################
|
45
59
|
|
46
|
-
def self.
|
47
|
-
raise "YENs are not yet supported!" if
|
60
|
+
def self.do_parameter_transformations!(parameters = {})
|
61
|
+
raise "YENs are not yet supported!" if parameters[:currency_code] == 'JPY' # TODO: fixme
|
48
62
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
63
|
+
parameters.replace(default_parameters.merge(parameters))
|
64
|
+
parameters[:recurring_contract] = 'DEFAULT' if parameters.delete(:recurring) == true
|
65
|
+
parameters[:order_data] = Adyen::Encoding.gzip_base64(parameters.delete(:order_data_raw)) if parameters[:order_data_raw]
|
66
|
+
parameters[:ship_before_date] = Adyen::Formatter::DateTime.fmt_date(parameters[:ship_before_date])
|
67
|
+
parameters[:session_validity] = Adyen::Formatter::DateTime.fmt_time(parameters[:session_validity])
|
53
68
|
|
54
|
-
if
|
55
|
-
skin = Adyen::Form.skin_by_name(
|
56
|
-
|
57
|
-
|
69
|
+
if parameters[:skin]
|
70
|
+
skin = Adyen::Form.skin_by_name(parameters.delete(:skin))
|
71
|
+
parameters[:skin_code] ||= skin[:skin_code]
|
72
|
+
parameters[:shared_secret] ||= skin[:shared_secret]
|
58
73
|
end
|
59
74
|
end
|
60
75
|
|
61
|
-
def self.
|
62
|
-
|
76
|
+
def self.payment_parameters(parameters = {})
|
77
|
+
do_parameter_transformations!(parameters)
|
63
78
|
|
64
|
-
raise "Cannot generate form: :currency code attribute not found!" unless
|
65
|
-
raise "Cannot generate form: :payment_amount code attribute not found!" unless
|
66
|
-
raise "Cannot generate form: :merchant_account attribute not found!" unless
|
67
|
-
raise "Cannot generate form: :skin_code attribute not found!" unless
|
68
|
-
raise "Cannot generate form: :shared_secret signing secret not provided!" unless
|
79
|
+
raise "Cannot generate form: :currency code attribute not found!" unless parameters[:currency_code]
|
80
|
+
raise "Cannot generate form: :payment_amount code attribute not found!" unless parameters[:payment_amount]
|
81
|
+
raise "Cannot generate form: :merchant_account attribute not found!" unless parameters[:merchant_account]
|
82
|
+
raise "Cannot generate form: :skin_code attribute not found!" unless parameters[:skin_code]
|
83
|
+
raise "Cannot generate form: :shared_secret signing secret not provided!" unless parameters[:shared_secret]
|
69
84
|
|
70
85
|
# Merchant signature
|
71
|
-
|
72
|
-
return
|
86
|
+
parameters[:merchant_sig] = calculate_signature(parameters)
|
87
|
+
return parameters
|
73
88
|
end
|
74
89
|
|
75
|
-
def self.redirect_url(
|
76
|
-
self.url + '?' +
|
90
|
+
def self.redirect_url(parameters = {})
|
91
|
+
self.url + '?' + payment_parameters(parameters).map { |(k, v)| "#{k.to_s.camelize(:lower)}=#{CGI.escape(v.to_s)}" }.join('&')
|
77
92
|
end
|
78
93
|
|
79
|
-
def self.hidden_fields(
|
94
|
+
def self.hidden_fields(parameters = {})
|
80
95
|
# Generate hidden input tags
|
81
|
-
|
96
|
+
payment_parameters(parameters).map { |key, value|
|
82
97
|
self.tag(:input, :type => 'hidden', :name => key.to_s.camelize(:lower), :value => value)
|
83
98
|
}.join("\n")
|
84
99
|
end
|
85
100
|
|
86
|
-
|
87
|
-
|
101
|
+
######################################################
|
102
|
+
# MERCHANT SIGNATURE CALCULATION
|
103
|
+
######################################################
|
104
|
+
|
105
|
+
def self.calculate_signature_string(parameters)
|
106
|
+
merchant_sig_string = ""
|
107
|
+
merchant_sig_string << parameters[:payment_amount].to_s << parameters[:currency_code].to_s <<
|
108
|
+
parameters[:ship_before_date].to_s << parameters[:merchant_reference].to_s <<
|
109
|
+
parameters[:skin_code].to_s << parameters[:merchant_account].to_s <<
|
110
|
+
parameters[:session_validity].to_s << parameters[:shopper_email].to_s <<
|
111
|
+
parameters[:shopper_reference].to_s << parameters[:recurring_contract].to_s <<
|
112
|
+
parameters[:allowed_methods].to_s << parameters[:blocked_methods].to_s <<
|
113
|
+
parameters[:shopper_statement].to_s << parameters[:billing_address_type].to_s
|
88
114
|
end
|
89
115
|
|
116
|
+
def self.calculate_signature(parameters)
|
117
|
+
Adyen::Encoding.hmac_base64(parameters.delete(:shared_secret), calculate_signature_string(parameters))
|
118
|
+
end
|
119
|
+
|
120
|
+
######################################################
|
121
|
+
# REDIRECT SIGNATURE CHECKING
|
122
|
+
######################################################
|
123
|
+
|
90
124
|
def self.redirect_signature_string(params)
|
91
125
|
params[:authResult].to_s + params[:pspReference].to_s + params[:merchantReference].to_s + params[:skinCode].to_s
|
92
126
|
end
|
data/spec/form_spec.rb
CHANGED
@@ -3,7 +3,8 @@ require "#{File.dirname(__FILE__)}/spec_helper.rb"
|
|
3
3
|
describe Adyen::Form do
|
4
4
|
|
5
5
|
before(:all) do
|
6
|
-
Adyen::Form.
|
6
|
+
Adyen::Form.register_skin(:testing, '4aD37dJA', 'Kah942*$7sdp0)')
|
7
|
+
Adyen::Form.default_parameters[:merchant_account] = 'TestMerchant'
|
7
8
|
end
|
8
9
|
|
9
10
|
describe 'Action URLs' do
|
@@ -73,7 +74,7 @@ describe Adyen::Form do
|
|
73
74
|
before(:each) do
|
74
75
|
@attributes = { :currency_code => 'GBP', :payment_amount => 10000, :ship_before_date => Date.today,
|
75
76
|
:merchant_reference => 'Internet Order 12345', :skin => :testing,
|
76
|
-
:
|
77
|
+
:session_validity => 1.hour.from_now }
|
77
78
|
|
78
79
|
@redirect_url = Adyen::Form.redirect_url(@attributes)
|
79
80
|
end
|
@@ -100,7 +101,7 @@ describe Adyen::Form do
|
|
100
101
|
before(:each) do
|
101
102
|
@attributes = { :currency_code => 'GBP', :payment_amount => 10000, :ship_before_date => Date.today,
|
102
103
|
:merchant_reference => 'Internet Order 12345', :skin => :testing,
|
103
|
-
:
|
104
|
+
:session_validity => 1.hour.from_now }
|
104
105
|
end
|
105
106
|
|
106
107
|
it "should generate a valid payment form" do
|
@@ -115,37 +116,36 @@ describe Adyen::Form do
|
|
115
116
|
|
116
117
|
before(:each) do
|
117
118
|
|
118
|
-
@
|
119
|
+
@parameters = { :currency_code => 'GBP', :payment_amount => 10000,
|
119
120
|
:ship_before_date => '2007-10-20', :merchant_reference => 'Internet Order 12345',
|
120
|
-
:skin => :testing, :
|
121
|
-
:session_validity => '2007-10-11T11:00:00Z' }
|
121
|
+
:skin => :testing, :session_validity => '2007-10-11T11:00:00Z' }
|
122
122
|
|
123
|
-
Adyen::Form.
|
123
|
+
Adyen::Form.do_parameter_transformations!(@parameters)
|
124
124
|
end
|
125
125
|
|
126
126
|
it "should construct the signature string correctly" do
|
127
|
-
signature_string = Adyen::Form.calculate_signature_string(@
|
127
|
+
signature_string = Adyen::Form.calculate_signature_string(@parameters)
|
128
128
|
signature_string.should eql("10000GBP2007-10-20Internet Order 123454aD37dJATestMerchant2007-10-11T11:00:00Z")
|
129
129
|
end
|
130
130
|
|
131
131
|
it "should calculate the signature correctly" do
|
132
|
-
signature = Adyen::Form.calculate_signature(@
|
132
|
+
signature = Adyen::Form.calculate_signature(@parameters)
|
133
133
|
signature.should eql('x58ZcRVL1H6y+XSeBGrySJ9ACVo=')
|
134
134
|
end
|
135
135
|
|
136
136
|
it "should calculate the signature correctly for a recurring payment" do
|
137
137
|
# Add the required recurrent payment attributes
|
138
|
-
@
|
138
|
+
@parameters.merge!(:recurring_contract => 'DEFAULT', :shopper_reference => 'grasshopper52', :shopper_email => 'gras.shopper@somewhere.org')
|
139
139
|
|
140
|
-
signature_string = Adyen::Form.calculate_signature_string(@
|
140
|
+
signature_string = Adyen::Form.calculate_signature_string(@parameters)
|
141
141
|
signature_string.should eql("10000GBP2007-10-20Internet Order 123454aD37dJATestMerchant2007-10-11T11:00:00Zgras.shopper@somewhere.orggrasshopper52DEFAULT")
|
142
142
|
end
|
143
143
|
|
144
144
|
it "should calculate the signature correctly for a recurring payment" do
|
145
145
|
# Add the required recurrent payment attributes
|
146
|
-
@
|
146
|
+
@parameters.merge!(:recurring_contract => 'DEFAULT', :shopper_reference => 'grasshopper52', :shopper_email => 'gras.shopper@somewhere.org')
|
147
147
|
|
148
|
-
signature = Adyen::Form.calculate_signature(@
|
148
|
+
signature = Adyen::Form.calculate_signature(@parameters)
|
149
149
|
signature.should eql('F2BQEYbE+EUhiRGuPtcD16Gm7JY=')
|
150
150
|
end
|
151
151
|
end
|