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 = %i[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 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