lib/active_merchant/billing/gateways/net_registry.rb
module ActiveMerchant
module Billing
# Gateway for netregistry.com.au.
#
# Note that NetRegistry itself uses gateway service providers. At the
# time of this writing, there are at least two (Quest and Ingenico).
# This module has only been tested with Quest.
#
# Also note that NetRegistry does not offer a test mode, nor does it
# have support for the authorize/capture/void functionality by default
# (you may arrange for this as described in "Programming for
# NetRegistry's E-commerce Gateway." [http://rubyurl.com/hNG]), and no
# #void functionality is documented. As a result, the #authorize and
# #capture have not yet been tested through a live gateway, and #void
# will raise an error.
#
# If you have this functionality enabled, please consider contributing
# to ActiveMerchant by writing tests/code for these methods, and
# submitting a patch.
#
# In addition to the standard ActiveMerchant functionality, the
# response will contain a 'receipt' parameter
# (response.params['receipt']) if a receipt was issued by the gateway.
class NetRegistryGateway < Gateway
self.live_url = self.test_url = 'https://paygate.ssllock.net/external2.pl'
FILTERED_PARAMS = %w[card_no card_expiry receipt_array]
self.supported_countries = ['AU']
# Note that support for Diners, Amex, and JCB require extra
# steps in setting up your account, as detailed in
# "Programming for NetRegistry's E-commerce Gateway."
# [http://rubyurl.com/hNG]
self.supported_cardtypes = %i[visa master diners_club american_express jcb]
self.display_name = 'NetRegistry'
self.homepage_url = 'http://www.netregistry.com.au'
TRANSACTIONS = {
authorization: 'preauth',
purchase: 'purchase',
capture: 'completion',
status: 'status',
refund: 'refund'
}
# Create a new NetRegistry gateway.
#
# Options :login and :password must be given.
def initialize(options = {})
requires!(options, :login, :password)
super
end
# Note that #authorize and #capture only work if your account
# vendor is St George, and if your account has been setup as
# described in "Programming for NetRegistry's E-commerce
# Gateway." [http://rubyurl.com/hNG]
def authorize(money, credit_card, options = {})
params = {
'AMOUNT' => amount(money),
'CCNUM' => credit_card.number,
'CCEXP' => expiry(credit_card)
}
add_request_details(params, options)
commit(:authorization, params)
end
# Note that #authorize and #capture only work if your account
# vendor is St George, and if your account has been setup as
# described in "Programming for NetRegistry's E-commerce
# Gateway." [http://rubyurl.com/hNG]
def capture(money, authorization, options = {})
requires!(options, :credit_card)
credit_card = options[:credit_card]
params = {
'PREAUTHNUM' => authorization,
'AMOUNT' => amount(money),
'CCNUM' => credit_card.number,
'CCEXP' => expiry(credit_card)
}
add_request_details(params, options)
commit(:capture, params)
end
def purchase(money, credit_card, options = {})
params = {
'AMOUNT' => amount(money),
'CCNUM' => credit_card.number,
'CCEXP' => expiry(credit_card)
}
add_request_details(params, options)
commit(:purchase, params)
end
def refund(money, identification, options = {})
params = {
'AMOUNT' => amount(money),
'TXNREF' => identification
}
add_request_details(params, options)
commit(:refund, params)
end
def credit(money, identification, options = {})
ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
refund(money, identification, options)
end
# Specific to NetRegistry.
#
# Run a 'status' command. This lets you view the status of a
# completed transaction.
#
def status(identification)
params = {
'TXNREF' => identification
}
commit(:status, params)
end
private
def add_request_details(params, options)
params['COMMENT'] = options[:description] unless options[:description].blank?
end
# Return the expiry for the given creditcard in the required
# format for a command.
def expiry(credit_card)
month = format(credit_card.month, :two_digits)
year = format(credit_card.year, :two_digits)
"#{month}/#{year}"
end
# Post the a request with the given parameters and return the
# response object.
#
# Login and password are added automatically, and the comment is
# omitted if nil.
def commit(action, params)
# get gateway response
response = parse(ssl_post(self.live_url, post_data(action, params)))
Response.new(
response['status'] == 'approved',
message_from(response),
response,
authorization: authorization_from(response, action)
)
end
def post_data(action, params)
params['COMMAND'] = TRANSACTIONS[action]
params['LOGIN'] = "#{@options[:login]}/#{@options[:password]}"
escape_uri(params.map { |k, v| "#{k}=#{v}" }.join('&'))
end
# The upstream is picky and so we can't use CGI.escape like we want to
def escape_uri(uri)
URI::DEFAULT_PARSER.escape(uri)
end
def parse(response)
params = {}
lines = response.split("\n")
# Just incase there is no real response returned
params['status'] = lines[0]
params['response_text'] = lines[1]
started = false
lines.each do |line|
if started
key, val = line.chomp.split(/=/, 2)
params[key] = val unless FILTERED_PARAMS.include?(key)
end
started = line.chomp =~ /^\.$/ unless started
end
params
end
def message_from(response)
response['response_text']
end
def authorization_from(response, command)
case command
when :purchase
response['txn_ref']
when :authorization
response['transaction_no']
end
end
end
end
end