14

我在沙箱中工作,并使用 PayPal REST .net SDK 方法 Payment.Create 和 CreditCard 对象。当所有参数都有效并使用来自https://developer.paypal.com/webapps/developer/docs/integration/direct/accept-credit-cards/的测试 CC 编号时,Payment 对象将从该方法返回,并且全部为出色地。

但是,当参数无效时,例如过去的到期日期或沙盒无法识别的 CC 编号,则不会返回 Payment 对象。相反,该方法会引发异常:“HttpConnection Execute 中的异常:无效的 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 对象,但没有找到任何指示它应该如何使用或者它是否与这个问题相关的东西。

非常感谢所有帮助。

4

8 回答 8

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);
    }
}

结果响应:

{"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"} 
于 2013-08-24T06:36:45.197 回答
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);
    }                       
}

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


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

Catch ex As PayPal.Exception.PaymentsException
    Dim tmpPmtErr As PayPal.Exception.PaymentsError = _
        JsonConvert.DeserializeObject(Of PayPal.Exception.PaymentsError)(ex.Response)

感谢@lance 在另一个答案中的提醒,以便更仔细地检查异常。我尝试使用该解决方案,但无法使其工作。

于 2013-03-26T19:21:23.720 回答
2

这似乎已经改变了,虽然其中许多答案都指向正确的方向,但没有一个对我完全有效。这相当于我目前最赞成的答案:

catch (PayPal.PaymentsException ex)
{
    context.Response.Write(ex.Response);
}

回应:

{"name":"VALIDATION_ERROR","details":[{"field":"start_date","issue":"Agreement start date is required, should be valid and greater than the current date. Should be consistent with ISO 8601 Format"}],"message":"Invalid request. See details.","information_link":"https://developer.paypal.com/docs/api/payments.billing-agreements#errors","debug_id":"8c56c13fccd49"}
于 2017-10-19T21:42:01.390 回答
1

@Jonathan,REST API 集成了 log4net,如果您进行了设置,它会将完整的错误响应输出到日志文件。您必须将此配置部分添加到您的 web.config:

<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>

并设置选项:

<log4net>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
  <file value="rest-api.log"/>
  <appendToFile value="true"/>
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] %message%newline"/>
  </layout>
</appender>
<root>
  <level value="DEBUG"/>
  <appender-ref ref="FileAppender"/>
</root>

打开你的 global.asax 并将其添加到 Application_Start 中:

log4net.Config.XmlConfigurator.Configure();

现在,只要在您的日志文件夹上设置了写入权限,PayPal REST SDK 就会向日志文件发送错误消息。

于 2013-05-17T05:49:01.203 回答
0

我的问题是 my total, detail.subtotal, 和items.price正在传递像 $1,000.00 这样的值,它需要十进制,所以使用类似的东西:

total = Regex.Replace(model.OrderTotal, "[^0-9.]", "")
于 2013-12-21T11:44:29.170 回答
0

改进这里的解决方案是......简单(进口贝宝)

    Try
    Catch ex As PaymentsException
        For Each i In ex.Details.details
            Response.Write(i.field) 'Name of Field
            Response.Write(i.code) 'Code If Any
            Response.Write(i.issue) 'Validation Issue
        Next
    End Try
于 2016-06-13T20:42:54.160 回答
0

以上所有解决方案都没有真正掌握问题..

不久前我遇到了一个类似的问题..在调试了我的代码后,我发现我所做的交易在逻辑上是错误的..小计是 0.25 美元,贝宝服务器看到它并拒绝处理它,并给出我 400 错误的请求

于 2017-08-08T07:42:14.033 回答
-1

如果您在美国以外使用全球化,则需要将小数转换为 InvariantCulture:

order.GetTotal().ToString("N2", CultureInfo.InvariantCulture)
于 2014-06-04T15:46:49.710 回答