QuickBooks Online
QuickBooks Online x Perigee
The Core of the Process
//Reach out to: https://developer.api.intuit.com/.well-known/openid_configuration
// Get the token endpoint
ThreadRegistry reg = ThreadRegistry.Instance;
string TokenEndpoint = "";
//Create a client pointing to the QBO Token Endpoint
using var authClient = new RestClient(new RestClientOptions(TokenEndpoint)
{
Authenticator = new RestSharp.Authenticators.HttpBasicAuthenticator(
reg.GetValue<string>("AppSettings:client_id")!,
reg.GetValue<string>("AppSettings:client_secret")!)
});
var authReq = new RestRequest("", Method.Post);
//Add parameters
authReq.AddParameter("redirect_uri", reg.GetValue<string>("AppSettings:redirect"));
authReq.AddParameter("grant_type", "authorization_code");
authReq.AddParameter("code", code);
//Execute - Getting back an initial authorization code and refresh code.
var rsp = authClient.ExecuteRetry<QBAuth.Tokens>(authReq, 2);
if (rsp.IsSuccessful)
{
//Each credential is assigned a name: QBA- + realmID
string qbaName = $"QBA-{realmId}";
//Step 1) Persist an initial credential we received from the token callback
CredentialStore.PersistCredential(
new RestSharpCredentialStoreItem(new RestSharp.Authenticators.JwtAuthenticator(rsp.Data?.AccessToken ?? ""), DateTimeOffset.UtcNow.AddSeconds(rsp.Data?.ExpiresIn ?? 3000))
{
RefreshToken = rsp.Data?.RefreshToken,
StoreA = rsp.Data?.IdToken,
Environment = realmId,
Name = qbaName
});
//Step 2) Register realm refresh for future usage on expiration
CredentialStore.RegisterRefresh(qbaName, (o) =>
{
using var authClient = new RestClient(new RestClientOptions(TokenEndpoint)
{
Authenticator = new RestSharp.Authenticators.HttpBasicAuthenticator(
reg.GetValue<string>("AppSettings:client_id")!,
reg.GetValue<string>("AppSettings:client_secret")!)
});
var authReq = new RestRequest("", Method.Post);
authReq.AddParameter("redirect_uri", reg.GetValue<string>("AppSettings:redirect")!);
authReq.AddParameter("grant_type", "refresh_token");
authReq.AddParameter("refresh_token", CredentialStore.GetRefreshToken(qbaName));
var rsp = authClient.ExecuteRetry<QBAuth.Tokens>(authReq, retries: 1);
if (rsp.IsSuccessful)
{
//Get previous expired credential using peek to pull environment from last run...
var expCred = CredentialStore.PeekCredential(qbaName);
return new RestSharpCredentialStoreItem(new RestSharp.Authenticators.JwtAuthenticator(rsp.Data?.AccessToken ?? ""), DateTimeOffset.UtcNow.AddSeconds(rsp.Data?.ExpiresIn ?? 3000))
{
RefreshToken = rsp.Data?.RefreshToken,
StoreA = rsp.Data?.IdToken,
Environment = expCred?.Environment ?? "",
};
}
else
{
return new FaultedCredentialStoreItem($"Couldn't refresh token for realm {qbaName}, {rsp.Content}");
}
});
}Re-Register the Callback on Application Startup 🔄
Making Authorized Realm Calls Is Simpler Than Ever
Last updated

