1

I am developing an integration web service in php for quickbooks. I have been able to figure out all of the add and query strings already but I cannot figure out how to properly send a mod request. I know my request has something wrong with my xml string because I am not getting a response back from the web connector. I have tried to follow the onscreen reference my best, but for some reason it still wont work.

Here is my query response string from the connector:

`<?xml version="1.0" ?>
<QBXML>
<QBXMLMsgsRs>
<CustomerQueryRs requestID="183" statusCode="0" statusSeverity="Info" statusMessage="Status OK">
<CustomerRet>
<ListID>80000062-1431710964</ListID>
<TimeCreated>2015-05-15T11:29:24-07:00</TimeCreated>
<TimeModified>2015-05-15T11:29:24-07:00</TimeModified>
<EditSequence>1431710964</EditSequence>
<Name>Test 2 Contractor, Inc.</Name>
<FullName>Test 2 Contractor, Inc.</FullName>
<IsActive>true</IsActive>
<Sublevel>0</Sublevel>
<CompanyName>Test 2 Contractor, Inc.</CompanyName>
<BillAddress>
<Addr1>Test bill 1</Addr1>
<Addr2>Test bill 2</Addr2>
<City>Test City</City>
<State>UT</State>
<PostalCode>84057</PostalCode>
<Country>USA</Country>
</BillAddress>
<BillAddressBlock>
<Addr1>Test bill 1</Addr1>
<Addr2>Test bill 2</Addr2>
<Addr3>Test City, Utah 84057</Addr3>
<Addr4>United States</Addr4>
</BillAddressBlock>
<ShipAddress>
<Addr1>Test ship 1</Addr1>
<Addr2>Test ship 2</Addr2>
<City>Test City</City>
<State>UT</State>
<PostalCode>84057</PostalCode>
<Country>USA</Country>
</ShipAddress>
<ShipAddressBlock>
<Addr1>Test ship 1</Addr1>
<Addr2>Test ship 2</Addr2>
<Addr3>Test City, Utah 84057</Addr3>
<Addr4>United States</Addr4>
</ShipAddressBlock>
<ShipToAddress>
<Name>Ship To 1</Name>
<Addr1>Test ship 1</Addr1>
<Addr2>Test ship 2</Addr2>
<City>Test City</City>
<State>UT</State>
<PostalCode>84057</PostalCode>
<Country>USA</Country>
<DefaultShipTo>true</DefaultShipTo>
</ShipToAddress>
<Phone>555-555-5555</Phone>
<AltPhone>555-555-5554</AltPhone>
<Fax>555-555-5553</Fax>
<Email>business@mail.com</Email>
<AdditionalContactRef>
<ContactName>Main Phone</ContactName>
<ContactValue>555-555-5555</ContactValue>
</AdditionalContactRef>
<AdditionalContactRef>
<ContactName>Alt. Phone</ContactName>
<ContactValue>555-555-5554</ContactValue>
</AdditionalContactRef>
<AdditionalContactRef>
<ContactName>Fax</ContactName>
<ContactValue>555-555-5553</ContactValue>
</AdditionalContactRef>
<AdditionalContactRef>
<ContactName>Main Email</ContactName>
<ContactValue>business@mail.com</ContactValue>
</AdditionalContactRef>
<Balance>0.00</Balance>
<TotalBalance>0.00</TotalBalance>
<JobStatus>None</JobStatus>
<PreferredDeliveryMethod>None</PreferredDeliveryMethod>
</CustomerRet>
</CustomerQueryRs>
</QBXMLMsgsRs>
</QBXML>`

Here is the mod request I sent to the connector:

`<?xml version="1.0" encoding="utf-8"?>
<?qbxml version="13.0"?>
<QBXML>
    <QBXMLMsgsRq onError="stopOnError">
        <CustomerModRq requestID="184">
            <CustomerMod>
                <ListID>80000062-1431710964</ListID>
                <EditSequence>1431710964</EditSequence>
                <Name>Test 2 Contractor, Inc.Updated</Name>
                <CompanyName>Test 2 Contractor, Inc.</CompanyName>
            </CustomerMod>
        </CustomerModRq>
    </QBXMLMsgsRq>
</QBXML>`

Here is the code i used to generate the xml:

$mod_info = json_decode($queue_set['qb_queue_item']->extra);
                $list_id = $mod_info->list_id;
                $edit_sequence = $mod_info->edit_sequence;

                //Get the contractor to be sent to quickbooks
                $contractor = new Contractor();

                if(!($contractor = $contractor::find($queue_set['kyco_queue_item']->obj_id)))
                    return array('status' => $this::STATUS_ERROR, 'data' => "Failed to find contractor in the database");

                if(!isset($contractor->contractor))
                    return array('status' => $this::STATUS_ERROR, 'data' => "Contractor does not have a valid name");

                /*$address_billing = Address::Primary(get_class($contractor), $contractor->id, Address::ADDRESS_TYPE_BILLING);
                $address_shipping = Address::Primary(get_class($contractor), $contractor->id, Address::ADDRESS_TYPE_SHIPPING);
                $phone_primary = PhoneNumber::Primary(get_class($contractor), $contractor->id, PhoneNumber::PHONE_TYPE_STATIC);
                $phone_alt = PhoneNumber::Primary(get_class($contractor), $contractor->id, PhoneNumber::PHONE_TYPE_MOBILE);
                $phone_fax = PhoneNumber::Primary(get_class($contractor), $contractor->id, PhoneNumber::PHONE_TYPE_FAX);
                $email = Email::Primary(get_class($contractor), $contractor->id, Email::EMAIL_TYPE_BUSINESS);*/

                // Build the qbXML request from the contractors data
                $xml = "";
                $xml .= '<?xml version="1.0" encoding="utf-8"?>'. LINE_RETURN;
                $xml .= '<?qbxml version="13.0"?>'. LINE_RETURN;
                $xml .= '<QBXML>'. LINE_RETURN;
                $xml .= LINE_TAB . '<QBXMLMsgsRq onError="stopOnError">'. LINE_RETURN;
                $xml .= LINE_TAB . LINE_TAB . '<CustomerModRq requestID="' . $queue_set['qb_queue_item']->quickbooks_queue_id . '">'. LINE_RETURN;
                $xml .= LINE_TAB . LINE_TAB . LINE_TAB . '<CustomerMod>'. LINE_RETURN;
                $xml .= LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . '<ListID>' . $list_id . '</ListID>'. LINE_RETURN;

                $xml .= LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . '<EditSequence>' . $edit_sequence . '</EditSequence>'. LINE_RETURN;
                //$xml .= LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . '<Name>' . $contractor->contractor . "Updated". '</Name>'. LINE_RETURN;
                $xml .= LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . '<CompanyName>' . $contractor->contractor . '</CompanyName>'. LINE_RETURN;

                /*if($address_billing)
                {
                    $xml .= LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . '<BillAddress>'. LINE_RETURN;
                    $xml .= LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . '<Addr1>' . $address_billing->address_1 . '</Addr1>'. LINE_RETURN;
                    $xml .= LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . '<Addr2>' . $address_billing->address_2 . '</Addr2>'. LINE_RETURN;
                    $xml .= LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . '<City>' . $address_billing->city . '</City>'. LINE_RETURN;
                    $xml .= LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . '<State>' . $address_billing->state . '</State>'. LINE_RETURN;
                    $xml .= LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . '<PostalCode>' . $address_billing->postal_code . '</PostalCode>'. LINE_RETURN;
                    $xml .= LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . '<Country>' . $address_billing->country . '</Country>'. LINE_RETURN;
                    $xml .= LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . '</BillAddress>'. LINE_RETURN;
                }

                if($address_shipping)
                {
                    $xml .= LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . '<ShipAddress>' . LINE_RETURN;
                    $xml .= LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . '<Addr1>' . $address_shipping->address_1. '</Addr1>'. LINE_RETURN;
                    $xml .= LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . '<Addr2>' . $address_shipping->address_2 . '</Addr2>'. LINE_RETURN;
                    $xml .= LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . '<City>' . $address_shipping->city . '</City>'. LINE_RETURN;
                    $xml .= LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . '<State>' . $address_shipping->state . '</State>'. LINE_RETURN;
                    $xml .= LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . '<PostalCode>' . $address_shipping->postal_code . '</PostalCode>'. LINE_RETURN;
                    $xml .= LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . '<Country>' . $address_shipping->country . '</Country>' . LINE_RETURN;
                    $xml .= LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . '</ShipAddress>' . LINE_RETURN;
                }

                if($phone_primary)
                {
                    $xml .= LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . '<Phone>' . $phone_primary->number . '</Phone>'. LINE_RETURN;
                }

                if($phone_alt)
                {
                    $xml .= LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . '<AltPhone>' . $phone_alt->number . '</AltPhone>'. LINE_RETURN;
                }

                if($phone_fax)
                {
                    $xml .= LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . '<Fax>' . $phone_fax->number . '</Fax>'. LINE_RETURN;
                }

                if($email)
                {
                    $xml .= LINE_TAB . LINE_TAB . LINE_TAB . LINE_TAB . '<Email>' . $email->email . '</Email>'. LINE_RETURN;
                }*/

                $xml .= LINE_TAB . LINE_TAB . LINE_TAB . '</CustomerMod>'. LINE_RETURN;
                $xml .= LINE_TAB . LINE_TAB . '</CustomerModRq>'. LINE_RETURN;
                $xml .= LINE_TAB . '</QBXMLMsgsRq>'. LINE_RETURN;
                $xml .= '</QBXML>'. LINE_RETURN;

                //get the relational entry attached to the quickbooks queue id ($qb_queue_id)
                $queue_set['kyco_queue_item']->status = KycoQueueItem::STATUS_MOD_SENT;
                $queue_set['kyco_queue_item']->save();

                return array('status' => $this::STATUS_SUCCESS, 'data' => $xml);

That is returned to my mapped customer mod request function.

Here is my web connector log file:

https://drive.google.com/file/d/0B5iqqn5sniRDTGpJbkhKZDl6cTA/view?usp=sharing

My php log file has nothing to report. Apache Log has nothing to report and both of those xml strings I have posted are the log_message messages I printed out to the log before the xml left to the web connector.

The only other thing I can think of that may be relevant is that after I complete the query for the listID and EditSequence I store those in a json string within the extra field of my newly queued mod request so i can get them back again when I generate the mod request. That string stays in there when the request is sent. Could that be messing it up somehow?

My integration is being done through the quickbooks web connector for quickbooks enterprise solutions contractor 15.0

Nick Pray
  • 231
  • 2
  • 4
  • We can't help you because you didn't post your code, or the Web Connector log files, or your PHP error log, etc. etc. etc. – Keith Palmer Jr. May 15 '15 at 21:18
  • Alright I have given you a little more information @KeithPalmer-consolibyte let me know if you need anything else. – Nick Pray May 29 '15 at 17:41
  • Update, I figured it out. The extra column was causing the issue. As a temporary fix until I understand your consolibyte library a bit better i forced the unserialize on line 783 of WebConnector/Handlers to unserialize a blank string instead of the actual extra value. – Nick Pray May 29 '15 at 18:44
  • That sounds like a gigantic red flag to me. Something is wrong with your code if you're having to screw with the library like that. Where's the rest of your code? – Keith Palmer Jr. May 29 '15 at 21:27
  • Another update, I figured out that the json string i was putting into that field was just too big for the way you were unserializing the extra column. I dealt with the ListID and EditSequence another way and everything is working smoothly now. Thank you for all the quick responses @KeithPalmer-consolibyte. – Nick Pray Jun 06 '15 at 23:03
  • Why are you putting JSON into that field at all? You shouldn't be... – Keith Palmer Jr. Jun 07 '15 at 12:03
  • I was trying to generate a customer mod request. I sent out a query request to obtain the current ListID and EditSequence for the customer I was trying to edit. I thought it would be convenient if I could store both on the new mod request queue item I was going to generate so that when I generated the xml i would already have them at hand. At the time I thought that you intended the extra field to be for whatever extra crap we needed it for so thats what i tried to do, store the JSON in that field. As I know now, that was a misplaced assumption. – Nick Pray Jun 08 '15 at 16:32
  • That *is* what the $extra field is for, but there's no need to use JSON to store data into it. Just throw the data in an array when you queue it up. $extra = array( 'ListID' => '...', 'EditSequence' => '...' ); $Queue->enqueue(..., $extra, ...); There's no JSON involved anywhere, at all. – Keith Palmer Jr. Jun 08 '15 at 18:28
  • Example: https://github.com/consolibyte/quickbooks-php/blob/master/docs/web_connector/example_web_connector_import.php#L373 – Keith Palmer Jr. Jun 08 '15 at 18:30

0 Answers0