少しグーグルで、探していたものを見つけました。 Quickbooksは、小企業(米国で使用される主要市場)向けの会計プログラムです。 これは1Cのようなものですが、通常のGUIといくつかの便利な機能があります。 QBは、ユーザーが自分のコンピューター( Windowsのみ )にインストールし、数回クリックするだけで、会計を行う会社を展開するアプリケーションです。
さて、今、少なくとも、私は自分の敵を直接知っています。 統合に関しては、ここでのすべてはもう少し複雑です。 QBを統合できるものについては、 こちらをご覧ください 。 そこで何が見えますか:
- .NET SDK
- Java SDK
- PHP SDK(近日公開)
- Windows Azure SDK
- QuickBooks QBXML v12 SDK(ただし、デスクトップシナリオのみ )
うーん、PHP SDK(Coming Soon)が最後の希望です...私はほとんど絶望しましたが、 それは私を救いました。 このWebコネクタとはどのようなものですか? このオフサイトには、 QuickBooks Web Connectorプログラマーズガイドをダウンロードするための小さなページがあり、それだけです(少なくとも、オフサイトの情報を探すのにうんざりしています)。
Webコネクタとは何ですか?
Web Connectorは、QBとWebサーバーの間の一種の仲介者です(QBと共にインストールされます)。 タイムアウトまたはマウスクリックにより、彼はサイトの特定のURLにアクセスし、QBに問い合わせる必要があるサイトからリクエストを受け取り、それを渡します。 QBからの応答を待機し、彼が待機すると、サイトをノックしてQBから応答を送信します。
それでは始めましょう...
まず、Webコネクタにノッキングする場所を指示する必要があります。これは、 * .QWCファイルを使用して行われます。
clients.QWC
<?xml version="1.0"?> <QBWCXML> <AppName>QuickBooks Integrator (clients)</AppName> <AppID></AppID> <AppURL>http://localhost/quickbooks/clients.php</AppURL> <AppDescription>Export Customers from QB to csv file</AppDescription> <AppSupport>http://localhost/</AppSupport> <UserName>admin</UserName> <OwnerID>{90A44FB7-33D6-4815-AC85-AC86A7E7123B}</OwnerID> <FileID>{57F3B9B6-86F6-4FCC-B1FF-967DE1813123}</FileID> <QBType>QBFS</QBType> <IsReadOnly>false</IsReadOnly> </QBWCXML>
- AppName-Web Connectorのリストに表示されるサービスの名前
- AppID-これが必要な理由はわかりませんが、それがないと機能しません
- AppURL-ここでは、WebコネクタがノックされるURLを示します。 ここで注意が必要です。httpはデバッグ目的でのみ使用できます、それら。 ドメインにlocalhost (test-localhost-serv、localhost-admin ...)という単語が含まれている場合、httpを使用できます。 しかし、そうでない場合は、オプションなしでhttpsを使用する必要があります。
- AppDescription-サービスの説明
- AppSupport-ヘルプへのリンクとしてWebコネクタのリストに表示されるURL(ここでhttpを指定できます)
- UserName-QBデータベースと通信するためのユーザー名(このようなユーザーはQBで作成する必要があります)
- OwnerIDとFileIDは、16進文字で構成される一意のシーケンスです(各サービスについて、1つの値を変更しただけです)
- QBTypeは、Web ConnectorのQBへの接続のタイプです( QBFSまたはQBPOSの可能な値)
- IsReadOnly-サービスがデータを変更、削除、QBに追加する場合、 trueである必要があります
5分ごとにサービスを自動的に開始する必要がある場合は、次を追加する必要があります。
<Scheduler> <RunEveryNMinutes>5</RunEveryNMinutes> </Scheduler>
AppURLの短い補足:サーバーでhttpsを構成する機能がない場合(または実際の証明書にお金がない場合)、2つの抜け穴があります。
1) QBが存在するホストでは、サーバーのIPとドメイン名をlocalhostで指定します。サーバーのApache設定でこのドメインを読むことを忘れないでください
2) 自作の証明書を入れて、信頼できるサーバーのリストに追加します。そうしないと機能しません( 例 )
qwcを追加するには、次のものが必要です。
-QBを有効にして、アプリケーションが動作する会社を開きます
-オープンWebコネクタ
-Web Connector'eで[ アプリケーションの追加 ]ボタンをクリックし、qwcファイルを指定します。
-[OK]をクリックすると、QBはこのアプリケーションへのアクセスをQBデータベースに許可するかどうかを尋ねます(この場合はユーザー「admin」を選択する必要があります)
-最後のダイアログボックスで[完了]をクリックすると、Webコネクタに戻り、ユーザー「admin」のパスワードを入力します
-アプリケーションを起動するには、チェックボックスをオンにして、[ 選択を更新 ]ボタンをクリックする必要があります
それで、Webコネクタを受信するためにサイトを準備する番です。
覚えているように、
localhost/quickbooks/clients.php
localhost/quickbooks/clients.php
作成して
localhost/quickbooks/clients.php
。 WebコネクタはSOAPプロトコルを使用します。つまり、サイトはSOAPサーバーを上げる必要があります。
clients.php
<?php /** * File for integration QB * QB Webconnector send soap request to this file * * @package QB SOAP */ /** * Log function * * @param string $mess */ function _log($mess = '') { $file_name = './log/clients.log'; if(!file_exists(dirname($file_name))) mkdir(dirname($file_name), 0777); $f = fopen($file_name, "ab"); fwrite($f, "==============================================\n"); fwrite($f, "[" . date("m/d/YH:i:s") . "] ".$mess."\n"); fclose($f); } /** * Log function * * @param string $mess */ function requestId($id = '') { $file_name = './log/clients_id.log'; if(!file_exists(dirname($file_name))) mkdir(dirname($file_name), 0777); // save id into file if(trim($id) !== ''){ $f = fopen($file_name, "c+b"); fwrite($f, $id); fclose($f); } $id = trim(file_get_contents($file_name)); return $id; } /** * System variables */ define('QB_LOGIN', 'admin'); define('QB_PASSWORD', ''); define('QB_TICKET', '93f91a390fa604207f40e8a94d0d8fd11005de108ec1664234305e17e'); /** * Main class for SOAP SERVER */ require 'qb_clients.php'; /** * Create SOAP server */ $server = new SoapServer("qbwebconnectorsvc.wsdl", array('cache_wsdl' => WSDL_CACHE_NONE)); $server->setClass("Qb_Clients"); $server->handle();
requestId()関数は、トランザクションIDをファイルに保存するために必要です。 さらに検討される例では、すべての顧客のリストを取得したいと考えています。これは、1000社を超える企業である可能性があります。 したがって、500の部分を受け取るので、より信頼性が高く、サーバーの負荷が少なくなります。 なぜ'QB_LOGIN 、 QB_PASSWORDおよびQB_TICKETが必要なのですか? 最後の3行-これはSOAPサーバーの作成です。 qbwebconnectorsvc.wsdlこのファイルはサイトのオープンスペースで見つけましたが、どこにあったか覚えていません(しばらく前に再設計しました)。
Web Connectorが知っているのはclientVersion 、 serverVersion 、 authenticate 、 sendRequestXML 、 receiveResponseXML 、 connectionError 、 getLastError 、 closeConnectionの 8単語のみであることを忘れていました 。
qb.php
<?php /** * File contain base QB class and Result class (empty class for Qb reaponse) */ /** * Response class (empty class) * * @package QB SOAP * @version 2013-10-20 */ class Response{ } /** * Base class for QuickBooks integration * * @package QB SOAP * @version 2013-10-20 */ class Qb { /** * Response object * @var string */ var $response = ''; /** * Constructor * * @return void * @access public * @version 2013-10-20 */ public function __construct() { $this->response = new Response(); } /** * Function return client version * * @return string * @param object $param * @access public * @version 2013-10-20 */ public function clientVersion($param = '') { $response->clientVersionResult = ""; return $response; } /** * Function return server version * * @return string * @access public * @version 2013-10-20 */ public function serverVersion() { $this->response->serverVersionResult = ""; return $this->response; } /** * Function try authenticate user by username/password * * @return string * @param object $param * @access public * @version 2013-10-20 */ public function authenticate($param = '') { if(($param->strUserName == QB_LOGIN) && ($param->strPassword == QB_PASSWORD)) $this->response->authenticateResult = array(QB_TICKET, ""); else $this->response->authenticateResult = array("", "nvu"); return $this->response; } /** * Function return last error * * @return string * @param object $param * @access public * @version 2013-10-20 */ public function connectionError($param = '') { $this->response->connectionErrorResult = "connectionError"; return $this->response; } /** * Function return last error * * @return string * @param object $param * @access public * @version 2013-10-20 */ public function getLastError($param = '') { $this->response->getLastErrorResult = "getLastError"; return $this->response; } /** * Function close connection * * @return string * @param object $param * @access public * @version 2013-10-20 */ public function closeConnection($param = '') { $this->response->closeConnectionResult = "Complete"; return $this->response; } }
- clientVersion-ここで、Web Connectorは私たちをノックして言います。「聞いてください、バージョンxxxxxのWeb Connectorが来ます。 何が必要ですか?」 応答として、どのバージョンが欲しいかを言うことができます。または、黙っておくことができます。
- serverVersion-上記を参照してください。
- 認証 -ここで、Web Connectorは、そのようなログインを持つそのようなユーザー(qwcファイルでログインを指定し、Web Connectorのパスワードウィンドウでパスワードを指定した)を有効なパスワードと比較し、スキップまたはエラーを送信することを通知します。 成功した場合、現在のセッション中に使用されるWeb Connector'yチケットQB_TICKETを提供します
- sendRequestXML-ここで、WebコネクタがQBに渡すリクエストを作成します。
- receiveResponseXML-リクエストに応じてデータを受信します
- connectionError-データの送信中にエラーが発生した場合、このメソッドが呼び出されます
- getLastError-間違ったリクエストを書いた場合、このメソッドが呼び出されます
- closeConnection-すべてが計画どおりに進み、リクエストを正常に受け入れた場合
以下のファイルでは、リクエストの形成方法とデータ受信の処理方法を確認できます。
qb_clients.php
<?php /** * File contains class Qb_Clients() extends Qb() */ /** * Include base class for SOAP SERVER */ require 'qb.php'; /** * Class for import all clients from Qb * * @package QB SOAP * @version 2013-10-20 */ class Qb_Clients extends Qb { /** * Function send request for Quickbooks * * @return string * @param object $param * @access public * @version 2013-10-20 */ public function sendRequestXML($param = '') { $id = requestId(); // <!-- ActiveStatus may have one of the following values: ActiveOnly [DEFAULT], InactiveOnly, All --> if($param->ticket == QB_TICKET){ $request = '<?xml version="1.0" encoding="utf-8"?> <?qbxml version="12.0"?> <QBXML> <QBXMLMsgsRq onError="stopOnError"> <CustomerQueryRq requestID="'.time().'" metaData="NoMetaData" iterator="'.(($id != '')?'Continue':'Start').'" '.(($id != '')?'iteratorID="'.$id.'"':'').'> <MaxReturned>500</MaxReturned> <ActiveStatus>ActiveOnly</ActiveStatus> </CustomerQueryRq> </QBXMLMsgsRq> </QBXML>'; $this->response->sendRequestXMLResult = $request; } else $this->response->sendRequestXMLResult = "E: Invalid ticket."; return $this->response; } /** * Function get response from QB * * @return string * @param object $param * @access public * @version 2013-03-15 */ public function receiveResponseXML($param = '') { $response = simplexml_load_string($param->response); $iteratorID = trim($response->QBXMLMsgsRs->CustomerQueryRs->attributes()->iteratorID); // set new iteratorID requestId($iteratorID); if( ($param->ticket == QB_TICKET) && isset($response->QBXMLMsgsRs->CustomerQueryRs->CustomerRet) ){ $rows = $response->QBXMLMsgsRs->CustomerQueryRs; settype($rows, 'array'); // if list contain only one item row if(isset($rows['CustomerRet']->ListID)) $rows = array($rows['CustomerRet']); else $rows = $rows['CustomerRet']; $data = array(); foreach ($rows as $i=>$r) { settype($r, 'array'); $data[] = array( 'qb_id' => trim($r['ListID']), 'qb_es' => trim($r['EditSequence']), 'is_active' => trim($r['IsActive']), 'phone' => trim($r['Phone']), 'notes' => trim($r['Notes']), 'fax' => trim($r['Fax']), 'company_name' => trim($r['Name']), 'b_email' => trim($r['Email']), 'b_email_other' => trim($r['Cc']), 'b_phone' => trim($r['AltPhone']), 'b_salutation' => trim($r['Salutation']), 'b_fname' => trim($r['FirstName']), 'b_lname' => trim($r['LastName']), 'b_address' => trim($r['BillAddress']->Addr1), 'b_address2' => trim($r['BillAddress']->Addr2), 'b_address3' => trim($r['BillAddress']->Addr3), 'b_city' => trim($r['BillAddress']->City), 'b_state' => trim($r['BillAddress']->State), 'b_country' => trim($r['BillAddress']->Country), 'b_zip' => trim($r['BillAddress']->PostalCode), ); } // echo data into log file _log(print_r($data,1)); $this->response->receiveResponseXMLResult = '30'; } else $this->response->receiveResponseXMLResult = '100'; return $this->response; } }
<?qbxml version="12.0"?>
という行は、qbxmlの12番目のバージョンを使用していると言います。 現時点では、これは利用可能な最新バージョンです(13番目と14番目のQBでサポートされています)。 qbxmlのバージョンが高いほど、QBで作業する可能性が大きくなります。 利用可能なすべてのクエリのリストは、 ここにあります 。 リンクをたどると、QBに送信できるすべての可能なリクエストが表示されます(それらは[メッセージの選択]リストに表示されます)。 [リクエスト]タブと[ レスポンス]タブ-選択したリクエストに応じて生成されます。
PS。 1つだけですが、 たとえば、「 CustomerAdd 」というリクエストを選択すると、このリクエストが「Contacts」ブロックをサポートしていることがわかります。これは、qbxmlの12番目のバージョンから利用できます。 しかし、実際には実装されていませんが、実装プロセス中のみです(ドキュメントに含まれているのは謎であるため、この機能が説明されているフォーラムに誤ってアクセスするまで、1時間以上この問題に取り組みました)。 したがって、何かがqbxml v.12で機能しない場合、それが必要なのは事実ではありません:)
PSS ソースコードはこちらです。