Paypal REST api call works from cURL but not from C# code

前端 未结 4 1509
旧时难觅i
旧时难觅i 2021-02-09 01:12

I\'m trying to call Paypal api from my code. I set up the sandbox account and it works when I use curl but my code isn\'t working the same way, returning 401 Unauthorized instea

4条回答
  •  臣服心动
    2021-02-09 01:52

    This Works using HttpClient... 'RequestT' is a generic for the PayPal request arguments, however it is not used. The 'ResponseT' is used and it is the response from PayPal according to their documentation.

    'PayPalConfig' class reads the clientid and secret from the web.config file using ConfigurationManager. The thing to remember is to set the Authorization header to "Basic" NOT "Bearer" and if and to properly construct the 'StringContent' object with right media type (x-www-form-urlencoded).

        //gets PayPal accessToken
        public async Task InvokePostAsync(RequestT request, string actionUrl)
        {
            ResponseT result;
    
            // 'HTTP Basic Auth Post' 
            string clientId = PayPalConfig.clientId;
            string secret = PayPalConfig.clientSecret;
            string oAuthCredentials = Convert.ToBase64String(Encoding.Default.GetBytes(clientId + ":" + secret));
    
            //base uri to PayPAl 'live' or 'stage' based on 'productionMode'
            string uriString = PayPalConfig.endpoint(PayPalConfig.productionMode) + actionUrl;
    
            HttpClient client = new HttpClient();
    
            //construct request message
            var h_request = new HttpRequestMessage(HttpMethod.Post, uriString);
            h_request.Headers.Authorization = new AuthenticationHeaderValue("Basic", oAuthCredentials);
            h_request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            h_request.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue("en_US"));
    
            h_request.Content = new StringContent("grant_type=client_credentials", UTF8Encoding.UTF8, "application/x-www-form-urlencoded");
    
            try
            {
                HttpResponseMessage response = await client.SendAsync(h_request);
    
                //if call failed ErrorResponse created...simple class with response properties
                if (!response.IsSuccessStatusCode)
                {
                    var error = await response.Content.ReadAsStringAsync();
                    ErrorResponse errResp = JsonConvert.DeserializeObject(error);
                    throw new PayPalException { error_name = errResp.name, details = errResp.details, message = errResp.message };
                }
    
                var success = await response.Content.ReadAsStringAsync();
                result = JsonConvert.DeserializeObject(success);
            }
            catch (Exception)
            {
                throw new HttpRequestException("Request to PayPal Service failed.");
            }
    
            return result;
        }
    

    IMPORTANT: use Task.WhenAll() to ensure you have a result.

        // gets access token with HttpClient call..and ensures there is a Result before continuing
        // so you don't try to pass an empty or failed token.
        public async Task AuthorizeAsync(TokenRequest req)
        {
            TokenResponse response;
            try
            {
                var task = new PayPalHttpClient().InvokePostAsync(req, req.actionUrl);
                await Task.WhenAll(task);
    
                response = task.Result;
            }
            catch (PayPalException ex)
            {
                response = new TokenResponse { access_token = "error", Error = ex };
            }
    
            return response;
        }
    

提交回复
热议问题