我试图从我的代码中调用Paypal api.我设置了沙盒帐户,当我使用curl但它的代码工作方式不同时,它会起作用,返回401 Unauthorized.
这是curl命令,如documented by Paypal
curl https://api.sandBox.paypal.com/v1/oauth2/token -H "Accept: application/json" -H "Accept-Language: en_US" -u "A****:E****" -d "grant_type=client_credentials"
更新:显然.Credentials不能解决问题,而是手动设置Authorization标头(参见代码)
这是代码(修剪到它的本质):
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("https://api.sandBox.paypal.com/v1/oauth2/token"); request.Method = "POST"; request.Accept = "application/json"; request.Headers.Add("Accept-Language:en_US") // this doesn't work: **request.Credentials = new NetworkCredential("A****","E****");** // DO THIS INSTEAD **string authInfo = Convert.ToBase64String(System.Text.Encoding.Default.GetBytes("A****:E****"));** **request.Headers["Authorization"] = "Basic " + authInfo;** using (StreamWriter swt = new StreamWriter(request.GetRequestStream())) { swt.Write("grant_type=client_credentials"); } request.BeginGetResponse((r) => { try { HttpWebResponse response = request.EndGetResponse(r) as HttpWebResponse; // Exception here .... } catch (Exception x) { .... } // log the exception - 401 Unauthorized },null);
这是来自Fiddler(raw)捕获的代码的请求,由于某种原因没有授权参数:
POST https://api.sandBox.paypal.com/v1/oauth2/token HTTP/1.1 Accept: application/json Accept-Language: en_US Host: api.sandBox.paypal.com Content-Length: 29 Expect: 100-continue Connection: Keep-Alive grant_type=client_credentials
解决方法
希望以下代码能帮助任何仍在寻找好蛋糕的人与PayPal建立联系.
和很多人一样,我一直在投入大量时间试图让我的PayPal令牌访问失败,直到我找到以下内容:
public class PayPalClient { public async Task RequestPayPalToken() { // Discussion about SSL secure channel // https://stackoverflow.com/questions/32994464/could-not-create-ssl-tls-secure-channel-despite-setting-servercertificatevalida ServicePointManager.ServerCertificateValidationCallback += (sender,cert,chain,sslPolicyErrors) => true; ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; try { // ClientId of your Paypal app API string APIClientId = "**_[your_API_Client_Id]_**"; // secret key of you Paypal app API string APISecret = "**_[your_API_secret]_**"; using (var client = new System.Net.Http.HttpClient()) { var byteArray = Encoding.UTF8.GetBytes(APIClientId + ":" + APISecret); client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic",Convert.ToBase64String(byteArray)); var url = new Uri("https://api.sandBox.paypal.com/v1/oauth2/token",UriKind.Absolute); client.DefaultRequestHeaders.IfModifiedSince = DateTime.UtcNow; var requestParams = new List<KeyValuePair<string,string>> { new KeyValuePair<string,string>("grant_type","client_credentials") }; var content = new FormUrlEncodedContent(requestParams); var webresponse = await client.PostAsync(url,content); var jsonString = await webresponse.Content.ReadAsStringAsync(); // response will deserialized using Jsonconver var payPalTokenModel = JsonConvert.DeserializeObject<PayPalTokenModel>(jsonString); } } catch (System.Exception ex) { //TODO: Log connection error } } } public class PayPalTokenModel { public string scope { get; set; } public string nonce { get; set; } public string access_token { get; set; } public string token_type { get; set; } public string app_id { get; set; } public int expires_in { get; set; } }