lib/active_merchant/billing/gateways/secure_net.rb in activemerchant-1.35.1 vs lib/active_merchant/billing/gateways/secure_net.rb in activemerchant-1.36.0

- old
+ new

@@ -3,211 +3,123 @@ class SecureNetGateway < Gateway API_VERSION = "4.0" TRANSACTIONS = { - :auth_only => "0000", # - :partial_auth_only => "0001", - :auth_capture => "0100", # - :partial_auth_capture => "0101", + :auth_only => "0000", + :auth_capture => "0100", :prior_auth_capture => "0200", - :capture_only => "0300", # - :void => "0400", # - :partial_void => "0401", - :credit => "0500", # - :credit_authonly => "0501", - :credit_priorauthcapture => "0502", - :force_credit => "0600", - :force_credit_authonly => "0601", - :force_credit_priorauthcapture => "0602", - :verification => "0700", - :auth_increment => "0800", - :issue => "0900", - :activate => "0901", - :redeem => "0902", - :redeem_partial => "0903", - :deactivate => "0904", - :reactivate => "0905", - :inquiry_balance => "0906" + :void => "0400", + :credit => "0500" } - XML_ATTRIBUTES = { 'xmlns' => "http://gateway.securenet.com/API/Contracts", - 'xmlns:i' => "http://www.w3.org/2001/XMLSchema-instance" + XML_ATTRIBUTES = { + 'xmlns' => "http://gateway.securenet.com/API/Contracts", + 'xmlns:i' => "http://www.w3.org/2001/XMLSchema-instance" } NIL_ATTRIBUTE = { 'i:nil' => "true" } -# SUCCESS = "true" -# SENSITIVE_FIELDS = [ :verification_str2, :expiry_date, :card_number ] - self.supported_countries = ['US'] self.supported_cardtypes = [:visa, :master, :american_express, :discover] self.homepage_url = 'http://www.securenet.com/' self.display_name = 'SecureNet' -# self.wiredump_device = STDOUT -# self.test_url = 'https://certify.securenet.com/api/Gateway.svc' self.test_url = 'https://certify.securenet.com/API/gateway.svc/webHttp/ProcessTransaction' self.live_url = 'https://gateway.securenet.com/api/Gateway.svc' - APPROVED, DECLINED, ERROR = 1, 2, 3 + APPROVED, DECLINED = 1, 2 - RESPONSE_CODE, RESPONSE_REASON_CODE, RESPONSE_REASON_TEXT = 0, 2, 3 - AVS_RESULT_CODE, CARD_CODE_RESPONSE_CODE, TRANSACTION_ID = 5, 6, 8 - CARD_CODE_ERRORS = %w( N S ) AVS_ERRORS = %w( A E N R W Z ) def initialize(options = {}) requires!(options, :login, :password) super end def authorize(money, creditcard, options = {}) - commit(build_sale_or_authorization_request(creditcard, options, :auth_only), money) + commit(build_sale_or_authorization(creditcard, options, :auth_only, money)) end def purchase(money, creditcard, options = {}) - commit(build_sale_or_authorization_request(creditcard, options, :auth_capture), money) + commit(build_sale_or_authorization(creditcard, options, :auth_capture, money)) end - def capture(money, creditcard, authorization, options = {}) - commit(build_capture_request(authorization, creditcard, options, :prior_auth_capture), money) + def capture(money, authorization, options = {}) + commit(build_capture_refund_void(authorization, options, :prior_auth_capture, money)) end - def void(money, creditcard, authorization, options = {}) - commit(build_void_request(authorization, creditcard, options, :void), money) + def void(authorization, options = {}) + commit(build_capture_refund_void(authorization, options, :void)) end - def credit(money, creditcard, authorization, options = {}) - commit(build_credit_request(authorization, creditcard, options, :credit), money) + def refund(money, authorization, options = {}) + commit(build_capture_refund_void(authorization, options, :credit, money)) end + def credit(money, authorization, options = {}) + deprecated CREDIT_DEPRECATION_MESSAGE + refund(money, authorization, options) + end + + private - def commit(request, money) - xml = build_request(request, money) + def commit(request) + xml = build_request(request) data = ssl_post(self.test_url, xml, "Content-Type" => "text/xml") response = parse(data) test_mode = test? Response.new(success?(response), message_from(response), response, :test => test_mode, - :authorization => response[:transactionid], + :authorization => build_authorization(response), :avs_result => { :code => response[:avs_result_code] }, :cvv_result => response[:card_code_response_code] ) end - def build_request(request, money) + def build_request(request) xml = Builder::XmlMarkup.new xml.instruct! xml.tag!("TRANSACTION", XML_ATTRIBUTES) do - xml.tag! 'AMOUNT', amount(money) xml << request end xml.target! end - def build_sale_or_authorization_request(creditcard, options, action) + def build_sale_or_authorization(creditcard, options, action, money) xml = Builder::XmlMarkup.new + xml.tag! 'AMOUNT', amount(money) add_credit_card(xml, creditcard) - xml.tag! 'CODE', TRANSACTIONS[action] - add_customer_data(xml, options) + add_required_params(xml, action, options) add_address(xml, creditcard, options) - xml.tag! 'DCI', 0 # No duplicate checking will be done, except for ORDERID - xml.tag! 'INSTALLMENT_SEQUENCENUM', 1 add_invoice(xml, options) - add_merchant_key(xml, options) - xml.tag! 'METHOD', 'CC' - xml.tag! 'ORDERID', options[:order_id]#'30'.to_i.to_s#'22'# @options[:order_id] - xml.tag! 'OVERRIDE_FROM', 0 # Docs say not required, but doesn't work without it - xml.tag! 'RETAIL_LANENUM', '0' # Docs say string, but it's an integer!? - xml.tag! 'TEST', 'TRUE' - xml.tag! 'TOTAL_INSTALLMENTCOUNT', 0 - xml.tag! 'TRANSACTION_SERVICE', 0 + add_more_required_params(xml, options) xml.target! end - def build_capture_or_credit_request(identification, options) + def build_capture_refund_void(authorization, options, action, money = nil) xml = Builder::XmlMarkup.new - add_identification(xml, identification) - add_customer_data(xml, options) + transaction_id, amount_in_ref, last_four = split_authorization(authorization) - xml.target! - end + xml.tag! 'AMOUNT', amount(money) || amount_in_ref + xml.tag!("CARD") do + xml.tag! 'CARDNUMBER', last_four + end - def build_capture_request(authorization, creditcard, options, action) - xml = Builder::XmlMarkup.new + add_required_params(xml, action, options) + xml.tag! 'REF_TRANSID', transaction_id + add_more_required_params(xml, options) - add_credit_card(xml, creditcard) - xml.tag! 'CODE', TRANSACTIONS[action] - add_customer_data(xml, options) - xml.tag! 'DCI', 0 # No duplicate checking will be done, except for ORDERID - xml.tag! 'INSTALLMENT_SEQUENCENUM', 1 - add_merchant_key(xml, options) - xml.tag! 'METHOD', 'CC' - xml.tag! 'ORDERID', options[:order_id]#'30'.to_i.to_s#'22'# @options[:order_id] - xml.tag! 'OVERRIDE_FROM', 0 # Docs say not required, but doesn't work without it - xml.tag! 'REF_TRANSID', authorization - xml.tag! 'RETAIL_LANENUM', '0' # Docs say string, but it's an integer!? - xml.tag! 'TEST', 'TRUE' - xml.tag! 'TOTAL_INSTALLMENTCOUNT', 0 - xml.tag! 'TRANSACTION_SERVICE', 0 - xml.target! end - def build_credit_request(authorization, creditcard, options, action) -# requires!(options, :card_number) - xml = Builder::XmlMarkup.new - - add_credit_card(xml, creditcard) - xml.tag! 'CODE', TRANSACTIONS[action] - add_customer_data(xml, options) - xml.tag! 'DCI', 0 # No duplicate checking will be done, except for ORDERID - xml.tag! 'INSTALLMENT_SEQUENCENUM', 1 - add_merchant_key(xml, options) - xml.tag! 'METHOD', 'CC' - xml.tag! 'ORDERID', options[:order_id]#'30'.to_i.to_s#'22'# @options[:order_id] - xml.tag! 'OVERRIDE_FROM', 0 # Docs say not required, but doesn't work without it - xml.tag! 'REF_TRANSID', authorization - xml.tag! 'RETAIL_LANENUM', '0' # Docs say string, but it's an integer!? - xml.tag! 'TEST', 'TRUE' - xml.tag! 'TOTAL_INSTALLMENTCOUNT', 0 - xml.tag! 'TRANSACTION_SERVICE', 0 - - xml.target! - end - - def build_void_request(authorization, creditcard, options, action) - xml = Builder::XmlMarkup.new - - add_credit_card(xml, creditcard) - xml.tag! 'CODE', TRANSACTIONS[action] - add_customer_data(xml, options) - xml.tag! 'DCI', 0 # No duplicate checking will be done, except for ORDERID - xml.tag! 'INSTALLMENT_SEQUENCENUM', 1 - add_merchant_key(xml, options) - xml.tag! 'METHOD', 'CC' - xml.tag! 'ORDERID', options[:order_id]#'30'.to_i.to_s#'22'# @options[:order_id] - xml.tag! 'OVERRIDE_FROM', 0 # Docs say not required, but doesn't work without it - xml.tag! 'REF_TRANSID', authorization - xml.tag! 'RETAIL_LANENUM', '0' # Docs say string, but it's an integer!? - xml.tag! 'TEST', 'TRUE' - xml.tag! 'TOTAL_INSTALLMENTCOUNT', 0 - xml.tag! 'TRANSACTION_SERVICE', 0 - - xml.target! - end - - ######################################################################### - # FUNCTIONS RELATED TO BUILDING THE XML - ######################################################################### def add_credit_card(xml, creditcard) xml.tag!("CARD") do xml.tag! 'CARDCODE', creditcard.verification_value if creditcard.verification_value? xml.tag! 'CARDNUMBER', creditcard.number xml.tag! 'EXPDATE', expdate(creditcard) @@ -239,11 +151,10 @@ xml.tag! 'CITY', address[:city].to_s xml.tag! 'COMPANY', address[:company].to_s xml.tag! 'COUNTRY', address[:country].to_s if options.has_key? :email xml.tag! 'EMAIL', options[:email] -# xml.tag! 'EMAIL', 'myemail@yahoo.com' xml.tag! 'EMAILRECEIPT', 'FALSE' end xml.tag! 'FIRSTNAME', creditcard.first_name xml.tag! 'LASTNAME', creditcard.last_name xml.tag! 'PHONE', address[:phone].to_s @@ -281,13 +192,28 @@ xml.tag! 'SECUREKEY', @options[:password] xml.tag! 'SECURENETID', @options[:login] end end - ######################################################################### - # FUNCTIONS RELATED TO THE RESPONSE - ######################################################################### + def add_required_params(xml, action, options) + xml.tag! 'CODE', TRANSACTIONS[action] + add_customer_data(xml, options) + xml.tag! 'DCI', 0 # No duplicate checking will be done, except for ORDERID + xml.tag! 'INSTALLMENT_SEQUENCENUM', 1 + add_merchant_key(xml, options) + xml.tag! 'METHOD', 'CC' + xml.tag! 'ORDERID', options[:order_id] + xml.tag! 'OVERRIDE_FROM', 0 # Docs say not required, but doesn't work without it + end + + def add_more_required_params(xml, options) + xml.tag! 'RETAIL_LANENUM', '0' + xml.tag! 'TEST', 'TRUE' + xml.tag! 'TOTAL_INSTALLMENTCOUNT', 0 + xml.tag! 'TRANSACTION_SERVICE', 0 + end + def success?(response) response[:response_code].to_i == APPROVED end def message_from(response) @@ -300,13 +226,11 @@ end def parse(xml) response = {} xml = REXML::Document.new(xml) - root = REXML::XPath.first(xml, "//GATEWAYRESPONSE")# || -# root = REXML::XPath.first(xml, "//ProcessTransactionResponse")# || -# REXML::XPath.first(xml, "//ErrorResponse") + root = REXML::XPath.first(xml, "//GATEWAYRESPONSE") if root root.elements.to_a.each do |node| recurring_parse_element(response, node) end end @@ -320,9 +244,17 @@ else response[node.name.underscore.to_sym] = node.text end end + def split_authorization(authorization) + transaction_id, amount, last_four = authorization.split("|") + [transaction_id, amount, last_four] + end + + def build_authorization(response) + [response[:transactionid], response[:transactionamount], response[:last4_digits]].join("|") + end end end end