class ActiveMerchant::Billing::QbmsGateway

Constants

API_VERSION
TYPES

Public Class Methods

new(options = {}) click to toggle source

Creates a new QbmsGateway

The gateway requires that a valid app id, app login, and ticket be passed in the options hash.

Options

  • :login – The App Login (REQUIRED)

  • :ticket – The Connection Ticket. (REQUIRED)

  • :pem – The PEM-encoded SSL client key and certificate. (REQUIRED)

  • :testtrue or false. If true, perform transactions against the test server. Otherwise, perform transactions against the production server.

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

Public Instance Methods

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

Performs an authorization, which reserves the funds on the customer’s credit card, but does not charge the card.

Parameters

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

  • creditcard – The CreditCard details for the transaction.

  • options – A hash of optional parameters.

# File lib/active_merchant/billing/gateways/qbms.rb, line 53
def authorize(money, creditcard, options = {})
  commit(:authorize, money, options.merge(credit_card: creditcard))
end
capture(money, authorization, options = {}) click to toggle source

Captures the funds from an authorized transaction.

Parameters

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

  • authorization – The authorization returned from the previous authorize request.

# File lib/active_merchant/billing/gateways/qbms.rb, line 76
def capture(money, authorization, options = {})
  commit(:capture, money, options.merge(transaction_id: authorization))
end
credit(money, identification, options = {}) click to toggle source

Credit an account.

This transaction is also referred to as a Refund and 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 ID of the original transaction against which the credit is being issued.

  • options – A hash of parameters.

# File lib/active_merchant/billing/gateways/qbms.rb, line 102
def credit(money, identification, options = {})
  ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
  refund(money, identification, {})
end
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.

# File lib/active_merchant/billing/gateways/qbms.rb, line 65
def purchase(money, creditcard, options = {})
  commit(:purchase, money, options.merge(credit_card: creditcard))
end
query() click to toggle source

Query the merchant account status

# File lib/active_merchant/billing/gateways/qbms.rb, line 112
def query
  commit(:query, nil, {})
end
refund(money, identification, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/qbms.rb, line 107
def refund(money, identification, options = {})
  commit(:refund, money, options.merge(transaction_id: identification))
end
scrub(transcript) click to toggle source
# File lib/active_merchant/billing/gateways/qbms.rb, line 120
def scrub(transcript)
  transcript.
    gsub(%r((<ConnectionTicket>)[^<]*(</ConnectionTicket>))i, '\1[FILTERED]\2').
    gsub(%r((<CreditCardNumber>)[^<]*(</CreditCardNumber>))i, '\1[FILTERED]\2').
    gsub(%r((<CardSecurityCode>)[^<]*(</CardSecurityCode>))i, '\1[FILTERED]\2')
end
supports_scrubbing?() click to toggle source
# File lib/active_merchant/billing/gateways/qbms.rb, line 116
def supports_scrubbing?
  true
end
void(authorization, options = {}) click to toggle source

Void a previous transaction

Parameters

  • authorization - The authorization returned from the previous authorize request.

# File lib/active_merchant/billing/gateways/qbms.rb, line 86
def void(authorization, options = {})
  commit(:void, nil, options.merge(transaction_id: authorization))
end

Private Instance Methods

add_address(xml, parameters) click to toggle source
# File lib/active_merchant/billing/gateways/qbms.rb, line 276
def add_address(xml, parameters)
  if address = parameters[:billing_address] || parameters[:address]
    xml.tag!('CreditCardAddress', (address[:address1] || '')[0...30])
    xml.tag!('CreditCardPostalCode', (address[:zip] || '')[0...9])
  end
end
avs_result(response) click to toggle source
# File lib/active_merchant/billing/gateways/qbms.rb, line 291
def avs_result(response)
  case "#{response[:avs_street]}|#{response[:avs_zip]}"
  when 'Pass|Pass'                 then 'D'
  when 'Pass|Fail'                 then 'A'
  when 'Pass|NotAvailable'         then 'B'
  when 'Fail|Pass'                 then 'Z'
  when 'Fail|Fail'                 then 'C'
  when 'Fail|NotAvailable'         then 'N'
  when 'NotAvailable|Pass'         then 'P'
  when 'NotAvailable|Fail'         then 'N'
  when 'NotAvailable|NotAvailable' then 'U'
  end
end
build_CustomerCreditCardAuth(xml, money, parameters) click to toggle source
# File lib/active_merchant/billing/gateways/qbms.rb, line 225
def build_CustomerCreditCardAuth(xml, money, parameters)
  cc = parameters[:credit_card]
  name = "#{cc.first_name} #{cc.last_name}"[0...30]

  xml.tag!('TransRequestID', parameters[:trans_request_id])
  xml.tag!('CreditCardNumber', cc.number)
  xml.tag!('ExpirationMonth', cc.month)
  xml.tag!('ExpirationYear', cc.year)
  xml.tag!('IsECommerce', 'true')
  xml.tag!('Amount', amount(money))
  xml.tag!('NameOnCard', name)
  add_address(xml, parameters)
  xml.tag!('CardSecurityCode', cc.verification_value) if cc.verification_value?
end
build_CustomerCreditCardCapture(xml, money, parameters) click to toggle source
# File lib/active_merchant/billing/gateways/qbms.rb, line 240
def build_CustomerCreditCardCapture(xml, money, parameters)
  xml.tag!('TransRequestID', parameters[:trans_request_id])
  xml.tag!('CreditCardTransID', parameters[:transaction_id])
  xml.tag!('Amount', amount(money))
end
build_CustomerCreditCardCharge(xml, money, parameters) click to toggle source
# File lib/active_merchant/billing/gateways/qbms.rb, line 246
def build_CustomerCreditCardCharge(xml, money, parameters)
  cc = parameters[:credit_card]
  name = "#{cc.first_name} #{cc.last_name}"[0...30]

  xml.tag!('TransRequestID', parameters[:trans_request_id])
  xml.tag!('CreditCardNumber', cc.number)
  xml.tag!('ExpirationMonth', cc.month)
  xml.tag!('ExpirationYear', cc.year)
  xml.tag!('IsECommerce', 'true')
  xml.tag!('Amount', amount(money))
  xml.tag!('NameOnCard', name)
  add_address(xml, parameters)
  xml.tag!('CardSecurityCode', cc.verification_value) if cc.verification_value?
end
build_CustomerCreditCardTxnVoid(xml, money, parameters) click to toggle source
# File lib/active_merchant/billing/gateways/qbms.rb, line 267
def build_CustomerCreditCardTxnVoid(xml, money, parameters)
  xml.tag!('TransRequestID', parameters[:trans_request_id])
  xml.tag!('CreditCardTransID', parameters[:transaction_id])
end
build_CustomerCreditCardTxnVoidOrRefund(xml, money, parameters) click to toggle source
# File lib/active_merchant/billing/gateways/qbms.rb, line 261
def build_CustomerCreditCardTxnVoidOrRefund(xml, money, parameters)
  xml.tag!('TransRequestID', parameters[:trans_request_id])
  xml.tag!('CreditCardTransID', parameters[:transaction_id])
  xml.tag!('Amount', amount(money))
end
build_MerchantAccountQuery(xml, money, parameters) click to toggle source

Called reflectively by build_request

# File lib/active_merchant/billing/gateways/qbms.rb, line 273
def build_MerchantAccountQuery(xml, money, parameters)
end
build_request(type, money, parameters = {}) click to toggle source
# File lib/active_merchant/billing/gateways/qbms.rb, line 200
def build_request(type, money, parameters = {})
  xml = Builder::XmlMarkup.new(indent: 0)

  xml.instruct!(:xml, version: '1.0', encoding: 'utf-8')
  xml.instruct!(:qbmsxml, version: API_VERSION)

  xml.tag!('QBMSXML') do
    xml.tag!('SignonMsgsRq') do
      xml.tag!(hosted? ? 'SignonAppCertRq' : 'SignonDesktopRq') do
        xml.tag!('ClientDateTime', Time.now.xmlschema)
        xml.tag!('ApplicationLogin', @options[:login])
        xml.tag!('ConnectionTicket', @options[:ticket])
      end
    end

    xml.tag!('QBMSXMLMsgsRq') do
      xml.tag!("#{type}Rq") do
        method("build_#{type}").call(xml, money, parameters)
      end
    end
  end

  xml.target!
end
commit(action, money, parameters) click to toggle source
# File lib/active_merchant/billing/gateways/qbms.rb, line 133
def commit(action, money, parameters)
  url = test? ? self.test_url : self.live_url

  type = TYPES[action]
  parameters[:trans_request_id] ||= SecureRandom.hex(10)

  req = build_request(type, money, parameters)

  data = ssl_post(url, req, 'Content-Type' => 'application/x-qbmsxml')
  response = parse(type, data)
  message = (response[:status_message] || '').strip

  Response.new(
    success?(response),
    message,
    response,
    test: test?,
    authorization: response[:credit_card_trans_id],
    fraud_review: fraud_review?(response),
    avs_result: { code: avs_result(response) },
    cvv_result: cvv_result(response)
  )
end
cvv_result(response) click to toggle source
# File lib/active_merchant/billing/gateways/qbms.rb, line 283
def cvv_result(response)
  case response[:card_security_code_match]
  when 'Pass'         then 'M'
  when 'Fail'         then 'N'
  when 'NotAvailable' then 'P'
  end
end
fraud_review?(response) click to toggle source
# File lib/active_merchant/billing/gateways/qbms.rb, line 161
def fraud_review?(response)
  [10100, 10101].member? response[:status_code]
end
hosted?() click to toggle source
# File lib/active_merchant/billing/gateways/qbms.rb, line 129
def hosted?
  @options[:pem]
end
parse(type, body) click to toggle source
# File lib/active_merchant/billing/gateways/qbms.rb, line 165
def parse(type, body)
  xml = REXML::Document.new(body)

  signon = REXML::XPath.first(xml, "//SignonMsgsRs/#{hosted? ? 'SignonAppCertRs' : 'SignonDesktopRs'}")
  status_code = signon.attributes['statusCode'].to_i

  if status_code != 0
    return {
      status_code: status_code,
      status_message: signon.attributes['statusMessage']
    }
  end

  response = REXML::XPath.first(xml, "//QBMSXMLMsgsRs/#{type}Rs")

  results = {
    status_code: response.attributes['statusCode'].to_i,
    status_message: response.attributes['statusMessage']
  }

  response.elements.each do |e|
    name  = e.name.underscore.to_sym
    value = e.text()

    if old_value = results[name]
      results[name] = [old_value] if !old_value.kind_of?(Array)
      results[name] << value
    else
      results[name] = value
    end
  end

  results
end
success?(response) click to toggle source
# File lib/active_merchant/billing/gateways/qbms.rb, line 157
def success?(response)
  response[:status_code] == 0
end