lib/active_merchant/billing/gateways/bank_frick.rb
require 'nokogiri'
module ActiveMerchant #:nodoc:
module Billing #:nodoc:
# For more information visit {Bank Frick Acquiring Services}[http://www.bankfrickacquiring.com/merchantsolutions_en.html]
#
# Written by Piers Chambers (Varyonic.com)
class BankFrickGateway < Gateway
self.test_url = 'https://test.ctpe.io/payment/ctpe'
self.live_url = 'https://ctpe.io/payment/ctpe'
self.supported_countries = %w[LI US]
self.default_currency = 'EUR'
self.supported_cardtypes = %i[visa master american_express discover]
self.homepage_url = 'http://www.bankfrickacquiring.com/'
self.display_name = 'Bank Frick'
# The set of supported transactions for this gateway.
# More operations are supported by the gateway itself, but
# are not supported in this library.
SUPPORTED_TRANSACTIONS = {
'sale' => 'CC.DB',
'authonly' => 'CC.PA',
'capture' => 'CC.CP',
'refund' => 'CC.RF',
'void' => 'CC.RV'
}
def initialize(options = {})
requires!(options, :sender, :channel, :userid, :userpwd)
super
end
def purchase(money, payment, options = {})
post = {}
add_invoice(post, money, options)
add_payment(post, payment)
add_address(post, payment, options)
add_customer_data(post, options)
commit('sale', post)
end
def authorize(money, payment, options = {})
post = {}
add_invoice(post, money, options)
add_payment(post, payment)
add_address(post, payment, options)
add_customer_data(post, options)
commit('authonly', post)
end
def capture(money, authorization, options = {})
post = {}
post[:authorization] = authorization
add_invoice(post, money, options)
commit('capture', post)
end
def refund(money, authorization, options = {})
post = {}
post[:authorization] = authorization
add_invoice(post, money, options)
commit('refund', post)
end
def void(authorization, options = {})
post = {}
post[:authorization] = authorization
commit('void', post)
end
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
private
def add_customer_data(post, options)
post[:email] = options[:email] || 'noone@example.com'
post[:ip] = options[:ip] || '0.0.0.0'
end
def add_address(post, creditcard, options)
if address = options[:billing_address] || options[:address]
post[:address] = address[:address1].to_s
post[:company] = address[:company].to_s
post[:phone] = address[:phone].to_s.gsub(/[^0-9]/, '') || '0000000'
post[:zip] = address[:zip].to_s
post[:city] = address[:city].to_s
post[:country] = address[:country].to_s
post[:state] = address[:state].blank? ? 'n/a' : address[:state]
end
end
def add_invoice(post, money, options)
post[:order_id] = options[:order_id] if post.has_key? :order_id
post[:amount] = amount(money)
post[:currency] = (options[:currency] || currency(money))
post[:description] = options[:description]
end
def add_payment(post, payment)
post[:first_name] = payment.first_name
post[:last_name] = payment.last_name
post[:brand] = payment.brand
post[:card_num] = payment.number
post[:card_code] = payment.verification_value if payment.verification_value?
post[:exp_year] = payment.year
post[:exp_month] = payment.month
end
def parse(body)
results = {}
xml = Nokogiri::XML(body)
resp = xml.xpath('//Response/Transaction/Identification')
resp.children.each do |element|
results[element.name.downcase.to_sym] = element.text
end
resp = xml.xpath('//Response/Transaction/Processing')
resp.children.each do |element|
results[element.name.downcase.to_sym] = element.text
end
results
end
def commit(action, parameters)
url = (test? ? test_url : live_url)
headers = {
'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8'
}
response = parse(ssl_post(url, post_data(action, parameters), headers))
Response.new(
success_from(response),
message_from(response),
response,
authorization: authorization_from(response),
test: test?
)
end
def success_from(response)
response[:result] == 'ACK'
end
def message_from(response)
response[:return]
end
def authorization_from(response)
response[:uniqueid]
end
def post_data(action, parameters = {})
xml = build_xml_request(action, parameters)
"load=#{CGI.escape(xml)}"
end
def build_xml_request(action, data)
xml = Builder::XmlMarkup.new indent: 2
xml.Request(version: '1.0') do
xml.Header do
xml.Security(sender: @options[:sender], type: 'MERCHANT')
end
xml.Transaction(response: 'SYNC', channel: @options[:channel], mode: 'LIVE') do
xml.User(pwd: @options[:userpwd], login: @options[:userid])
xml.Identification do
xml.TransactionID data[:order_id] if data.has_key? :order_id
xml.ReferenceID data[:authorization] if data.has_key? :authorization
end
xml.Account do
xml.Holder "#{data[:first_name]} #{data[:last_name]}"
xml.Brand data[:brand]
xml.Number data[:card_num]
xml.Bank data[:bankname]
xml.Country data[:country]
xml.Authorization data[:authorization]
xml.Verification data[:card_code]
xml.Year data[:exp_year]
xml.Month data[:exp_month]
end if data.has_key? :card_num
xml.Payment(code: SUPPORTED_TRANSACTIONS[action]) do
xml.Presentation do
xml.Amount data[:amount]
xml.Currency data[:currency]
xml.Usage data[:description]
end
end
xml.Customer do
xml.Contact do
xml.Email data[:email]
xml.Mobile data[:mobile]
xml.Ip data[:ip]
xml.Phone data[:phone]
end
xml.Address do
xml.Street data[:address]
xml.Zip data[:zip]
xml.City data[:city]
xml.State data[:state]
xml.Country data[:country]
end
xml.Name do
xml.Salutation data[:salutation]
xml.Title data[:title]
xml.Given data[:first_name]
xml.Family data[:last_name]
xml.Company data[:company]
end
end if data.has_key? :last_name
end
end
end
end
end
end