Search code examples
c#access-tokenquickbooksquickbooks-online

How to get access token, refresh token in .NET Core (C#) without using SDK (Manually) in QuickBooks Online API?


I have created a simple console app in C#, I need to request access token without using SDK. I have managed to launch a URL to request code. I get code but trying to call the access_token endpoint is a challenge. I need help on how I can get access_token and refresh_token. Attached is the screenshot of codes having all the request details and the endpoint I used as follows.

Endpoint used: https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer

Parameters: code,=[codeReceived] grant_type = authorization_code and redirect_uri = [RedirectUrl]

Headers:Authorization: Basic [Base64EncodedBytes], Accept: application/json, Host: oauth.platform.intuit.com, Content-Type: application/x-www-form-urlencoded

I have created a simple console app in C#, I need to request access token without using SDK. I have managed to launch a URL to request code. I get code but trying to call the access_token endpoint is a challenge. I need help on how I can get access_token and refresh_token. Attached is the screenshot of codes having all the request details and the endpoint I used as follows.

Posting Endpoint used: https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer

Parameters:[enter image description here][1] code,=[codeReceived] grant_type = authorization_code and redirect_uri = [RedirectUrl]

Headers: Authorization: Basic [Base64EncodedBytes], Accept: application/json, Host: oauth.platform.intuit.com, Content-Type: application/x-www-form-urlencoded

This is the Client Class I've created:

   public class RestClient
{     
    public string ClientID;
    public string ClientSecret;
    public string RedirectUrl = "https://devices.pythonanywhere.com/";
    public string Environment = "sandbox";

    
    private async Task<string> GetAccessTokenAsync(string Url, string code, string ClientId, string ClientSecret)
    {
        var stringBytes = Encoding.UTF8.GetBytes($"{ClientId}:{ClientSecret}");
        var encodedBytes = Convert.ToBase64String(stringBytes);
        

        var uriBuilder = new UriBuilder(Url);
        var query = HttpUtility.ParseQueryString(uriBuilder.Query);
        
        query["grant_type"] = "authorization_code";
        query["code"] = $"{code}";
        query["redirect_uri"] = $"{RedirectUrl}";
        uriBuilder.Query = query.ToString();
        Url = uriBuilder.ToString();

        var DecodedUrl = HttpUtility.UrlDecode(Url);

        Console.WriteLine(encodedBytes);
        
        HttpRequestMessage request = new(HttpMethod.Post, DecodedUrl);

        request.Headers.Add("Accept", "application/json");
        request.Headers.Add("Authorization", $"Basic {encodedBytes}");
        request.Headers.Add("Host", "oauth.platform.intuit.com");
        request.Content = new StringContent("application/x-www-form-urlencoded");
        using HttpClient client = new();
        using HttpResponseMessage response = await client.SendAsync(request);

        var body = response.Content.ReadAsStringAsync();
        
        return body.Result;
    }

    public string GetTokens(string Url, string code, string ClientId, string ClientSecret)
    {
        try
        {
            var response = GetAccessTokenAsync(Url, code, ClientId, ClientSecret).Result;

            if (response.Length>0)
            {
                return "There is data";
            }

            return "No data";
        }
        catch (Exception ex)
        {
            return ex.Message;
        }

    }

}

and this here is where I'm calling it

class Program
{
    static void Main(string[] args)
    {
        var client = new RestClient();
        client.ClientID = "AB8EMz5arbI**************************************";
        client.ClientSecret = "4y4vsz*********************************";

        var OauthUrl = "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer";
        var code = "AB11644908535RgJ**************************";
        Console.WriteLine($"Response: {client.GetTokens(OauthUrl, code, client.ClientID, client.ClientSecret)}");

    }
}

Solution

  • I was making a mistake in my C# code. Here is the working code that I used in GetAccessTokenAsync:

    private async Task<string> GetAccessTokenAsync(string Url, string code, string ClientId, string ClientSecret)
        {
            var stringBytes = Encoding.UTF8.GetBytes($"{ClientId}:{ClientSecret}");
            var encodedBytes = Convert.ToBase64String(stringBytes);
           
            HttpRequestMessage request = new(HttpMethod.Post, Url);
    
            request.Headers.TryAddWithoutValidation("Accept", "application/json");
            request.Headers.TryAddWithoutValidation("Authorization", $"Basic {encodedBytes}");
    
            var contentList = new List<string>();
            contentList.Add("grant_type=authorization_code");
            contentList.Add($"code={code}");
            contentList.Add($"redirect_uri={RedirectUrl}");
            request.Content = new StringContent(string.Join("&", contentList));
            request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded");
    
    
            using HttpClient client = new();
            using HttpResponseMessage response = await client.SendAsync(request);
    
            var body = response.Content.ReadAsStringAsync();
            
            return body.Result;
        }