require "nokogiri" module ActiveMerchant #:nodoc: module Billing #:nodoc: class HdfcGateway < Gateway self.display_name = "HDFC" self.homepage_url = "http://www.hdfcbank.com/sme/sme-details/merchant-services/guzh6m0i" self.test_url = "https://securepgtest.fssnet.co.in/pgway/servlet/" self.live_url = "https://securepg.fssnet.co.in/pgway/servlet/" self.supported_countries = ["IN"] self.default_currency = "INR" self.money_format = :dollars self.supported_cardtypes = [:visa, :master, :discover, :diners_club] def initialize(options={}) requires!(options, :login, :password) super end def purchase(amount, payment_method, options={}) post = {} add_invoice(post, amount, options) add_payment_method(post, payment_method) add_customer_data(post, options) commit("purchase", post) end def authorize(amount, payment_method, options={}) post = {} add_invoice(post, amount, options) add_payment_method(post, payment_method) add_customer_data(post, options) commit("authorize", post) end def capture(amount, authorization, options={}) post = {} add_invoice(post, amount, options) add_reference(post, authorization) add_customer_data(post, options) commit("capture", post) end def refund(amount, authorization, options={}) post = {} add_invoice(post, amount, options) add_reference(post, authorization) add_customer_data(post, options) commit("refund", post) end private CURRENCY_CODES = Hash.new{|h,k| raise ArgumentError.new("Unsupported currency for HDFC: #{k}")} CURRENCY_CODES["AED"] = "784" CURRENCY_CODES["AUD"] = "036" CURRENCY_CODES["CAD"] = "124" CURRENCY_CODES["EUR"] = "978" CURRENCY_CODES["GBP"] = "826" CURRENCY_CODES["INR"] = "356" CURRENCY_CODES["OMR"] = "512" CURRENCY_CODES["QAR"] = "634" CURRENCY_CODES["SGD"] = "702" CURRENCY_CODES["USD"] = "840" def add_invoice(post, amount, options) post[:amt] = amount(amount) post[:currencycode] = CURRENCY_CODES[options[:currency] || currency(amount)] post[:trackid] = escape(options[:order_id], 40) if options[:order_id] post[:udf1] = escape(options[:description]) if options[:description] post[:eci] = options[:eci] if options[:eci] end def add_customer_data(post, options) post[:udf2] = escape(options[:email]) if options[:email] if address = (options[:billing_address] || options[:address]) post[:udf3] = escape(address[:phone]) if address[:phone] post[:udf4] = escape(< "1", "refund" => "2", "authorize" => "4", "capture" => "5", } def commit(action, post) post[:id] = @options[:login] post[:password] = @options[:password] post[:action] = ACTIONS[action] if ACTIONS[action] raw = parse(ssl_post(url(action), build_request(post))) succeeded = success_from(raw[:result]) Response.new( succeeded, message_from(succeeded, raw), raw, :authorization => authorization_from(post, raw), :test => test? ) end def build_request(post) xml = Builder::XmlMarkup.new :indent => 2 xml.instruct! post.each do |field, value| xml.tag!(field, value) end xml.target! end def url(action) endpoint = "TranPortalXMLServlet" (test? ? test_url : live_url) + endpoint end def success_from(result) case result when "CAPTURED", "APPROVED", "NOT ENROLLED", "ENROLLED" true else false end end def message_from(succeeded, response) if succeeded "Succeeded" else (response[:error_text] || response[:result] || "Unable to read error message").split("-").last end end def authorization_from(request, response) [response[:tranid], request[:member]].join("|") end def split_authorization(authorization) tranid, member = authorization.split("|") [tranid, member] end def escape(string, max_length=250) return "" unless string if max_length string = string[0...max_length] end string.gsub(/[^A-Za-z0-9 \-_@\.\n]/, '') end end end end