class ActiveMerchant::Billing::OptimalPaymentGateway

Public Class Methods

new(options = {}) click to toggle source
Calls superclass method ActiveMerchant::Billing::Gateway::new
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 19
def initialize(options = {})

  if(options[:login])
    ActiveMerchant.deprecated("The 'login' option is deprecated in favor of 'store_id' and will be removed in a future version.")
    options[:store_id] = options[:login]
  end

  if(options[:account])
    ActiveMerchant.deprecated("The 'account' option is deprecated in favor of 'account_number' and will be removed in a future version.")
    options[:account_number] = options[:account]
  end

  requires!(options, :account_number, :store_id, :password)
  super
end

Public Instance Methods

authorize(money, card_or_auth, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 35
def authorize(money, card_or_auth, options = {})
  parse_card_or_auth(card_or_auth, options)
  commit("cc#{@stored_data}Authorize", money, options)
end
Also aliased as: stored_authorize
capture(money, authorization, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 57
def capture(money, authorization, options = {})
  options[:confirmationNumber] = authorization
  commit('ccSettlement', money, options)
end
purchase(money, card_or_auth, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 41
def purchase(money, card_or_auth, options = {})
  parse_card_or_auth(card_or_auth, options)
  commit("cc#{@stored_data}Purchase", money, options)
end
Also aliased as: stored_purchase
refund(money, authorization, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 47
def refund(money, authorization, options = {})
  options[:confirmationNumber] = authorization
  commit('ccCredit', money, options)
end
stored_authorize(money, card_or_auth, options = {})
Alias for: authorize
stored_purchase(money, card_or_auth, options = {})
Alias for: purchase
void(authorization, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 52
def void(authorization, options = {})
  options[:confirmationNumber] = authorization
  commit('ccAuthorizeReversal', nil, options)
end

Private Instance Methods

authorization_from(response) click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 128
def authorization_from(response)
  get_text_from_document(response, '//confirmationNumber')
end
avs_result_from(response) click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 132
def avs_result_from(response)
  get_text_from_document(response, '//avsResponse')
end
build_address(xml, addr) click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 284
def build_address(xml, addr)
  if addr[:name]
    xml.tag! 'firstName', addr[:name].split(' ').first
    xml.tag! 'lastName' , addr[:name].split(' ').last
  end
  xml.tag! 'street' , addr[:address1] if addr[:address1].present?
  xml.tag! 'street2', addr[:address2] if addr[:address2].present?
  xml.tag! 'city'   , addr[:city]     if addr[:city].present?
  if addr[:state].present?
    state_tag = %w(US CA).include?(addr[:country]) ? 'state' : 'region'
    xml.tag! state_tag, addr[:state]
  end
  xml.tag! 'country', addr[:country]  if addr[:country].present?
  xml.tag! 'zip'    , addr[:zip]      if addr[:zip].present?
  xml.tag! 'phone'  , addr[:phone]    if addr[:phone].present?
end
build_billing_details(xml, opts) click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 269
def build_billing_details(xml, opts)
  xml.tag! 'billingDetails' do
    xml.tag! 'cardPayMethod', 'WEB'
    build_address(xml, opts[:billing_address]) if opts[:billing_address]
    xml.tag! 'email', opts[:email] if opts[:email]
  end
end
build_card(xml, opts) click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 252
def build_card(xml, opts)
  xml.tag! 'card' do
    xml.tag! 'cardNum'      , @credit_card.number
    xml.tag! 'cardExpiry' do
      xml.tag! 'month'      , @credit_card.month
      xml.tag! 'year'       , @credit_card.year
    end
    if brand = card_type(@credit_card.brand)
      xml.tag! 'cardType'     , brand
    end
    if @credit_card.verification_value
      xml.tag! 'cvdIndicator' , '1' # Value Provided
      xml.tag! 'cvd'          , @credit_card.verification_value
    end
  end
end
build_merchant_account(xml) click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 244
def build_merchant_account(xml)
  xml.tag! 'merchantAccount' do
    xml.tag! 'accountNum' , @options[:account_number]
    xml.tag! 'storeID'    , @options[:store_id]
    xml.tag! 'storePwd'   , @options[:password]
  end
end
build_shipping_details(xml, opts) click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 277
def build_shipping_details(xml, opts)
  xml.tag! 'shippingDetails' do
    build_address(xml, opts[:shipping_address])
    xml.tag! 'email', opts[:email] if opts[:email]
  end if opts[:shipping_address].present?
end
card_type(key) click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 301
def card_type(key)
  { 'visa'            => 'VI',
    'master'          => 'MC',
    'american_express'=> 'AM',
    'discover'        => 'DI',
    'diners_club'     => 'DC',
    #'switch'          => '',
    'solo'            => 'SO'
  }[key]
end
cc_auth_request(money, opts) click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 172
def cc_auth_request(money, opts)
  xml_document('ccAuthRequestV1') do |xml|
    build_merchant_account(xml)
    xml.merchantRefNum opts[:order_id]
    xml.amount(money/100.0)
    build_card(xml, opts)
    build_billing_details(xml, opts)
    build_shipping_details(xml, opts)
    xml.customerIP opts[:ip] if opts[:ip]
  end
end
cc_auth_reversal_request(opts) click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 184
def cc_auth_reversal_request(opts)
  xml_document('ccAuthReversalRequestV1') do |xml|
    build_merchant_account(xml)
    xml.confirmationNumber opts[:confirmationNumber]
    xml.merchantRefNum opts[:order_id]
  end
end
cc_post_auth_request(money, opts) click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 192
def cc_post_auth_request(money, opts)
  xml_document('ccPostAuthRequestV1') do |xml|
    build_merchant_account(xml)
    xml.confirmationNumber opts[:confirmationNumber]
    xml.merchantRefNum opts[:order_id]
    xml.amount(money/100.0)
  end
end
cc_stored_data_request(money, opts) click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 201
def cc_stored_data_request(money, opts)
  xml_document('ccStoredDataRequestV1') do |xml|
    build_merchant_account(xml)
    xml.merchantRefNum opts[:order_id]
    xml.confirmationNumber opts[:confirmationNumber]
    xml.amount(money/100.0)
  end
end
commit(action, money, post) click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 78
def commit(action, money, post)
  post[:order_id] ||= 'order_id'

  xml = case action
  when 'ccAuthorize', 'ccPurchase', 'ccVerification'
    cc_auth_request(money, post)
  when 'ccCredit', 'ccSettlement'
    cc_post_auth_request(money, post)
  when 'ccStoredDataAuthorize', 'ccStoredDataPurchase'
    cc_stored_data_request(money, post)
  when 'ccAuthorizeReversal'
    cc_auth_reversal_request(post)
  #when 'ccCancelSettle', 'ccCancelCredit', 'ccCancelPayment'
  #  cc_cancel_request(money, post)
  #when 'ccPayment'
  #  cc_payment_request(money, post)
  #when 'ccAuthenticate'
  #  cc_authenticate_request(money, post)
  else
    raise 'Unknown Action'
  end
  txnRequest = escape_uri(xml)
  response = parse(ssl_post(test? ? self.test_url : self.live_url, "txnMode=#{action}&txnRequest=#{txnRequest}"))

  Response.new(successful?(response), message_from(response), hash_from_xml(response),
    :test          => test?,
    :authorization => authorization_from(response),
    :avs_result => { :code => avs_result_from(response) },
    :cvv_result => cvv_result_from(response)
  )
end
cvv_result_from(response) click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 136
def cvv_result_from(response)
  get_text_from_document(response, '//cvdResponse')
end
escape_uri(uri) click to toggle source

The upstream is picky and so we can't use CGI.escape like we want to

# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 111
def escape_uri(uri)
  URI::DEFAULT_PARSER.escape(uri)
end
get_text_from_document(document, node) click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 167
def get_text_from_document(document, node)
  node = REXML::XPath.first(document, node)
  node && node.text
end
hash_from_xml(response) click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 140
def hash_from_xml(response)
  hsh = {}
  %w(confirmationNumber authCode
     decision code description
     actionCode avsResponse cvdResponse
     txnTime duplicateFound
  ).each do |tag|
    node = REXML::XPath.first(response, "//#{tag}")
    hsh[tag] = node.text if node
  end
  REXML::XPath.each(response, '//detail') do |detail|
    next unless detail.is_a?(REXML::Element)
    tag = detail.elements['tag'].text
    value = detail.elements['value'].text
    hsh[tag] = value
  end
  hsh
end
message_from(response) click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 119
def message_from(response)
  REXML::XPath.each(response, '//detail') do |detail|
    if detail.is_a?(REXML::Element) && detail.elements['tag'].text == 'InternalResponseDescription'
      return detail.elements['value'].text
    end
  end
  nil
end
parse(body) click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 74
def parse(body)
  REXML::Document.new(body || '')
end
parse_card_or_auth(card_or_auth, options) click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 64
def parse_card_or_auth(card_or_auth, options)
  if card_or_auth.respond_to?(:number)
    @credit_card = card_or_auth
    @stored_data = ""
  else
    options[:confirmationNumber] = card_or_auth
    @stored_data = "StoredData"
  end
end
schema() click to toggle source

untested

def cc_cancel_request(opts)

xml_document('ccCancelRequestV1') do |xml|
  build_merchant_account(xml)
  xml.confirmationNumber opts[:confirmationNumber]
end

end

def cc_payment_request(money, opts)

xml_document('ccPaymentRequestV1') do |xml|
  build_merchant_account(xml)
  xml.merchantRefNum opts[:order_id]
  xml.amount(money/100.0)
  build_card(xml, opts)
  build_billing_details(xml, opts)
end

end

def cc_authenticate_request(opts)

xml_document('ccAuthenticateRequestV1') do |xml|
  build_merchant_account(xml)
  xml.confirmationNumber opts[:confirmationNumber]
  xml.paymentResponse 'myPaymentResponse'
end

end

# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 237
def schema
  { 'xmlns' => 'http://www.optimalpayments.com/creditcard/xmlschema/v1',
    'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
    'xsi:schemaLocation' => 'http://www.optimalpayments.com/creditcard/xmlschema/v1'
  }
end
successful?(response) click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 115
def successful?(response)
  REXML::XPath.first(response, '//decision').text == 'ACCEPTED' rescue false
end
xml_document(root_tag) { |xml| ... } click to toggle source
# File lib/active_merchant/billing/gateways/optimal_payment.rb, line 159
def xml_document(root_tag)
  xml = Builder::XmlMarkup.new :indent => 2
  xml.tag!(root_tag, schema) do
    yield xml
  end
  xml.target!
end