module ActiveMerchant #:nodoc: module Billing #:nodoc: class PaySecureGateway < Gateway self.live_url = self.test_url = 'https://clearance.commsecure.com.au/cgi-bin/PSDirect' self.money_format = :cents # Currently Authorization and Capture is not implemented because # capturing requires the original credit card information TRANSACTIONS = { :purchase => 'PURCHASE', :authorization => 'AUTHORISE', :capture => 'ADVICE', :credit => 'REFUND' } SUCCESS = 'Accepted' SUCCESS_MESSAGE = 'The transaction was approved' self.supported_countries = ['AU'] self.homepage_url = 'http://www.commsecure.com.au/paysecure.shtml' self.display_name = 'PaySecure' self.supported_cardtypes = [:visa, :master, :american_express, :diners_club] def initialize(options = {}) requires!(options, :login, :password) super end def purchase(money, credit_card, options = {}) requires!(options, :order_id) post = {} add_amount(post, money) add_invoice(post, options) add_credit_card(post, credit_card) commit(:purchase, money, post) end private # Used for capturing, which is currently not supported. def add_reference(post, identification) auth, trans_id = identification.split(";") post[:authnum] = auth post[:transid] = trans_id end def add_amount(post, money) post[:amount] = amount(money) end def add_invoice(post, options) post[:merchant_transid] = options[:order_id].to_s.slice(0,21) post[:memnum] = options[:invoice] post[:custnum] = options[:customer] post[:clientdata] = options[:description] end def add_credit_card(post, credit_card) post[:cardnum] = credit_card.number post[:cardname] = credit_card.name post[:expiry] = expdate(credit_card) post[:cvv2] = credit_card.verification_value end def expdate(credit_card) year = sprintf("%.4i", credit_card.year) month = sprintf("%.2i", credit_card.month) "#{month}#{year[-2..-1]}" end def commit(action, money, parameters) response = parse( ssl_post(self.live_url, post_data(action, parameters)) ) Response.new(successful?(response), message_from(response), response, :test => test_response?(response), :authorization => authorization_from(response) ) end def successful?(response) response[:status] == SUCCESS end def authorization_from(response) [ response[:authnum], response[:transid] ].compact.join(";") end def test_response?(response) !!(response[:transid] =~ /SimProxy/) end def message_from(response) successful?(response) ? SUCCESS_MESSAGE : response[:errorstring] end def parse(body) response = {} body.to_s.each_line do |l| key, value = l.split(":", 2) response[key.to_s.downcase.to_sym] = value.strip end response end def post_data(action, parameters = {}) parameters[:request_type] = TRANSACTIONS[action] parameters[:merchant_id] = @options[:login] parameters[:password] = @options[:password] parameters.reject{|k,v| v.blank?}.collect { |key, value| "#{key.to_s.upcase}=#{CGI.escape(value.to_s)}" }.join("&") end end end end