lib/active_merchant/billing/gateways/trans_first.rb in activemerchant-1.55.0 vs lib/active_merchant/billing/gateways/trans_first.rb in activemerchant-1.56.0

- old
+ new

@@ -1,38 +1,73 @@ module ActiveMerchant #:nodoc: module Billing #:nodoc: class TransFirstGateway < Gateway - self.live_url = self.test_url = 'https://webservices.primerchants.com/creditcard.asmx/CCSale' + self.test_url = 'https://ws.cert.transfirst.com' + self.live_url = 'https://webservices.primerchants.com' self.supported_countries = ['US'] self.supported_cardtypes = [:visa, :master, :american_express, :discover] self.homepage_url = 'http://www.transfirst.com/' self.display_name = 'TransFirst' UNUSED_FIELDS = %w(ECIValue UserId CAVVData TrackData POSInd EComInd MerchZIP MerchCustPNum MCC InstallmentNum InstallmentOf POSEntryMode POSConditionCode AuthCharInd CardCertData) DECLINED = 'The transaction was declined' + ACTIONS = { + purchase: "CCSale", + purchase_echeck: "ACHDebit", + refund: "CreditCardAutoRefundorVoid", + refund_echeck: "ACHVoidTransaction", + void: "CreditCardAutoRefundorVoid", + } + + ENDPOINTS = { + purchase: "creditcard.asmx", + purchase_echeck: "checkverifyws/checkverifyws.asmx", + refund: "creditcard.asmx", + refund_echeck: "checkverifyws/checkverifyws.asmx", + void: "creditcard.asmx" + } + def initialize(options = {}) requires!(options, :login, :password) super end - def purchase(money, credit_card, options = {}) + def purchase(money, payment, options = {}) post = {} add_amount(post, money) add_invoice(post, options) - add_credit_card(post, credit_card) + add_payment(post, payment) add_address(post, options) - commit(post) + commit((payment.is_a?(Check) ? :purchase_echeck : :purchase), post) end + def refund(money, authorization, options={}) + post = {} + transaction_id, payment_type = split_authorization(authorization) + add_amount(post, money) + add_invoice(post, options) + add_pair(post, :TransID, transaction_id) + commit((payment_type == "check" ? :refund_echeck : :refund), post) + end + + def void(authorization, options={}) + post = {} + transaction_id, _ = split_authorization(authorization) + add_pair(post, :TransID, transaction_id) + + commit(:void, post) + end + private + def add_amount(post, money) - add_pair(post, :Amount, amount(money), :required => true) + add_pair(post, :Amount, amount(money), required: true) end def add_address(post, options) address = options[:billing_address] || options[:address] @@ -41,25 +76,44 @@ add_pair(post, :ZipCode, address[:zip]) end end def add_invoice(post, options) - add_pair(post, :RefID, options[:order_id], :required => true) - add_pair(post, :PONumber, options[:invoice], :required => true) + add_pair(post, :RefID, options[:order_id], required: true) + add_pair(post, :SECCCode, options[:invoice], required: true) + add_pair(post, :PONumber, options[:invoice], required: true) add_pair(post, :SaleTaxAmount, amount(options[:tax] || 0)) - add_pair(post, :PaymentDesc, options[:description], :required => true) + add_pair(post, :PaymentDesc, options[:description], required: true) add_pair(post, :TaxIndicator, 0) + add_pair(post, :CompanyName, options[:company_name] || "", required: true) end - def add_credit_card(post, credit_card) - add_pair(post, :CardHolderName, credit_card.name, :required => true) - add_pair(post, :CardNumber, credit_card.number, :required => true) + def add_payment(post, payment) + if payment.is_a?(Check) + add_echeck(post, payment) + else + add_credit_card(post, payment) + end + end - add_pair(post, :Expiration, expdate(credit_card), :required => true) - add_pair(post, :CVV2, credit_card.verification_value) + def add_credit_card(post, payment) + add_pair(post, :CardHolderName, payment.name, required: true) + add_pair(post, :CardNumber, payment.number, required: true) + add_pair(post, :Expiration, expdate(payment), required: true) + add_pair(post, :CVV2, payment.verification_value) end + def add_echeck(post, payment) + add_pair(post, :TransRoute, payment.routing_number, required: true) + add_pair(post, :BankAccountNo, payment.account_number, required: true) + add_pair(post, :BankAccountType, payment.account_type.capitalize, required: true) + add_pair(post, :CheckType, payment.account_holder_type.capitalize, required: true) + add_pair(post, :Name, payment.name, required: true) + add_pair(post, :ProcessDate, Time.now.strftime("%m%d%y"), required: true) + add_pair(post, :Description, "", required: true) + end + def add_unused_fields(post) UNUSED_FIELDS.each do |f| post[f] = "" end end @@ -73,11 +127,11 @@ def parse(data) response = {} xml = REXML::Document.new(data) - root = REXML::XPath.first(xml, "//CCSaleDebitResponse") + root = REXML::XPath.first(xml, "*") if root.nil? response[:message] = data.to_s.strip else root.elements.to_a.each do |node| @@ -86,21 +140,47 @@ end response end - def commit(params) - response = parse( ssl_post(self.live_url, post_data(params)) ) + def commit(action, params) + response = parse(ssl_post(url(action), post_data(params))) - Response.new(response[:status] == "Authorized", message_from(response), response, + Response.new( + success_from(response), + message_from(response), + response, :test => test?, - :authorization => response[:trans_id], + :authorization => authorization_from(response), :avs_result => { :code => response[:avs_code] }, :cvv_result => response[:cvv2_code] ) end + def authorization_from(response) + if response[:status] == "APPROVED" + "#{response[:trans_id]}|check" + else + "#{response[:trans_id]}|creditcard" + end + end + + def success_from(response) + case response[:status] + when "Authorized" + true + when "Voided" + true + when "APPROVED" + true + when "VOIDED" + true + else + false + end + end + def message_from(response) case response[:message] when 'Call Voice Center' DECLINED else @@ -117,9 +197,18 @@ request end def add_pair(post, key, value, options = {}) post[key] = value if !value.blank? || options[:required] + end + + def url(action) + base_url = test? ? test_url : live_url + "#{base_url}/#{ENDPOINTS[action]}/#{ACTIONS[action]}" + end + + def split_authorization(authorization) + authorization.split("|") end end end end