├── LICENSE ├── README.md ├── composer.json ├── composer.lock ├── example ├── hubshake.qwc └── sample.qwc ├── notes.txt └── src ├── Config ├── maps.php └── quickbooks.php ├── LaravelQbd.php ├── LaravelQbdController.php ├── LaravelQbdServiceProvider.php ├── Services ├── Customer │ └── Customer.php └── ErrorHandler.php ├── Views └── example.blade.php └── routes.php /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Ire Satamh 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel QBD 2 | I've been searching how to integrate QB Web connector with Laravel 5.x but coudn't find any. So I made this example package for you if ever you are in the same situation as I was. Feel free to clone/copy and modify it however you like. 3 | 4 | ## Getting Started 5 | These instructions will get you a copy of the package up and running on your local machine for development and testing purposes. 6 | 7 | If you are not yet familiar with QB Web Connector, visit [this](https://github.com/consolibyte/quickbooks-php) for quick start guides 8 | 9 | ### Installation 10 | Require the QuickBooks PHP DevKit (QuickBooks integration support for PHP 5.x+) 11 | ``` 12 | composer require consolibyte/quickbooks 13 | ``` 14 | 15 | Then manually require this package: 16 | 1. Download/clone the files and save it under your app's `packages/iresci23/laravel-qbd/` folder. Just create this folder if it is not yet existing. 17 | 18 | 2. Add this to your `composer.json` psr-4 autoload. It would look like this: 19 | ``` 20 | "psr-4": { 21 | "App\\": "app/", 22 | "Iresci23\\LaravelQbd\\": "packages/iresci23/laravel-qbd/src" 23 | } 24 | ``` 25 | 26 | 3. Add this line to your config/app.php provider 27 | ``` 28 | Iresci23\LaravelQbd\LaravelQbdServiceProvider::class 29 | ``` 30 | 31 | 4. On the command line publish the config file for the package 32 | ``` 33 | php artisan vendor:publish --tag=config 34 | ``` 35 | 36 | 5. These are the variables you need to set in your `.env` file 37 | ``` 38 | QB_DSN= #if this is empty, it will auto use your app db config 39 | # web connector username & password has nothing to do with the real QB user login 40 | QB_USERNAME=quickbooks 41 | QB_PASSWORD=password 42 | QB_TIMEZONE=America/New_York 43 | QB_LOGLEVEL=QUICKBOOKS_LOG_DEVELOP 44 | QB_MEMLIMIT=512M 45 | QB_SOAPSERVER=QUICKBOOKS_SOAPSERVER_BUILTIN 46 | ``` 47 | 48 | 6. Visit `http://yourappurl/qbd-connector/qbwc` to see if [it works](http://prntscr.com/i1jrsu) 49 | 50 | 7. Generate your `.qwc` file by visiting `http://yourappurl/qbd-connector/generate-qwc` 51 | Upload this qwc file into the QB Web Connector application. 52 | 53 | That's it. 54 | 55 | You can check the code, there is a sample for syncing Customer info. 56 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "iresci23/laravel-qbd", 3 | "description": "Integrate your laravel app to Quickbooks Desktop", 4 | "type": "library", 5 | "authors": [ 6 | { 7 | "name": "Ire Satamh", 8 | "email": "irelenecosicol@gmail.com" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "hash": "012bef2c467ce480cdececacb47aed51", 8 | "content-hash": "6fb59c095354ac302ad31f801ce05eb2", 9 | "packages": [ 10 | { 11 | "name": "consolibyte/quickbooks", 12 | "version": "v3.3", 13 | "source": { 14 | "type": "git", 15 | "url": "https://github.com/consolibyte/quickbooks-php.git", 16 | "reference": "36a3f8e8deb248840fd824b1bf4f615be7598239" 17 | }, 18 | "dist": { 19 | "type": "zip", 20 | "url": "https://api.github.com/repos/consolibyte/quickbooks-php/zipball/36a3f8e8deb248840fd824b1bf4f615be7598239", 21 | "reference": "36a3f8e8deb248840fd824b1bf4f615be7598239", 22 | "shasum": "" 23 | }, 24 | "require": { 25 | "php": ">=5.0.0" 26 | }, 27 | "type": "library", 28 | "autoload": { 29 | "files": [ 30 | "QuickBooks.php" 31 | ] 32 | }, 33 | "notification-url": "https://packagist.org/downloads/", 34 | "license": [ 35 | "EPL-1.0" 36 | ], 37 | "authors": [ 38 | { 39 | "name": "Keith Palmer", 40 | "email": "support@consolibyte.com", 41 | "homepage": "http://www.consolibyte.com/", 42 | "role": "Developer" 43 | } 44 | ], 45 | "description": "QuickBooks DevKit with support for Intuit Anywhere, Intuit Partner Platform, Web Connector, QuickBooks Merchant Services, and more.", 46 | "homepage": "http://www.consolibyte.com/", 47 | "keywords": [ 48 | "intuit", 49 | "intuit anywhere", 50 | "intuit data services", 51 | "intuit merchant services", 52 | "intuit partner platform", 53 | "qbxml", 54 | "quickbooks", 55 | "quickbooks merchant services", 56 | "quickbooks web connector", 57 | "web connector" 58 | ], 59 | "time": "2017-03-23 11:32:58" 60 | } 61 | ], 62 | "packages-dev": [], 63 | "aliases": [], 64 | "minimum-stability": "stable", 65 | "stability-flags": [], 66 | "prefer-stable": false, 67 | "prefer-lowest": false, 68 | "platform": [], 69 | "platform-dev": [] 70 | } 71 | -------------------------------------------------------------------------------- /example/hubshake.qwc: -------------------------------------------------------------------------------- 1 | 2 | 3 | Lara QDB 4 | 5 | http://localhost/erp-v3/public/qbd-connector/qbwc 6 | Laravel QuickBooks Demo 7 | http://localhost/erp-v3/public/qbd-connector/qbwc 8 | quickbooks 9 | {3679a403-4ccf-24f4-5527-f7c0bfaa80eb} 10 | {50693eb9-6a28-e6c4-add2-591b671fc440} 11 | QBFS 12 | false 13 | 14 | 10 15 | 16 | false 17 | -------------------------------------------------------------------------------- /example/sample.qwc: -------------------------------------------------------------------------------- 1 | 2 | 3 | Lara QBD 4 | 0097 5 | http://localhost/laravel-vue-kanban/public/qbd/qbwc 6 | Lara QBD Desc 7 | http://localhost/laravel-vue-kanban/public/qbd/qbwc 8 | quickbooks 9 | {90A44FB7-33D9-4815-AC85-AC86A7E7D1EF} 10 | {57F3B9B6-86F1-4FCC-B1FF-967DE1813D29} 11 | QBFS 12 | 13 | 5 14 | 15 | false 16 | -------------------------------------------------------------------------------- /notes.txt: -------------------------------------------------------------------------------- 1 | http://www.consolibyte.com/docs/index.php/QuickBooks_Web_Connector_Overview#Do_You_Really_Need_an_SSL_Certificate.3F 2 | 3 | 4 | === installation of the package === 5 | 1. composer require consolibyte/quickbooks 6 | 2. add in autoload psr4 7 | 8 | "psr-4": { 9 | "App\\": "app/", 10 | "Iresci23\\LaravelQbd\\": "packages/iresci23/laravel-qbd/src" 11 | } 12 | 3. Add in config/app.php service provider 13 | 14 | Iresci23\LaravelQbd\LaravelQbdServiceProvider::class, 15 | 16 | 4. add .env info 17 | QB_DSN= 18 | QB_USERNAME=quickbooks 19 | QB_PASSWORD=password 20 | QB_TIMEZONE=America/New_York 21 | QB_LOGLEVEL=QUICKBOOKS_LOG_DEVELOP 22 | QB_MEMLIMIT=512M 23 | QB_SOAPSERVER=QUICKBOOKS_SOAPSERVER_BUILTIN 24 | 25 | 5. Access 26 | http://{your domain}/qbd/qbwc -------------------------------------------------------------------------------- /src/Config/maps.php: -------------------------------------------------------------------------------- 1 | [ 6 | QUICKBOOKS_ADD_CUSTOMER => [ 7 | [ Iresci23\LaravelQbd\Services\Customer\Customer::class, 'xmlRequest' ], 8 | [ Iresci23\LaravelQbd\Services\Customer\Customer::class, 'xmlResponse' ] 9 | ] 10 | ] 11 | 12 | ]; -------------------------------------------------------------------------------- /src/Config/quickbooks.php: -------------------------------------------------------------------------------- 1 | env('QB_DSN'), 4 | 'qb_username' => env('QB_USERNAME'), 5 | 'qb_password' => env('QB_PASSWORD'), 6 | 7 | 'qb_timezone' => env('QB_TIMEZONE'), 8 | 'qb_log_level' => constant(env('QB_LOGLEVEL')), 9 | 'qb_mem_limit' => env('QB_MEMLIMIT'), 10 | 11 | 'error_map' => array( 12 | '*' => array(Iresci23\LaravelQbd\Services\ErrorHandler::class,'catchallErrors') 13 | ), 14 | 15 | 'hooks' => array(), // An array of callback hooks 16 | 17 | 'soap' => array( 18 | 'server' => constant(env('QB_SOAPSERVER')), // A pure-PHP SOAP server (no PHP ext/soap extension required, also makes debugging easier) 19 | 'options' => [] // See http://www.php.net/soap 20 | ), 21 | 22 | 'handler_options'=> array( 23 | 'deny_concurrent_logins' => false, 24 | 'deny_reallyfast_logins' => false 25 | ), // // See the comments in the QuickBooks/Server/Handlers.php file 26 | 27 | 'driver_options' => array(), //// See the comments in the QuickBooks/Driver/.php file ( i.e. 'Mysql.php', etc. ) 28 | 29 | 'callback_options'=> array() 30 | ]; -------------------------------------------------------------------------------- /src/LaravelQbd.php: -------------------------------------------------------------------------------- 1 | config = config('quickbooks'); 22 | 23 | $this->dsn = $this->config['qb_dsn']; 24 | } 25 | 26 | public function connect(){ 27 | 28 | date_default_timezone_set($this->config['qb_timezone']); 29 | // error_reporting(E_ALL | E_STRICT); 30 | 31 | if(!$this->config['qb_dsn']){ 32 | $dbconf = config('database'); 33 | $db = $dbconf['connections'][$dbconf['default']]; 34 | if($db['driver'] == 'mysql'){ 35 | $db['driver'] = 'mysqli'; 36 | } 37 | $this->dsn = $db['driver'] . '://' . $db['username'] . ':' .$db['password'] . '@' . $db['host'] . ':' . $db['port'] .'/'. $db['database']; 38 | } 39 | 40 | // Check to make sure our database is set up 41 | if (!\QuickBooks_Utilities::initialized($this->dsn)) 42 | { 43 | // Initialize creates the neccessary database schema for queueing up requests and logging 44 | \QuickBooks_Utilities::initialize($this->dsn); 45 | 46 | // This creates a username and password which is used by the Web Connector to authenticate 47 | \QuickBooks_Utilities::createUser($this->dsn, $this->config['qb_username'], $this->config['qb_password']); 48 | } 49 | 50 | // Set up our queue singleton 51 | \QuickBooks_WebConnector_Queue_Singleton::initialize($this->dsn); 52 | // 53 | return \QuickBooks_Utilities::initialized($this->dsn); 54 | } 55 | 56 | public function initServer($return = true, $debug = false) 57 | { 58 | 59 | // Create a new server and tell it to handle the requests 60 | $Server = new \QuickBooks_WebConnector_Server( 61 | $this->dsn, 62 | $this->config['actions'], 63 | $this->config['error_map'], 64 | $this->config['hooks'], 65 | $this->config['qb_log_level'], 66 | $this->config['soap']['server'], 67 | QUICKBOOKS_WSDL, 68 | $this->config['soap']['options'], 69 | $this->config['handler_options'], 70 | $this->config['driver_options'], 71 | $this->config['callback_options'] 72 | ); 73 | 74 | return $Server->handle($return, $debug); 75 | // if $return is turned-on, there is an error "Response is not well-formed XML". Probably because of whitespaces somewhere. I haven't figured out this yet 76 | } 77 | 78 | // Generate and return a .QWC Web Connector configuration file 79 | public function generateQWC() 80 | { 81 | $name = 'Lara QDB'; // A name for your server (make it whatever you want) 82 | $descrip = 'Laravel QuickBooks Demo'; // A description of your server 83 | 84 | $appurl = 'https://' . $_SERVER['HTTP_HOST'] . dirname($_SERVER['REQUEST_URI']) . '/qbwc'; // This *must* be httpS:// (path to your QuickBooks SOAP server) 85 | $appsupport = $appurl; // This *must* be httpS:// and the domain name must match the domain name above 86 | 87 | $username = $this->config['qb_username']; // This is the username you stored in the 'quickbooks_user' table by using QuickBooks_Utilities::createUser() 88 | 89 | $fileid = \QuickBooks_WebConnector_QWC::fileID(); // Just make this up, but make sure it keeps that format 90 | $ownerid = \QuickBooks_WebConnector_QWC::ownerID(); // Just make this up, but make sure it keeps that format 91 | 92 | $qbtype = QUICKBOOKS_TYPE_QBFS; // You can leave this as-is unless you're using QuickBooks POS 93 | 94 | $readonly = false; // No, we want to write data to QuickBooks 95 | 96 | $run_every_n_seconds = 600; // Run every 600 seconds (10 minutes) 97 | 98 | // Generate the XML file 99 | $QWC = new \QuickBooks_WebConnector_QWC($name, $descrip, $appurl, $appsupport, $username, $fileid, $ownerid, $qbtype, $readonly, $run_every_n_seconds); 100 | $xml = $QWC->generate(); 101 | 102 | return $xml; 103 | 104 | } 105 | 106 | // Queue up a request for the Web Connector to process 107 | public function enqueue($action, $ident, $priority = 0, $extra = null, $user = null) 108 | { 109 | $Queue = new \QuickBooks_WebConnector_Queue($this->dsn); 110 | Log::alert(print_r(array($action, $ident, $priority, $extra, $user), true)); 111 | return $Queue->enqueue($action, $ident, $priority, $extra, $user); 112 | } 113 | } -------------------------------------------------------------------------------- /src/LaravelQbdController.php: -------------------------------------------------------------------------------- 1 | QBD = new LaravelQbd; 17 | 18 | $this->QBD->connect(); 19 | 20 | } 21 | 22 | public function initQBWC(Request $request){ 23 | 24 | $response = $this->QBD->initServer(false, false); //$return,$debug 25 | 26 | $contentType = 'text/plain'; 27 | 28 | if($request->isMethod('post')) 29 | { 30 | $contentType = 'text/xml'; 31 | } 32 | elseif($request->input('wsdl') !== null or $request->input('WSDL') !== null) 33 | { 34 | $contentType = 'text/xml'; 35 | } 36 | 37 | if($contentType == 'text/xml'){ 38 | $tidy = new \tidy(); 39 | $response = $tidy->repairString($response, ['input-xml'=> 1, 'indent' => 0, 'wrap' => 0]); 40 | } 41 | 42 | // Uncomment log if you want to see the request headers submitted from WebConnector 43 | // Log::info(print_r(getallheaders(), true)); 44 | 45 | return response($response,200)->header('Content-Type', $contentType); 46 | 47 | } 48 | 49 | public function generateQWC(){ 50 | 51 | $xml = $this->QBD->generateQWC(); 52 | 53 | // header('Content-type: text/xml'); 54 | // print($xml); 55 | // exit; 56 | 57 | return response($xml,200) 58 | ->header('Content-Type', 'text/xml') 59 | ->header('Content-Disposition', 'attachment; filename="my-quickbooks-wc-file.qwc"'); // Send as a file download 60 | 61 | } 62 | 63 | public function testForm(){ 64 | 65 | return view('qbd::example'); 66 | } 67 | 68 | public function addCustomer(Request $request){ 69 | 70 | $this->QBD->enqueue(QUICKBOOKS_ADD_CUSTOMER, $request->input('id')); 71 | 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/LaravelQbdServiceProvider.php: -------------------------------------------------------------------------------- 1 | publishes([ 18 | __DIR__.'/Config/quickbooks.php' => config_path('quickbooks.php'), 19 | ], 'config'); 20 | 21 | $this->loadRoutesFrom(__DIR__.'/routes.php'); 22 | } 23 | 24 | /** 25 | * Register the application services. 26 | * 27 | * @return void 28 | */ 29 | public function register() 30 | { 31 | 32 | $this->mergeConfigFrom( 33 | __DIR__.'/Config/quickbooks.php', 'quickbooks' 34 | ); 35 | 36 | $this->mergeConfigFrom( 37 | __DIR__.'/Config/maps.php', 'quickbooks' 38 | ); 39 | 40 | $this->app->make('Iresci23\LaravelQbd\LaravelQbdController'); 41 | 42 | $this->loadViewsFrom(__DIR__.'/Views', 'qbd'); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Services/Customer/Customer.php: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 21 | 22 | Irelene C (' . mt_rand() . ') 23 | Irelene C 24 | Keith 25 | Palmer 26 | 27 | ConsoliBYTE, LLC 28 | 134 Stonemill Road 29 | Mansfield 30 | CT 31 | 06268 32 | United States 33 | 34 | 860-634-1602 35 | 860-429-0021 36 | 860-429-5183 37 | Keith@ConsoliBYTE.com 38 | Keith Palmer 39 | 40 | 41 | 42 | '; 43 | 44 | return $xml; 45 | } 46 | 47 | /** 48 | * Handle a response from QuickBooks indicating a new customer has been added 49 | */ 50 | public static function xmlResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents) 51 | { 52 | // Do something here to record that the data was added to QuickBooks successfully 53 | Log::info(print_r(array($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents), true)); 54 | return true; 55 | } 56 | } -------------------------------------------------------------------------------- /src/Services/ErrorHandler.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Calculator 5 | 6 | 7 |
8 | {{ csrf_field() }} 9 | 10 | 11 |
12 | 13 | -------------------------------------------------------------------------------- /src/routes.php: -------------------------------------------------------------------------------- 1 | 'qbd-connector', 'namespace' => 'Iresci23\LaravelQbd'], function(){ 3 | 4 | Route::any('/qbwc', 'LaravelQbdController@initQBWC'); 5 | Route::get('/generate-qwc', 'LaravelQbdController@generateQWC'); 6 | Route::get('/test', 'LaravelQbdController@testForm'); 7 | Route::post('/test', 'LaravelQbdController@addCustomer')->name('Customer.add'); 8 | 9 | }); --------------------------------------------------------------------------------