我正在關注step 6 of this guide以使用php sdk更新客戶的信息。這個想法是通過它的id檢索客戶,併爲該客戶發出更新請求。我的代碼:QBO IPP PHP SDK QuickBooks V3 API - 無法更新客戶
$ipp_customer = $data_service->FindById(
new IPPCustomer(array('Id' => '120'), true)
);
$ipp_customer->sparse = 'true';
$ipp_customer->DisplayName = 'Carrier Name';
$data_service->Update($ipp_customer);
我得到了有關更新響應的驗證錯誤(錯誤代碼2090)。看起來SDK在生成更新請求時沒有使用0填充SyncToken。這導致驗證錯誤。
然後我看了一下php SDK中提供的示例代碼(/v3-php-sdk-2.0.1/_Samples/CustomerUpdate.php)。示例代碼使用$dataService->Add
來執行更新。由此產生的請求Add
沒有SyncToken
,所以示例代碼似乎不適用。
如何正確使用SDK來更新客戶?
的請求/響應消息如下:
REQUEST BODY
=============
<?xml version="1.0" encoding="UTF-8"?>
<ns0:Customer xmlns:ns0="http://schema.intuit.com/finance/v3" sparse="true">
<ns0:Id>120</ns0:Id>
<ns0:SyncToken/>
<ns0:MetaData>
<ns0:CreateTime/>
<ns0:LastUpdatedTime/>
</ns0:MetaData>
<ns0:FullyQualifiedName/>
<ns0:DisplayName>Carrier Name</ns0:DisplayName>
<ns0:PrintOnCheckName/>
<ns0:Active>true</ns0:Active>
<ns0:PrimaryPhone>
<ns0:FreeFormNumber/>
</ns0:PrimaryPhone>
<ns0:Fax>
<ns0:FreeFormNumber/>
</ns0:Fax>
<ns0:Taxable>false</ns0:Taxable>
<ns0:BillAddr>
<ns0:Id>87</ns0:Id>
<ns0:Line1/>
<ns0:Line2/>
<ns0:City/>
<ns0:CountrySubDivisionCode/>
<ns0:PostalCode/>
<ns0:Lat/>
<ns0:Long/>
</ns0:BillAddr>
<ns0:Job>false</ns0:Job>
<ns0:BillWithParent>false</ns0:BillWithParent>
<ns0:Balance>0</ns0:Balance>
<ns0:BalanceWithJobs>0</ns0:BalanceWithJobs>
<ns0:PreferredDeliveryMethod/>
</ns0:Customer>
RESPONSE BODY
=============
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<IntuitResponse xmlns="http://schema.intuit.com/finance/v3" time="2014-01-21T12:53:53.838-08:00">
<Fault type="ValidationFault">
<Error code="2090" element="SyncToken">
<Message>Invalid Number</Message>
<Detail>Invalid Number : </Detail>
</Error>
</Fault>
</IntuitResponse>
感謝。
編輯1 這裏是響應身體FindById調用的結果:
RESPONSE BODY
=============
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<IntuitResponse xmlns="http://schema.intuit.com/finance/v3" time="2014-01-24T10:21:58.493-08:00">
<Customer domain="QBO" sparse="false">
<Id>120</Id>
<SyncToken>13</SyncToken>
<MetaData>
<CreateTime>2014-01-17T14:08:42-08:00</CreateTime>
<LastUpdatedTime>2014-01-24T09:27:00-08:00</LastUpdatedTime>
</MetaData>
<FullyQualifiedName>Carrier Name Modif</FullyQualifiedName>
<DisplayName>Carrier Name Modif</DisplayName>
<PrintOnCheckName>Carrier Name</PrintOnCheckName>
<Active>true</Active>
<Taxable>false</Taxable>
<BillAddr>
<Id>87</Id>
</BillAddr>
<Job>false</Job>
<BillWithParent>false</BillWithParent>
<Balance>0</Balance>
<BalanceWithJobs>0</BalanceWithJobs>
<PreferredDeliveryMethod>Print</PreferredDeliveryMethod>
</Customer>
</IntuitResponse>
編輯2我通過SDK使用樣品腳本(CustomerUpdate.php),並使用我的應用程序調試代碼(這是一個cakephp webapp)。使用的print_r,示例腳本對FindById通話產生的IPPCustomer與SyncToken輸出:
[SyncToken] => 46
我的應用程序代碼對FindById調用生成:
[SyncToken] => String Object
(
[value] => 46
)
這個結果讓我相信了XML到對象由於某些上下文的差異,解析處理有所不同。 cakephp有一個定義的String類,可供應用程序代碼使用。 在v3-php-sdk-2.0.1/Dependencies/XDS2PHP/src/com/mikebevz/xsd2php/Bind.php中,bindXml函數調用class_exists
(在第138行左右)。下面是摘錄:
if (!class_exists($class_name)) {
// assign $model->{$name} to child node's value
} else {
// assign $model->{$name) to newly created object $class_name, which wraps child nodes' value
}
的class_exists('string')
使用CakePHP(我的應用程序代碼)時,計算結果爲真。當不使用cakephp(示例腳本)時,class_exists('string')
的計算結果爲false。我相信這就是爲什麼xml-to-object分析在使用這個庫時的行爲不同。因此,我得到
<ns0:SyncToken/>
,而不是預期
<ns0:SyncToken>46</ns0:SyncToken>
似乎CakePHP的,其定義的String類,運行與IPP PHP SDK衝突局勢。
require_once('cake/libs/string.php'); // assuming cakephp 1.3's string class
我認爲這個問題是更清晰了,有什麼建議的解決方案:這種相互矛盾的情況下,可以通過添加以下行到樣品CustomerUpdate.php腳本重新創建?
您是否從FindByID調用獲取synctoken? –
是的,我從FindById調用獲取synctoken(請參閱編輯1) – EricC