require 'digest/md5' module ActiveMerchant #:nodoc: module Billing #:nodoc: class NetaxeptGateway < Gateway self.test_url = 'https://epayment-test.bbs.no/' self.live_url = 'https://epayment.bbs.no/' # The countries the gateway supports merchants from as 2 digit ISO country codes self.supported_countries = ['NO', 'DK', 'SE', 'FI'] # The card types supported by the payment gateway self.supported_cardtypes = [:visa, :master, :american_express] # The homepage URL of the gateway self.homepage_url = 'http://www.betalingsterminal.no/Netthandel-forside/' # The name of the gateway self.display_name = 'BBS Netaxept' self.money_format = :cents self.default_currency = 'NOK' def initialize(options = {}) requires!(options, :login, :password) super end def purchase(money, creditcard, options = {}) requires!(options, :order_id) MultiResponse.run do |r| r.process { authorize(money, creditcard, options) } r.process { capture(money, r.authorization, options) } end end def authorize(money, creditcard, options = {}) requires!(options, :order_id) MultiResponse.run do |r| r.process { setup_transaction(money, options) } r.process { add_and_auth_credit_card(r.authorization, creditcard, options) } r.process { query_transaction(r.authorization, options) } end end def capture(money, authorization, options = {}) post = {} add_credentials(post, options) add_authorization(post, authorization, money) post[:operation] = 'Capture' commit('Netaxept/process.aspx', post) end def refund(money, authorization, options = {}) post = {} add_credentials(post, options) add_authorization(post, authorization, money) post[:operation] = 'Credit' commit('Netaxept/process.aspx', post) end def void(authorization, options = {}) post = {} add_credentials(post, options) add_authorization(post, authorization) post[:operation] = 'Annul' commit('Netaxept/process.aspx', post) end private def setup_transaction(money, options) post = {} add_credentials(post, options) add_order(post, money, options) commit('Netaxept/Register.aspx', post) end def add_and_auth_credit_card(authorization, creditcard, options) post = {} add_credentials(post, options, false) add_authorization(post, authorization) add_creditcard(post, creditcard) commit('terminal/default.aspx', post, false) end def query_transaction(authorization, options) post = {} add_credentials(post, options) add_authorization(post, authorization) commit('Netaxept/query.aspx', post) end def add_credentials(post, options, secure=true) post[:merchantId] = @options[:login] post[:token] = @options[:password] if secure end def add_authorization(post, authorization, money=nil) post[:transactionId] = authorization post[:transactionAmount] = amount(money) if money end def add_order(post, money, options) post[:serviceType] = 'M' post[:orderNumber] = options[:order_id] post[:amount] = amount(money) post[:currencyCode] = (options[:currency] || currency(money)) post[:autoAuth] = 'true' end def add_creditcard(post, options) post[:pan] = options.number post[:expiryDate] = format(options.month, :two_digits) + format(options.year, :two_digits) post[:securityCode] = options.verification_value end def commit(path, parameters, xml=true) raw = parse(ssl_get(build_url(path, parameters)), xml) success = false authorization = (raw['TransactionId'] || parameters[:transactionId]) if raw[:container] =~ /Exception|Error/ message = (raw['Message'] || raw['Error']['Message']) elsif raw['Error'] && !raw['Error'].empty? message = (raw['Error']['ResponseText'] || raw['Error']['ResponseCode']) else message = (raw['ResponseText'] || raw['ResponseCode'] || 'OK') success = true end Response.new( success, message, raw, :test => test?, :authorization => authorization ) end def parse(result, expects_xml=true) if expects_xml doc = REXML::Document.new(result) extract_xml(doc.root).merge(:container => doc.root.name) else {:result => result} end end def extract_xml(element) if element.has_elements? hash = {} element.elements.each do |e| hash[e.name] = extract_xml(e) end hash else element.text end end def build_url(base, parameters=nil) url = (test? ? self.test_url : self.live_url).dup url << base if parameters url << '?' url << encode(parameters) end url end def encode(hash) hash.collect { |(k, v)| "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}" }.join('&') end end end end