module ActiveMerchant #:nodoc: module Billing #:nodoc: class SoEasyPayGateway < Gateway self.live_url = self.test_url = 'https://secure.soeasypay.com/gateway.asmx' self.money_format = :cents self.supported_countries = [ 'US', 'CA', 'AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE', 'GB', 'IS', 'NO', 'CH' ] self.supported_cardtypes = [:visa, :master, :american_express, :discover, :maestro, :jcb, :diners_club] self.homepage_url = 'http://www.soeasypay.com/' self.display_name = 'SoEasyPay' def initialize(options = {}) requires!(options, :login, :password) super end def authorize(money, payment_source, options = {}) if payment_source.respond_to?(:number) commit('AuthorizeTransaction', do_authorization(money, payment_source, options), options) else commit('ReauthorizeTransaction', do_reauthorization(money, payment_source, options), options) end end def purchase(money, payment_source, options = {}) if payment_source.respond_to?(:number) commit('SaleTransaction', do_sale(money, payment_source, options), options) else commit('RebillTransaction', do_rebill(money, payment_source, options), options) end end def capture(money, authorization, options = {}) commit('CaptureTransaction', do_capture(money, authorization, options), options) end def refund(money, authorization, options={}) commit('RefundTransaction', do_refund(money, authorization, options), options) end def void(authorization, options={}) commit('CancelTransaction', do_void(authorization, options), options) end private def do_authorization(money, card, options) build_soap('AuthorizeTransaction') do |soap| fill_credentials(soap, options) fill_order_info(soap, money, options) fill_cardholder(soap, card, options) fill_card(soap, card) end end def do_sale(money, card, options) build_soap('SaleTransaction') do |soap| fill_credentials(soap, options) fill_order_info(soap, money, options) fill_cardholder(soap, card, options) fill_card(soap, card) end end def do_reauthorization(money, authorization, options) build_soap('ReauthorizeTransaction') do |soap| fill_credentials(soap, options) fill_order_info(soap, money, options) fill_transaction_id(soap, authorization) end end def do_rebill(money, authorization, options) build_soap('RebillTransaction') do |soap| fill_credentials(soap, options) fill_order_info(soap, money, options) fill_transaction_id(soap, authorization) end end def do_capture(money, authorization, options) build_soap('CaptureTransaction') do |soap| fill_credentials(soap, options) fill_order_info(soap, money, options, :no_currency) fill_transaction_id(soap, authorization) end end def do_refund(money, authorization, options) build_soap('RefundTransaction') do |soap| fill_credentials(soap, options) fill_order_info(soap, money, options, :no_currency) fill_transaction_id(soap, authorization) end end def do_void(authorization, options) build_soap('CancelTransaction') do |soap| fill_credentials(soap, options) fill_transaction_id(soap, authorization) end end def fill_credentials(soap, options) soap.tag!('websiteID', @options[:login].to_s) soap.tag!('password', @options[:password].to_s) end def fill_cardholder(soap, card, options) ch_info = options[:billing_address] || options[:address] soap.tag!('customerIP', options[:ip].to_s) name = card.name || ch_info[:name] soap.tag!('cardHolderName', name.to_s) address = ch_info[:address1] || '' address << ch_info[:address2] if ch_info[:address2] soap.tag!('cardHolderAddress', address.to_s) soap.tag!('cardHolderZipcode', ch_info[:zip].to_s) soap.tag!('cardHolderCity', ch_info[:city].to_s) soap.tag!('cardHolderState', ch_info[:state].to_s) soap.tag!('cardHolderCountryCode', ch_info[:country].to_s) soap.tag!('cardHolderPhone', ch_info[:phone].to_s) soap.tag!('cardHolderEmail', options[:email].to_s) end def fill_transaction_id(soap, transaction_id) soap.tag!('transactionID', transaction_id.to_s) end def fill_card(soap, card) soap.tag!('cardNumber', card.number.to_s) soap.tag!('cardSecurityCode', card.verification_value.to_s) soap.tag!('cardExpireMonth', card.month.to_s.rjust(2, '0')) soap.tag!('cardExpireYear', card.year.to_s) end def fill_order_info(soap, money, options, skip_currency=false) soap.tag!('orderID', options[:order_id].to_s) soap.tag!('orderDescription', "Order #{options[:order_id]}") soap.tag!('amount', amount(money).to_s) soap.tag!('currency', (options[:currency] || currency(money)).to_s) unless skip_currency end def parse(response, action) result = {} document = REXML::Document.new(response) response_element = document.root.get_elements("//[@xsi:type='tns:#{action}Response']").first response_element.elements.each do |element| result[element.name.underscore] = element.text end result end def commit(soap_action, soap, options) headers = {'SOAPAction' => "\"urn:Interface##{soap_action}\"", 'Content-Type' => 'text/xml; charset=utf-8'} response_string = ssl_post(test? ? self.test_url : self.live_url, soap, headers) response = parse(response_string, soap_action) return Response.new(response['errorcode'] == '000', response['errormessage'], response, test: test?, authorization: response['transaction_id']) end def build_soap(request) retval = Builder::XmlMarkup.new(indent: 2) retval.instruct!(:xml, version: '1.0', encoding: 'utf-8') retval.tag!('soap:Envelope', { 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema', 'xmlns:soapenc' => 'http://schemas.xmlsoap.org/soap/encoding/', 'xmlns:tns' => 'urn:Interface', 'xmlns:types' => 'urn:Interface/encodedTypes', 'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/' }) do retval.tag!('soap:Body', {'soap:encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/'}) do retval.tag!("tns:#{request}") do retval.tag!("#{request}Request", {'xsi:type' => "tns:#{request}Request"}) do yield retval end end end end retval.target! end end end end