lib/active_merchant/billing/gateways/protx.rb in activemerchant-1.3.2 vs lib/active_merchant/billing/gateways/protx.rb in activemerchant-1.4.0

- old
+ new

@@ -21,10 +21,11 @@ CREDIT_CARDS = { :visa => "VISA", :master => "MC", :delta => "DELTA", :solo => "SOLO", + :switch => "MAESTRO", :maestro => "MAESTRO", :american_express => "AMEX", :electron => "UKE", :diners_club => "DC", :jcb => "JCB" @@ -37,11 +38,11 @@ "NOTCHECKED" => 'X', "MATCHED" => 'Y', "NOTMATCHED" => 'N' } - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :solo, :maestro, :diners_club] + self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :switch, :solo, :maestro, :diners_club] self.supported_countries = ['GB'] self.default_currency = 'GBP' self.homepage_url = 'http://www.protx.com' self.display_name = 'Protx' @@ -51,11 +52,11 @@ @options = options super end def test? - @options[:test] || Base.gateway_mode == :test + @options[:test] || super end def purchase(money, credit_card, options = {}) requires!(options, :order_id) @@ -82,15 +83,17 @@ add_customer_data(post, options) commit(:authorization, post) end - # Only supports capturing the original amount of the transaction + # You can only capture a transaction once, even if you didn't capture the full amount the first time. def capture(money, identification, options = {}) post = {} add_reference(post, identification) + add_release_amount(post, money, options) + commit(:capture, post) end def void(identification, options = {}) post = {} @@ -134,14 +137,19 @@ def add_amount(post, money, options) add_pair(post, :Amount, amount(money), :required => true) add_pair(post, :Currency, options[:currency] || currency(money), :required => true) end + # doesn't actually use the currency -- dodgy! + def add_release_amount(post, money, options) + add_pair(post, :ReleaseAmount, amount(money), :required => true) + end + def add_customer_data(post, options) - add_pair(post, :BillingEmail, options[:email]) - add_pair(post, :ContactNumber, options[:phone]) - add_pair(post, :ContactFax, options[:fax]) + add_pair(post, :BillingEmail, options[:email][0,255]) unless options[:email].blank? + add_pair(post, :ContactNumber, options[:phone].gsub(/[^0-9+]/, '')[0,20]) unless options[:phone].blank? + add_pair(post, :ContactFax, options[:fax].gsub(/[^0-9+]/, '')[0,20]) unless options[:fax].blank? add_pair(post, :ClientIPAddress, options[:ip]) end def add_address(post, options) address = options[:billing_address] || options[:address] @@ -169,16 +177,15 @@ def add_credit_card(post, credit_card) add_pair(post, :CardHolder, credit_card.name, :required => true) add_pair(post, :CardNumber, credit_card.number, :required => true) - add_pair(post, :ExpiryDate, format_expiry_date(credit_card), :required => true) + add_pair(post, :ExpiryDate, format_date(credit_card.month, credit_card.year), :required => true) if requires_start_date_or_issue_number?(credit_card) - add_pair(post, :StartDate, format(credit_card.start_year, :four_digits)) - - add_pair(post, :IssueNumber, format_issue_number(credit_card)) + add_pair(post, :StartDate, format_date(credit_card.start_month, credit_card.start_year)) + add_pair(post, :IssueNumber, credit_card.issue_number) end add_pair(post, :CardType, map_card_type(credit_card)) add_pair(post, :CV2, credit_card.verification_value) end @@ -199,21 +206,19 @@ CREDIT_CARDS[card_type] end end # MMYY format - def format_expiry_date(credit_card) - year = sprintf("%.4i", credit_card.year) - month = sprintf("%.2i", credit_card.month) + def format_date(month, year) + return nil if year.blank? || month.blank? + + year = sprintf("%.4i", year) + month = sprintf("%.2i", month) "#{month}#{year[-2..-1]}" end - def format_issue_number(credit_card) - card_brand(credit_card).to_s == 'solo' ? format(credit_card.issue_number, :two_digits) : credit_card.issue_number - end - def commit(action, parameters) response = parse( ssl_post(url_for(action), post_data(action, parameters)) ) Response.new(response["Status"] == APPROVED, message_from(response), response, :test => test?, @@ -228,11 +233,11 @@ def authorization_from(response, params) [ params[:VendorTxCode], response["VPSTxId"], response["TxAuthNo"], - response["SecurityKey"] ].compact.join(";") + response["SecurityKey"] ].join(";") end def url_for(action) simulate ? build_simulator_url(action) : build_url(action) end @@ -246,16 +251,11 @@ endpoint = [ :purchase, :authorization ].include?(action) ? "VSPDirectGateway.asp" : "VSPServerGateway.asp?Service=Vendor#{TRANSACTIONS[action].capitalize}Tx" "#{SIMULATOR_URL}/#{endpoint}" end def message_from(response) - if response["Status"] == APPROVED - return 'Success' - else - return 'Unspecified error' if response["StatusDetail"].blank? - return response["StatusDetail"] - end + response['Status'] == APPROVED ? 'Success' : (response['StatusDetail'] || 'Unspecified error') # simonr 20080207 can't actually get non-nil blanks, so this is shorter end def post_data(action, parameters = {}) parameters.update( :Vendor => @options[:login], @@ -269,10 +269,10 @@ # Protx returns data in the following format # Key1=value1 # Key2=value2 def parse(body) result = {} - body.to_a.collect {|v| c=v.split('='); result[c[0]] = c[1].chomp if !c[1].blank? } + body.to_a.each { |pair| result[$1] = $2 if pair.strip =~ /\A([^=]+)=(.+)\Z/im } result end def add_pair(post, key, value, options = {}) post[key] = value if !value.blank? || options[:required]