class ActiveMerchant::Billing::SafeChargeGateway

Constants

VERSION

Public Class Methods

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

Public Instance Methods

authorize(money, payment, options={}) click to toggle source
# File lib/active_merchant/billing/gateways/safe_charge.rb, line 34
def authorize(money, payment, options={})
  post = {}
  add_transaction_data('Auth', post, money, options)
  add_payment(post, payment, options)
  add_customer_details(post, payment, options)

  commit(post)
end
capture(money, authorization, options={}) click to toggle source
# File lib/active_merchant/billing/gateways/safe_charge.rb, line 43
def capture(money, authorization, options={})
  post = {}
  auth, transaction_id, token, exp_month, exp_year, _, original_currency = authorization.split('|')
  add_transaction_data('Settle', post, money, options.merge!({currency: original_currency}))
  post[:sg_AuthCode] = auth
  post[:sg_TransactionID] = transaction_id
  post[:sg_CCToken] = token
  post[:sg_ExpMonth] = exp_month
  post[:sg_ExpYear] = exp_year

  commit(post)
end
credit(money, payment, options={}) click to toggle source
# File lib/active_merchant/billing/gateways/safe_charge.rb, line 70
def credit(money, payment, options={})
  post = {}
  add_payment(post, payment, options)
  add_transaction_data('Credit', post, money, options)
  post[:sg_CreditType] = 1

  commit(post)
end
purchase(money, payment, options={}) click to toggle source
# File lib/active_merchant/billing/gateways/safe_charge.rb, line 23
def purchase(money, payment, options={})
  post = {}
  post[:sg_APIType] = 1 if options[:three_d_secure]
  trans_type = options[:three_d_secure] ? 'Sale3D' : 'Sale'
  add_transaction_data(trans_type, post, money, options)
  add_payment(post, payment, options)
  add_customer_details(post, payment, options)

  commit(post)
end
refund(money, authorization, options={}) click to toggle source
# File lib/active_merchant/billing/gateways/safe_charge.rb, line 56
def refund(money, authorization, options={})
  post = {}
  auth, transaction_id, token, exp_month, exp_year, _, original_currency = authorization.split('|')
  add_transaction_data('Credit', post, money, options.merge!({currency: original_currency}))
  post[:sg_CreditType] = 2
  post[:sg_AuthCode] = auth
  post[:sg_TransactionID] = transaction_id
  post[:sg_CCToken] = token
  post[:sg_ExpMonth] = exp_month
  post[:sg_ExpYear] = exp_year

  commit(post)
end
scrub(transcript) click to toggle source
# File lib/active_merchant/billing/gateways/safe_charge.rb, line 104
def scrub(transcript)
  transcript.
    gsub(%r((sg_ClientPassword=)[^&]+(&?)), '\1[FILTERED]\2').
    gsub(%r((sg_CardNumber=)[^&]+(&?)), '\1[FILTERED]\2').
    gsub(%r((sg_CVV2=)\d+), '\1[FILTERED]')
end
supports_scrubbing?() click to toggle source
# File lib/active_merchant/billing/gateways/safe_charge.rb, line 100
def supports_scrubbing?
  true
end
verify(credit_card, options={}) click to toggle source
# File lib/active_merchant/billing/gateways/safe_charge.rb, line 93
def verify(credit_card, options={})
  MultiResponse.run(:use_first_response) do |r|
    r.process { authorize(100, credit_card, options) }
    r.process(:ignore_result) { void(r.authorization, options) }
  end
end
void(authorization, options={}) click to toggle source
# File lib/active_merchant/billing/gateways/safe_charge.rb, line 79
def void(authorization, options={})
  post = {}
  auth, transaction_id, token, exp_month, exp_year, original_amount, original_currency = authorization.split('|')
  add_transaction_data('Void', post, (original_amount.to_f * 100), options.merge!({currency: original_currency}))
  post[:sg_CreditType] = 2
  post[:sg_AuthCode] = auth
  post[:sg_TransactionID] = transaction_id
  post[:sg_CCToken] = token
  post[:sg_ExpMonth] = exp_month
  post[:sg_ExpYear] = exp_year

  commit(post)
end

Private Instance Methods

add_customer_details(post, payment, options) click to toggle source
# File lib/active_merchant/billing/gateways/safe_charge.rb, line 142
def add_customer_details(post, payment, options)
  if address = options[:billing_address] || options[:address]
    post[:sg_FirstName] = payment.first_name
    post[:sg_LastName] = payment.last_name
    post[:sg_Address] = address[:address1] if address[:address1]
    post[:sg_City] = address[:city] if address[:city]
    post[:sg_State] = address[:state]  if address[:state]
    post[:sg_Zip] = address[:zip]  if address[:zip]
    post[:sg_Country] = address[:country]  if address[:country]
    post[:sg_Phone] = address[:phone]  if address[:phone]
  end

  post[:sg_Email] = options[:email]
end
add_payment(post, payment, options={}) click to toggle source
# File lib/active_merchant/billing/gateways/safe_charge.rb, line 133
def add_payment(post, payment, options={})
  post[:sg_NameOnCard] = payment.name
  post[:sg_CardNumber] = payment.number
  post[:sg_ExpMonth] = format(payment.month, :two_digits)
  post[:sg_ExpYear] = format(payment.year, :two_digits)
  post[:sg_CVV2] = payment.verification_value
  post[:sg_StoredCredentialMode] = (options[:stored_credential_mode] == true ? 1 : 0)
end
add_transaction_data(trans_type, post, money, options) click to toggle source
# File lib/active_merchant/billing/gateways/safe_charge.rb, line 113
def add_transaction_data(trans_type, post, money, options)
  post[:sg_TransType] = trans_type
  post[:sg_Currency] = (options[:currency] || currency(money))
  post[:sg_Amount] = amount(money)
  post[:sg_ClientLoginID] = @options[:client_login_id]
  post[:sg_ClientPassword] = @options[:client_password]
  post[:sg_ResponseFormat] = '4'
  post[:sg_Version] = VERSION
  post[:sg_ClientUniqueID] = options[:order_id] if options[:order_id]
  post[:sg_UserID] = options[:user_id] if options[:user_id]
  post[:sg_AuthType] = options[:auth_type] if options[:auth_type]
  post[:sg_ExpectedFulfillmentCount] = options[:expected_fulfillment_count] if options[:expected_fulfillment_count]
  post[:sg_WebsiteID] = options[:website_id] if options[:website_id]
  post[:sg_IPAddress] = options[:ip] if options[:ip]
  post[:sg_VendorID] = options[:vendor_id] if options[:vendor_id]
  post[:sg_Descriptor] = options[:merchant_descriptor] if options[:merchant_descriptor]
  post[:sg_MerchantPhoneNumber] = options[:merchant_phone_number] if options[:merchant_phone_number]
  post[:sg_MerchantName] = options[:merchant_name] if options[:merchant_name]
end
authorization_from(response, parameters) click to toggle source
# File lib/active_merchant/billing/gateways/safe_charge.rb, line 213
def authorization_from(response, parameters)
  [
    response[:auth_code],
    response[:transaction_id],
    response[:token],
    parameters[:sg_ExpMonth],
    parameters[:sg_ExpYear],
    parameters[:sg_Amount],
    parameters[:sg_Currency]
  ].join('|')
end
childnode_to_response(response, childnode) click to toggle source
# File lib/active_merchant/billing/gateways/safe_charge.rb, line 173
def childnode_to_response(response, childnode)
  if childnode.elements.size == 0
    element_name_to_symbol(response, childnode)
  else
    childnode.traverse do |node|
      element_name_to_symbol(response, node)
    end
  end
end
commit(parameters) click to toggle source
# File lib/active_merchant/billing/gateways/safe_charge.rb, line 188
def commit(parameters)
  url = (test? ? test_url : live_url)
  response = parse(ssl_post(url, post_data(parameters)))

  Response.new(
    success_from(response),
    message_from(response),
    response,
    authorization: authorization_from(response, parameters),
    avs_result: AVSResult.new(code: response[:avs_code]),
    cvv_result: CVVResult.new(response[:cvv2_reply]),
    test: test?,
    error_code: error_code_from(response)
  )
end
element_name_to_symbol(response, childnode) click to toggle source
# File lib/active_merchant/billing/gateways/safe_charge.rb, line 183
def element_name_to_symbol(response, childnode)
  name = childnode.name.downcase
  response[name.to_sym] = childnode.text
end
error_code_from(response) click to toggle source
# File lib/active_merchant/billing/gateways/safe_charge.rb, line 247
def error_code_from(response)
  unless success_from(response)
    response[:ex_err_code] || response[:err_code]
  end
end
message_from(response) click to toggle source
# File lib/active_merchant/billing/gateways/safe_charge.rb, line 208
def message_from(response)
  return 'Success' if success_from(response)
  response[:reason_codes] || response[:reason]
end
parse(xml) click to toggle source
# File lib/active_merchant/billing/gateways/safe_charge.rb, line 157
def parse(xml)
  response = {}

  doc = Nokogiri::XML(xml)
  doc.root.xpath('*').each do |node|
    if node.elements.size == 0
      response[node.name.underscore.downcase.to_sym] = node.text
    else
      node.traverse do |childnode|
        childnode_to_response(response, childnode)
      end
    end
  end
  response
end
post_data(params) click to toggle source
# File lib/active_merchant/billing/gateways/safe_charge.rb, line 238
def post_data(params)
  return nil unless params

  params.map do |key, value|
    next if value != false && value.blank?
    "#{key}=#{CGI.escape(value.to_s)}"
  end.compact.join('&')
end
split_authorization(authorization) click to toggle source
# File lib/active_merchant/billing/gateways/safe_charge.rb, line 225
def split_authorization(authorization)
  auth_code, transaction_id, token, month, year, original_amount = authorization.split('|')

  {
    auth_code: auth_code,
    transaction_id: transaction_id,
    token: token,
    exp_month: month,
    exp_year: year,
    original_amount: amount(original_amount.to_f * 100)
  }
end
success_from(response) click to toggle source
# File lib/active_merchant/billing/gateways/safe_charge.rb, line 204
def success_from(response)
  response[:status] == 'APPROVED'
end
underscore(camel_cased_word) click to toggle source
# File lib/active_merchant/billing/gateways/safe_charge.rb, line 253
def underscore(camel_cased_word)
  camel_cased_word.to_s.gsub(/::/, '/').
    gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
    gsub(/([a-z\d])([A-Z])/, '\1_\2').
    tr('-', '_').
    downcase
end