class ActiveMerchant::Billing::RedsysGateway

Redsys Merchant Gateway

Gateway support for the Spanish “Redsys” payment gateway system. This is used by many banks in Spain and is particularly well supported by Catalunya Caixa’s ecommerce department.

Redsys requires an order_id be provided with each transaction and it must follow a specific format. The rules are as follows:

* First 4 digits must be numerical
* Remaining 8 digits may be alphanumeric
* Max length: 12

If an invalid order_id is provided, we do our best to clean it up.

Much of the code for this library is based on the active_merchant_sermepa integration gateway which uses essentially the same API but with the banks own payment screen.

Written by Samuel Lown for Cabify. For implementation questions, or test access details please get in touch: sam@cabify.com.

*** SHA256 Authentication Update ***

Redsys is dropping support for the SHA1 authentication method. This adapter has been updated to work with the new SHA256 authentication method, however in your initialization options hash you will need to specify the key/value :signature_algorithm => “sha256” to use the SHA256 method. Otherwise it will default to using the SHA1.

Constants

CURRENCY_CODES
RESPONSE_TEXTS

These are the text meanings sent back by the acquirer when a card has been rejected. Syntax or general request errors are not covered here.

SUPPORTED_TRANSACTIONS

The set of supported transactions for this gateway. More operations are supported by the gateway itself, but are not supported in this library.

THREE_DS_V1

Expected values as per documentation

THREE_DS_V2

Public Class Methods

new(options = {}) click to toggle source

Creates a new instance

Redsys requires a login and secret_key, and optionally also accepts a non-default terminal.

Options

  • :login – The Redsys Merchant ID (REQUIRED)

  • :secret_key – The Redsys Secret Key. (REQUIRED)

  • :terminal – The Redsys Terminal. Defaults to 1. (OPTIONAL)

  • :testtrue or false. Defaults to false. (OPTIONAL)

  • :signature_algorithm – +“sha256”+ Defaults to +“sha1”+. (OPTIONAL)

Calls superclass method ActiveMerchant::Billing::Gateway::new
# File lib/active_merchant/billing/gateways/redsys.rb, line 190
def initialize(options = {})
  requires!(options, :login, :secret_key)
  options[:terminal] ||= 1
  options[:signature_algorithm] ||= 'sha1'
  super
end

Public Instance Methods

authorize(money, payment, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 216
def authorize(money, payment, options = {})
  requires!(options, :order_id)

  data = {}
  add_action(data, :authorize, options)
  add_amount(data, money, options)
  add_order(data, options[:order_id])
  add_payment(data, payment)
  add_external_mpi_fields(data, options)
  add_three_ds_data(data, options) if options[:execute_threed]
  add_stored_credential_options(data, options)
  data[:description] = options[:description]
  data[:store_in_vault] = options[:store]
  data[:sca_exemption] = options[:sca_exemption]
  data[:sca_exemption_direct_payment_enabled] = options[:sca_exemption_direct_payment_enabled]

  commit data, options
end
capture(money, authorization, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 235
def capture(money, authorization, options = {})
  data = {}
  add_action(data, :capture)
  add_amount(data, money, options)
  order_id, = split_authorization(authorization)
  add_order(data, order_id)
  data[:description] = options[:description]

  commit data, options
end
purchase(money, payment, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 197
def purchase(money, payment, options = {})
  requires!(options, :order_id)

  data = {}
  add_action(data, :purchase, options)
  add_amount(data, money, options)
  add_order(data, options[:order_id])
  add_payment(data, payment)
  add_external_mpi_fields(data, options)
  add_three_ds_data(data, options) if options[:execute_threed]
  add_stored_credential_options(data, options)
  data[:description] = options[:description]
  data[:store_in_vault] = options[:store]
  data[:sca_exemption] = options[:sca_exemption]
  data[:sca_exemption_direct_payment_enabled] = options[:sca_exemption_direct_payment_enabled]

  commit data, options
end
refund(money, authorization, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 257
def refund(money, authorization, options = {})
  data = {}
  add_action(data, :refund)
  add_amount(data, money, options)
  order_id, = split_authorization(authorization)
  add_order(data, order_id)
  data[:description] = options[:description]

  commit data, options
end
scrub(transcript) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 276
def scrub(transcript)
  transcript.
    gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]').
    gsub(%r((%3CDS_MERCHANT_PAN%3E)\d+(%3C%2FDS_MERCHANT_PAN%3E))i, '\1[FILTERED]\2').
    gsub(%r((%3CDS_MERCHANT_CVV2%3E)\d+(%3C%2FDS_MERCHANT_CVV2%3E))i, '\1[FILTERED]\2').
    gsub(%r((<DS_MERCHANT_PAN>)\d+(</DS_MERCHANT_PAN>))i, '\1[FILTERED]\2').
    gsub(%r((<DS_MERCHANT_PAN>)\d+(</DS_MERCHANT_PAN>))i, '\1[FILTERED]\2').
    gsub(%r((<DS_MERCHANT_CVV2>)\d+(</DS_MERCHANT_CVV2>))i, '\1[FILTERED]\2').
    gsub(%r((&lt;DS_MERCHANT_CVV2&gt;)\d+(&lt;/DS_MERCHANT_CVV2&gt;))i, '\1[FILTERED]\2').
    gsub(%r((DS_MERCHANT_CVV2)%2F%3E%0A%3C%2F)i, '\1[BLANK]').
    gsub(%r((DS_MERCHANT_CVV2)%2F%3E%3C)i, '\1[BLANK]').
    gsub(%r((DS_MERCHANT_CVV2%3E)(%3C%2FDS_MERCHANT_CVV2))i, '\1[BLANK]\2').
    gsub(%r((<DS_MERCHANT_CVV2>)(</DS_MERCHANT_CVV2>))i, '\1[BLANK]\2').
    gsub(%r((DS_MERCHANT_CVV2%3E)\++(%3C%2FDS_MERCHANT_CVV2))i, '\1[BLANK]\2').
    gsub(%r((<DS_MERCHANT_CVV2>)\s+(</DS_MERCHANT_CVV2>))i, '\1[BLANK]\2')
end
supports_scrubbing() click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 272
def supports_scrubbing
  true
end
verify(creditcard, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 268
def verify(creditcard, options = {})
  purchase(0, creditcard, options)
end
void(authorization, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 246
def void(authorization, options = {})
  data = {}
  add_action(data, :cancel)
  order_id, amount, currency = split_authorization(authorization)
  add_amount(data, amount, currency: currency)
  add_order(data, order_id)
  data[:description] = options[:description]

  commit data, options
end

Private Instance Methods

add_action(data, action, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 295
def add_action(data, action, options = {})
  data[:action] = options[:execute_threed].present? ? '0' : transaction_code(action)
end
add_amount(data, money, options) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 299
def add_amount(data, money, options)
  data[:amount] = amount(money).to_s
  data[:currency] = currency_code(options[:currency] || currency(money))
end
add_external_mpi_fields(data, options) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 332
def add_external_mpi_fields(data, options)
  return unless options[:three_d_secure]

  if options[:three_d_secure][:version] == THREE_DS_V2
    data[:threeDSServerTransID] = options[:three_d_secure][:three_ds_server_trans_id] if options[:three_d_secure][:three_ds_server_trans_id]
    data[:dsTransID] = options[:three_d_secure][:ds_transaction_id] if options[:three_d_secure][:ds_transaction_id]
    data[:authenticacionValue] = options[:three_d_secure][:cavv] if options[:three_d_secure][:cavv]
    data[:protocolVersion] = options[:three_d_secure][:version] if options[:three_d_secure][:version]
    data[:authenticacionMethod] = options[:authentication_method] if options[:authentication_method]
    data[:authenticacionType] = options[:authentication_type] if options[:authentication_type]
    data[:authenticacionFlow] = options[:authentication_flow] if options[:authentication_flow]
    data[:eci_v2] = options[:three_d_secure][:eci] if options[:three_d_secure][:eci]
  elsif options[:three_d_secure][:version] == THREE_DS_V1
    data[:txid] = options[:three_d_secure][:xid] if options[:three_d_secure][:xid]
    data[:cavv] = options[:three_d_secure][:cavv] if options[:three_d_secure][:cavv]
    data[:eci_v1] = options[:three_d_secure][:eci] if options[:three_d_secure][:eci]
  end
end
add_order(data, order_id) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 304
def add_order(data, order_id)
  data[:order_id] = clean_order_id(order_id)
end
add_payment(data, card) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 316
def add_payment(data, card)
  if card.is_a?(String)
    data[:credit_card_token] = card
  else
    name  = [card.first_name, card.last_name].join(' ').slice(0, 60)
    year  = sprintf('%.4i', card.year)
    month = sprintf('%.2i', card.month)
    data[:card] = {
      name: name,
      pan: card.number,
      date: "#{year[2..3]}#{month}",
      cvv: card.verification_value
    }
  end
end
add_stored_credential_options(data, options) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 351
def add_stored_credential_options(data, options)
  return unless options[:stored_credential]

  case options[:stored_credential][:initial_transaction]
  when true
    data[:DS_MERCHANT_COF_INI] = 'S'
  when false
    data[:DS_MERCHANT_COF_INI] = 'N'
    data[:DS_MERCHANT_COF_TXNID] = options[:stored_credential][:network_transaction_id] if options[:stored_credential][:network_transaction_id]
  end

  case options[:stored_credential][:reason_type]
  when 'recurring'
    data[:DS_MERCHANT_COF_TYPE] = 'R'
  when 'installment'
    data[:DS_MERCHANT_COF_TYPE] = 'I'
  when 'unscheduled'
    return
  end
end
add_three_ds_data(data, options) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 372
def add_three_ds_data(data, options)
  data[:three_ds_data] = { threeDSInfo: 'CardData' } if options[:execute_threed] == true
end
build_authorization(params) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 619
def build_authorization(params)
  [params[:ds_order], params[:ds_amount], params[:ds_currency]].join('|')
end
build_merchant_data(xml, data, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 478
def build_merchant_data(xml, data, options = {})
  # See https://sis-t.redsys.es:25443/sis/services/SerClsWSEntradaV2/wsdl/SerClsWSEntradaV2.wsdl
  # (which results from calling #webservice_url + '?WSDL', https://sis-t.redsys.es:25443/sis/services/SerClsWSEntradaV2?WSDL)
  xml.DATOSENTRADA do
    # Basic elements
    xml.DS_Version 0.1
    xml.DS_MERCHANT_CURRENCY           data[:currency]
    xml.DS_MERCHANT_AMOUNT             data[:amount]
    xml.DS_MERCHANT_ORDER              data[:order_id]
    xml.DS_MERCHANT_TRANSACTIONTYPE    data[:action]
    if data[:description] && use_webservice_endpoint?(data, options)
      xml.DS_MERCHANT_PRODUCTDESCRIPTION CGI.escape(data[:description])
    else
      xml.DS_MERCHANT_PRODUCTDESCRIPTION data[:description]
    end
    xml.DS_MERCHANT_TERMINAL           options[:terminal] || @options[:terminal]
    xml.DS_MERCHANT_MERCHANTCODE       @options[:login]
    xml.DS_MERCHANT_MERCHANTSIGNATURE  build_signature(data) unless sha256_authentication?

    peticion_type = determine_peticion_type(data) if data[:three_ds_data]
    if peticion_type == 'iniciaPeticion' && data[:sca_exemption]
      xml.DS_MERCHANT_EXCEP_SCA 'Y'
    else
      xml.DS_MERCHANT_EXCEP_SCA data[:sca_exemption] if data[:sca_exemption]
      xml.DS_MERCHANT_DIRECTPAYMENT data[:sca_exemption_direct_payment_enabled] || 'true' if data[:sca_exemption] == 'MIT'
    end

    # Only when card is present
    if data[:card]
      if data[:card][:name] && use_webservice_endpoint?(data, options)
        xml.DS_MERCHANT_TITULAR    CGI.escape(data[:card][:name])
      else
        xml.DS_MERCHANT_TITULAR    data[:card][:name]
      end
      xml.DS_MERCHANT_PAN        data[:card][:pan]
      xml.DS_MERCHANT_EXPIRYDATE data[:card][:date]
      xml.DS_MERCHANT_CVV2       data[:card][:cvv]
      xml.DS_MERCHANT_IDENTIFIER 'REQUIRED' if data[:store_in_vault]

      build_merchant_mpi_external(xml, data)

    elsif data[:credit_card_token]
      xml.DS_MERCHANT_IDENTIFIER data[:credit_card_token]
      xml.DS_MERCHANT_DIRECTPAYMENT 'true'
    end

    # Set moto flag only if explicitly requested via moto field
    # Requires account configuration to be able to use
    xml.DS_MERCHANT_DIRECTPAYMENT 'moto' if options.dig(:moto) && options.dig(:metadata, :manual_entry)

    xml.DS_MERCHANT_EMV3DS data[:three_ds_data].to_json if data[:three_ds_data]

    if options[:stored_credential]
      xml.DS_MERCHANT_COF_INI data[:DS_MERCHANT_COF_INI]
      xml.DS_MERCHANT_COF_TYPE data[:DS_MERCHANT_COF_TYPE]
      xml.DS_MERCHANT_COF_TXNID data[:DS_MERCHANT_COF_TXNID] if data[:DS_MERCHANT_COF_TXNID]
      xml.DS_MERCHANT_DIRECTPAYMENT 'false' if options[:stored_credential][:initial_transaction]
    end
  end
end
build_merchant_mpi_external(xml, data) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 539
def build_merchant_mpi_external(xml, data)
  return unless data[:txid] || data[:threeDSServerTransID]

  ds_merchant_mpi_external = {}
  ds_merchant_mpi_external[:TXID] = data[:txid] if data[:txid]
  ds_merchant_mpi_external[:CAVV] = data[:cavv] if data[:cavv]
  ds_merchant_mpi_external[:ECI] = data[:eci_v1] if data[:eci_v1]

  ds_merchant_mpi_external[:threeDSServerTransID] = data[:threeDSServerTransID] if data[:threeDSServerTransID]
  ds_merchant_mpi_external[:dsTransID] = data[:dsTransID] if data[:dsTransID]
  ds_merchant_mpi_external[:authenticacionValue] = data[:authenticacionValue] if data[:authenticacionValue]
  ds_merchant_mpi_external[:protocolVersion] = data[:protocolVersion] if data[:protocolVersion]
  ds_merchant_mpi_external[:Eci] = data[:eci_v2] if data[:eci_v2]
  ds_merchant_mpi_external[:authenticacionMethod] = data[:authenticacionMethod] if data[:authenticacionMethod]
  ds_merchant_mpi_external[:authenticacionType] = data[:authenticacionType] if data[:authenticacionType]
  ds_merchant_mpi_external[:authenticacionFlow] = data[:authenticacionFlow] if data[:authenticacionFlow]

  xml.DS_MERCHANT_MPIEXTERNAL ds_merchant_mpi_external.to_json unless ds_merchant_mpi_external.empty?
  xml.target!
end
build_sha1_xml_request(data, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 466
def build_sha1_xml_request(data, options = {})
  xml = Builder::XmlMarkup.new indent: 2
  build_merchant_data(xml, data, options)
  xml.target!
end
build_sha256_xml_request(data, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 455
def build_sha256_xml_request(data, options = {})
  xml = Builder::XmlMarkup.new
  xml.instruct!
  xml.REQUEST do
    build_merchant_data(xml, data, options)
    xml.DS_SIGNATUREVERSION 'HMAC_SHA256_V1'
    xml.DS_SIGNATURE sign_request(merchant_data_xml(data, options), data[:order_id])
  end
  xml.target!
end
build_signature(data) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 433
def build_signature(data)
  str = data[:amount] +
        data[:order_id].to_s +
        @options[:login].to_s +
        data[:currency]

  if card = data[:card]
    str << card[:pan]
    str << card[:cvv] if card[:cvv]
  end

  str << data[:action]
  if data[:store_in_vault]
    str << 'REQUIRED'
  elsif data[:credit_card_token]
    str << data[:credit_card_token]
  end
  str << @options[:secret_key]

  Digest::SHA1.hexdigest(str)
end
clean_order_id(order_id) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 663
def clean_order_id(order_id)
  cleansed = order_id.gsub(/[^\da-zA-Z]/, '')
  if /^\d{4}/.match?(cleansed)
    cleansed[0..11]
  else
    '%04d%s' % [rand(0..9999), cleansed[0...8]]
  end
end
commit(data, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 388
      def commit(data, options = {})
        xmlreq = xml_request_from(data, options)

        if use_webservice_endpoint?(data, options)
          peticion_type = determine_peticion_type(data)

          request = <<-REQUEST
            <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://webservice.sis.sermepa.es" xmlns:intf="http://webservice.sis.sermepa.es" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
            <soapenv:Header/>
            <soapenv:Body>
              <intf:#{peticion_type} xmlns:intf="http://webservice.sis.sermepa.es">
                <intf:datoEntrada>
                <![CDATA[#{xmlreq}]]>
                </intf:datoEntrada>
              </intf:#{peticion_type}>
            </soapenv:Body>
          </soapenv:Envelope>
          REQUEST
          parse(ssl_post(webservice_url, request, headers(peticion_type)), peticion_type)
        else
          parse(ssl_post(url, "entrada=#{CGI.escape(xmlreq)}", headers), peticion_type)
        end
      end
currency_code(currency) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 628
def currency_code(currency)
  return currency if currency =~ /^\d+$/
  raise ArgumentError, "Unknown currency #{currency}" unless CURRENCY_CODES[currency]

  CURRENCY_CODES[currency]
end
determine_peticion_type(data) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 376
def determine_peticion_type(data)
  three_ds_info = data.dig(:three_ds_data, :threeDSInfo)
  return 'iniciaPeticion' if three_ds_info == 'CardData'
  return 'trataPeticion' if three_ds_info == 'AuthenticationData' ||
                            three_ds_info == 'ChallengeResponse' ||
                            data[:sca_exemption] == 'MIT'
end
encrypt(key, order_id) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 681
def encrypt(key, order_id)
  block_length = 8
  cipher = OpenSSL::Cipher.new('DES3')
  cipher.encrypt

  cipher.key = Base64.urlsafe_decode64(key)
  # The OpenSSL default of an all-zeroes ("\\0") IV is used.
  cipher.padding = 0

  order_id += "\0" until order_id.bytesize % block_length == 0 # Pad with zeros

  cipher.update(order_id) + cipher.final
end
get_key(order_id) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 710
def get_key(order_id)
  encrypt(@options[:secret_key], order_id)
end
headers(peticion_type = nil) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 412
def headers(peticion_type = nil)
  if peticion_type
    {
      'Content-Type' => 'text/xml',
      'SOAPAction' => peticion_type
    }
  else
    {
      'Content-Type' => 'application/x-www-form-urlencoded'
    }
  end
end
mac256(key, data) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 695
def mac256(key, data)
  OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), key, data)
end
merchant_data_xml(data, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 472
def merchant_data_xml(data, options = {})
  xml = Builder::XmlMarkup.new
  build_merchant_data(xml, data, options)
  xml.target!
end
parse(data, action) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 560
def parse(data, action)
  params  = {}
  success = false
  message = ''
  options = @options.merge(test: test?)
  xml     = Nokogiri::XML(data)
  code    = xml.xpath('//RETORNOXML/CODIGO').text

  if code == '0' && xml.xpath('//RETORNOXML/OPERACION').present?
    op = xml.xpath('//RETORNOXML/OPERACION')
    op.children.each do |element|
      params[element.name.downcase.to_sym] = element.text
    end
    if validate_signature(params)
      message = response_text(params[:ds_response])
      options[:authorization] = build_authorization(params)
      success = success_response?(params[:ds_response])
    else
      message = 'Response failed validation check'
    end
  elsif %w[iniciaPeticion trataPeticion].include?(action)
    vxml = Nokogiri::XML(data).remove_namespaces!.xpath("//Envelope/Body/#{action}Response/#{action}Return").inner_text
    xml = Nokogiri::XML(vxml)
    node = (action == 'iniciaPeticion' ? 'INFOTARJETA' : 'OPERACION')
    op = xml.xpath("//RETORNOXML/#{node}")
    op.children.each do |element|
      params[element.name.downcase.to_sym] = element.text
    end
    message = response_text_3ds(xml, params)
    options[:authorization] = build_authorization(params)
    success = params.size > 0 && success_response?(params[:ds_response])
  else
    # Some kind of programmer error with the request!
    message = "#{code} ERROR"
  end

  Response.new(success, message, params, options)
end
response_text(code) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 639
def response_text(code)
  code = code.to_i
  code = 0 if code < 100
  RESPONSE_TEXTS[code] || 'Unknown code, please check in manual'
end
response_text_3ds(xml, params) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 645
def response_text_3ds(xml, params)
  code = xml.xpath('//RETORNOXML/CODIGO').text
  message = ''
  if code != '0'
    message = "#{code} ERROR"
  elsif params[:ds_emv3ds]
    three_ds_data = JSON.parse(params[:ds_emv3ds])
    message = three_ds_data['threeDSInfo']
  elsif params[:ds_response]
    message = response_text(params[:ds_response])
  end
  message
end
sha256_authentication?() click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 672
def sha256_authentication?
  @options[:signature_algorithm] == 'sha256'
end
sign_request(xml_request_string, order_id) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 676
def sign_request(xml_request_string, order_id)
  key = encrypt(@options[:secret_key], order_id)
  Base64.strict_encode64(mac256(key, xml_request_string))
end
split_authorization(authorization) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 623
def split_authorization(authorization)
  order_id, amount, currency = authorization.split('|')
  [order_id, amount.to_i, currency]
end
success_response?(code) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 659
def success_response?(code)
  (code.to_i < 100) || [400, 481, 500, 900].include?(code.to_i)
end
transaction_code(type) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 635
def transaction_code(type)
  SUPPORTED_TRANSACTIONS[type]
end
url() click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 308
def url
  test? ? test_url : live_url
end
use_webservice_endpoint?(data, options) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 384
def use_webservice_endpoint?(data, options)
  options[:use_webservice_endpoint].to_s == 'true' || data[:three_ds_data] || data[:sca_exemption] == 'MIT'
end
validate_signature(data) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 599
def validate_signature(data)
  if sha256_authentication?
    sig = Base64.strict_encode64(mac256(get_key(data[:ds_order].to_s), xml_signed_fields(data)))
    sig.casecmp(data[:ds_signature].to_s).zero?
  else
    str = data[:ds_amount] +
          data[:ds_order].to_s +
          data[:ds_merchantcode] +
          data[:ds_currency] +
          data[:ds_response] +
          data[:ds_cardnumber].to_s +
          data[:ds_transactiontype].to_s +
          data[:ds_securepayment].to_s +
          @options[:secret_key]

    sig = Digest::SHA1.hexdigest(str)
    data[:ds_signature].to_s.downcase == sig
  end
end
webservice_url() click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 312
def webservice_url
  test? ? 'https://sis-t.redsys.es:25443/sis/services/SerClsWSEntradaV2' : 'https://sis.redsys.es/sis/services/SerClsWSEntradaV2'
end
xml_request_from(data, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 425
def xml_request_from(data, options = {})
  if sha256_authentication?
    build_sha256_xml_request(data, options)
  else
    build_sha1_xml_request(data, options)
  end
end
xml_signed_fields(data) click to toggle source
# File lib/active_merchant/billing/gateways/redsys.rb, line 699
def xml_signed_fields(data)
  xml_signed_fields = data[:ds_amount] + data[:ds_order] + data[:ds_merchantcode] +
                      data[:ds_currency] + data[:ds_response]

  xml_signed_fields += data[:ds_cardnumber] if data[:ds_cardnumber]

  xml_signed_fields += data[:ds_emv3ds] if data[:ds_emv3ds]

  xml_signed_fields + data[:ds_transactiontype] + data[:ds_securepayment]
end