Infusionsoft API – Using OAuth with .Net

[vc_row][vc_column width=”1/1″][vc_column_text]

Getting Started

My first thought when firing up Visual Studio to start on the new Infusionsoft OAuth authentication was “this should be easy”.  I underestimated the amount of time it would take for me get a project up and running.

Once it was done, it ended up being pretty straight forward. I have also provided an example project that you are welcome to use as a reference. Near the end of this post you will find a list of gotchas that I ran into and how they were resolved.

This post will describe the steps it takes to begin using the OAuth version implementation of the Infusionsoft API.[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column width=”1/1″][vc_column_text]

About OAuth 2.0

Not everyone is used to implementing OAuth 2.0, especially since the Visual Studio ASP.NET MVC 4 Web Application Internet Template (Gotcha #3) is configured to use OAuth 1.0, so here is a quick overview of the moving parts.
OAuth 2

Developer Application

The application for which the Infusionsoft User will approve or deny access to their Infusionsoft Application.

Client Key

A public key which is sent to request authorization and token creation. This key is always visible to the end user as it is displayed in the URL.

Secret Key

As the name implies, this is the secret, private key that are only known to the Developer and Infusionsoft. This key is presented to prove that you are who you say you are. This value should never be made known to the public. For that reason, you should always use SSL when using OAuth 2.0.

Authorization Endpoint

The URL for which the user is redirect to Approve or Deny access to their Infusionsoft Application. This URL is redirected as a GET request and includes your Client Key.

Token Endpoint

The URL for which specific permission is requested from Infusionsoft. This URL should always be a POST request and will include both your Client Key and your Secret Key. This URL will be used for requesting the original access and refresh tokens as well as refreshing an expired access token.

Access Token

The access token is required for accessing any Infusionsoft data via the Infusionsoft API. The access token has a short life span of 60 minutes before it expires. The access token does not need to be stored in a permanent location because of its short life span. Once the access token expires, you will need to request a new one by using the Refresh Token. The access token should be kept private and never displayed to the user.

Request Token

The request token is used to refresh the access token. By using the refresh token, you can easily get a new access token rather than requiring the user to re-authorize your Developer Application each time the old access token expires. The refresh token should be stored in a secure, permanent location and never shared publicly. If you happen to delete, remove or lose the refresh token, then the user will be required to re-authenticate your application.[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column width=”1/1″][vc_column_text]

Step 1 – Register For a Developer Account and Application

First things first. In order to get the whole OAuth 2.0 thing working, you will first need to have a developer account. During the registration process, you will also create your first developer application  (not to be confused with an Infusionsoft account).

Confirmation

Authentication Screen presented to User to Deny or Approve access to their Infusionsoft Application.

The developer account is the username, password and display name (Gotcha #1) used to log in to the Developers by Infusionsoft website.

The developer application is the application for which access will be granted.  Both the account Display Name and the Application Name will be prominently displayed to the user when presented with the option to Grant or Deny your developer application’s permission to connect to their Infusionsoft application (see image).

Once your Developer Account has been created and approved, you will be able to proceed with your new OAuth 2.0 Developer Application.[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column width=”1/1″][vc_column_text]

Step 2 – Download Source Code

All of the code used in this post is available for download.

Once you have downloaded the source code, you will need to update the DeveloperAppKey and DeveloperAppSecret and CallbackUrl fields in the HomeController.cs file.

[sourcecode language=”csharp” highlight=”3,4,6″]
public class HomeController : Controller
{
    private string DeveloperAppKey = "aaaaaaaaaaaaaaaaaaaaaaaa";
    private string DeveloperAppSecret = "bbbbbbbbbb";

    private string CallbackUrl = "http://localhost:2412/home/callback";

    // Other code….
}
[/sourcecode]

[/vc_column_text][vc_message color=”alert-info”]NOTE: The Callback URL should work as is with the source code provided. If IISExpress changes the port, then you will need to update the CallbackURL field to match the port.

The value that you use for the Callback URL must match exactly the URL that you have specified when setting up your Developer Account.[/vc_message][/vc_column][/vc_row][vc_row][vc_column width=”1/1″][vc_column_text]

Step 3 – Request Authorization

Requesting authorization from a user is a multi-step process. We first need to redirect the user to the Infusionsoft Authorization Endpoint with our Client Key, our Callback UR

L and other permissions:

[sourcecode language=”csharp”]
public ActionResult Authorize()
{
    // Hard coded "scope=full" and "responseType=code" since they are the only supported options
    string authorizeUrlFormat = "https://signin.infusionsoft.com/app/oauth/authorize?scope=full&redirect_uri={0}&response_type=code&client_id={1}";

    // Url encode CallbackUrl
    return Redirect(string.Format(authorizeUrlFormat, Server.UrlEncode(CallbackUrl), DeveloperAppKey));
}
[/sourcecode]

By redirecting the user to the Infusionsoft Authorization Endpoint we are letting Infusionsoft handle the authorization and access. If the user is has not logged in to Infusionsoft they will be shown the standard sign in screen.

Standard Infusionsoft Sign In Screen

Standard Infusionsoft Sign In Screen

After the user successfully logs into Infusionsoft, they will be presented with the option to approve or deny access to your application for each of the Infusionsoft Applications for which they have.

OAuth-Allow-Access-Confirmation-2

Infusionsoft Authorization Confirmation

When the user clicks the Allow button they will be sent back to the Callback URL provided by your developer application.

[sourcecode language=”csharp”]
public ActionResult Callback(string code)
{
if (!string.IsNullOrEmpty(code))
{
string tokenUrl = "https://api.infusionsoft.com/token";

// Hard coded "grant_type=authorization_code" since it is the only supported option
string tokenDataFormat = "code={0}&client_id={1}&client_secret={2}&redirect_uri={3}&grant_type=authorization_code";

HttpWebRequest request = HttpWebRequest.Create(tokenUrl) as HttpWebRequest;
request.Method = "POST";
request.KeepAlive = true;
request.ContentType = "application/x-www-form-urlencoded";

// Url encode CallbackUrl
string dataString = string.Format(tokenDataFormat, code, DeveloperAppKey, DeveloperAppSecret, Server.UrlEncode(CallbackUrl));
var dataBytes = Encoding.UTF8.GetBytes(dataString);
using (Stream reqStream = request.GetRequestStream())
{
reqStream.Write(dataBytes, 0, dataBytes.Length);
}

string resultJSON = string.Empty;
using (WebResponse response = request.GetResponse())
{
var sr = new StreamReader(response.GetResponseStream());
resultJSON = sr.ReadToEnd();
sr.Close();
}

var jsonSerializer = new JavaScriptSerializer();

var tokenData = jsonSerializer.Deserialize<TokenData>(resultJSON);

ViewData.Add("AccessToken", tokenData.Access_Token);
}

return View();
}
[/sourcecode]

In order for use to send our request to Infusionsoft for an access token, we need to package up the code that Infusionsoft sent us, our Developer Application Client Key, Developer Application Secret and our URL encoded Callback URL. To package up the data, we need to convert the string data into a byte array and then post the data to Infusionsoft with a content type of “application/x-www-form-urlencoded”.

[sourcecode language=”csharp” highlight=”8,12,15″]
public ActionResult Callback(string code)
{
// Other Code …

HttpWebRequest request = HttpWebRequest.Create(tokenUrl) as HttpWebRequest;
request.Method = "POST";
request.KeepAlive = true;
request.ContentType = "application/x-www-form-urlencoded";

// Url encode CallbackUrl
string dataString = string.Format(tokenDataFormat, code, DeveloperAppKey, DeveloperAppSecret, Server.UrlEncode(CallbackUrl));
var dataBytes = Encoding.UTF8.GetBytes(dataString);
using (Stream reqStream = request.GetRequestStream())
{
reqStream.Write(dataBytes, 0, dataBytes.Length);
}

// Other Code …
}
[/sourcecode]

Infusionsoft will then evaluate our data and send back a JSON formatted result. We can use the .Net JavaScriptSerializer class to deserialize the JSON and return our custom TokenData object.

[sourcecode language=”csharp”]
var jsonSerializer = new JavaScriptSerializer();

var tokenData = jsonSerializer.Deserialize<TokenData>(resultJSON);
[/sourcecode]

Now that we have our access token, we can move on to the actual API Development that we wanted to start with an hour ago!

[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column width=”1/1″][vc_column_text]

Step 4 – Finally Use the Infusionsoft API

We have jumped through a lot of hoops so far. It was all to get to this point. We finally created an access token. Congratulations. Now you can access the Infusionsoft API.

Since this post was intended to walk through Steps 1 and 2, this step will quickly show how to properly use the Infusionsoft API now that we have our authorization.

In our sample project, you will find a FindContact method. This method will use the Infusionsoft ContactService.findByEmail API.

[sourcecode language=”csharp” highlight=”11,13″]

public ActionResult FindContact()
{
var accessToken = Request.QueryString["AccessToken"];
var email = Request.QueryString["Email"];

var viewData = new List&lt;Contact&gt;();

if (!string.IsNullOrEmpty(accessToken))
{
var contactService = XmlRpcProxyGen.Create&lt;IInfusionsoftAPI&gt;();
contactService.Url = "https://api.infusionsoft.com/crm/xmlrpc/v1?access_token=" + accessToken;

var contacts = contactService.LookupByEmail(DeveloperAppKey, email, new[] { "Id", "FirstName", "LastName" });

foreach (var contact in contacts)
{
viewData.Add(new Contact { Id = (int)contact["Id"], FirstName = (string)contact["FirstName"], LastName = (string)contact["LastName"]});
}
}

return View(viewData);
}

[/sourcecode]

For anyone used to using the legacy way to connect to the Infusionsoft API, you will notice the URL on line 11 (https://api.infusionsoft.com) does not reference a specific Infusionsoft Application and the Infusionsof API Key is no longer referenced because we append the access token to the API URL (/crm/xmlrpc/v1?access_token=” + accessToken).

[sourcecode language=”csharp” firstline=”11″]
contactService.Url = "https://api.infusionsoft.com/crm/xmlrpc/v1?access_token=" + accessToken;
[/sourcecode]

When actually calling the Infusionsoft API methods, Infusionsoft recommends adding your Developer Application Client Key in for parameter named "key" for each method. You also notice line 13 offers the Developer App Key.

[sourcecode language=”csharp” firstline=”13″]
var contacts = contactService.LookupByEmail(DeveloperAppKey, email, new[] { "Id", "FirstName", "LastName" });
[/sourcecode]

[/vc_column_text][vc_message color=”alert-info”]NOTE: When using OAuth 2.0, we will no longer use the Infusionsoft API Key. Even though all of the documentation for the Infusionsoft API Methods will document a required “key” parameter as “Your Infusionsoft API key”

Infusionsoft Documentation is still geared toward the

Infusionsoft Documentation is still geared toward the “old way”.

[/vc_message][/vc_column][/vc_row][vc_row][vc_column width=”1/1″][vc_column_text]

Gotchas

Gotcha #1 – Developer Account “Display Name”

Choose wisely when setting up your Infusionsoft Developer Account “Display Name” because once it is set, there is no way to change it without the help of “The Right Guy” at Infusionsoft.

Gotcha #2 – Visual Studio ASP.NET MVC 4 Web Application Internet Template

One of the biggest challenges I had when using this template was that DotNetOpenAuth packages were automatically installed in the project with the ability to connect to Facebook, Twitter, Google and Microsoft. Wow, that is awesome, except that they are all set up for OAuth 1.0 and Infusionsoft uses OAuth 2.0. The methods are NOT compatible and due to all of the dependencies, it is a pain to remove all of the DotNetOpenAuth packages from the project.

I ended up using the Basic Template without the DotNetOpenAuth packages and things went much smoother.

Gotcha #3 – IISExpress

You can get the tutorial to work using IISExpress without SSL, but you will need to URL Encode the callback URL otherwise Infusionsoft will get confused with a custom port (it’s the colon) and rewrite your URL with HTTPS. It drove me crazy, but thanks to a bit of guidance from “The Right Guy” at Infusionsoft we were able to get it sorted out.[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column width=”1/1″][vc_column_text]

References

[/vc_column_text][/vc_column][/vc_row]

By | 2014-09-04T13:42:16+00:00 September 4th, 2014|Categories: API, Infusionsoft, OAuth|Tags: , , , |2 Comments

About the Author:

Brad Ullery started off a little different – he was a jock in high school and college, and he found that he could talk to machines as easily as he could swing a bat. He spent years honing his craft, and has never met a technology he didn’t like (although there are some he prefers). A father or three amazing kids, a husband to an amazing wife, a baseball and hockey fan, Brad now spends his time architecting solutions designed to do one thing – deliver results.

2 Comments

  1. Britt July 29, 2015 at 3:52 am

    I red this article fully about the comparison of newest annd earlier
    technologies, it’s awesome article.

  2. Aayush April 8, 2016 at 5:59 am

    Where can I update the callback URL after creating the application? Couldn’t find it anywhere in the settings.

Leave A Comment