Module: Adyen::Form
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 Configuration#register_form_skin for more information.
Constant Summary
- ACTION_DOMAIN =
The DOMAIN of the Adyen payment system that still requires the current Adyen enviroment.
"%s.adyen.com"- ACTION_URL =
The URL of the Adyen payment system that still requires the current domain and payment flow to be filled.
"https://%s/hpp/%s.shtml"
Instance Method Summary (collapse)
-
- (String) calculate_billing_address_signature(parameters, shared_secret = nil)
Calculates the billing address request signature for the given billing address parameters.
-
- (String) calculate_billing_address_signature_string(parameters)
Generates the string that is used to calculate the request signature.
-
- (String) calculate_signature(parameters, shared_secret = nil)
Calculates the payment request signature for the given payment parameters.
-
- (String) calculate_signature_string(parameters)
Generates the string that is used to calculate the request signature.
-
- (String) camelize(identifier)
Returns the camelized version of a string.
-
- (Object) do_parameter_transformations!(parameters = {})
Transforms the payment parameters hash to be in the correct format.
-
- (String) domain(environment = nil)
Returns the DOMAIN of the Adyen payment system, adjusted for an Adyen environment.
-
- (Hash) flat_payment_parameters(parameters = {})
Transforms and flattens payment parameters to be in the correct format which is understood and accepted by adyen.
-
- (Hash) flatten(parameters, prefix = "", return_hash = {})
Transforms the nested parameters Hash into a 'flat' Hash which is understood by adyen.
-
- (String) hidden_fields(parameters = {})
Returns a HTML snippet of hidden INPUT tags with the provided payment parameters.
-
- (Hash) payment_parameters(parameters = {}, shared_secret = nil)
Transforms the payment parameters to be in the correct format and calculates the merchant signature parameter.
-
- (String) redirect_signature(params, shared_secret = nil)
Computes the redirect signature using the request parameters, so that the redirect can be checked for forgery.
-
- (true, false) redirect_signature_check(params, shared_secret = nil)
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.
-
- (String) redirect_signature_string(params)
Generates the string for which the redirect signature is calculated, using the request paramaters.
-
- (String) redirect_url(parameters = {})
Returns an absolute URL to the Adyen payment system, with the payment parameters included as GET parameters in the URL.
-
- (String) url(environment = nil, payment_flow = nil)
Returns the URL of the Adyen payment system, adjusted for an Adyen environment.
Instance Method Details
- (String) calculate_billing_address_signature(parameters, shared_secret = nil)
Calculates the billing address request signature for the given billing address 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 billing address request parameters as the billingAddressSig parameter; the shared secret should of course not be included.
263 264 265 266 267 |
# File 'lib/adyen/form.rb', line 263 def calculate_billing_address_signature(parameters, shared_secret = nil) shared_secret ||= parameters.delete(:shared_secret) raise ArgumentError, "Cannot calculate billing address request signature with empty shared_secret" if shared_secret.to_s.empty? Adyen::Encoding.hmac_base64(shared_secret, calculate_billing_address_signature_string(parameters[:billing_address])) end |
- (String) calculate_billing_address_signature_string(parameters)
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.
243 244 245 246 247 |
# File 'lib/adyen/form.rb', line 243 def calculate_billing_address_signature_string(parameters) %w(street house_number_or_name city postal_code state_or_province country).map do |key| parameters[key.to_sym] end.join end |
- (String) calculate_signature(parameters, shared_secret = nil)
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.
233 234 235 236 237 |
# File 'lib/adyen/form.rb', line 233 def calculate_signature(parameters, shared_secret = nil) shared_secret ||= parameters.delete(:shared_secret) raise ArgumentError, "Cannot calculate payment request signature with empty shared_secret" if shared_secret.to_s.empty? Adyen::Encoding.hmac_base64(shared_secret, calculate_signature_string(parameters)) end |
- (String) calculate_signature_string(parameters)
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.
207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/adyen/form.rb', line 207 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[:merchant_return_data].to_s << parameters[:billing_address_type].to_s << parameters[:offset].to_s end |
- (String) camelize(identifier)
Returns the camelized version of a string.
333 334 335 |
# File 'lib/adyen/form.rb', line 333 def camelize(identifier) identifier.to_s.gsub(/_(.)/) { $1.upcase } end |
- (Object) do_parameter_transformations!(parameters = {})
Transforms the payment parameters hash to be in the correct format. It will also include the Adyen::Configuration#default_form_params hash. Finally, switches the :skin parameter out for the :skin_code and :shared_secret parameter using the list of registered skins.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/adyen/form.rb', line 78 def do_parameter_transformations!(parameters = {}) parameters.replace(Adyen.configuration.default_form_params.merge(parameters)) if parameters[:skin] skin = Adyen.configuration.form_skin_by_name(parameters.delete(:skin)) parameters[:skin_code] ||= skin[:skin_code] parameters[:shared_secret] ||= skin[:shared_secret] parameters.merge!(skin[:default_form_params]) end 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]) end |
- (String) domain(environment = nil)
Returns the DOMAIN of the Adyen payment system, adjusted for an Adyen environment.
46 47 48 49 |
# File 'lib/adyen/form.rb', line 46 def domain(environment = nil) environment ||= Adyen.configuration.environment (Adyen.configuration.payment_flow_domain || ACTION_DOMAIN) % [environment.to_s] end |
- (Hash) flat_payment_parameters(parameters = {})
Transforms and flattens payment parameters to be in the correct format which is understood and accepted by adyen
130 131 132 |
# File 'lib/adyen/form.rb', line 130 def flat_payment_parameters(parameters = {}) flatten(payment_parameters(parameters)) end |
- (Hash) flatten(parameters, prefix = "", return_hash = {})
Transforms the nested parameters Hash into a 'flat' Hash which is understood by adyen. This is:
* all keys are camelized
* all keys are stringified
* nested hash is flattened, keys are prefixed with root key
352 353 354 355 356 357 358 359 360 361 362 363 |
# File 'lib/adyen/form.rb', line 352 def flatten(parameters, prefix = "", return_hash = {}) parameters ||= {} parameters.inject(return_hash) do |hash, (key, value)| key = "#{prefix}#{camelize(key)}" if value.is_a?(Hash) flatten(value, "#{key}.", return_hash) else hash[key] = value.to_s end hash end end |
- (String) hidden_fields(parameters = {})
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 Configuration#default_form_params 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.
189 190 191 192 193 194 195 196 197 |
# File 'lib/adyen/form.rb', line 189 def hidden_fields(parameters = {}) # Generate a hidden input tag per parameter, join them by newlines. form_str = flat_payment_parameters(parameters).map { |key, value| "<input type=\"hidden\" name=\"#{CGI.escapeHTML(key)}\" value=\"#{CGI.escapeHTML(value)}\" />" }.join("\n") form_str.respond_to?(:html_safe) ? form_str.html_safe : form_str end |
- (Hash) payment_parameters(parameters = {}, shared_secret = nil)
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.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/adyen/form.rb', line 105 def payment_parameters(parameters = {}, shared_secret = nil) do_parameter_transformations!(parameters) raise ArgumentError, "Cannot generate form: :currency code attribute not found!" unless parameters[:currency_code] raise ArgumentError, "Cannot generate form: :payment_amount code attribute not found!" unless parameters[:payment_amount] raise ArgumentError, "Cannot generate form: :merchant_account attribute not found!" unless parameters[:merchant_account] raise ArgumentError, "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 ArgumentError, "Cannot calculate payment request signature without shared secret!" unless shared_secret parameters[:merchant_sig] = calculate_signature(parameters, shared_secret) if parameters[:billing_address] parameters[:billing_address_sig] = calculate_billing_address_signature(parameters, shared_secret) end return parameters end |
- (String) redirect_signature(params, shared_secret = nil)
Computes the redirect signature using the request parameters, so that the redirect can be checked for forgery.
290 291 292 293 294 |
# File 'lib/adyen/form.rb', line 290 def redirect_signature(params, shared_secret = nil) shared_secret ||= Adyen.configuration.form_skin_shared_secret_by_code(params[:skinCode]) raise ArgumentError, "Cannot compute redirect signature with empty shared_secret" if shared_secret.to_s.empty? Adyen::Encoding.hmac_base64(shared_secret, redirect_signature_string(params)) end |
- (true, false) redirect_signature_check(params, shared_secret = nil)
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.
326 327 328 |
# File 'lib/adyen/form.rb', line 326 def redirect_signature_check(params, shared_secret = nil) params[:merchantSig] == redirect_signature(params, shared_secret) end |
- (String) redirect_signature_string(params)
Generates the string for which the redirect signature is calculated, using the request paramaters.
276 277 278 279 |
# File 'lib/adyen/form.rb', line 276 def redirect_signature_string(params) params[:authResult].to_s + params[:pspReference].to_s + params[:merchantReference].to_s + params[:skinCode].to_s + params[:merchantReturnData].to_s end |
- (String) redirect_url(parameters = {})
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 Configuration#default_form_params 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.
162 163 164 165 166 |
# File 'lib/adyen/form.rb', line 162 def redirect_url(parameters = {}) url + '?' + flat_payment_parameters(parameters).map { |(k, v)| "#{k}=#{CGI.escape(v)}" }.join('&') end |
- (String) url(environment = nil, payment_flow = nil)
Returns the URL of the Adyen payment system, adjusted for an Adyen environment.
62 63 64 65 |
# File 'lib/adyen/form.rb', line 62 def url(environment = nil, payment_flow = nil) payment_flow ||= Adyen.configuration.payment_flow Adyen::Form::ACTION_URL % [domain(environment), payment_flow.to_s] end |