class ActiveMerchant::Billing::CecabankXmlGateway

Constants

CECA_ACTION_PURCHASE
CECA_ACTION_REFUND
CECA_DECIMALS
CECA_MODE
CECA_NOTIFICATIONS_URL

CECA’s MAGIC NUMBERS

CECA_UI_LESS_LANGUAGE
CECA_UI_LESS_LANGUAGE_REFUND
CECA_UI_LESS_REFUND_PAGE

Public Instance Methods

purchase(money, creditcard, options = {}) click to toggle source

Perform a purchase, which is essentially an authorization and capture in a single operation.

Parameters

  • money – The amount to be purchased as an Integer value in cents.

  • creditcard – The CreditCard details for the transaction.

  • options – A hash of optional parameters.

Options

  • :order_id – order_id passed used purchase. (REQUIRED)

  • :currency – currency. Supported: EUR, USD, GBP.

  • :description – description to be pased to the gateway.

# File lib/active_merchant/billing/gateways/cecabank/cecabank_xml.rb, line 34
def purchase(money, creditcard, options = {})
  requires!(options, :order_id)

  post = { 'Descripcion' => options[:description],
          'Num_operacion' => options[:order_id],
          'Idioma' => CECA_UI_LESS_LANGUAGE,
          'Pago_soportado' => CECA_MODE,
          'URL_OK' => CECA_NOTIFICATIONS_URL,
          'URL_NOK' => CECA_NOTIFICATIONS_URL,
          'Importe' => amount(money),
          'TipoMoneda' => CECA_CURRENCIES_DICTIONARY[options[:currency] || currency(money)] }

  add_creditcard(post, creditcard)

  commit(CECA_ACTION_PURCHASE, post)
end
refund(money, identification, options = {}) click to toggle source

Refund a transaction.

This transaction indicates to the gateway that money should flow from the merchant to the customer.

Parameters

  • money – The amount to be credited to the customer as an Integer value in cents.

  • identification – The reference given from the gateway on purchase (reference, not operation).

  • options – A hash of parameters.

# File lib/active_merchant/billing/gateways/cecabank/cecabank_xml.rb, line 61
def refund(money, identification, options = {})
  reference, order_id = split_authorization(identification)

  post = { 'Referencia' => reference,
          'Num_operacion' => order_id,
          'Idioma' => CECA_UI_LESS_LANGUAGE_REFUND,
          'Pagina' => CECA_UI_LESS_REFUND_PAGE,
          'Importe' => amount(money),
          'TipoMoneda' => CECA_CURRENCIES_DICTIONARY[options[:currency] || currency(money)] }

  commit(CECA_ACTION_REFUND, post)
end
scrub(transcript) click to toggle source
# File lib/active_merchant/billing/gateways/cecabank/cecabank_xml.rb, line 74
def scrub(transcript)
  transcript.
    gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]').
    gsub(%r((&?pan=)[^&]*)i, '\1[FILTERED]').
    gsub(%r((&?cvv2=)[^&]*)i, '\1[FILTERED]')
end

Private Instance Methods

add_creditcard(post, creditcard) click to toggle source
# File lib/active_merchant/billing/gateways/cecabank/cecabank_xml.rb, line 83
def add_creditcard(post, creditcard)
  post['PAN'] = creditcard.number
  post['Caducidad'] = expdate(creditcard)
  post['CVV2'] = creditcard.verification_value
  post['Pago_elegido'] = CECA_MODE
end
build_authorization(response) click to toggle source
# File lib/active_merchant/billing/gateways/cecabank/cecabank_xml.rb, line 181
def build_authorization(response)
  [response[:reference], response[:authorization]].join('|')
end
commit(action, parameters) click to toggle source
# File lib/active_merchant/billing/gateways/cecabank/cecabank_xml.rb, line 131
def commit(action, parameters)
  parameters.merge!(
    'Cifrado' => CECA_ENCRIPTION,
    'Firma' => generate_signature(action, parameters),
    'Exponente' => CECA_DECIMALS,
    'MerchantID' => options[:merchant_id],
    'AcquirerBIN' => options[:acquirer_bin],
    'TerminalID' => options[:terminal_id]
  )
  url = (test? ? self.test_url : self.live_url) + "/tpvweb/#{action}.action"
  xml = ssl_post("#{url}?", post_data(parameters))
  response = parse(xml)
  Response.new(
    response[:success],
    message_from(response),
    response,
    test: test?,
    authorization: build_authorization(response),
    error_code: response[:error_code]
  )
end
expdate(creditcard) click to toggle source
# File lib/active_merchant/billing/gateways/cecabank/cecabank_xml.rb, line 90
def expdate(creditcard)
  "#{format(creditcard.year, :four_digits)}#{format(creditcard.month, :two_digits)}"
end
generate_signature(action, parameters) click to toggle source
# File lib/active_merchant/billing/gateways/cecabank/cecabank_xml.rb, line 189
def generate_signature(action, parameters)
  signature_fields =
    case action
    when CECA_ACTION_REFUND
      options[:signature_key].to_s +
      options[:merchant_id].to_s +
      options[:acquirer_bin].to_s +
      options[:terminal_id].to_s +
      parameters['Num_operacion'].to_s +
      parameters['Importe'].to_s +
      parameters['TipoMoneda'].to_s +
      CECA_DECIMALS +
      parameters['Referencia'].to_s +
      CECA_ENCRIPTION
    else
      options[:signature_key].to_s +
      options[:merchant_id].to_s +
      options[:acquirer_bin].to_s +
      options[:terminal_id].to_s +
      parameters['Num_operacion'].to_s +
      parameters['Importe'].to_s +
      parameters['TipoMoneda'].to_s +
      CECA_DECIMALS +
      CECA_ENCRIPTION +
      CECA_NOTIFICATIONS_URL +
      CECA_NOTIFICATIONS_URL
    end
  Digest::SHA2.hexdigest(signature_fields)
end
message_from(response) click to toggle source
# File lib/active_merchant/billing/gateways/cecabank/cecabank_xml.rb, line 153
def message_from(response)
  if response[:message] == 'ERROR' && response[:error_message]
    response[:error_message]
  elsif response[:error_message]
    "#{response[:message]} #{response[:error_message]}"
  else
    response[:message]
  end
end
parse(body) click to toggle source
# File lib/active_merchant/billing/gateways/cecabank/cecabank_xml.rb, line 94
def parse(body)
  response = {}

  root = REXML::Document.new(body).root

  response[:success] = (root.attributes['valor'] == 'OK')
  response[:date] = root.attributes['fecha']
  response[:operation_number] = root.attributes['numeroOperacion']
  response[:message] = root.attributes['valor']

  if root.elements['OPERACION']
    response[:operation_type] = root.elements['OPERACION'].attributes['tipo']
    response[:amount] = root.elements['OPERACION/importe'].text.strip
  end

  response[:description] = root.elements['OPERACION/descripcion'].text if root.elements['OPERACION/descripcion']
  response[:authorization_number] = root.elements['OPERACION/numeroAutorizacion'].text if root.elements['OPERACION/numeroAutorizacion']
  response[:reference] = root.elements['OPERACION/referencia'].text if root.elements['OPERACION/referencia']
  response[:pan] = root.elements['OPERACION/pan'].text if root.elements['OPERACION/pan']

  if root.elements['ERROR']
    response[:error_code] = root.elements['ERROR/codigo'].text
    response[:error_message] = root.elements['ERROR/descripcion'].text
  elsif root.elements['OPERACION'].attributes['numeroOperacion'] == '000'
    response[:authorization] = root.elements['OPERACION/numeroAutorizacion'].text if root.elements['OPERACION/numeroAutorizacion']
  else
    response[:authorization] = root.attributes['numeroOperacion']
  end

  return response
rescue REXML::ParseException => e
  response[:success] = false
  response[:message] = 'Unable to parse the response.'
  response[:error_message] = e.message
  response
end
post_data(params) click to toggle source
# File lib/active_merchant/billing/gateways/cecabank/cecabank_xml.rb, line 163
def post_data(params)
  return nil unless params

  params.map do |key, value|
    next if value.blank?

    if value.is_a?(Hash)
      h = {}
      value.each do |k, v|
        h["#{key}.#{k}"] = v unless v.blank?
      end
      post_data(h)
    else
      "#{key}=#{CGI.escape(value.to_s)}"
    end
  end.compact.join('&')
end
split_authorization(authorization) click to toggle source
# File lib/active_merchant/billing/gateways/cecabank/cecabank_xml.rb, line 185
def split_authorization(authorization)
  authorization.split('|')
end