class Robokassa::Interface
Public Class Methods
Fail callback requiest handler It requires Robokassa::Interface.fail_implementation to be inmplemented by user
# File lib/robokassa/interface.rb, line 65 def self.fail(params, controller) parsed_params = map_params(params, @@notification_params_map) fail_implementation( parsed_params[:invoice_id], parsed_params[:amount], parsed_params[:language], parsed_params[:custom_options], controller) end
Maps gem parameter names, to robokassa names
# File lib/robokassa/interface.rb, line 338 def self.map_params(params, map) Hash[params.map do|key, value| [(map[key] || map[key.to_sym] || key), value] end] end
Handler for success api callback this method calls from RobokassaController It requires Robokassa::Interface.success_implementation to be inmplemented by user
# File lib/robokassa/interface.rb, line 53 def self.success(params, controller) parsed_params = map_params(params, @@notification_params_map) success_implementation( parsed_params[:invoice_id], parsed_params[:amount], parsed_params[:language], parsed_params[:custom_options], controller) end
Public Instance Methods
returns test.robokassa.ru or merchant.roboxchange.com in order to current mode
# File lib/robokassa/interface.rb, line 288 def base_url test_mode? ? 'http://test.robokassa.ru' : 'https://merchant.roboxchange.com' end
# File lib/robokassa/interface.rb, line 191 def currencies @cache[:currencies] ||= Hash[currencies_long.map do |key, value| [key, { :description => value[:description], :currencies => value[:currencies] }] end] end
# File lib/robokassa/interface.rb, line 162 def currencies_long return @cache[:currencies_long] if @cache[:currencies_long] xml = get_remote_xml(currencies_url) if xml.elements['CurrenciesList/Result/Code'].text != '0' raise (a=xml.elements['CurrenciesList/Result/Description']) ? a.text : "Unknown error" end @cache[:currencies_long] = Hash[xml.elements.each('CurrenciesList/Groups/Group'){}.map do|g| code = g.attributes['Code'] description = g.attributes['Description'] [ code, { :code => code, :description => description, :currencies => Hash[g.elements.each('Items/Currency'){}.map do|c| label = c.attributes['Label'] name = c.attributes['Name'] [label, { :currency => label, :currency_description => name, :group => code, :group_description => description }] end] } ] end] end
# File lib/robokassa/interface.rb, line 246 def currencies_options map_params(subhash(@options, %w{login language}), @@service_params_map) end
# File lib/robokassa/interface.rb, line 242 def currencies_url @cache[:get_currencies_url] ||= "#{xml_services_base_url}/GetCurrencies?#{query_string(currencies_options)}" end
make request and parse XML from specified url
# File lib/robokassa/interface.rb, line 353 def get_remote_xml(url) # xml_data = Net::HTTP.get_response(URI.parse(url)).body begin xml_data = URI.parse(url).read doc = REXML::Document.new(xml_data) rescue REXML::ParseException => e sleep 1 get_remote_xml(url) end end
returns url to redirect user to payment page
# File lib/robokassa/interface.rb, line 293 def init_payment_base_url "#{base_url}/Index.aspx" end
make hash of options for init_payment_url
# File lib/robokassa/interface.rb, line 251 def init_payment_options(invoice_id, amount, description, custom_options = {}, currency='', language='ru', email='') options = { :login => @options[:login], :amount => amount.to_s, :invoice_id => invoice_id, :description => description[0, 100], :signature => init_payment_signature(invoice_id, amount, description, custom_options), :currency => currency, :email => email, :language => language }.merge(Hash[custom_options.sort.map{|x| ["shp#{x[0]}", x[1]]}]) map_params(options, @@params_map) end
calculates md5 from result of :init_payment_signature_string
# File lib/robokassa/interface.rb, line 277 def init_payment_signature(invoice_id, amount, description, custom_options={}) md5 init_payment_signature_string(invoice_id, amount, description, custom_options) end
generates signature string to calculate ‘SignatureValue’ url parameter
# File lib/robokassa/interface.rb, line 282 def init_payment_signature_string(invoice_id, amount, description, custom_options={}) custom_options_fmt = custom_options.sort.map{|x|"shp#{x[0]}=#{x[1]}"}.join(":") "#{@options[:login]}:#{amount}:#{invoice_id}:#{@options[:password1]}#{unless custom_options_fmt.blank? then ":" + custom_options_fmt else "" end}" end
Generates url for payment page
Example¶ ↑
<%= link_to “Pay with Robokassa”, interface.init_payment_url(order.id, order.amount, “Order #{order.id}”, ”, ‘ru’, order.user.email) %>
# File lib/robokassa/interface.rb, line 81 def init_payment_url(invoice_id, amount, description, currency='', language='ru', email='', custom_options={}) url_options = init_payment_options(invoice_id, amount, description, custom_options, currency, language, email) "#{init_payment_base_url}?" + url_options.map do |k, v| "#{CGI::escape(k.to_s)}=#{CGI::escape(v.to_s)}" end.join('&') end
for testing
Example¶ ↑
i.default_url_options = { :host => ‘127.0.0.1’, :port => 3000 } i.notification_url # => ‘127.0.0.1:3000/robokassa/asfadsf/notify’
# File lib/robokassa/interface.rb, line 204 def notification_url robokassa_notification_url :notification_key => @options[:notification_key] end
This method verificates request params recived from robocassa server
# File lib/robokassa/interface.rb, line 40 def notify(params, controller) parsed_params = map_params(params, @@notification_params_map) notify_implementation( parsed_params[:invoice_id], parsed_params[:amount], parsed_params[:custom_options], controller) "OK#{parsed_params[:invoice_id]}" end
for testing
# File lib/robokassa/interface.rb, line 214 def on_fail_url robokassa_on_fail_url end
for testing
# File lib/robokassa/interface.rb, line 209 def on_success_url robokassa_on_success_url end
# File lib/robokassa/interface.rb, line 25 def owner @options[:owner] end
# File lib/robokassa/interface.rb, line 218 def parse_response_params(params) parsed_params = map_params(params, @@notification_params_map) parsed_params[:custom_options] = Hash[args.select do |k,v| o.starts_with?('shp') end.sort.map do|k, v| [k[3, k.size], v] end] if response_signature(parsed_params)!=parsed_params[:signature].downcase raise "Invalid signature" end end
# File lib/robokassa/interface.rb, line 238 def payment_methods_options map_params(subhash(@options, %w{login language}), @@service_params_map) end
# File lib/robokassa/interface.rb, line 234 def payment_methods_url @cache[:get_currencies_url] ||= "#{xml_services_base_url}/GetPaymentMethods?#{query_string(payment_methods_options)}" end
# File lib/robokassa/interface.rb, line 130 def rates(amount, currency='') cache_key = "rates_#{currency}_#{amount}" @cache[cache_key] ||= Hash[rates_long(amount, currency).map do |key, value| [key, { :description => value[:description], :currencies => Hash[(value[:currencies] || []).map do |k, v| [k, v] end] }] end] end
# File lib/robokassa/interface.rb, line 142 def rates_linear(amount, currency='') cache_key = "rates_linear#{currency}_#{amount}" @cache[cache_key] ||= begin retval = rates(amount, currency).map do |group| group_name, group = group group[:currencies].map do |currency| currency_name, currency = currency { :name => currency_name, :desc => currency[:currency_description], :group_name => group[:name], :group_desc => group[:description], :amount => currency[:amount] } end end Hash[retval.flatten.map { |v| [v[:name], v] }] end end
# File lib/robokassa/interface.rb, line 98 def rates_long(amount, currency='') cache_key = "rates_long_#{currency}_#{amount}" return @cache[cache_key] if @cache[cache_key] xml = get_remote_xml(rates_url(amount, currency)) if xml.elements['RatesList/Result/Code'].text != '0' raise (a=xml.elements['RatesList/Result/Description']) ? a.text : "Unknown error" end @cache[cache_key] = Hash[xml.elements.each('RatesList/Groups/Group'){}.map do|g| code = g.attributes['Code'] description = g.attributes['Description'] [ code, { :code => code, :description => description, :currencies => Hash[g.elements.each('Items/Currency'){}.map do|c| label = c.attributes['Label'] name = c.attributes['Name'] [label, { :currency => label, :currency_description => name, :group => code, :group_description => description, :amount => BigDecimal.new(c.elements['Rate'].attributes['IncSum']) }] end] } ] end] end
# File lib/robokassa/interface.rb, line 230 def rates_options(amount, currency) map_params(subhash(@options.merge(:amount=>amount, :currency=>currency), %w{login language amount currency}), @@service_params_map) end
# File lib/robokassa/interface.rb, line 226 def rates_url(amount, currency) "#{xml_services_base_url}/GetRates?#{query_string(rates_options(amount, currency))}" end
calculates signature to check params from Robokassa
# File lib/robokassa/interface.rb, line 266 def response_signature(parsed_params) md5 response_signature_string(parsed_params) end
build signature string
# File lib/robokassa/interface.rb, line 271 def response_signature_string(parsed_params) custom_options_fmt = custom_options.sort.map{|x|"shp#{x[0]}=x[1]]"}.join(":") "#{parsed_params[:amount]}:#{parsed_params[:invoice_id]}:#{@options[:password2]}#{unless custom_options_fmt.blank? then ":" + custom_options_fmt else "" end}" end
returns base url for API access
# File lib/robokassa/interface.rb, line 298 def xml_services_base_url "#{base_url}/WebService/Service.asmx" end