# QuickBooks Desktop WSDL Starter

This proof of concept implements the SOAP contract expected by QuickBooks
Web Connector and sends one read-only `CompanyQueryRq`.

## 1. Server requirements

- PHP 8.x
- Apache
- Valid HTTPS certificate
- PHP SOAP extension
- Writable `storage` directory

Enable SOAP in `php.ini`:

```ini
extension=soap
```

Check it:

```bash
php -m
```

## 2. Configure the project

Edit:

```text
config/app.php
```

Change:

```php
'username' => 'qbwc_user',
'password' => 'CHANGE_THIS_PASSWORD',
```

Edit both:

```text
public/qbwebconnector.wsdl
public/quickbooks-test.qwc
```

Replace:

```text
https://YOUR-DOMAIN.example.com/qb/public/
```

with your real HTTPS URL.

The SOAP address in the WSDL and `AppURL` in the QWC must point to the same
`server.php` endpoint.

## 3. Upload to the VPS

Example public URLs:

```text
https://portal.example.com/qb/public/server.php
https://portal.example.com/qb/public/qbwebconnector.wsdl
https://portal.example.com/qb/public/support.html
```

Do not expose `config` or `storage` as public web folders. Ideally, set
`public` as the web root or block those directories in Apache.

## 4. Validate the WSDL

Open this in a browser:

```text
https://portal.example.com/qb/public/qbwebconnector.wsdl
```

It should display XML.

You can also run locally:

```bash
php -r "$c=new SoapClient('https://portal.example.com/qb/public/qbwebconnector.wsdl'); print_r($c->__getFunctions());"
```

You should see the eight Web Connector methods.

## 5. Connect QuickBooks

1. Use a test copy of the company file.
2. Open QuickBooks Desktop as Administrator.
3. Open the test company.
4. Open QuickBooks Web Connector.
5. Add `public/quickbooks-test.qwc`.
6. Authorize read-only access.
7. Enter the password from `config/app.php`.
8. Select the application and run `Update Selected`.

## 6. Expected output

The raw QuickBooks response is saved under:

```text
storage/logs/quickbooks-response-YYYYMMDD-HHMMSS.xml
```

The call sequence is recorded in:

```text
storage/logs/qbwc-YYYY-MM-DD.log
```

## 7. First qbXML request

```xml
<?xml version="1.0" encoding="utf-8"?>
<?qbxml version="13.0"?>
<QBXML>
  <QBXMLMsgsRq onError="stopOnError">
    <CompanyQueryRq requestID="1"/>
  </QBXMLMsgsRq>
</QBXML>
```

After this test succeeds, the next step is to replace this fixed request with
a queue stored in MySQL and add `CustomerQueryRq`, `ItemQueryRq`, and finally
`SalesOrderAddRq`.
