Module: Adyen::Form
- Extended by:
- Form
- Includes:
- ActionView::Helpers::TagHelper
- Included in:
- Form
- Defined in:
- lib/adyen/form.rb
Overview
The Adyen::Form module contains all functionality that is used to send payment requests to the Adyen payment system, using either a HTML form (see hidden_fields) or a HTTP redirect (see redirect_url).
Moreover, this module contains the method redirect_signature_check to check the request that is made to your website after the visitor has made his payment on the Adyen system for genuinity.
You can use different skins in Adyen to define different payment environments. You can register these skins under a custom name in the module. The other methods will automatically use this information (i.e. the skin code and the shared secret) if it is available. Otherwise, you have to provide it yourself for every method call you make. See register_skin for more information.
Constant Summary collapse
- ACTION_URL =
The URL of the Adyen payment system that still requires the current Adyen enviroment to be filled in.
"https://%s.adyen.com/hpp/select.shtml"
Instance Method Summary collapse
-
#calculate_signature(parameters, shared_secret = nil) ⇒ String
Calculates the payment request signature for the given payment parameters.
-
#calculate_signature_string(parameters) ⇒ String
Generates the string that is used to calculate the request signature.
-
#default_parameters ⇒ Hash
Returns the default parameters to use, unless they are overridden.
-
#default_parameters=(hash) ⇒ Object
Sets the default parameters to use.
-
#do_parameter_transformations!(parameters = {}) ⇒ Object
Transforms the payment parameters hash to be in the correct format.
-
#hidden_fields(parameters = {}) ⇒ String
Returns a HTML snippet of hidden INPUT tags with the provided payment parameters.
-
#lookup_shared_secret(skin_code) ⇒ String?
Returns the shared secret belonging to a skin code.
-
#payment_parameters(parameters = {}, shared_secret = nil) ⇒ Hash
Transforms the payment parameters to be in the correct format and calculates the merchant signature parameter.
-
#redirect_signature(params, shared_secret = nil) ⇒ String
Computes the redirect signature using the request parameters, so that the redirect can be checked for forgery.
-
#redirect_signature_check(params, shared_secret = nil) ⇒ true, false
Checks the redirect signature for this request by calcultating the signature from the provided parameters, and comparing it to the signature provided in the
merchantSig
parameter. -
#redirect_signature_string(params) ⇒ String
Generates the string for which the redirect signature is calculated, using the request paramaters.
-
#redirect_url(parameters = {}) ⇒ String
Returns an absolute URL to the Adyen payment system, with the payment parameters included as GET parameters in the URL.
-
#register_skin(name, skin_code, shared_secret) ⇒ Object
Registers a skin for later use.
-
#skin_by_code(skin_code) ⇒ Hash?
Returns skin information given a skin code.
-
#skin_by_name(skin_name) ⇒ Hash?
Returns skin information given a skin name.
-
#skins ⇒ Hash
Returns all registered skins and their accompanying skin code and shared secret.
-
#skins=(hash) ⇒ Object
Sets the registered skins.
-
#url(environment = nil) ⇒ String
Returns the URL of the Adyen payment system, adjusted for an Adyen environment.
Instance Method Details
#calculate_signature(parameters, shared_secret = nil) ⇒ String
Calculates the payment request signature for the given payment parameters.
This signature is used by Adyen to check whether the request is genuinely originating from you. The resulting signature should be included in the payment request parameters as the merchantSig
parameter; the shared secret should of course not be included.
275 276 277 278 |
# File 'lib/adyen/form.rb', line 275 def calculate_signature(parameters, shared_secret = nil) shared_secret ||= parameters.delete(:shared_secret) Adyen::Encoding.hmac_base64(shared_secret, calculate_signature_string(parameters)) end |
#calculate_signature_string(parameters) ⇒ String
Generates the string that is used to calculate the request signature. This signature is used by Adyen to check whether the request is genuinely originating from you.
251 252 253 254 255 256 257 258 259 260 |
# File 'lib/adyen/form.rb', line 251 def calculate_signature_string(parameters) merchant_sig_string = "" merchant_sig_string << parameters[:payment_amount].to_s << parameters[:currency_code].to_s << parameters[:ship_before_date].to_s << parameters[:merchant_reference].to_s << parameters[:skin_code].to_s << parameters[:merchant_account].to_s << parameters[:session_validity].to_s << parameters[:shopper_email].to_s << parameters[:shopper_reference].to_s << parameters[:recurring_contract].to_s << parameters[:allowed_methods].to_s << parameters[:blocked_methods].to_s << parameters[:shopper_statement].to_s << parameters[:billing_address_type].to_s end |
#default_parameters ⇒ Hash
Returns the default parameters to use, unless they are overridden.
93 94 95 |
# File 'lib/adyen/form.rb', line 93 def default_parameters @default_arguments ||= {} end |
#default_parameters=(hash) ⇒ Object
Sets the default parameters to use.
100 101 102 |
# File 'lib/adyen/form.rb', line 100 def default_parameters=(hash) @default_arguments = hash end |
#do_parameter_transformations!(parameters = {}) ⇒ Object
Transforms the payment parameters hash to be in the correct format. It will also include the default_parameters hash. Finally, switches the :skin
parameter out for the :skin_code
and :shared_secret
parameter using the list of registered skins.
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/adyen/form.rb', line 136 def do_parameter_transformations!(parameters = {}) raise "YENs are not yet supported!" if parameters[:currency_code] == 'JPY' # TODO: fixme parameters.replace(default_parameters.merge(parameters)) parameters[:recurring_contract] = 'RECURRING' if parameters.delete(:recurring) == true parameters[:order_data] = Adyen::Encoding.gzip_base64(parameters.delete(:order_data_raw)) if parameters[:order_data_raw] parameters[:ship_before_date] = Adyen::Formatter::DateTime.fmt_date(parameters[:ship_before_date]) parameters[:session_validity] = Adyen::Formatter::DateTime.fmt_time(parameters[:session_validity]) if parameters[:skin] skin = Adyen::Form.skin_by_name(parameters.delete(:skin)) parameters[:skin_code] ||= skin[:skin_code] parameters[:shared_secret] ||= skin[:shared_secret] end end |
#hidden_fields(parameters = {}) ⇒ String
Returns a HTML snippet of hidden INPUT tags with the provided payment parameters. The snippet can be included in a payment form that POSTs to the Adyen payment system.
The payment parameters that are provided to this method will be merged with the default_parameters hash. The default parameter values will be overrided if another value is provided to this method.
You do not have to provide the :merchant_sig
parameter: it will be calculated automatically if you provide either a registered skin name as the :skin
parameter or provide both the :skin_code
and :shared_secret
parameters.
233 234 235 236 237 238 239 240 241 |
# File 'lib/adyen/form.rb', line 233 def hidden_fields(parameters = {}) # Generate a hidden input tag per parameter, join them by newlines. form_str = payment_parameters(parameters).map { |key, value| tag(:input, :type => 'hidden', :name => key.to_s.camelize(:lower), :value => value) }.join("\n") form_str.respond_to?(:html_safe) ? form_str.html_safe : form_str end |
#lookup_shared_secret(skin_code) ⇒ String?
Returns the shared secret belonging to a skin code.
82 83 84 |
# File 'lib/adyen/form.rb', line 82 def lookup_shared_secret(skin_code) skin = skin_by_code(skin_code)[:shared_secret] rescue nil end |
#payment_parameters(parameters = {}, shared_secret = nil) ⇒ Hash
Transforms the payment parameters to be in the correct format and calculates the merchant signature parameter. It also does some basic health checks on the parameters hash.
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/adyen/form.rb', line 163 def payment_parameters(parameters = {}, shared_secret = nil) do_parameter_transformations!(parameters) raise "Cannot generate form: :currency code attribute not found!" unless parameters[:currency_code] raise "Cannot generate form: :payment_amount code attribute not found!" unless parameters[:payment_amount] raise "Cannot generate form: :merchant_account attribute not found!" unless parameters[:merchant_account] raise "Cannot generate form: :skin_code attribute not found!" unless parameters[:skin_code] # Calculate the merchant signature using the shared secret. shared_secret ||= parameters.delete(:shared_secret) raise "Cannot calculate payment request signature without shared secret!" unless shared_secret parameters[:merchant_sig] = calculate_signature(parameters, shared_secret) return parameters end |
#redirect_signature(params, shared_secret = nil) ⇒ String
Computes the redirect signature using the request parameters, so that the redirect can be checked for forgery.
299 300 301 302 |
# File 'lib/adyen/form.rb', line 299 def redirect_signature(params, shared_secret = nil) shared_secret ||= lookup_shared_secret(params[:skinCode]) Adyen::Encoding.hmac_base64(shared_secret, redirect_signature_string(params)) end |
#redirect_signature_check(params, shared_secret = nil) ⇒ true, false
Checks the redirect signature for this request by calcultating the signature from the provided parameters, and comparing it to the signature provided in the merchantSig
parameter.
If this method returns false, the request could be a forgery and should not be handled. Therefore, you should include this check in a before_filter
, and raise an error of the signature check fails.
334 335 336 |
# File 'lib/adyen/form.rb', line 334 def redirect_signature_check(params, shared_secret = nil) params[:merchantSig] == redirect_signature(params, shared_secret) end |
#redirect_signature_string(params) ⇒ String
Generates the string for which the redirect signature is calculated, using the request paramaters.
287 288 289 |
# File 'lib/adyen/form.rb', line 287 def redirect_signature_string(params) params[:authResult].to_s + params[:pspReference].to_s + params[:merchantReference].to_s + params[:skinCode].to_s end |
#redirect_url(parameters = {}) ⇒ String
Returns an absolute URL to the Adyen payment system, with the payment parameters included as GET parameters in the URL. The URL also depends on the current Adyen enviroment.
The payment parameters that are provided to this method will be merged with the default_parameters hash. The default parameter values will be overrided if another value is provided to this method.
You do not have to provide the :merchant_sig
parameter: it will be calculated automatically if you provide either a registered skin name as the :skin
parameter or provide both the :skin_code
and :shared_secret
parameters.
Note that Internet Explorer has a maximum length for URLs it can handle (2083 characters). Make sure that the URL is not longer than this limit if you want your site to work in IE.
207 208 209 210 |
# File 'lib/adyen/form.rb', line 207 def redirect_url(parameters = {}) url + '?' + payment_parameters(parameters).map { |(k, v)| "#{k.to_s.camelize(:lower)}=#{CGI.escape(v.to_s)}" }.join('&') end |
#register_skin(name, skin_code, shared_secret) ⇒ Object
Registers a skin for later use.
You can store a skin using a self defined symbol. Once the skin is registered, you can refer to it using this symbol instead of the hard-to-remember skin code. Moreover, the skin’s shared_secret will be looked up automatically for calculting signatures.
61 62 63 |
# File 'lib/adyen/form.rb', line 61 def register_skin(name, skin_code, shared_secret) skins[name.to_sym] = {:name => name.to_sym, :skin_code => skin_code, :shared_secret => shared_secret } end |
#skin_by_code(skin_code) ⇒ Hash?
Returns skin information given a skin code.
75 76 77 |
# File 'lib/adyen/form.rb', line 75 def skin_by_code(skin_code) skins.detect { |(name, skin)| skin[:skin_code] == skin_code }.last rescue nil end |
#skin_by_name(skin_name) ⇒ Hash?
Returns skin information given a skin name.
68 69 70 |
# File 'lib/adyen/form.rb', line 68 def skin_by_name(skin_name) skins[skin_name.to_sym] end |
#skins ⇒ Hash
Returns all registered skins and their accompanying skin code and shared secret.
33 34 35 |
# File 'lib/adyen/form.rb', line 33 def skins @skins ||= {} end |
#skins=(hash) ⇒ Object
Sets the registered skins.
41 42 43 44 45 46 |
# File 'lib/adyen/form.rb', line 41 def skins=(hash) @skins = hash.inject({}) do |skins, (name, skin)| skins[name.to_sym] = skin.merge(:name => name.to_sym) skins end end |
#url(environment = nil) ⇒ String
Returns the URL of the Adyen payment system, adjusted for an Adyen environment.
120 121 122 123 |
# File 'lib/adyen/form.rb', line 120 def url(environment = nil) environment ||= Adyen.environment Adyen::Form::ACTION_URL % environment.to_s end |