lib/active_merchant/billing/gateways/cc5.rb
module ActiveMerchant #:nodoc:
module Billing #:nodoc:
# CC5 API is used by many banks in Turkey. Extend this base class to provide
# concrete implementations.
class CC5Gateway < Gateway
self.default_currency = 'TRY'
CURRENCY_CODES = {
'TRY' => 949,
'YTL' => 949,
'TRL' => 949,
'TL' => 949,
'USD' => 840,
'EUR' => 978,
'GBP' => 826,
'JPY' => 392
}
def initialize(options = {})
requires!(options, :login, :password, :client_id)
super
end
def purchase(money, creditcard, options = {})
commit(build_sale_request('Auth', money, creditcard, options))
end
def authorize(money, creditcard, options = {})
commit(build_sale_request('PreAuth', money, creditcard, options))
end
def capture(money, authorization, options = {})
commit(build_capture_request(money, authorization, options))
end
def void(authorization, options = {})
commit(build_void_request(authorization, options))
end
def refund(money, authorization, options = {})
commit(build_authorization_credit_request(money, authorization, options))
end
def credit(money, creditcard, options = {})
commit(build_creditcard_credit_request(money, creditcard, options))
end
protected
def build_sale_request(type, money, creditcard, options = {})
requires!(options, :order_id)
xml = Builder::XmlMarkup.new indent: 2
xml.tag! 'CC5Request' do
add_login_tags(xml)
xml.tag! 'OrderId', options[:order_id]
xml.tag! 'Type', type
xml.tag! 'Number', creditcard.number
xml.tag! 'Expires', [format(creditcard.month, :two_digits), format(creditcard.year, :two_digits)].join('/')
xml.tag! 'Cvv2Val', creditcard.verification_value
add_amount_tags(money, options, xml)
xml.tag! 'Email', options[:email] if options[:email]
if (address = (options[:billing_address] || options[:address]))
xml.tag! 'BillTo' do
add_address(xml, address)
end
xml.tag! 'ShipTo' do
add_address(xml, address)
end
end
end
xml.target!
end
def build_capture_request(money, authorization, options = {})
xml = Builder::XmlMarkup.new indent: 2
xml.tag! 'CC5Request' do
add_login_tags(xml)
xml.tag! 'OrderId', authorization
xml.tag! 'Type', 'PostAuth'
add_amount_tags(money, options, xml)
end
end
def build_void_request(authorization, options = {})
xml = Builder::XmlMarkup.new indent: 2
xml.tag! 'CC5Request' do
add_login_tags(xml)
xml.tag! 'OrderId', authorization
xml.tag! 'Type', 'Void'
end
end
def build_authorization_credit_request(money, authorization, options = {})
xml = Builder::XmlMarkup.new indent: 2
xml.tag! 'CC5Request' do
add_login_tags(xml)
xml.tag! 'OrderId', authorization
xml.tag! 'Type', 'Credit'
add_amount_tags(money, options, xml)
end
end
def build_creditcard_credit_request(money, creditcard, options = {})
xml = Builder::XmlMarkup.new indent: 2
xml.tag! 'CC5Request' do
add_login_tags(xml)
xml.tag! 'Type', 'Credit'
xml.tag! 'Number', creditcard.number
add_amount_tags(money, options, xml)
end
end
def add_address(xml, address)
xml.tag! 'Name', normalize(address[:name])
xml.tag! 'Street1', normalize(address[:address1])
xml.tag! 'Street2', normalize(address[:address2]) if address[:address2]
xml.tag! 'City', normalize(address[:city])
xml.tag! 'PostalCode', address[:zip]
xml.tag! 'Country', normalize(address[:country])
xml.tag! 'Company', normalize(address[:company])
xml.tag! 'TelVoice', address[:phone].to_s.gsub(/[^0-9]/, '') if address[:phone]
end
def add_login_tags(xml)
xml.tag! 'Name', @options[:login]
xml.tag! 'Password', @options[:password]
xml.tag! 'ClientId', @options[:client_id]
xml.tag! 'Mode', (test? ? 'T' : 'P')
end
def add_amount_tags(money, options, xml)
xml.tag! 'Total', amount(money)
xml.tag! 'Currency', currency_code(options[:currency] || currency(money))
end
def currency_code(currency)
(CURRENCY_CODES[currency] || CURRENCY_CODES[default_currency])
end
def commit(request)
raw_response = ssl_post((test? ? self.test_url : self.live_url), 'DATA=' + request)
response = parse(raw_response)
success = success?(response)
Response.new(
success,
(success ? 'Approved' : "Declined (Reason: #{response[:proc_return_code]} - #{response[:err_msg]})"),
response,
test: test?,
authorization: response[:order_id]
)
end
def parse(body)
xml = REXML::Document.new(body)
response = {}
xml.root.elements.to_a.each do |node|
parse_element(response, node)
end
response
end
def parse_element(response, node)
if node.has_elements?
node.elements.each { |element| parse_element(response, element) }
else
response[node.name.underscore.to_sym] = node.text
end
end
def success?(response)
(response[:response] == 'Approved')
end
def normalize(text)
return unless text
if ActiveSupport::Inflector.method(:transliterate).arity == -2
ActiveSupport::Inflector.transliterate(text, '')
else
text.gsub(/[^\x00-\x7F]+/, '')
end
end
end
end
end