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