PayPal REST API .net SDK - 400个错误请求

Jon*_*ack 13 .net rest sdk paypal paypal-sandbox

我正在沙箱中使用PayPal REST .net SDK方法Payment.Create与CreditCard对象.当所有参数都有效并使用https://developer.paypal.com/webapps/developer/docs/integration/direct/accept-credit-cards/中的测试CC编号时,将从该方法返回Payment对象,并且所有参数都是好.

但是,如果参数无效,例如过去的到期日期或沙箱无法识别的CC编号,则不会返回Payment对象.相反,该方法抛出异常:"HttpConnection中的异常执行:无效的HTTP响应远程服务器返回错误:(400)错误请求",但没有进一步说明.

当我在cURL中执行相同的请求时,除了"400 Bad Request"之外,我还得到了一个JSON响应.这包括更多有用的消息,例如"VALIDATION_ERROR"和"无效的过期(不能过去)".

我的问题:有没有办法从SDK中恢复这些消息?

我尝试过的:

  • PayPal文档:https://developer.paypal.com/webapps/developer/docs/api/#errors 本文档提到,如果出现错误,它们会返回响应正文中的详细信息.不幸的是,它没有提供关于SDK是否可以访问它们的线索.
  • 各种Google和SO搜索.
  • 随SDK提供的PizzaApp示例代码没有任何异常处理方式或对此问题的进一步了解.
  • 我在SDK中看到了一个PayPalException对象,但没有发现任何指示它应该如何使用的内容,或者它是否与此问题相关.

非常感谢所有帮助.

小智 22

我今天才开始搞乱SDK和API,并立即遇到了这个问题.我的意思是,如果我要创建自己的表单来处理付款,我想在出现任何问题时提供用户的反馈意见.

无论如何,我确实在内部异常中找到了一些隐藏信息.也许这会有所帮助.

catch (PayPal.Exception.PayPalException ex)
{
    if (ex.InnerException is PayPal.Exception.ConnectionException)
    {
        context.Response.Write(((PayPal.Exception.ConnectionException)ex.InnerException).Response);
    }
    else
    {
        context.Response.Write(ex.Message);
    }
}
Run Code Online (Sandbox Code Playgroud)

由此产生的反应:

{"name":"VALIDATION_ERROR","details":[{"field":"payer.funding_instruments[0].credit_card.number","issue":"Must be numeric"}],"message":"Invalid request - see details","information_link":"https://developer.paypal.com/webapps/developer/docs/api/#VALIDATION_ERROR","debug_id":"0548e52ef9d95"} 
Run Code Online (Sandbox Code Playgroud)


Jon*_*ack 7

由于似乎没有人知道答案,我挖掘了PayPal .NET SDK for REST API的源代码.从该评论看,从当前版本开始,当服务器返回任何4xx或5xx HTTP状态代码时,没有规定返回错误消息.我引用了这个问题的答案并更改了SDK以允许在适用时返回错误响应.这是HttpConnection.cs的相关部分.

catch (WebException ex)
{
    if (ex.Response is HttpWebResponse)
    {
        HttpStatusCode statusCode = ((HttpWebResponse)ex.Response).StatusCode;
        logger.Info("Got " + statusCode.ToString() + " response from server");
        using (WebResponse wResponse = (HttpWebResponse)ex.Response)
        {
            using (Stream data = wResponse.GetResponseStream ())
            {
                string text = new StreamReader (data).ReadToEnd ();
                return text;
            }
        }                           
    }
    if (!RequiresRetry(ex))
    {
        // Server responses in the range of 4xx and 5xx throw a WebException
        throw new ConnectionException("Invalid HTTP response " + ex.Message);
    }                       
}
Run Code Online (Sandbox Code Playgroud)

当然,这需要更改调用函数以正确解释错误响应.由于我只使用了Payment Create API,因此我采用了一些不适用于一般用途的快捷方式.但是,基本思想是我创建了PaymentError和Detail类,然后更改了Payment.Create和PayPalResource.ConfigureAndExecute方法来填充并传回PaymentError对象.


三年后,PayPal的API错误响应处理有了一些改进.由于一些其他问题,我不得不重新处理我的应用程序,并删除先前的代码.我发现您现在可以捕获PayPal.Exception.PaymentsException,然后将JSON Response字符串反序列化为PayPal.Exception.PaymentsError对象.

Catch ex As PayPal.Exception.PaymentsException
    Dim tmpPmtErr As PayPal.Exception.PaymentsError = _
        JsonConvert.DeserializeObject(Of PayPal.Exception.PaymentsError)(ex.Response)
Run Code Online (Sandbox Code Playgroud)

感谢@lance在另一个答案中让单挑对象更仔细地检查异常.我试图使用该解决方案,但无法使其工作.