Sample code for 30+ languages & platforms
Pascal (Lazarus/Delphi)

Quickbooks Update an Invoice

See more QuickBooks Examples

Demonstrates how to update an invoice using the Quickbooks REST API.

Chilkat Pascal (Lazarus/Delphi) Downloads

Pascal (Lazarus/Delphi)
program ChilkatDemo;

// Demonstrates using the Chilkat Pascal wrapper via the C bridge DLL.
// Builds as a console application under Lazarus (FPC) or Delphi.

{$IFDEF FPC}
  {$MODE DELPHI}
{$ENDIF}
{$APPTYPE CONSOLE}

uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  SysUtils,
  CkDllLoader,
  Chilkat.StringBuilder,
  Chilkat.Rest,
  Chilkat.JsonObject;

// ---------------------------------------------------------------------------

procedure RunDemo;
var
  success: Boolean;
  jsonToken: TJsonObject;
  rest: TRest;
  bTls: Boolean;
  port: Integer;
  bAutoReconnect: Boolean;
  sbAuth: TStringBuilder;
  jsonReq: TJsonObject;
  sbRequestBody: TStringBuilder;
  sbResponseBody: TStringBuilder;
  respStatusCode: Integer;
  jsonResponse: TJsonObject;
  LineNum: Integer;
  Amount: string;
  SalesItemLineDetailTaxCodeRefValue: string;
  SalesItemLineDetailItemRefName: string;
  SalesItemLineDetailItemRefValue: string;
  Id: string;
  DetailType: string;
  DefinitionId: string;
  invType: string;
  Name: string;
  InvoiceTxnDate: string;
  InvoiceDomain: string;
  InvoicePrintStatus: string;
  InvoiceTotalAmt: string;
  InvoiceDueDate: string;
  InvoiceApplyTaxAfterDiscount: Boolean;
  InvoiceDocNumber: string;
  InvoiceSparse: Boolean;
  InvoiceCustomerMemoValue: string;
  InvoiceDeposit: Integer;
  InvoiceBalance: string;
  InvoiceCustomerRefName: string;
  InvoiceCustomerRefValue: string;
  InvoiceTxnTaxDetailTotalTax: Integer;
  InvoiceSyncToken: string;
  InvoiceShipAddrCountrySubDivisionCode: string;
  InvoiceShipAddrCity: string;
  InvoiceShipAddrPostalCode: string;
  InvoiceShipAddrId: string;
  InvoiceShipAddrLine1: string;
  InvoiceEmailStatus: string;
  InvoiceBillAddrCountrySubDivisionCode: string;
  InvoiceBillAddrCity: string;
  InvoiceBillAddrPostalCode: string;
  InvoiceBillAddrId: string;
  InvoiceBillAddrLine1: string;
  InvoiceMetaDataCreateTime: string;
  InvoiceMetaDataLastUpdatedTime: string;
  InvoiceId: string;
  time: string;
  i: Integer;
  count_i: Integer;

begin
  success := False;

  //  This example requires the Chilkat API to have been previously unlocked.
  //  See Global Unlock Sample for sample code.

  //  First get our previously obtained OAuth2 access token.
  jsonToken := TJsonObject.Create;
  success := jsonToken.LoadFile('qa_data/tokens/qb-access-token.json');

  rest := TRest.Create;

  //  Connect to the REST server.
  bTls := True;
  port := 443;
  bAutoReconnect := True;
  success := rest.Connect('sandbox-quickbooks.api.intuit.com',port,bTls,bAutoReconnect);

  sbAuth := TStringBuilder.Create;
  sbAuth.Append('Bearer ');
  sbAuth.Append(jsonToken.StringOf('access_token'));
  rest.Authorization := sbAuth.GetAsString();

  //  --------------------------------------------------------------------------
  //  Note: The above code to setup the initial REST connection
  //  can be done once.  After connecting, any number of REST calls can be made.
  //  If the connection is lost, the next REST method call will automatically
  //  reconnect if needed.
  //  --------------------------------------------------------------------------

  //  Create the following JSON:

  //  {
  //    "DocNumber": "1070",
  //    "SyncToken": "0",
  //    "domain": "QBO",
  //    "Balance": 150.0,
  //    "BillAddr": {
  //      "City": "Bayshore",
  //      "Line1": "4581 Finch St.",
  //      "PostalCode": "94326",
  //      "Lat": "INVALID",
  //      "Long": "INVALID",
  //      "CountrySubDivisionCode": "CA",
  //      "Id": "2"
  //    },
  //    "TxnDate": "2015-07-24",
  //    "TotalAmt": 150.0,
  //    "CustomerRef": {
  //      "name": "Amy's Bird Sanctuary",
  //      "value": "1"
  //    },
  //    "CustomerMemo": {
  //      "value": "Added customer memo."
  //    },
  //    "ShipAddr": {
  //      "City": "Bayshore",
  //      "Line1": "4581 Finch St.",
  //      "PostalCode": "94326",
  //      "Lat": "INVALID",
  //      "Long": "INVALID",
  //      "CountrySubDivisionCode": "CA",
  //      "Id": "109"
  //    },
  //    "LinkedTxn": [
  //    ],
  //    "DueDate": "2015-08-23",
  //    "PrintStatus": "NeedToPrint",
  //    "EmailStatus": "NotSet",
  //    "sparse": false,
  //    "Line": [
  //      {
  //        "LineNum": 1,
  //        "Amount": 150.0,
  //        "SalesItemLineDetail": {
  //          "TaxCodeRef": {
  //            "value": "NON"
  //          },
  //          "ItemRef": {
  //            "name": "Services",
  //            "value": "1"
  //          }
  //        },
  //        "Id": "1",
  //        "DetailType": "SalesItemLineDetail"
  //      },
  //      {
  //        "DetailType": "SubTotalLineDetail",
  //        "Amount": 150.0,
  //        "SubTotalLineDetail": {}
  //      }
  //    ],
  //    "ApplyTaxAfterDiscount": false,
  //    "CustomField": [
  //      {
  //        "DefinitionId": "1",
  //        "Type": "StringType",
  //        "Name": "Crew #"
  //      }
  //    ],
  //    "Id": "239",
  //    "TxnTaxDetail": {
  //      "TotalTax": 0
  //    },
  //    "MetaData": {
  //      "CreateTime": "2015-07-24T10:35:08-07:00",
  //      "LastUpdatedTime": "2015-07-24T10:35:08-07:00"
  //    }
  //  }
  //  
  //  Use the this online tool to generate the code from sample JSON: 
  //  Generate Code to Create JSON

  jsonReq := TJsonObject.Create;
  jsonReq.UpdateString('DocNumber','1070');
  jsonReq.UpdateString('SyncToken','0');
  jsonReq.UpdateString('domain','QBO');
  jsonReq.UpdateNumber('Balance','150.0');
  jsonReq.UpdateString('BillAddr.City','Bayshore');
  jsonReq.UpdateString('BillAddr.Line1','4581 Finch St.');
  jsonReq.UpdateString('BillAddr.PostalCode','94326');
  jsonReq.UpdateString('BillAddr.Lat','INVALID');
  jsonReq.UpdateString('BillAddr.Long','INVALID');
  jsonReq.UpdateString('BillAddr.CountrySubDivisionCode','CA');
  jsonReq.UpdateString('BillAddr.Id','2');
  jsonReq.UpdateString('TxnDate','2015-07-24');
  jsonReq.UpdateNumber('TotalAmt','150.0');
  jsonReq.UpdateString('CustomerRef.name','Amy''s Bird Sanctuary');
  jsonReq.UpdateString('CustomerRef.value','1');
  jsonReq.UpdateString('CustomerMemo.value','Added customer memo.');
  jsonReq.UpdateString('ShipAddr.City','Bayshore');
  jsonReq.UpdateString('ShipAddr.Line1','4581 Finch St.');
  jsonReq.UpdateString('ShipAddr.PostalCode','94326');
  jsonReq.UpdateString('ShipAddr.Lat','INVALID');
  jsonReq.UpdateString('ShipAddr.Long','INVALID');
  jsonReq.UpdateString('ShipAddr.CountrySubDivisionCode','CA');
  jsonReq.UpdateString('ShipAddr.Id','109');
  jsonReq.UpdateNewArray('LinkedTxn');
  jsonReq.UpdateString('DueDate','2015-08-23');
  jsonReq.UpdateString('PrintStatus','NeedToPrint');
  jsonReq.UpdateString('EmailStatus','NotSet');
  jsonReq.UpdateBool('sparse',False);
  jsonReq.UpdateInt('Line[0].LineNum',1);
  jsonReq.UpdateNumber('Line[0].Amount','150.0');
  jsonReq.UpdateString('Line[0].SalesItemLineDetail.TaxCodeRef.value','NON');
  jsonReq.UpdateString('Line[0].SalesItemLineDetail.ItemRef.name','Services');
  jsonReq.UpdateString('Line[0].SalesItemLineDetail.ItemRef.value','1');
  jsonReq.UpdateString('Line[0].Id','1');
  jsonReq.UpdateString('Line[0].DetailType','SalesItemLineDetail');
  jsonReq.UpdateString('Line[1].DetailType','SubTotalLineDetail');
  jsonReq.UpdateNumber('Line[1].Amount','150.0');
  jsonReq.UpdateNewObject('Line[1].SubTotalLineDetail');
  jsonReq.UpdateBool('ApplyTaxAfterDiscount',False);
  jsonReq.UpdateString('CustomField[0].DefinitionId','1');
  jsonReq.UpdateString('CustomField[0].Type','StringType');
  jsonReq.UpdateString('CustomField[0].Name','Crew #');
  jsonReq.UpdateString('Id','239');
  jsonReq.UpdateInt('TxnTaxDetail.TotalTax',0);
  jsonReq.UpdateString('MetaData.CreateTime','2015-07-24T10:35:08-07:00');
  jsonReq.UpdateString('MetaData.LastUpdatedTime','2015-07-24T10:35:08-07:00');

  sbRequestBody := TStringBuilder.Create;
  jsonReq.EmitSb(sbRequestBody);

  rest.AddHeader('Content-Type','application/json');
  rest.AddHeader('Accept','application/json');
  rest.AllowHeaderFolding := False;

  sbResponseBody := TStringBuilder.Create;
  success := rest.FullRequestSb('POST','/v3/company/<realmID>/invoice',sbRequestBody,sbResponseBody);
  if (success <> True) then
    begin
      WriteLn(rest.LastErrorText);
      Exit;
    end;

  respStatusCode := rest.ResponseStatusCode;

  //  Success is indicated by a 200 response status code.
  WriteLn('response status code = ' + respStatusCode);

  jsonResponse := TJsonObject.Create;
  jsonResponse.LoadSb(sbResponseBody);
  jsonResponse.EmitCompact := False;
  WriteLn(jsonResponse.Emit());

  if (rest.ResponseStatusCode <> 200) then
    begin
      WriteLn('Failed.');
      Exit;
    end;

  //  Sample output...
  //  (See the parsing code below..)
  //  
  //  Use the this online tool to generate parsing code from sample JSON: 
  //  Generate Parsing Code from JSON

  //  {
  //    "Invoice": {
  //      "TxnDate": "2015-07-24",
  //      "domain": "QBO",
  //      "PrintStatus": "NeedToPrint",
  //      "TotalAmt": 150.0,
  //      "Line": [
  //        {
  //          "LineNum": 1,
  //          "Amount": 150.0,
  //          "SalesItemLineDetail": {
  //            "TaxCodeRef": {
  //              "value": "NON"
  //            },
  //            "ItemRef": {
  //              "name": "Services",
  //              "value": "1"
  //            }
  //          },
  //          "Id": "1",
  //          "DetailType": "SalesItemLineDetail"
  //        },
  //        {
  //          "DetailType": "SubTotalLineDetail",
  //          "Amount": 150.0,
  //          "SubTotalLineDetail": {}
  //        }
  //      ],
  //      "DueDate": "2015-08-23",
  //      "ApplyTaxAfterDiscount": false,
  //      "DocNumber": "1070",
  //      "sparse": false,
  //      "CustomerMemo": {
  //        "value": "Added customer memo."
  //      },
  //      "Deposit": 0,
  //      "Balance": 150.0,
  //      "CustomerRef": {
  //        "name": "Amy's Bird Sanctuary",
  //        "value": "1"
  //      },
  //      "TxnTaxDetail": {
  //        "TotalTax": 0
  //      },
  //      "SyncToken": "1",
  //      "LinkedTxn": [
  //      ],
  //      "ShipAddr": {
  //        "CountrySubDivisionCode": "CA",
  //        "City": "Bayshore",
  //        "PostalCode": "94326",
  //        "Id": "118",
  //        "Line1": "4581 Finch St."
  //      },
  //      "EmailStatus": "NotSet",
  //      "BillAddr": {
  //        "CountrySubDivisionCode": "CA",
  //        "City": "Bayshore",
  //        "PostalCode": "94326",
  //        "Id": "117",
  //        "Line1": "4581 Finch St."
  //      },
  //      "MetaData": {
  //        "CreateTime": "2015-07-24T10:35:08-07:00",
  //        "LastUpdatedTime": "2015-07-24T10:53:39-07:00"
  //      },
  //      "CustomField": [
  //        {
  //          "DefinitionId": "1",
  //          "Type": "StringType",
  //          "Name": "Crew #"
  //        }
  //      ],
  //      "Id": "239"
  //    },
  //    "time": "2015-07-24T10:53:39.287-07:00"
  //  }
  //  

  InvoiceTxnDate := jsonResponse.StringOf('Invoice.TxnDate');
  InvoiceDomain := jsonResponse.StringOf('Invoice.domain');
  InvoicePrintStatus := jsonResponse.StringOf('Invoice.PrintStatus');
  InvoiceTotalAmt := jsonResponse.StringOf('Invoice.TotalAmt');
  InvoiceDueDate := jsonResponse.StringOf('Invoice.DueDate');
  InvoiceApplyTaxAfterDiscount := jsonResponse.BoolOf('Invoice.ApplyTaxAfterDiscount');
  InvoiceDocNumber := jsonResponse.StringOf('Invoice.DocNumber');
  InvoiceSparse := jsonResponse.BoolOf('Invoice.sparse');
  InvoiceCustomerMemoValue := jsonResponse.StringOf('Invoice.CustomerMemo.value');
  InvoiceDeposit := jsonResponse.IntOf('Invoice.Deposit');
  InvoiceBalance := jsonResponse.StringOf('Invoice.Balance');
  InvoiceCustomerRefName := jsonResponse.StringOf('Invoice.CustomerRef.name');
  InvoiceCustomerRefValue := jsonResponse.StringOf('Invoice.CustomerRef.value');
  InvoiceTxnTaxDetailTotalTax := jsonResponse.IntOf('Invoice.TxnTaxDetail.TotalTax');
  InvoiceSyncToken := jsonResponse.StringOf('Invoice.SyncToken');
  InvoiceShipAddrCountrySubDivisionCode := jsonResponse.StringOf('Invoice.ShipAddr.CountrySubDivisionCode');
  InvoiceShipAddrCity := jsonResponse.StringOf('Invoice.ShipAddr.City');
  InvoiceShipAddrPostalCode := jsonResponse.StringOf('Invoice.ShipAddr.PostalCode');
  InvoiceShipAddrId := jsonResponse.StringOf('Invoice.ShipAddr.Id');
  InvoiceShipAddrLine1 := jsonResponse.StringOf('Invoice.ShipAddr.Line1');
  InvoiceEmailStatus := jsonResponse.StringOf('Invoice.EmailStatus');
  InvoiceBillAddrCountrySubDivisionCode := jsonResponse.StringOf('Invoice.BillAddr.CountrySubDivisionCode');
  InvoiceBillAddrCity := jsonResponse.StringOf('Invoice.BillAddr.City');
  InvoiceBillAddrPostalCode := jsonResponse.StringOf('Invoice.BillAddr.PostalCode');
  InvoiceBillAddrId := jsonResponse.StringOf('Invoice.BillAddr.Id');
  InvoiceBillAddrLine1 := jsonResponse.StringOf('Invoice.BillAddr.Line1');
  InvoiceMetaDataCreateTime := jsonResponse.StringOf('Invoice.MetaData.CreateTime');
  InvoiceMetaDataLastUpdatedTime := jsonResponse.StringOf('Invoice.MetaData.LastUpdatedTime');
  InvoiceId := jsonResponse.StringOf('Invoice.Id');
  time := jsonResponse.StringOf('time');
  i := 0;
  count_i := jsonResponse.SizeOfArray('Invoice.Line');
  while i < count_i do
    begin
      jsonResponse.I := i;
      LineNum := jsonResponse.IntOf('Invoice.Line[i].LineNum');
      Amount := jsonResponse.StringOf('Invoice.Line[i].Amount');
      SalesItemLineDetailTaxCodeRefValue := jsonResponse.StringOf('Invoice.Line[i].SalesItemLineDetail.TaxCodeRef.value');
      SalesItemLineDetailItemRefName := jsonResponse.StringOf('Invoice.Line[i].SalesItemLineDetail.ItemRef.name');
      SalesItemLineDetailItemRefValue := jsonResponse.StringOf('Invoice.Line[i].SalesItemLineDetail.ItemRef.value');
      Id := jsonResponse.StringOf('Invoice.Line[i].Id');
      DetailType := jsonResponse.StringOf('Invoice.Line[i].DetailType');
      i := i + 1;
    end;

  i := 0;
  count_i := jsonResponse.SizeOfArray('Invoice.LinkedTxn');
  while i < count_i do
    begin
      jsonResponse.I := i;
      i := i + 1;
    end;

  i := 0;
  count_i := jsonResponse.SizeOfArray('Invoice.CustomField');
  while i < count_i do
    begin
      jsonResponse.I := i;
      DefinitionId := jsonResponse.StringOf('Invoice.CustomField[i].DefinitionId');
      invType := jsonResponse.StringOf('Invoice.CustomField[i].Type');
      Name := jsonResponse.StringOf('Invoice.CustomField[i].Name');
      i := i + 1;
    end;



  jsonToken.Free;
  rest.Free;
  sbAuth.Free;
  jsonReq.Free;
  sbRequestBody.Free;
  sbResponseBody.Free;
  jsonResponse.Free;

end;

// ---------------------------------------------------------------------------

begin

  try
    RunDemo;
  except
    on E: Exception do
      WriteLn('Unhandled exception: ', E.ClassName, ': ', E.Message);
  end;

  WriteLn;
  {$IFDEF MSWINDOWS}
  WriteLn('Press Enter to exit...');
  ReadLn;
  {$ENDIF}
end.