class ActiveMerchant::Billing::ItransactGateway

iTransact, Inc. is an authorized reseller of the PaymentClearing gateway. If your merchant service provider uses PaymentClearing.com to process payments, you can use this module.

Please note, the username and API Access Key are not what you use to log into the Merchant Control Panel.

How to get your GatewayID and API Access Key

  1. If you don't already have a Gateway Account, go to www.itransact.com/merchant/test.html to sign up.

  2. Go to support.paymentclearing.com and login or register, if necessary.

  3. Click on “Submit a Ticket.”

  4. Select “Merchant Support” as the department and click “Next”

  5. Enter both your company name and GatewayID. Put “API Access Key” in the subject. In the body, you can request a username, but it may already be in use.

Initialization

Once you have the username, API Access Key, and your GatewayId, you're ready to begin. You initialize the Gateway like so:

gateway = ActiveMerchant::Billing::ItransactGateway.new(
  :login => "#{THE_USERNAME}",
  :password => "#{THE_API_ACCESS_KEY}",
  :gateway_id => "#{THE_GATEWAY_ID}"
)

Important Notes

  1. Recurring is not implemented

  2. CreditTransactions are not implemented (these are credits not related to a previously run transaction).

  3. TransactionStatus is not implemented

Public Class Methods

new(options = {}) click to toggle source

Creates a new instance of the iTransact Gateway.

Parameters

  • options - A Hash of options

Options Hash

  • :login - A String containing your PaymentClearing assigned API Access Username

  • :password - A String containing your PaymentClearing assigned API Access Key

  • :gateway_id - A String containing your PaymentClearing assigned GatewayID

  • :test_mode - true or false. Run all transactions with the 'TestMode' element set to 'TRUE'.

Calls superclass method ActiveMerchant::Billing::Gateway::new
# File lib/active_merchant/billing/gateways/itransact.rb, line 61
def initialize(options = {})
  requires!(options, :login, :password, :gateway_id)
  super
end

Public Instance Methods

authorize(money, payment_source, options = {}) click to toggle source

Performs an authorize transaction. In PaymentClearing's documentation this is known as a “PreAuth” transaction.

Parameters

  • money - The amount to be captured. Should be an Integer amount in cents.

  • creditcard - The CreditCard details for the transaction

  • options - A Hash of options

Options Hash

The standard options apply here (:order_id, :ip, :customer, :invoice, :merchant, :description, :email, :currency, :address, :billing_address, :shipping_address), as well as:

  • :order_items - An Array of Hash objects with the keys :description, :cost (in cents!), and :quantity. If this is provided, :description and money will be ignored.

  • :vendor_data - An Array of Hash objects with the keys being the name of the VendorData element and value being the value.

  • :send_customer_email - true or false. Runs the transaction with the 'SendCustomerEmail' element set to 'TRUE' or 'FALSE'.

  • :send_merchant_email - true or false. Runs the transaction with the 'SendMerchantEmail' element set to 'TRUE' or 'FALSE'.

  • :email_text - An Array of (up to ten (10)) String objects to be included in emails

  • :test_mode - true or false. Runs the transaction with the 'TestMode' element set to 'TRUE' or 'FALSE'.

Examples

response = gateway.authorize(1000, creditcard,
  :order_id => '1212', :address => {...}, :email => 'test@test.com',
  :order_items => [
    {:description => 'Line Item 1', :cost => '8.98', :quantity => '6'},
    {:description => 'Line Item 2', :cost => '6.99', :quantity => '4'}
  ],
  :vendor_data => [{'repId' => '1234567'}, {'customerId' => '9886'}],
  :send_customer_email => true,
  :send_merchant_email => true,
  :email_text => ['line1', 'line2', 'line3'],
  :test_mode => true
)
# File lib/active_merchant/billing/gateways/itransact.rb, line 97
def authorize(money, payment_source, options = {})
  payload = Nokogiri::XML::Builder.new do |xml|
    xml.AuthTransaction {
      xml.Preauth
      add_customer_data(xml, payment_source, options)
      add_invoice(xml, money, options)
      add_payment_source(xml, payment_source)
      add_transaction_control(xml, options)
      add_vendor_data(xml, options)
    }
  end.doc

  commit(payload)
end
capture(money, authorization, options = {}) click to toggle source

Captures the funds from an authorize transaction. In PaymentClearing's documentation this is known as a “PostAuth” transaction.

Parameters

  • money - The amount to be captured. Should be an Integer amount in cents

  • authorization - The authorization returned from the previous capture or purchase request

  • options - A Hash of options, all are optional.

Options Hash

The standard options apply here (:order_id, :ip, :customer, :invoice, :merchant, :description, :email, :currency, :address, :billing_address, :shipping_address), as well as:

  • :vendor_data - An Array of Hash objects with the keys being the name of the VendorData element and value being the value.

  • :send_customer_email - true or false. Runs the transaction with the 'SendCustomerEmail' element set to 'TRUE' or 'FALSE'.

  • :send_merchant_email - true or false. Runs the transaction with the 'SendMerchantEmail' element set to 'TRUE' or 'FALSE'.

  • :email_text - An Array of (up to ten (10)) String objects to be included in emails

  • :test_mode - true or false. Runs the transaction with the 'TestMode' element set to 'TRUE' or 'FALSE'.

Examples

response = gateway.capture(1000, creditcard,
  :vendor_data => [{'repId' => '1234567'}, {'customerId' => '9886'}],
  :send_customer_email => true,
  :send_merchant_email => true,
  :email_text => ['line1', 'line2', 'line3'],
  :test_mode => true
)
# File lib/active_merchant/billing/gateways/itransact.rb, line 182
def capture(money, authorization, options = {})
  payload = Nokogiri::XML::Builder.new do |xml|
    xml.PostAuthTransaction {
      xml.OperationXID(authorization)
      add_invoice(xml, money, options)
      add_transaction_control(xml, options)
      add_vendor_data(xml, options)
    }
  end.doc

  commit(payload)
end
purchase(money, payment_source, options = {}) click to toggle source

Performs an authorize and capture in single transaction. In PaymentClearing's documentation this is known as an “Auth” or a “Sale” transaction

Parameters

  • money - The amount to be captured. Should be nil or an Integer amount in cents.

  • creditcard - The CreditCard details for the transaction

  • options - A Hash of options

Options Hash

The standard options apply here (:order_id, :ip, :customer, :invoice, :merchant, :description, :email, :currency, :address, :billing_address, :shipping_address), as well as:

  • :order_items - An Array of Hash objects with the keys :description, :cost (in cents!), and :quantity. If this is provided, :description and money will be ignored.

  • :vendor_data - An Array of Hash objects with the keys being the name of the VendorData element and value being the value.

  • :send_customer_email - true or false. Runs the transaction with the 'SendCustomerEmail' element set to 'TRUE' or 'FALSE'.

  • :send_merchant_email - true or false. Runs the transaction with the 'SendMerchantEmail' element set to 'TRUE' or 'FALSE'.

  • :email_text - An Array of (up to ten (10)) String objects to be included in emails

  • :test_mode - true or false. Runs the transaction with the 'TestMode' element set to 'TRUE' or 'FALSE'.

Examples

response = gateway.purchase(1000, creditcard,
  :order_id => '1212', :address => {...}, :email => 'test@test.com',
  :order_items => [
    {:description => 'Line Item 1', :cost => '8.98', :quantity => '6'},
    {:description => 'Line Item 2', :cost => '6.99', :quantity => '4'}
  ],
  :vendor_data => [{'repId' => '1234567'}, {'customerId' => '9886'}],
  :send_customer_email => true,
  :send_merchant_email => true,
  :email_text => ['line1', 'line2', 'line3'],
  :test_mode => true
)
# File lib/active_merchant/billing/gateways/itransact.rb, line 143
def purchase(money, payment_source, options = {})
  payload = Nokogiri::XML::Builder.new do |xml|
    xml.AuthTransaction {
      add_customer_data(xml, payment_source, options)
      add_invoice(xml, money, options)
      add_payment_source(xml, payment_source)
      add_transaction_control(xml, options)
      add_vendor_data(xml, options)
    }
  end.doc

  commit(payload)
end
refund(money, authorization, options = {}) click to toggle source

This will reverse a previously run transaction which has settled.

Parameters

  • money - The amount to be credited. Should be an Integer amount in cents

  • authorization - The authorization returned from the previous capture or purchase request

  • options - A Hash of options, all are optional

Options Hash

The standard options (:order_id, :ip, :customer, :invoice, :merchant, :description, :email, :currency, :address, :billing_address, :shipping_address) are ignored.

  • :vendor_data - An Array of Hash objects with the keys being the name of the VendorData element and value being the value.

  • :send_customer_email - true or false. Runs the transaction with the 'SendCustomerEmail' element set to 'TRUE' or 'FALSE'.

  • :send_merchant_email - true or false. Runs the transaction with the 'SendMerchantEmail' element set to 'TRUE' or 'FALSE'.

  • :email_text - An Array of (up to ten (10)) String objects to be included in emails

  • :test_mode - true or false. Runs the transaction with the 'TestMode' element set to 'TRUE' or 'FALSE'.

Examples

response = gateway.refund(555, '9999999999',
  :vendor_data => [{'repId' => '1234567'}, {'customerId' => '9886'}],
  :send_customer_email => true,
  :send_merchant_email => true,
  :email_text => ['line1', 'line2', 'line3'],
  :test_mode => true
)
# File lib/active_merchant/billing/gateways/itransact.rb, line 254
def refund(money, authorization, options = {})
  payload = Nokogiri::XML::Builder.new do |xml|
    xml.TranCredTransaction {
      xml.OperationXID(authorization)
      add_invoice(xml, money, options)
      add_transaction_control(xml, options)
      add_vendor_data(xml, options)
    }
  end.doc

  commit(payload)
end
void(authorization, options = {}) click to toggle source

This will reverse a previously run transaction which has not settled.

Parameters

  • authorization - The authorization returned from the previous capture or purchase request

  • options - A Hash of options, all are optional

Options Hash

The standard options (:order_id, :ip, :customer, :invoice, :merchant, :description, :email, :currency, :address, :billing_address, :shipping_address) are ignored.

  • :vendor_data - An Array of Hash objects with the keys being the name of the VendorData element and value being the value.

  • :send_customer_email - true or false. Runs the transaction with the 'SendCustomerEmail' element set to 'TRUE' or 'FALSE'.

  • :send_merchant_email - true or false. Runs the transaction with the 'SendMerchantEmail' element set to 'TRUE' or 'FALSE'.

  • :email_text - An Array of (up to ten (10)) String objects to be included in emails

  • :test_mode - true or false. Runs the transaction with the 'TestMode' element set to 'TRUE' or 'FALSE'.

Examples

response = gateway.void('9999999999',
  :vendor_data => [{'repId' => '1234567'}, {'customerId' => '9886'}],
  :send_customer_email => true,
  :send_merchant_email => true,
  :email_text => ['line1', 'line2', 'line3'],
  :test_mode => true
)
# File lib/active_merchant/billing/gateways/itransact.rb, line 218
def void(authorization, options = {})
  payload = Nokogiri::XML::Builder.new do |xml|
    xml.VoidTransaction {
      xml.OperationXID(authorization)
      add_transaction_control(xml, options)
      add_vendor_data(xml, options)
    }
  end.doc

  commit(payload)
end

Private Instance Methods

add_check(xml, check) click to toggle source
# File lib/active_merchant/billing/gateways/itransact.rb, line 346
def add_check(xml, check)
  xml.AccountInfo {
    xml.ABA(check.routing_number.to_s)
    xml.AccountNumber(check.account_number.to_s)
    xml.AccountSource(check.account_type.to_s)
    xml.AccountType(check.account_holder_type.to_s)
    xml.CheckNumber(check.number.to_s)
  }
end
add_creditcard(xml, creditcard) click to toggle source
# File lib/active_merchant/billing/gateways/itransact.rb, line 335
def add_creditcard(xml, creditcard)
  xml.AccountInfo {
    xml.CardAccount {
      xml.AccountNumber(creditcard.number.to_s)
      xml.ExpirationMonth(creditcard.month.to_s.rjust(2, '0'))
      xml.ExpirationYear(creditcard.year.to_s)
      xml.CVVNumber(creditcard.verification_value.to_s) unless creditcard.verification_value.blank?
    }
  }
end
add_customer_data(xml, payment_source, options) click to toggle source
# File lib/active_merchant/billing/gateways/itransact.rb, line 269
def add_customer_data(xml, payment_source, options)
  billing_address = options[:billing_address] || options[:address]
  shipping_address = options[:shipping_address] || options[:address]

  xml.CustomerData {
    xml.Email(options[:email]) unless options[:email].blank?
    xml.CustId(options[:order_id]) unless options[:order_id].blank?
    xml.BillingAddress {
      xml.FirstName(payment_source.first_name || parse_first_name(billing_address[:name]))
      xml.LastName(payment_source.last_name || parse_last_name(billing_address[:name]))
      xml.Address1(billing_address[:address1])
      xml.Address2(billing_address[:address2]) unless billing_address[:address2].blank?
      xml.City(billing_address[:city])
      xml.State(billing_address[:state])
      xml.Zip(billing_address[:zip])
      xml.Country(billing_address[:country])
      xml.Phone(billing_address[:phone])
    }
    xml.ShippingAddress {
      xml.FirstName(payment_source.first_name || parse_first_name(shipping_address[:name]))
      xml.LastName(payment_source.last_name || parse_last_name(shipping_address[:name]))
      xml.Address1(shipping_address[:address1])
      xml.Address2(shipping_address[:address2]) unless shipping_address[:address2].blank?
      xml.City(shipping_address[:city])
      xml.State(shipping_address[:state])
      xml.Zip(shipping_address[:zip])
      xml.Country(shipping_address[:country])
      xml.Phone(shipping_address[:phone])
    } unless shipping_address.blank?
  }
end
add_invoice(xml, money, options) click to toggle source
# File lib/active_merchant/billing/gateways/itransact.rb, line 301
def add_invoice(xml, money, options)
  xml.AuthCode options[:force] if options[:force]
  if options[:order_items].blank?
    xml.Total(amount(money)) unless(money.nil? || money < 0.01)
    xml.Description(options[:description]) unless(options[:description].blank?)
  else
    xml.OrderItems {
      options[:order_items].each do |item|
        xml.Item {
          xml.Description(item[:description])
          xml.Cost(amount(item[:cost]))
          xml.Qty(item[:quantity].to_s)
        }
      end
    }
  end
end
add_payment_source(xml, source) click to toggle source
# File lib/active_merchant/billing/gateways/itransact.rb, line 319
def add_payment_source(xml, source)
  case determine_funding_source(source)
  when :credit_card then add_creditcard(xml, source)
  when :check       then add_check(xml, source)
  end
end
add_transaction_control(xml, options) click to toggle source
# File lib/active_merchant/billing/gateways/itransact.rb, line 356
def add_transaction_control(xml, options)
  xml.TransactionControl {
    # if there was a 'global' option set...
    xml.TestMode(@options[:test_mode].upcase) if !@options[:test_mode].blank?
    # allow the global option to be overridden...
    xml.TestMode(options[:test_mode].upcase) if !options[:test_mode].blank?
    xml.SendCustomerEmail(options[:send_customer_email].upcase) unless options[:send_customer_email].blank?
    xml.SendMerchantEmail(options[:send_merchant_email].upcase) unless options[:send_merchant_email].blank?
    xml.EmailText {
      options[:email_text].each do |item|
        xml.EmailTextItem(item)
      end
    } if options[:email_text]
  }
end
add_vendor_data(xml, options) click to toggle source
# File lib/active_merchant/billing/gateways/itransact.rb, line 372
def add_vendor_data(xml, options)
  return if options[:vendor_data].blank?
  xml.VendorData {
    options[:vendor_data].each do |k, v|
      xml.Element {
        xml.Name(k)
        xml.Key(v)
      }
    end
  }
end
commit(payload) click to toggle source
# File lib/active_merchant/billing/gateways/itransact.rb, line 384
def commit(payload)
  # Set the Content-Type header -- otherwise the URL decoding messes up
  # the Base64 encoded payload signature!
  response = parse(ssl_post(self.live_url, post_data(payload), 'Content-Type' => 'text/xml'))

  Response.new(successful?(response), response[:error_message], response,
    :test => test?,
    :authorization => response[:xid],
    :avs_result => { :code => response[:avs_response] },
    :cvv_result => response[:cvv_response])
end
determine_funding_source(payment_source) click to toggle source
# File lib/active_merchant/billing/gateways/itransact.rb, line 326
def determine_funding_source(payment_source)
  case payment_source
  when ActiveMerchant::Billing::CreditCard
    :credit_card
  when ActiveMerchant::Billing::Check
    :check
  end
end
message_from(response) click to toggle source
# File lib/active_merchant/billing/gateways/itransact.rb, line 435
def message_from(response)
  response[:error_message]
end
parse(raw_xml) click to toggle source
# File lib/active_merchant/billing/gateways/itransact.rb, line 415
def parse(raw_xml)
  doc = REXML::Document.new(raw_xml)
  response = Hash.new
  transaction_result = doc.root.get_elements('TransactionResponse/TransactionResult/*')
  transaction_result.each do |e|
    response[e.name.to_s.underscore.to_sym] = e.text unless e.text.blank?
  end
  response
end
post_data(payload) click to toggle source
# File lib/active_merchant/billing/gateways/itransact.rb, line 396
def post_data(payload)
  payload_xml = payload.root.to_xml(:indent => 0)

  payload_signature = sign_payload(payload_xml)

  request = Nokogiri::XML::Builder.new do |xml|
    xml.GatewayInterface {
      xml.APICredentials {
        xml.Username(@options[:login])
        xml.PayloadSignature(payload_signature)
        xml.TargetGateway(@options[:gateway_id])
      }
    }
  end.doc

  request.root.children.first.after payload.root
  request.to_xml(:indent => 0)
end
sign_payload(payload) click to toggle source
# File lib/active_merchant/billing/gateways/itransact.rb, line 439
def sign_payload(payload)
  key = @options[:password].to_s
  digest=OpenSSL::HMAC.digest(OpenSSL::Digest::SHA1.new(key), key, payload)
  signature = Base64.encode64(digest)
  signature.chomp!
end
successful?(response) click to toggle source
# File lib/active_merchant/billing/gateways/itransact.rb, line 425
def successful?(response)
  # Turns out the PaymentClearing gateway is not consistent...
  response[:status].casecmp('ok').zero?
end
test_mode?(response) click to toggle source
# File lib/active_merchant/billing/gateways/itransact.rb, line 430
def test_mode?(response)
  # The '1' is a legacy thing; most of the time it should be 'TRUE'...
  response[:test_mode] == 'TRUE' || response[:test_mode] == '1'
end