2013-03-22 292 views
12

我正在沙箱中使用PayPal REST .net SDK方法Payment.Create與CreditCard對象。當所有參數都有效並使用https://developer.paypal.com/webapps/developer/docs/integration/direct/accept-credit-cards/中的測試CC號碼時,支付對象將從該方法返回並一切正常。PayPal REST API .net SDK - 400錯誤請求

但是,如果某個參數無效(例如過期到期日期或沙箱未識別的CC號碼),則不會返回Payment對象。相反,該方法拋出一個異常:「HttpConnection中的異常執行:無效的HTTP響應遠程服務器返回錯誤:(400)錯誤請求」,但沒有進一步解釋。

當我在cURL中執行相同的請求時,除了「400 Bad Request」之外,我還得到了一個JSON響應。這包括更多有用的消息,如「VALIDATION_ERROR」和「無效到期(不能在過去)」。

我的問題:有沒有辦法從SDK中獲取這些消息?

我已經試過:

  • 貝文檔:https://developer.paypal.com/webapps/developer/docs/api/#errors 該文件提到,在錯誤的情況下,他們在響應的正文返回的細節。不幸的是,它沒有提供這些SDK是否可以訪問的線索。
  • 各種Google和SO搜索。
  • 隨SDK提供的PizzaApp示例代碼沒有任何異常處理方式或進一步深入瞭解此問題。
  • 我在SDK中看到一個PayPalException對象,但沒有發現任何指示應該如何使用它或者它甚至與此問題有關的東西。

非常感謝所有幫助。

回答

6

由於沒有人似乎知道這個答案,所以我翻譯了PayPal .NET SDK for REST API的源代碼。從該評論看來,從當前版本看來,當服務器返回任何4xx或5xx HTTP狀態代碼時,沒有規定返回錯誤消息。我引用了this question的答案,並修改了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); 
    }      
} 

當然,這需要更改調用函數來正確解釋錯誤響應。由於我只使用付款創建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在單挑的其他答案中更仔細地檢查異常。我試圖使用該解決方案,但無法使其工作。

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 S DK會向日志文件吐出錯誤信息。

+0

感謝您的答覆。我會爲未來的應用記住這一點。不幸的是,這在這種情況下沒有幫助,因爲我需要在應用程序範圍內回錯錯誤。此外,該應用程序是Windows窗體,但我認爲可以對app.config進行類似的更改以啓用相同的日誌記錄。 –

+0

我在試圖構建連接到PP API的一部分時遇到了這個問題,並且想知道是否有辦法獲取所記錄的內容並返回?否則,當卡被拒絕時(例如無效號碼,過期卡等),400/Bad Request不會告訴我們爲什麼它不起作用,只是它沒有。 – RubyHaus

+0

@digitall,正好!這就是爲什麼我必須使用第一個答案中提到的黑客。我從未找到過使用股票API的方法,正如您所提到的,日誌記錄對應用程序內容沒有多大幫助。 –

21

我今天才開始討論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"} 
+0

如何解析此json以在用戶面前顯示消息。 –

+0

不幸的是,這似乎並沒有工作。截至API的最新版本,「響應」不是ConnectionException的元素。然而,在嘗試這一個的過程中,我發現它可以工作,如果你只是直接捕獲PaymentsException而不是InnerException。我用另一種解決方案編輯了我的答案。 –

0

我的問題是,我totaldetail.subtotal,並items.price是在像$ 1,000.00值傳遞,它需要小數所以使用這樣的:

total = Regex.Replace(model.OrderTotal, "[^0-9.]", "") 
-1

如果您在美國以外使用全球化,您需要將您的小數轉換爲InvariantCulture:

order.GetTotal().ToString("N2", CultureInfo.InvariantCulture) 
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 
0

所有不要的上述解決方案的真正抓住問題..

我跑了類似問題一會兒回來..在調試我的代碼後,我發現我做的事務在邏輯上是錯誤的..小計沒有0.25美元,PayPal服務器看到它並拒絕處理它,並給了我400個不好的請求

0

這似乎已經發生了變化,雖然這些答案中的很多都指向了正確的方向,但他們中的任何一個都不能完全爲我工作。這是我的等值目前最upvoted答案:

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"} 
+0

請注意:從我最近看到的情況來看,似乎PayPal正在擺脫他們的REST API,至少對於CC處理而言。此時,我的客戶似乎正在獲取混合信號。我正在將我的發展轉移到別處。 –