lib/active_merchant/billing/gateways/borgun.rb in activemerchant-1.126.0 vs lib/active_merchant/billing/gateways/borgun.rb in activemerchant-1.129.0
- old
+ new
@@ -21,22 +21,38 @@
super
end
def purchase(money, payment, options = {})
post = {}
- post[:TransType] = '1'
+ action = ''
+ if options[:apply_3d_secure] == '1'
+ add_3ds_preauth_fields(post, options)
+ action = '3ds_preauth'
+ else
+ post[:TransType] = '1'
+ add_3ds_fields(post, options)
+ action = 'sale'
+ end
add_invoice(post, money, options)
add_payment_method(post, payment)
- commit('sale', post)
+ commit(action, post, options)
end
def authorize(money, payment, options = {})
post = {}
- post[:TransType] = '5'
+ action = ''
+ if options[:apply_3d_secure] == '1'
+ add_3ds_preauth_fields(post, options)
+ action = '3ds_preauth'
+ else
+ post[:TransType] = '5'
+ add_3ds_fields(post, options)
+ action = 'authonly'
+ end
add_invoice(post, money, options)
add_payment_method(post, payment)
- commit('authonly', post, options)
+ commit(action, post, options)
end
def capture(money, authorization, options = {})
post = {}
post[:TransType] = '1'
@@ -79,13 +95,30 @@
CURRENCY_CODES = Hash.new { |_h, k| raise ArgumentError.new("Unsupported currency for HDFC: #{k}") }
CURRENCY_CODES['ISK'] = '352'
CURRENCY_CODES['EUR'] = '978'
CURRENCY_CODES['USD'] = '840'
+ def add_3ds_fields(post, options)
+ post[:ThreeDSMessageId] = options[:three_ds_message_id] if options[:three_ds_message_id]
+ post[:ThreeDS_PARes] = options[:three_ds_pares] if options[:three_ds_pares]
+ post[:ThreeDS_CRes] = options[:three_ds_cres] if options[:three_ds_cres]
+ end
+
+ def add_3ds_preauth_fields(post, options)
+ post[:SaleDescription] = options[:sale_description] || ''
+ post[:MerchantReturnURL] = options[:merchant_return_url] if options[:merchant_return_url]
+ end
+
def add_invoice(post, money, options)
post[:TrAmount] = amount(money)
post[:TrCurrency] = CURRENCY_CODES[options[:currency] || currency(money)]
+ # The ISK currency must have a currency exponent of 2 on the 3DS request but not on the auth request
+ if post[:TrCurrency] == '352' && options[:apply_3d_secure] == '1'
+ post[:TrCurrencyExponent] = 2
+ else
+ post[:TrCurrencyExponent] = 0
+ end
post[:TerminalID] = options[:terminal_id] || '1'
end
def add_payment_method(post, payment_method)
post[:PAN] = payment_method.number
@@ -101,15 +134,15 @@
post[:Transaction] = transaction
post[:RRN] = rrn
post[:AuthCode] = authcode
end
- def parse(xml)
+ def parse(xml, options = nil)
response = {}
doc = Nokogiri::XML(CGI.unescapeHTML(xml))
- body = doc.xpath('//getAuthorizationReply')
+ body = options[:apply_3d_secure] == '1' ? doc.xpath('//get3DSAuthenticationReply') : doc.xpath('//getAuthorizationReply')
body = doc.xpath('//cancelAuthorizationReply') if body.length == 0
body.children.each do |node|
if node.text?
next
elsif node.elements.size == 0
@@ -119,22 +152,21 @@
name = "#{node.name.downcase}_#{childnode.name.downcase}"
response[name.to_sym] = childnode.text
end
end
end
-
response
end
def commit(action, post, options = {})
post[:Version] = '1000'
post[:Processor] = @options[:processor]
post[:MerchantID] = @options[:merchant_id]
request = build_request(action, post, options)
raw = ssl_post(url(action), request, headers)
- pairs = parse(raw)
+ pairs = parse(raw, options)
success = success_from(pairs)
Response.new(
success,
message_from(success, pairs),
@@ -143,11 +175,11 @@
test: test?
)
end
def success_from(response)
- (response[:actioncode] == '000')
+ (response[:actioncode] == '000') || (response[:status_resultcode] == '0')
end
def message_from(succeeded, response)
if succeeded
'Succeeded'
@@ -180,20 +212,21 @@
}
end
def build_request(action, post, options = {})
mode = action == 'void' ? 'cancel' : 'get'
+ transaction_type = action == '3ds_preauth' ? '3DSAuthentication' : 'Authorization'
xml = Builder::XmlMarkup.new indent: 18
xml.instruct!(:xml, version: '1.0', encoding: 'utf-8')
- xml.tag!("#{mode}Authorization") do
+ xml.tag!("#{mode}#{transaction_type}") do
post.each do |field, value|
xml.tag!(field, value)
end
build_airline_xml(xml, options[:passenger_itinerary_data]) if options[:passenger_itinerary_data]
end
inner = CGI.escapeHTML(xml.target!)
- envelope(mode).sub(/{{ :body }}/, inner)
+ envelope(mode, action).sub(/{{ :body }}/, inner)
end
def build_airline_xml(xml, airline_data)
xml.tag!('PassengerItineraryData') do
xml.tag!('A1') do
@@ -202,19 +235,26 @@
end
end
end
end
- def envelope(mode)
+ def envelope(mode, action)
+ if action == '3ds_preauth'
+ transaction_action = "#{mode}3DSAuthentication"
+ request_action = "#{mode}Auth3DSReqXml"
+ else
+ transaction_action = "#{mode}AuthorizationInput"
+ request_action = "#{mode}AuthReqXml"
+ end
<<-XML
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:aut="http://Borgun/Heimir/pub/ws/Authorization">
<soapenv:Header/>
<soapenv:Body>
- <aut:#{mode}AuthorizationInput>
- <#{mode}AuthReqXml>
+ <aut:#{transaction_action}>
+ <#{request_action}>
{{ :body }}
- </#{mode}AuthReqXml>
- </aut:#{mode}AuthorizationInput>
+ </#{request_action}>
+ </aut:#{transaction_action}>
</soapenv:Body>
</soapenv:Envelope>
XML
end