lib/adyen/form.rb in adyen-0.3.8 vs lib/adyen/form.rb in adyen-1.0.0

- old
+ new

@@ -1,109 +1,31 @@ -require 'action_view' +require 'cgi' module Adyen # 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 {Adyen::Form.hidden_fields}) # or a HTTP redirect (see {Adyen::Form.redirect_url}). # # Moreover, this module contains the method {Adyen::Form.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. + # 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 - # {Adyen::Form.register_skin} for more information. + # {Adyen::Configuration#register_form_skin} for more information. # - # @see Adyen::Form.register_skin + # @see Adyen::Configuration#register_form_skin # @see Adyen::Form.hidden_fields # @see Adyen::Form.redirect_url # @see Adyen::Form.redirect_signature_check module Form - include ActionView::Helpers::TagHelper extend self ###################################################### - # SKINS - ###################################################### - - # Returns all registered skins and their accompanying skin code and shared secret. - # @return [Hash] The hash of registered skins. - def skins - @skins ||= {} - end - - # Sets the registered skins. - # @param [Hash<Symbol, Hash>] hash A hash with the skin name as key and the skin parameter hash - # (which should include +:skin_code+ and +:shared_secret+) as value. - # @see Adyen::Form.register_skin - def skins=(hash) - @skins = hash.inject({}) do |skins, (name, skin)| - skins[name.to_sym] = skin.merge(:name => name.to_sym) - skins - end - end - - # 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. - # - # @example - # Adyen::Form.register_skin(:my_skin, 'dsfH67PO', 'Dfs*7uUln9') - # @param [Symbol] name The name of the skin. - # @param [String] skin_code The skin code for this skin, as defined by Adyen. - # @param [String] shared_secret The shared secret used for signature calculation. - # @see Adyen.load_config - 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 - - # Returns skin information given a skin name. - # @param [Symbol] skin_name The name of the skin - # @return [Hash, nil] A hash with the skin information, or nil if not found. - def skin_by_name(skin_name) - skins[skin_name.to_sym] - end - - # Returns skin information given a skin code. - # @param [String] skin_code The skin code of the skin - # @return [Hash, nil] A hash with the skin information, or nil if not found. - def skin_by_code(skin_code) - skins.detect { |(name, skin)| skin[:skin_code] == skin_code }.last rescue nil - end - - # Returns the shared secret belonging to a skin code. - # @param [String] skin_code The skin code of the skin - # @return [String, nil] The shared secret for the skin, or nil if not found. - def lookup_shared_secret(skin_code) - skin = skin_by_code(skin_code)[:shared_secret] rescue nil - end - - ###################################################### - # DEFAULT FORM / REDIRECT PARAMETERS - ###################################################### - - # Returns the default parameters to use, unless they are overridden. - # @see Adyen::Form.default_parameters - # @return [Hash] The hash of default parameters - def default_parameters - @default_arguments ||= {} - end - - # Sets the default parameters to use. - # @see Adyen::Form.default_parameters - # @param [Hash] hash The hash of default parameters - def default_parameters=(hash) - @default_arguments = hash - end - - ###################################################### # ADYEN FORM URL ###################################################### # The URL of the Adyen payment system that still requires the current # Adyen enviroment to be filled in. @@ -116,74 +38,72 @@ # @return [String] The absolute URL of the Adyen payment system that can be used # for payment forms or redirects. # @see Adyen::Form.environment # @see Adyen::Form.redirect_url def url(environment = nil) - environment ||= Adyen.environment + environment ||= Adyen.configuration.environment Adyen::Form::ACTION_URL % environment.to_s end ###################################################### # POSTING/REDIRECTING TO ADYEN ###################################################### - # 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. + # 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. # # @private # @param [Hash] parameters The payment parameters hash to transform 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.replace(Adyen.configuration.default_form_params.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)) + skin = Adyen.configuration.form_skin_by_name(parameters.delete(:skin)) parameters[:skin_code] ||= skin[:skin_code] parameters[:shared_secret] ||= skin[:shared_secret] end end # 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. # # @param [Hash] parameters The payment parameters. The parameters set in the - # {Adyen::Form.default_parameters} hash will be included automatically. + # {Adyen::Configuration#default_form_params} hash will be included automatically. # @param [String] shared_secret The shared secret that should be used to calculate # the payment request signature. This parameter can be left if the skin that is - # used is registered (see {Adyen::Form.register_skin}), or if the shared secret - # is provided as the +:shared_secret+ parameter. + # used is registered (see {Adyen::Configuration#register_form_skin}), or if the + # shared secret is provided as the +:shared_secret+ parameter. # @return [Hash] The payment parameters with the +:merchant_signature+ parameter set. - # @raise [StandardError] Thrown if some parameter health check fails. + # @raise [ArgumentError] Thrown if some parameter health check fails. 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] + 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 "Cannot calculate payment request signature without shared secret!" unless shared_secret + raise ArgumentError, "Cannot calculate payment request signature without shared secret!" unless shared_secret parameters[:merchant_sig] = calculate_signature(parameters, shared_secret) return parameters end # 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 - # {Adyen::Form.default_parameters} hash. The default parameter values will be overrided - # if another value is provided to this method. + # {Adyen::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. # @@ -204,19 +124,19 @@ # # @param [Hash] parameters The payment parameters to include in the payment request. # @return [String] An absolute URL to redirect to the Adyen payment system. def redirect_url(parameters = {}) url + '?' + payment_parameters(parameters).map { |(k, v)| - "#{k.to_s.camelize(:lower)}=#{CGI.escape(v.to_s)}" }.join('&') + "#{camelize(k)}=#{CGI.escape(v.to_s)}" }.join('&') end # 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 - # {Adyen::Form.default_parameters} hash. The default parameter values will be overrided - # if another value is provided to this method. + # {Adyen::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. # @@ -232,11 +152,11 @@ # Adyen payment system. 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) + "<input type=\"hidden\" name=\"#{CGI.escapeHTML(camelize(key))}\" value=\"#{CGI.escapeHTML(value.to_s)}\" />" }.join("\n") form_str.respond_to?(:html_safe) ? form_str.html_safe : form_str end @@ -295,11 +215,11 @@ # @param [String] shared_secret The shared secret for the Adyen skin that was used for # the original payment form. You can leave this out of the skin is registered # using the {Adyen::Form.register_skin} method. # @return [String] The redirect signature def redirect_signature(params, shared_secret = nil) - shared_secret ||= lookup_shared_secret(params[:skinCode]) + shared_secret ||= Adyen.configuration.form_skin_shared_secret_by_code(params[:skinCode]) Adyen::Encoding.hmac_base64(shared_secret, redirect_signature_string(params)) end # 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+ @@ -327,12 +247,20 @@ # # @param [Hash] params params A hash of HTTP GET parameters for the redirect request. This # should include the +:merchantSig+ parameter, which contains the signature. # @param [String] shared_secret The shared secret for the Adyen skin that was used for # the original payment form. You can leave this out of the skin is registered - # using the {Adyen::Form.register_skin} method. + # using the {Adyen::Configuration#register_form_skin} method. # @return [true, false] Returns true only if the signature in the parameters is correct. def redirect_signature_check(params, shared_secret = nil) params[:merchantSig] == redirect_signature(params, shared_secret) end + + # Returns the camelized version of a string. + # @param [:to_s] identifier The identifier to turn to camelcase + # @return [String] The camelcase version of the identifier provided. + def camelize(identifier) + identifier.to_s.gsub(/_(.)/) { $1.upcase } + end + end end