Quickbooks 错误 "Response is not well-formed XML"

Quickbooks Error "Response is not well-formed XML"

我正在尝试使用 Consolibyte 的 php 库在 Quickbooks 中为 Windows 创建销售订单。但是,每次我这样做时,Quickbooks Web 连接器都会失败并显示错误消息 "Response is not well-formed XML"

这是我要传递的 XML 请求:

 <?xml version="1.0" encoding="utf-8"?><?qbxml version="13.0"?>
    <QBXML><QBXMLMsgsRq onError="stopOnError">
    <SalesOrderAddRq requestID="">
    <SalesOrderAdd>
                <CustomerRef>
                    <FullName>Matthew Ong</FullName>
                </CustomerRef>
                <TxnDate>08/07/2015</TxnDate>

                <BillAddress>
                    <Addr1>Matthew Ong</Addr1>
                    <Addr2>146 Woodland Ave</Addr2>
                    <City>Winnetka</City>
                    <State>IL</State>
                    <PostalCode>60093</PostalCode>
                    <Country>US</Country>
                </BillAddress>
                <ShipAddress>
                    <Addr1>Matthew Ong</Addr1>
                    <Addr2>146 Woodland Ave</Addr2>
                    <City>Winnetka</City>
                    <State>IL</State>
                    <PostalCode>60093</PostalCode>
                    <Country>US</Country>
                </ShipAddress>
                <ItemSalesTaxRef>
                    <FullName>Out of State</FullName>
                </ItemSalesTaxRef>

                             <SalesOrderLineAdd>
                    <ItemRef>
                        <FullName>FG.EP12SALOEP</FullName>
                    </ItemRef>
                    <Desc>12 oz - Aloe Vera &amp; Eucalyptus Shampoo</Desc>
                    <Quantity>5</Quantity>
                    <Amount>32.5</Amount>
                </SalesOrderLineAdd>

                             <SalesOrderLineAdd>
                    <ItemRef>
                        <FullName>FG.EP1OZ12PKBEARDOIL</FullName>
                    </ItemRef>
                    <Desc>1 oz - Beard Oil - Black Seed</Desc>
                    <Quantity>3</Quantity>
                    <Amount>27</Amount>
                </SalesOrderLineAdd>

                <SalesOrderLineAdd>
                    <ItemRef>
                        <FullName>Shipping</FullName>
                    </ItemRef>
                    <Quantity>1</Quantity>
                    <Amount>15.31</Amount>
                </SalesOrderLineAdd>
            </SalesOrderAdd>
</SalesOrderAddRq>
</QBXMLMsgsRq>
</QBXML>

有谁知道出了什么问题吗?

编辑:这是我的完整网络连接器 php 文件

    <?php
require_once("../../init.php");

error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 1);

if (function_exists('date_default_timezone_set'))
{
    date_default_timezone_set('America/Chicago');
}

require_once '../../QuickBooks.php';

$user = '(blurred out)';
$pass = '(blurred out)';


// Map QuickBooks actions to handler functions
$map = array(
    QUICKBOOKS_ADD_CUSTOMER => array( '_quickbooks_customer_add_request', '_quickbooks_customer_add_response' ),
    QUICKBOOKS_ADD_SALESORDER => array( '_quickbooks_add_sales_order_request', '_quickbooks_add_sales_order_response' ),

    );


$errmap = array(
    3070 => '_quickbooks_error_stringtoolong',
    );

$hooks = array(

    );

$log_level = QUICKBOOKS_LOG_DEVELOP;    

$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 = '(blurred out)';


if (!QuickBooks_Utilities::initialized($dsn))
{

    QuickBooks_Utilities::initialize($dsn);

    QuickBooks_Utilities::createUser($dsn, $user, $pass);


}

$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);

function _quickbooks_customer_add_request($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale)
{

     $order = "SELECT * FROM patron_orders WHERE order_id = $ID";
    $result = mysql_query($order);
    $data = mysql_fetch_row($result);


    $type = $data[23];
    $database_company = $data[22];
    $database_billing_name = $data[10];
    $database_billing_address = $data[11];
    $database_billing_zipcode = $data[12];
    $database_billing_state = $data[13];
    $database_billing_city = $data[14];
    $database_phone = $data[9];
    $database_email = $data[8];


    $contactname = $data[10];


    if($type == "salon") {
        $listingname = $database_company;
        $companyname = "<CompanyName>" . $database_company . "</CompanyName>";  
    } else {
        $listingname = strtoupper($database_billing_name);
    }


    $xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>
        <?qbxml version=\"2.0\"?>
        <QBXML>
            <QBXMLMsgsRq onError=\"stopOnError\">
                <CustomerAddRq requestID=\"$requestID\">
                    <CustomerAdd>
                        <Name>$listingname</Name>
                        $companyname
                        <FirstName>$contactname</FirstName>
                        <BillAddress>
                            <Addr1>$contactname</Addr1>
                            <Addr2>$database_billing_address</Addr2>
                            <City>$database_billing_city</City>
                            <State>$database_billing_state</State>
                            <PostalCode>$database_billing_zipcode</PostalCode>
                            <Country>United States</Country>
                        </BillAddress>
                        <Phone>$database_phone</Phone>
                        <Email>$database_email</Email>
                        <Contact>$contactname</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)
{   

}


function _quickbooks_add_sales_order_request($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale)
{



     $order = "SELECT * FROM patron_orders WHERE order_id = $ID";
    $result = mysql_query($order);
    $data = mysql_fetch_row($result);


    $type = $data[23];
    $database_company = $data[22];
    $database_billing_name = $data[10];
    $database_billing_address = $data[11];
    $database_billing_zipcode = $data[12];
    $database_billing_state = $data[13];
    $database_billing_city = $data[14];
    $database_phone = $data[9];
    $database_email = $data[8];
    $database_date = $data[3];
    $fullname = $database_billing_name;
    $dateformat = date("Y-m-d", $database_date);  
    $contactname = $data[10];

    $database_shipping_name = $data[1];
    $database_shipping_address = $data[4];
    $database_shipping_zipcode = $data[5];
    $database_shipping_state = $data[6];
    $database_shipping_city = $data[7];

    $database_shipping_cost = $data[19];
    $database_shipping_cost = number_format((float)($database_shipping_cost), 2, '.', '');



    if($type == "salon") {
        $listingname = $database_company;
        $companyname = "<CompanyName>" . $database_company . "</CompanyName>";  
    } else {
        $listingname = strtoupper($database_billing_name);
    }

    $orderlinesstr = "";



    $database_products = $data[2];

                        $cost = 0;
                        $database_products = rtrim($database_products, ',');
                        $database_products = trim($database_products, ',');
                    //echo($items);


                    $array = explode(',', $database_products);
                    foreach($array as $value) {
                        //echo $value . "<br>";
                            $numberarr = explode(":", $value);
                            $productnumber = $numberarr[0];
                    //  echo $productnumber . "<br>";
                            $quantity = substr($value, strpos($value, ":") + 1);
                        //echo $quantity . "<br>";
                            $itemcount += $quantity;

                            if($type == "salon") {
                            $price = mysql_result(mysql_query("SELECT `salon_price` FROM `patron_products` WHERE `product_id` = $productnumber"),0);
                            } else {
                                $price = mysql_result(mysql_query("SELECT `price` FROM `patron_products` WHERE `product_id` = $productnumber"),0);
                            }

                            $cost += $price * $quantity;
                            $totalitemprice = $price * $quantity;
                            $totalitemprice = number_format((float)($totalitemprice), 2, '.', '');
                            $name = mysql_result(mysql_query("SELECT `name` FROM `patron_products` WHERE `product_id` = $productnumber"),0);
                            $size = mysql_result(mysql_query("SELECT `size` FROM `patron_products` WHERE `product_id` = $productnumber"),0);
                            $itemreference = mysql_result(mysql_query("SELECT `item_reference` FROM `patron_products` WHERE `product_id` = $productnumber"),0);
                            $itemreference = htmlspecialchars($itemreference);



                            $qb_desc = mysql_result(mysql_query("SELECT `qb_desc` FROM `patron_products` WHERE `product_id` = $productnumber"),0);
                        $qb_desc = htmlspecialchars($qb_desc);

                            $orderlinesstr = $orderlinesstr . "
                <SalesOrderLineAdd>
                    <ItemRef>
                        <FullName>$itemreference</FullName>
                    </ItemRef>
                    <Desc>$qb_desc</Desc>
                    <Quantity>$quantity</Quantity>
                    <Amount>$totalitemprice</Amount>
                </SalesOrderLineAdd>
                            ";
                    }


    $xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>
    <?qbxml version=\"13.0\"?>
    <QBXML>
    <QBXMLMsgsRq onError=\"stopOnError\">
    <SalesOrderAddRq requestID=\"\">
    <SalesOrderAdd>
                <CustomerRef>
                    <FullName>$fullname</FullName>
                </CustomerRef>
                <TxnDate>$dateformat</TxnDate>
                <BillAddress>
                    <Addr1>$contactname</Addr1>
                    <Addr2>$database_billing_address</Addr2>
                    <City>$database_billing_city</City>
                    <State>$database_billing_state</State>
                    <PostalCode>$database_billing_zipcode</PostalCode>
                    <Country>US</Country>
                </BillAddress>
                <ShipAddress>
                    <Addr1>$database_shipping_name</Addr1>
                    <Addr2>$database_shipping_address</Addr2>
                    <City>$database_shipping_city</City>
                    <State>$database_shipping_state</State>
                    <PostalCode>$database_shipping_zipcode</PostalCode>
                    <Country>US</Country>
                </ShipAddress>
                <ItemSalesTaxRef>
                    <FullName>Out of State</FullName>
                </ItemSalesTaxRef>
                $orderlinesstr
                <SalesOrderLineAdd>
                    <ItemRef>
                        <FullName>Shipping</FullName>
                    </ItemRef>
                    <Desc>Shipping</Desc>
                    <Quantity>1</Quantity>
                    <Amount>$database_shipping_cost</Amount>
                </SalesOrderLineAdd>
            </SalesOrderAdd>
</SalesOrderAddRq>
</QBXMLMsgsRq>
</QBXML>";


    return $xml;
}



function _quickbooks_add_sales_order_response($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
{   

}


function _quickbooks_error_stringtoolong($requestID, $user, $action, $ID, $extra, &$err, $xml, $errnum, $errmsg)
{
    mail('matthew910@gmail.com', 
        'QuickBooks error occured!', 
        'QuickBooks thinks that ' . $action . ': ' . $ID . ' has a value which will not fit in a QuickBooks field...');
}

这个错误:

Response is not well-formed XML

与您发布的 XML 没有任何关系。您发布的代码无关紧要。

如果您查看日志,格式不正确的 XML 是 Web Connector/your SOAP 服务包装 qbXML 请求的实际 SOAP 响应。您的实际 SOAP 响应格式不正确。

检查您的 PHP 错误日志。检查您的 Apache 错误日志。 99.999% 的情况是因为您在编码时犯了 PHP 或 SQL 错误。修复错误。