Search code examples
phpquickbooks

want to integrate quickbooks desktop with php


I am trying to integrate quickbook desktop version using following github repository:

https://github.com/consolibyte/quickbooks-php

but when I have created a custom new file to create customer into QB desktop application from our website using your sample code i.e. mydomain.com/qb_desktop/docs/web_connector/customer.php

After adding this file in web connector and run this, it keeps running continuously and keeps creating new unlimited customer until I add "die" in the php script to stop forcefully this.

Can you please take a look into my following codes and let me know what exactly I am doing wrong here?

Thanks in advance.

<?php
$primary_key_of_your_customer = 5;
require_once '../../QuickBooks.php';
$user = 'user';
$pass = 'password';
$map = array(QUICKBOOKS_ADD_CUSTOMER => array( '_quickbooks_customer_add_request', '_quickbooks_customer_add_response'));
$errmap = array( 3070 => '_quickbooks_error_stringtoolong');
$hooks = array();
$log_level = QUICKBOOKS_LOG_DEBUG;  
$soapserver = QUICKBOOKS_SOAPSERVER_BUILTIN;
$soap_options = array();
$handler_options = array('deny_concurrent_logins' => false,
            'deny_reallyfast_logins' => false);
$driver_options = array();
$callback_options = array();
$dsn = 'mysqli://root:password@localhost/quickbooks';
$Server = new QuickBooks_WebConnector_Server($dsn, $map, $errmap, $hooks, $log_level, $soapserver, QUICKBOOKS_WSDL, $soap_options, $handler_options, $driver_options, $callback_options);
$response = $Server->handle(true, true);
$Queue = new QuickBooks_WebConnector_Queue($dsn);
$Queue->enqueue(QUICKBOOKS_ADD_CUSTOMER, $primary_key_of_your_customer);

function _quickbooks_customer_add_request($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale)
{
    $xml = '<?xml version="1.0" encoding="utf-8"?>
        <?qbxml version="2.0"?>
        <QBXML>
            <QBXMLMsgsRq onError="stopOnError">
                <CustomerAddRq requestID="' . $requestID . '">
                    <CustomerAdd>
                        <Name>ConsoliBYTE, LLC (' . mt_rand() . ')</Name>
                        <CompanyName>ConsoliBYTE, LLC</CompanyName>
                        <FirstName>Keith</FirstName>
                        <LastName>Palmer</LastName>
                        <BillAddress>
                            <Addr1>ConsoliBYTE, LLC</Addr1>
                            <Addr2>134 Stonemill Road</Addr2>
                            <City>Mansfield</City>
                            <State>CT</State>
                            <PostalCode>06268</PostalCode>
                            <Country>United States</Country>
                        </BillAddress>
                        <Phone>860-634-1602</Phone>
                        <AltPhone>860-429-0021</AltPhone>
                        <Fax>860-429-5183</Fax>
                        <Email>[email protected]</Email>
                        <Contact>Keith Palmer</Contact>
                    </CustomerAdd>
                </CustomerAddRq>
            </QBXMLMsgsRq>
        </QBXML>';
    return $xml;
}
function _quickbooks_customer_add_response($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
{
    // Great, customer $ID has been added to QuickBooks with a QuickBooks
    //  ListID value of: $idents['ListID']
    //
    // We probably want to store that ListID in our database, so we can use it
    //  later. (You'll need to refer to the customer by either ListID or Name
    //  in other requests, say, to update the customer or to add an invoice for
    //  the customer.
}

Solution

  • The Web Connector is based on SOAP, so what you're actually doing here is setting up a SOAP server that the Web Connector connects to.

    What's important to realize here is that the Web Connector makes many calls to the SOAP service (e.g. many independent HTTP requests to your PHP script) every single time it connects. At the very least, even if there's no actual data to exchange, it makes at least 4 calls:

    • clientVersion
    • serverVersion
    • authenticate
    • closeConnection

    The implication here is that whatever you put in your PHP script runs at least 4 times every time the Web Connector connects to your service to try to exchange data with QuickBooks. So every time the Web Connector connects, this piece of code runs at least 4 times:

    $Queue = new QuickBooks_WebConnector_Queue($dsn);
    $Queue->enqueue(QUICKBOOKS_ADD_CUSTOMER, $primary_key_of_your_customer);
    

    You should not have this piece of code in this file. It should be elsewhere. Remove it from this file, and your problem will go away.

    Instead, modify your web app so that when a new customer is created in your web app, you queue up the request for QuickBooks at that same time. So somewhere in your application when you're doing something like this:

    // Person submitted the form, so save the data they submitted into my database
    $my_customer['first_name'] = $_POST['first_name'];
    $my_customer['last_name'] = $_POST['last_name'];
    
    $my_customer_id = $MyModelOrDatabase->insert('customer_table', $my_customer);
    

    You should do this:

    // Person submitted the form, so save the data they submitted into my database
    $my_customer['first_name'] = $_POST['first_name'];
    $my_customer['last_name'] = $_POST['last_name'];
    
    $my_customer_id = $MyModelOrDatabase->insert('customer_table', $my_customer);
    
    if ($my_customer_id)
    {
        $Queue = new QuickBooks_WebConnector_Queue($dsn);
        $Queue->enqueue(QUICKBOOKS_ADD_CUSTOMER, $my_customer_id);
    }
    

    This puts a record in the queue for QuickBooks. Then, when the Web Connector connects it can pick this up out of the queue that you already built and process it.

    If you look at the examples, there's an example which illustrates this:

    Specifically, this example:

    Which looks something like this:

    // Handle the form post
    if (isset($_POST['submitted']))
    {
        // Save the record
        mysql_query("
            INSERT INTO
                my_customer_table
            (
                name, 
                fname, 
                lname
            ) VALUES (
                '" . mysql_escape_string($_POST['name']) . "', 
                '" . mysql_escape_string($_POST['fname']) . "', 
                '" . mysql_escape_string($_POST['lname']) . "'
            )");
    
        // Get the primary key of the new record
        $id = mysql_insert_id();
    
        // Queue up the customer add 
        $Queue = new QuickBooks_WebConnector_Queue($dsn);
        $Queue->enqueue(QUICKBOOKS_ADD_CUSTOMER, $id);
    
        die('Great, queued up a customer!');
    }
    

    And if you look at the docs, they actually explicitly warn you not to do what you've done so far:

    Docs:

        // NOTE: You would normally *never* want to do this in this file! This is 
        //  meant as an initial test ONLY. See example_web_connector_queueing.php for more 
        //  details!
        // 
        // IMPORTANT NOTE: This particular example of queueing something up will 
        //  only ever happen *once* when these scripts are first run/used. After 
        //  this initial test, you MUST do your queueing in another script. DO NOT 
        //  DO YOUR OWN QUEUEING IN THIS FILE! See 
        //  docs/example_web_connector_queueing.php for more details and examples 
        //  of queueing things up.