Few days ago I noticed that ActiveMerchant Paypal gateway implementation is too strict (version 1.2.1)

Here is a code snippet for method commit

module ActiveMerchant #:nodoc:
  module Billing #:nodoc:
    # This class is included in both PaypalGateway and PaypalExpressGateway
    module PaypalCommonAPI
...
      def commit(action, request)
        url = test? ? TEST_URL : LIVE_URL

        data = ssl_post(url, build_request(request))
        @response = parse(action, data)
       
        success = @response[:ack] == "Success"
        message = @response[:message] || @response[:ack]

        build_response(success, message, @response,
    	    :test => test?,
    	    :authorization => @response[:transaction_id] || @response[:authorization_id] # latter one is from reauthorization
        )
      end
...
end

It turns out Paypal can return "SuccessWithWarning", and ActiveMerchant doesn't handle it well. It would be nice if for test mode it can be strict, however in production more forgiving. Meantime I wrapped commit with alias_method_chain

require 'active_merchant'
require 'active_support'
class ActiveMerchant::Billing::PaypalGateway

  def commit_with_successwithwarning(*args)
     result = commit_without_successwithwarning(*args)
     return result if result.success? || result.test?
      if result.params['ack'] == "SuccessWithWarning"
        RAILS_DEFAULT_LOGGER.error("Paypal SuccessWithWarning #{result.inspect}")
        result.params['ack'] = "Success"
        return ActiveMerchant::Billing::Response.new(
          true, 
          result.message, 
          result.params, 
          {
            :test => result.test, 
            :authorization => result.authorization
          }
        )
      end
      result
  end
  alias_method_chain :commit, :successwithwarning
end