class ActiveMerchant::Billing::TransFirstTransactionExpressGateway

Constants

APPROVAL_CODES
AUTHORIZATION_FIELD_SEPARATOR
CURRENCY_CODES
EXTENDED_RESPONSE_MESSAGES
RESPONSE_MESSAGES
SOAPENV_NAMESPACE
TRANSACTION_CODES
V1_NAMESPACE

Public Class Methods

new(options = {}) click to toggle source
Calls superclass method ActiveMerchant::Billing::Gateway::new
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 185
def initialize(options = {})
  requires!(options, :gateway_id, :reg_key)
  super
end

Public Instance Methods

authorize(amount, payment_method, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 219
def authorize(amount, payment_method, options = {})
  if credit_card?(payment_method)
    request = build_xml_transaction_request do |doc|
      add_credit_card(doc, payment_method)
      add_contact(doc, payment_method.name, options)
      add_amount(doc, amount)
    end
  else
    wallet_id = split_authorization(payment_method).last
    request = build_xml_transaction_request do |doc|
      add_amount(doc, amount)
      add_wallet_id(doc, wallet_id)
    end
  end

  commit(:authorize, request)
end
capture(amount, authorization, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 237
def capture(amount, authorization, options = {})
  transaction_id = split_authorization(authorization)[1]
  request = build_xml_transaction_request do |doc|
    add_amount(doc, amount)
    add_original_transaction_data(doc, transaction_id)
  end

  commit(:capture, request)
end
credit(amount, payment_method, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 268
def credit(amount, payment_method, options = {})
  request = build_xml_transaction_request do |doc|
    add_pan(doc, payment_method)
    add_amount(doc, amount)
  end

  commit(:credit, request)
end
purchase(amount, payment_method, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 190
def purchase(amount, payment_method, options = {})
  if credit_card?(payment_method)
    action = :purchase
    request = build_xml_transaction_request do |doc|
      add_credit_card(doc, payment_method)
      add_contact(doc, payment_method.name, options)
      add_amount(doc, amount)
      add_order_number(doc, options)
    end
  elsif echeck?(payment_method)
    action = :purchase_echeck
    request = build_xml_transaction_request do |doc|
      add_echeck(doc, payment_method)
      add_contact(doc, payment_method.name, options)
      add_amount(doc, amount)
      add_order_number(doc, options)
    end
  else
    action = :wallet_sale
    wallet_id = split_authorization(payment_method).last
    request = build_xml_transaction_request do |doc|
      add_amount(doc, amount)
      add_wallet_id(doc, wallet_id)
    end
  end

  commit(action, request)
end
refund(amount, authorization, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 257
def refund(amount, authorization, options = {})
  action, transaction_id = split_authorization(authorization)

  request = build_xml_transaction_request do |doc|
    add_amount(doc, amount) unless action == 'purchase_echeck'
    add_original_transaction_data(doc, transaction_id)
  end

  commit(refund_type(action), request)
end
scrub(transcript) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 315
def scrub(transcript)
  transcript.
    gsub(%r((<[^>]+pan>)[^<]+(<))i, '\1[FILTERED]\2').
    gsub(%r((<[^>]+sec>)[^<]+(<))i, '\1[FILTERED]\2').
    gsub(%r((<[^>]+id>)[^<]+(<))i, '\1[FILTERED]\2').
    gsub(%r((<[^>]+regKey>)[^<]+(<))i, '\1[FILTERED]\2').
    gsub(%r((<[^>]+acctNr>)[^<]+(<))i, '\1[FILTERED]\2')
end
store(payment_method, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 286
def store(payment_method, options = {})
  store_customer_request = build_xml_payment_storage_request do |doc|
    store_customer_details(doc, payment_method.name, options)
  end

  MultiResponse.run do |r|
    r.process { commit(:store, store_customer_request) }
    return r unless r.success? && r.params['custId']

    customer_id = r.params['custId']

    store_payment_method_request = build_xml_payment_storage_request do |doc|
      doc['v1'].cust do
        add_customer_id(doc, customer_id)
        doc['v1'].pmt do
          doc['v1'].type 0 # add
          add_credit_card(doc, payment_method)
        end
      end
    end

    r.process { commit(:store, store_payment_method_request) }
  end
end
supports_scrubbing?() click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 311
def supports_scrubbing?
  true
end
verify(credit_card, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 277
def verify(credit_card, options = {})
  request = build_xml_transaction_request do |doc|
    add_credit_card(doc, credit_card)
    add_contact(doc, credit_card.name, options)
  end

  commit(:verify, request)
end
void(authorization, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 247
def void(authorization, options = {})
  action, transaction_id = split_authorization(authorization)

  request = build_xml_transaction_request do |doc|
    add_original_transaction_data(doc, transaction_id)
  end

  commit(void_type(action), request)
end

Private Instance Methods

add_amount(doc, money) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 490
def add_amount(doc, money)
  doc['v1'].reqAmt amount(money)
end
add_contact(doc, fullname, options) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 529
def add_contact(doc, fullname, options)
  doc['v1'].contact do
    doc['v1'].fullName fullname unless fullname.blank?
    doc['v1'].coName options[:company_name] if options[:company_name]
    doc['v1'].title options[:title] if options[:title]

    if (billing_address = options[:billing_address])
      if billing_address[:phone]
        doc['v1'].phone do
          doc['v1'].type(options[:phone_number_type] || '4')
          doc['v1'].nr billing_address[:phone].gsub(/\D/, '')
        end
      end
      doc['v1'].addrLn1 billing_address[:address1] if billing_address[:address1]
      doc['v1'].addrLn2 billing_address[:address2] unless billing_address[:address2].blank?
      doc['v1'].city billing_address[:city] if billing_address[:city]
      doc['v1'].state billing_address[:state] if billing_address[:state]
      doc['v1'].zipCode billing_address[:zip].delete('-') if billing_address[:zip]
      doc['v1'].ctry 'US'
    end

    doc['v1'].email options[:email] if options[:email]
    doc['v1'].type options[:contact_type] if options[:contact_type]
    doc['v1'].stat options[:contact_stat] if options[:contact_stat]

    if (shipping_address = options[:shipping_address])
      doc['v1'].ship do
        doc['v1'].fullName fullname unless fullname.blank?
        doc['v1'].addrLn1 shipping_address[:address1] if shipping_address[:address1]
        doc['v1'].addrLn2 shipping_address[:address2] unless shipping_address[:address2].blank?
        doc['v1'].city shipping_address[:city] if shipping_address[:city]
        doc['v1'].state shipping_address[:state] if shipping_address[:state]
        doc['v1'].zipCode shipping_address[:zip].delete('-') if shipping_address[:zip]
        doc['v1'].phone shipping_address[:phone].gsub(/\D/, '') if shipping_address[:phone]
        doc['v1'].email shipping_address[:email] if shipping_address[:email]
      end
    end
  end
end
add_credit_card(doc, payment_method) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 502
def add_credit_card(doc, payment_method)
  doc['v1'].card {
    doc['v1'].pan payment_method.number
    doc['v1'].sec payment_method.verification_value if payment_method.verification_value?
    doc['v1'].xprDt expiration_date(payment_method)
  }
end
add_customer_id(doc, customer_id) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 591
def add_customer_id(doc, customer_id)
  doc['v1'].contact do
    doc['v1'].id customer_id
  end
end
add_echeck(doc, payment_method) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 510
def add_echeck(doc, payment_method)
  doc['v1'].achEcheck {
    doc['v1'].bankRtNr payment_method.routing_number
    doc['v1'].acctNr payment_method.account_number
  }
end
add_merchant(doc, product_type = nil) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 481
def add_merchant(doc, product_type = nil)
  doc['v1'].merc do
    doc['v1'].id @options[:gateway_id]
    doc['v1'].regKey @options[:reg_key]
    doc['v1'].inType '1'
    doc['v1'].prodType product_type if product_type
  end
end
add_name(doc, payment_method) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 569
def add_name(doc, payment_method)
  doc['v1'].contact do
    doc['v1'].fullName payment_method.name unless payment_method.name.blank?
  end
end
add_order_number(doc, options) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 494
def add_order_number(doc, options)
  return unless options[:order_id]

  doc['v1'].authReq {
    doc['v1'].ordNr options[:order_id]
  }
end
add_original_transaction_data(doc, authorization) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 575
def add_original_transaction_data(doc, authorization)
  doc['v1'].origTranData do
    doc['v1'].tranNr authorization
  end
end
add_pan(doc, payment_method) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 523
def add_pan(doc, payment_method)
  doc['v1'].card do
    doc['v1'].pan payment_method.number
  end
end
add_transaction_code_to_request(request, action) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 471
def add_transaction_code_to_request(request, action)
  # store requests don't get a transaction code
  return request if action == :store

  doc = Nokogiri::XML::Document.parse(request)
  merc_nodeset = doc.xpath('//v1:merc', 'v1' => V1_NAMESPACE)
  merc_nodeset.after "<v1:tranCode>#{TRANSACTION_CODES[action]}</v1:tranCode>"
  doc.root.to_xml
end
add_wallet_id(doc, wallet_id) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 597
def add_wallet_id(doc, wallet_id)
  doc['v1'].recurMan do
    doc['v1'].id wallet_id
  end
end
authorization_from(action, response) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 410
def authorization_from(action, response)
  authorization = response['tranNr'] || response['pmtId']

  # guard so we don't return something like "purchase|"
  return unless authorization

  [action, authorization].join(AUTHORIZATION_FIELD_SEPARATOR)
end
build_xml_payment_search_request(&block) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 454
def build_xml_payment_search_request(&block)
  build_xml_request('FndRecurrProfRequest', &block)
end
build_xml_payment_storage_request(&block) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 445
def build_xml_payment_storage_request(&block)
  build_xml_request('UpdtRecurrProfRequest', &block)
end
build_xml_payment_update_request(&block) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 449
def build_xml_payment_update_request(&block)
  merchant_product_type = 5 # credit card
  build_xml_request('UpdtRecurrProfRequest', merchant_product_type, &block)
end
build_xml_request(wrapper, merchant_product_type = nil) { |xml| ... } click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 458
def build_xml_request(wrapper, merchant_product_type = nil)
  Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
    xml['soapenv'].Envelope('xmlns:soapenv' => SOAPENV_NAMESPACE) do
      xml['soapenv'].Body do
        xml['v1'].send(wrapper, 'xmlns:v1' => V1_NAMESPACE) do
          add_merchant(xml)
          yield(xml)
        end
      end
    end
  end.doc.root.to_xml
end
build_xml_transaction_request(&block) click to toggle source

– request methods —————————————————

# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 441
def build_xml_transaction_request(&block)
  build_xml_request('SendTranRequest', &block)
end
commit(action, request) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 335
def commit(action, request)
  request = add_transaction_code_to_request(request, action)

  raw_response =
    begin
      ssl_post(url, request, headers)
    rescue ActiveMerchant::ResponseError => e
      e.response.body
    end

  response = parse(raw_response)

  succeeded = success_from(response)

  Response.new(
    succeeded,
    message_from(succeeded, response),
    response,
    error_code: error_code_from(succeeded, response),
    authorization: authorization_from(action, response),
    avs_result: AVSResult.new(code: response['avsRslt']),
    cvv_result: CVVResult.new(response['secRslt']),
    test: test?
  )
end
credit_card?(payment_method) click to toggle source

– helper methods —————————————————-

# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 420
def credit_card?(payment_method)
  payment_method.respond_to?(:verification_value)
end
echeck?(payment_method) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 424
def echeck?(payment_method)
  payment_method.respond_to?(:routing_number)
end
error_code_from(succeeded, response) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 387
def error_code_from(succeeded, response)
  return if succeeded

  response['errorCode'] || response['rspCode']
end
expiration_date(payment_method) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 517
def expiration_date(payment_method)
  yy = format(payment_method.year, :two_digits)
  mm = format(payment_method.month, :two_digits)
  yy + mm
end
headers() click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 329
def headers
  {
    'Content-Type' => 'text/xml'
  }
end
message_from(succeeded, response) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 393
def message_from(succeeded, response)
  return 'Succeeded' if succeeded

  if response['rspCode']
    code = response['rspCode']
    extended_code = response['extRspCode']

    message = RESPONSE_MESSAGES[code]
    extended = EXTENDED_RESPONSE_MESSAGES[extended_code]
    ach_response = response['achResponse']

    [message, extended, ach_response].compact.join('. ')
  else
    response['faultstring']
  end
end
parse(xml) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 365
def parse(xml)
  response = {}
  doc = Nokogiri::XML(xml).remove_namespaces!

  doc.css('Envelope Body *').each do |node|
    # node.name is more readable, but uniq_name is occasionally necessary
    uniq_name = [node.parent.name, node.name].join('_')
    response[uniq_name] = node.text
    response[node.name] = node.text
  end

  response
end
refund_type(action) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 436
def refund_type(action)
  action == 'purchase_echeck' ? :refund_echeck : :refund
end
split_authorization(authorization) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 428
def split_authorization(authorization)
  authorization.split(AUTHORIZATION_FIELD_SEPARATOR)
end
store_customer_details(doc, fullname, options) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 581
def store_customer_details(doc, fullname, options)
  options[:contact_type] = 1 # recurring
  options[:contact_stat] = 1 # active

  doc['v1'].cust do
    doc['v1'].type 0 # add
    add_contact(doc, fullname, options)
  end
end
success_from(response) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 379
def success_from(response)
  fault = response['Fault']
  approved_transaction = APPROVAL_CODES.include?(response['rspCode'])
  found_contact = response['FndRecurrProfResponse']

  return !fault && (approved_transaction || found_contact)
end
url() click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 361
def url
  test? ? test_url : live_url
end
void_type(action) click to toggle source
# File lib/active_merchant/billing/gateways/trans_first_transaction_express.rb, line 432
def void_type(action)
  action == 'purchase_echeck' ? :void_echeck : :"void_#{action}"
end