IronBark
IronBark

Reputation: 74

Creating Customer in Quickbooks Online from C#

I need to add new customers to QuickBooks Online from C#.

I'm struggling to find any working end-to-end samples. Based on this: how to add invoice or sales receipt quickbooks rest api v3.0 I need accessToken, accessTokenSecret, consumerKey, consumerKeySecret, realmId.

Based on this: IPP .NET SDK for QuickBooks v3.0 Create Invoice Error - Bad Request I need accessToken, accessTokenSecret, consumerKey,consumerKeySecret, appToken, companyId.

I only have App Token, Oauth Consumer Key, OAuth consumer Secret, possibly realmId (App ID)

Where do I find the access token, access token secret, realm id and/or company ID?

I don't have a reputation to post images, but the developer settings page on https://developer.intuit.com/Application/Manage/IA?appId=XXX shows the following informations:

App ID: what is this? realm Id, company id?

App Token,OAuth Consumer Key,OAuth Consumer Secret

I'm using the QuickBooks Online REST API v3.0 for .Net

The code follows:

   var customer = new Customer();

   customer.GivenName = txtFirstName.Text;
   customer.FamilyName = txtLastName.Text;
   customer.MiddleName = txtMiddleName.Text;
   customer.CompanyName = txtCompany.Text;

   customer.PrimaryEmailAddr = new EmailAddress() { Address = txtEmail.Text, Default = true };
   customer.PrimaryPhone = new TelephoneNumber() { FreeFormNumber = txtPrimaryPhone.Text };


   OAuthRequestValidator oauthValidator = new OAuthRequestValidator(accessToken, accessTokenSecret, consumerKey, consumerSecret);
   ServiceContext context = new ServiceContext(accessToken, consumerKey, IntuitServicesType.QBO, oauthValidator);

   DataService service = new DataService(context);
   var c = service.Add(customer);
   // do something with c.Id

Upvotes: 2

Views: 5538

Answers (3)

juanespty
juanespty

Reputation: 84

I'm new to the QuickBooks Online API and had trouble getting the code working for a .NET 5.0 WPF application, so here's some sample code that worked for me:

Install the required QBO dependencies:

  • IppDotNetSdkForQuickBooksApiV3
  • IppOAuth2PlatformSdk

WPF Window C# Code:

using Intuit.Ipp.Data;

public partial class MainWindow : Window
{  
    QuickbooksOnline qbo = new QuickbooksOnline();

    public MainWindow()
    {
        qbo.FindCustomerResponse += HandleFindQBOCustomerResponse;
        qbo.FindInvoiceResponse += HandleFindQBOInvoiceResponse;
        qbo.FindCreditMemoResponse += HandleFindQBOCreditMemoResponse;
    }

    private void btnTest_Click(object sender, RoutedEventArgs e)
    {
        //Get IDs to test from QBO website URL when accessing a record

        string customerId = "737";
        qbo.FindCustomer(customerId);

        string invoiceId = "3198";
        qbo.FindInvoice(invoiceId);

        string creditMemoId = "3077";
        qbo.FindCreditMemo(creditMemoId);
    }

    private void HandleFindQBOCustomerResponse(object sender, Intuit.Ipp.Data.Customer customer)
    {
        if (customer == null)
        {
            MessageBox.Show("Customer not found");
        }
        else
        {
            MessageBox.Show(customer.DisplayName);
        }
    }

    private void HandleFindQBOInvoiceResponse(object sender, Intuit.Ipp.Data.Invoice invoice)
    {
        if (invoice == null)
        {
            MessageBox.Show("Invoice not found");
        }
        else
        {
            MessageBox.Show(invoice.TotalAmt.ToString());
        }
    }

    private void HandleFindQBOCreditMemoResponse(object sender, Intuit.Ipp.Data.CreditMemo creditMemo)
    {
        if (creditMemo == null)
        {
            MessageBox.Show("CreditMemo not found");
        }
        else
        {
            MessageBox.Show(creditMemo.TotalAmt.ToString());
        }
    }
}

Quickbooks Online Class:

using System;
using System.Threading.Tasks;
using Intuit.Ipp.Core;
using Intuit.Ipp.Data;
using Intuit.Ipp.Security;
using Intuit.Ipp.DataService;
using System.Windows;
using System.Reflection;
using Intuit.Ipp.OAuth2PlatformClient;

class QuickbooksOnline
{
    //Get this information from the OAuth 2.0 Playground: https://developer.intuit.com/app/developer/playground
    private string ClientId = "";
    private string ClientSecret = "";
    private string RedirectURI = "https://developer.intuit.com/v2/OAuth2Playground/RedirectUrl";
    private string RealmId = "";
    private string AccessToken = "";
    private string RefreshToken = "";
    private string QBOBaseURL = "https://quickbooks.api.intuit.com/";
    private string QBOMinorVersion = "55";

    private OAuth2Client OAuthClient;

    public event EventHandler<Intuit.Ipp.Data.Customer> FindCustomerResponse;
    public event EventHandler<Intuit.Ipp.Data.Invoice> FindInvoiceResponse;
    public event EventHandler<Intuit.Ipp.Data.CreditMemo> FindCreditMemoResponse;

    public QuickbooksOnline()
    {
        this.OAuthClient = new OAuth2Client(ClientId, ClientSecret, RedirectURI, "production");
    }

    public async void FindCustomer(string customerId)
    {
        OAuth2RequestValidator oAuthValidator = new OAuth2RequestValidator(AccessToken);
        ServiceContext serviceContext = new ServiceContext(RealmId, IntuitServicesType.QBO, oAuthValidator);
        serviceContext.IppConfiguration.BaseUrl.Qbo = QBOBaseURL;
        serviceContext.IppConfiguration.MinorVersion.Qbo = QBOMinorVersion;
        DataService service = new DataService(serviceContext);

        Customer customer = new Customer();
        customer.Id = customerId;

        service.OnFindByIdAsyncCompleted += HandlePrivateFindByIdResponse;

        service.FindByIdAsync(customer);
    }


    public void FindInvoice(string invoiceId)
    {
        OAuth2RequestValidator oAuthValidator = new OAuth2RequestValidator(AccessToken);
        ServiceContext serviceContext = new ServiceContext(RealmId, IntuitServicesType.QBO, oAuthValidator);
        serviceContext.IppConfiguration.BaseUrl.Qbo = QBOBaseURL;
        serviceContext.IppConfiguration.MinorVersion.Qbo = QBOMinorVersion;
        DataService service = new DataService(serviceContext);

        Intuit.Ipp.Data.Invoice invoice = new Intuit.Ipp.Data.Invoice();
        invoice.Id = invoiceId;

        service.OnFindByIdAsyncCompleted += HandlePrivateFindByIdResponse;

        service.FindByIdAsync(invoice);
    }

    public void FindCreditMemo(string creditMemoId)
    {
        OAuth2RequestValidator oAuthValidator = new OAuth2RequestValidator(AccessToken);
        ServiceContext serviceContext = new ServiceContext(RealmId, IntuitServicesType.QBO, oAuthValidator);
        serviceContext.IppConfiguration.BaseUrl.Qbo = QBOBaseURL;
        serviceContext.IppConfiguration.MinorVersion.Qbo = QBOMinorVersion;
        DataService service = new DataService(serviceContext);

        CreditMemo creditMemo = new CreditMemo();
        creditMemo.Id = creditMemoId;

        service.OnFindByIdAsyncCompleted += HandlePrivateFindByIdResponse;

        service.FindByIdAsync(creditMemo);
    }

    private async void HandlePrivateFindByIdResponse(object sender, CallCompletedEventArgs<IEntity> entity)
    {
        // The Intuit.Ipp.DataService.AsyncService class is not public, so that to use reflection
        // to get the requestedEntity object and determine the sender type.
        // This is useful when the authToken has expired and after refreshing the tokens
        // the request has to be sent again.
        string entityType = sender.GetType().GetField("requestedEntity", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(sender).GetType().FullName;

        if (entity.Error != null && entity.Error.Message.Equals("Unauthorized-401"))
        {
            
            if (await RefreshTokens())
            {
                switch (entityType)
                {
                    case "Intuit.Ipp.Data.Customer":
                        Customer senderCustomer = (Customer)sender.GetType().GetField("requestedEntity", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(sender);
                        FindCustomer(senderCustomer.Id);
                        break;
                    case "Intuit.Ipp.Data.Invoice":
                        Intuit.Ipp.Data.Invoice senderInvoice = (Intuit.Ipp.Data.Invoice)sender.GetType().GetField("requestedEntity", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(sender);
                        FindInvoice(senderInvoice.Id);
                        break;
                    case "Intuit.Ipp.Data.CreditMemo":
                        Intuit.Ipp.Data.CreditMemo senderCreditMemo = (Intuit.Ipp.Data.CreditMemo)sender.GetType().GetField("requestedEntity", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(sender);
                        FindCreditMemo(senderCreditMemo.Id);
                        break;
                }
            }
            else
            {
                MessageBox.Show("Error refreshing tokens.");
            }
        }
        else if (entity.Entity != null)
        {
            switch (entity.Entity.GetType().FullName)
            {
                case "Intuit.Ipp.Data.Customer":
                    if (FindCustomerResponse != null)
                    {
                        FindCustomerResponse(this, entity.Entity as Intuit.Ipp.Data.Customer);
                    }
                    break;
                case "Intuit.Ipp.Data.Invoice":
                    if (FindInvoiceResponse != null)
                    {
                        FindInvoiceResponse(this, entity.Entity as Intuit.Ipp.Data.Invoice);
                    }
                    break;
                case "Intuit.Ipp.Data.CreditMemo":
                    if (FindCreditMemoResponse != null)
                    {
                        FindCreditMemoResponse(this, entity.Entity as Intuit.Ipp.Data.CreditMemo);
                    }
                    break;
            }
        }
        else if (entity.Entity == null)
        {
            switch (entityType)
            {
                case "Intuit.Ipp.Data.Customer":
                    if (FindCustomerResponse != null)
                    {
                        FindCustomerResponse(this, null);
                    }
                    
                    break;
                case "Intuit.Ipp.Data.Invoice":
                    if (FindInvoiceResponse != null)
                    {
                        FindInvoiceResponse(this, null);
                    }
                    break;
                case "Intuit.Ipp.Data.CreditMemo":
                    if (FindCreditMemoResponse != null)
                    {
                        FindCreditMemoResponse(this, null);
                    }
                    break;
            }
        }
    }

    private async Task<bool> RefreshTokens()
    {
        var tokenResp = await OAuthClient.RefreshTokenAsync(RefreshToken);

        if (tokenResp.AccessToken != null && tokenResp.RefreshToken != null)
        {
            this.AccessToken = tokenResp.AccessToken;
            this.RefreshToken = tokenResp.RefreshToken;
            return true;
        }
        else
        {
            return false;
        }
    }

}

Upvotes: 0

Vivek Kumar
Vivek Kumar

Reputation: 2929

Intuit Anywhere Developer Playground provides facility to get accessToken, accessTokenSecret and realmId.

Go to QuickBooks playground by clicking link mentioned below –

https://appcenter.intuit.com/Playground/OAuth/IA

Make sure that you are already logged into your Intuit account.

Fill consumer Key, Consumer Secret and Access Token Duration (120000 seconds).

enter image description here

Click on Connect to QuickBooks icon as shown in the picture. You will be asked to select company. If you have more than one company connected to your sandbox account, choose any according to your requirement. Then click Authorize Button.

You will get Access Token, Access Token Secret, RealmId (Company Id) and DataSource. Now you have all the keys to implement Accounting API. These keys will expire after 120000 seconds.

I have written a blog on how you can add, update, find and delete Customer.

https://vivekkumar11432.wordpress.com/2016/06/07/implement-intuits-quickbooks-online-api-in-restful-service-c/

Upvotes: 1

nimisha shrivastava
nimisha shrivastava

Reputation: 2367

You need to implement the 3 legged oauth flow in your app using C2QB button to get the access token and secret. Please see our sample apps to see how this is implemented. Download the sample app and then configure the consumer key and secret in the config file. Then check how the 3-legged oauth happens.You can try making calls to the V3 API using the local copy of the sample apps too. https://github.com/IntuitDeveloperRelations/ Also refer: https://developer.intuit.com/docs/0025_quickbooksapi/0010_getting_started

Upvotes: 2

Related Questions