Overview
This guide describes how QuickBooks Online (QBO) — Intuit's cloud accounting product — connects to TrustBill, a UAE FTA-accredited service provider (ASP), so QBO users in the UAE can issue PINT-AE compliant e-invoices without leaving QuickBooks.
QuickBooks Online is Intuit's SaaS product. UAE users almost always run the QuickBooks Online Global (International) edition, which supports VAT out of the box but does not ship with native Peppol / PINT-AE e-invoicing. TrustBill sits between QBO and the FTA: invoices are pulled from QBO via the Intuit App Store connector (or webhooks / SDK / Zapier), translated to PINT-AE XML, validated in real time, delivered over the Peppol network via a certified ASP (Tron-Stride or Storecove), and the FTA acknowledgement is written back into QBO custom fields.
What this integration delivers
- Certified Intuit App Store app — installed with two clicks, OAuth 2.0 handshake, no code
- Works across all QBO editions with a VAT-capable region (Global / UK / South Africa / Ireland)
- Sales invoices, credit memos, vendor credits and recurring invoices all mapped to PINT-AE document types
- UAE VAT tax codes (5% Standard, Zero-Rated, Exempt, RCM, Out of Scope) mapped to FTA tax categories automatically
- Live FTA status written back into QBO custom fields (Advanced) or the Memo field (Simple Start / Essentials / Plus)
- Bulk migration path for historical QBO invoices via CSV
- Multi-company support (one Intuit realm per TRN)
- Works with QBO Payments, QBO Time, QBO Commerce as upstream sources
Supported QuickBooks Products & Editions
QBO is the system of record for VAT and invoicing. The integration reads from QBO regardless of which upstream Intuit app originated the invoice.
| QuickBooks product / edition | Role in the flow | Support level |
|---|---|---|
| QuickBooks Online — Simple Start | Basic invoicing (no custom fields) | Full — write-back via Memo field |
| QuickBooks Online — Essentials | Invoicing + bills | Full — write-back via Memo field |
| QuickBooks Online — Plus | Inventory + classes + recurring | Full — up to 3 custom fields available |
| QuickBooks Online — Advanced | Custom fields (12), workflows, batch invoicing | Full — recommended edition (uses 3 dedicated TrustBill custom fields + workflow triggers) |
| QBO — Global (International) edition | Non-US regions — the UAE customer default | Full — primary edition for UAE VAT |
| QBO — UK / South Africa / Ireland | Also VAT-capable | Supported — override country in QBO to UAE for TRN-based invoicing |
| QBO — US / Canada / Australia / India | Country-specific tax models (sales tax / GST) | Not recommended — no built-in VAT; move UAE data to Global edition first |
| QuickBooks Payments | Card / bank payments recorded against QBO invoices | Full — payment status does not affect FTA submission |
| QuickBooks Time (formerly TSheets) | Time entries → QBO invoice lines | Full — TrustBill reads the resulting QBO invoice |
| QuickBooks Commerce | Multi-channel inventory → QBO invoices | Full — via QBO |
| QuickBooks Desktop | Not covered by this guide | See the dedicated QuickBooks Desktop integration |
Regional Edition Notes (Global vs US/UK)
QBO is sold in country-specific flavours. The tax engine changes per country. For UAE FTA e-invoicing, only the Global (International), UK, South Africa or Ireland flavours have a VAT engine that can carry TRN + VAT rates in a shape the connector can read.
| QBO region | Tax engine | API host | UAE recommendation |
|---|---|---|---|
| QBO Global (INT) | VAT (fully configurable) | quickbooks.api.intuit.com | Recommended |
| QBO UK | VAT + Making Tax Digital | quickbooks.api.intuit.com | Supported — override country to UAE |
| QBO Ireland / South Africa | VAT | quickbooks.api.intuit.com | Supported |
| QBO US | Sales Tax | quickbooks.api.intuit.com | Not compatible — no VAT model; migrate to Global first |
| QBO Canada | GST/HST/PST | quickbooks.api.intuit.com | Not compatible |
| QBO Australia | GST + STP | quickbooks.api.intuit.com | Not compatible |
| QBO India | GST | quickbooks.api.intuit.com | Not compatible |
All QBO regions share one API host (quickbooks.api.intuit.com). The tax engine is chosen at company creation and cannot be swapped later without a full data migration. If you are still on a US/CA/AU/IN edition, spin up a fresh QBO Global company, migrate customers/vendors/items, then install the TrustBill app.
Prerequisites
On the QuickBooks side
- An active QBO Global / UK / Ireland / South Africa company with VAT enabled under Taxes → Set up VAT
- Valid 15-digit UAE TRN saved under Settings → Account and Settings → Company → VAT / TRN
- Customers populated with a Tax Identifier (TRN for B2B), country and billing address
- UAE VAT tax rates configured: 5% Standard, Zero-Rated Sales, Exempt Sales, Out of Scope, Reverse Charge (RCM)
- QBO Admin or Company Admin role (only these roles can install App Store apps)
- Optional: QBO Advanced if you want dedicated custom fields (Simple Start / Essentials / Plus fall back to the Memo field)
On the TrustBill side
- A TrustBill SME account (one account = one TRN = one QBO realm)
- Completed KYB (business verification) — trade licence + TRN certificate uploaded
- Submission mode set to
testorsandboxduring onboarding,livefor production - OAuth is provisioned automatically when you install the App Store app; no manual client credentials needed
Integration Architecture
The QBO ↔ TrustBill integration is event-driven — Intuit's Webhook Service pushes on invoice change, TrustBill fetches the full record and drives the pipeline.
Outbound flow (QBO → TrustBill → FTA)
- An invoice is saved in QuickBooks Online.
- Intuit's Webhook Service fires
Invoice.Create(orInvoice.Update/Invoice.Emailed) to the URL registered by the TrustBill App Store app. - TrustBill's Intuit webhook receiver verifies the HMAC-SHA256 signature (using the App Store app secret), then fetches the full Invoice + line items + Customer + Company info via the QBO API.
- The payload is translated into TrustBill's
InvoiceCreateInputshape. - TrustBill calls its own
POST /v1/invoices— stored asdraft. - If auto-submit is enabled on the TrustBill tenant,
POST /v1/invoices/submitfires immediately; otherwise the invoice sits until Submit-to-FTA is clicked (from QBO or the TrustBill dashboard). - Pipeline runs:
queued → transformed → validated → delivered(PINT-AE XML built, Schematron-validated, handed to the ASP). - ASP forwards the XML to the FTA over Peppol.
Inbound flow (FTA → TrustBill → QBO)
- The ASP posts an inbound webhook to TrustBill when the FTA acknowledges or rejects the invoice.
- TrustBill verifies the ASP's HMAC signature and updates the status to
acknowledgedorrejected. - TrustBill's QBO worker calls
POST /invoice?operation=updateto update the three custom fields (Advanced) or the Memo (Simple Start / Essentials / Plus) on the QBO invoice. - QBO users see the status in the invoice list view (Advanced supports column-level filtering by custom fields).
Connection Methods
Six paths, ordered from easiest (no-code) to most custom:
1. Intuit App Store App (recommended)
Install TrustBill E-Invoicing for QuickBooks from appstore.intuit.com. Uses Intuit's OpenID Connect + OAuth 2.0 handshake. Custom fields auto-created (Advanced), webhooks auto-registered, custom action added to the invoice screen.
- No code, no server, no keys to manage
- Reviewed and certified by Intuit's Developer Platform (IPP)
- Adds a Send to FTA action on every invoice
- Adds a TrustBill panel on the invoice sidebar showing FTA status + timeline
- Handles token refresh automatically (Intuit access tokens live 60 min; refresh tokens live 100 days)
2. QBO Webhooks + your own middleware
Register your own Intuit Developer app and subscribe to Invoice.Create / Invoice.Update webhooks. Your middleware receives them, fetches the invoice from QBO, and calls the TrustBill REST API.
- Best when you need custom transformation logic or already run middleware
- You manage the Intuit OAuth tokens (refresh flow, retry, HMAC verification)
- Use the TrustBill REST endpoints documented in the ERP Partner API guide
3. Intuit SDK (server-side)
Use the official node-quickbooks, QuickBooks-V3-PHP-SDK or .NET SDK to poll for invoices on a schedule. Best when your firewall blocks inbound webhooks.
- Query with
SELECT * FROM Invoice WHERE MetaData.LastUpdatedTime > '{last_seen}' ORDER BY MetaData.LastUpdatedTime ASC - Handle Intuit's minor-version parameter (
?minorversion=75) to lock the response schema - Respect the 500-request-per-minute realm-wide rate limit
4. Zapier / Make (no-code)
TrustBill publishes a Zapier and a Make (formerly Integromat) connector — build a "New QuickBooks Online invoice → Create TrustBill invoice → Submit" zap in minutes.
- Best for small teams that already standardise on Zapier/Make
- Handles retry, error branching, and Slack / email notification on failure
- Adds latency (Zapier polls every 1–15 minutes on paid plans)
5. CSV Export
Export invoices from Sales → Invoices → Export to Excel and upload the file to TrustBill's bulk import endpoint. Best for one-off historical migrations.
- Zero technical setup
- Runs through TrustBill's
POST /v1/invoices/bulk— up to 1,000 rows / 5 MB per file - See Bulk Migration
6. Upstream: QBO Time / Commerce / Payments
Time entries (from QBO Time), commerce orders (from QBO Commerce), or payment reconciliations (from QBO Payments) that generate a QBO invoice flow through the same path — TrustBill reads the invoice created in QBO, no separate connector.
Which method should I use?
For 95% of QBO UAE customers, install the Intuit App Store app. Use Zapier/Make if you already standardise on it. Use the SDK / webhooks + middleware only when your firewall blocks inbound webhooks or you need custom transformation logic. Use the CSV path only for one-off historical migrations.
Authentication (Intuit OAuth 2.0)
QBO uses Intuit OAuth 2.0 authorization-code flow with OpenID Connect. The App Store app requests these scopes at install time:
com.intuit.quickbooks.accounting (read + write QBO entities)
openid (identity)
profile (user profile)
email (user email)
address (billing address)
phone (optional)TrustBill stores only the refresh_token (Intuit's refresh tokens are valid for 100 days and rotate on every access-token refresh — TrustBill handles rotation automatically).
Realm ID
Every QBO company has a numeric Realm ID — required on every API call. The App Store app receives it as part of the OAuth callback. TrustBill stores the mapping realm_id → trustbill_tenant_id so one Intuit login can serve multiple companies without confusion.
Idempotency-Key derivation for QBO
Every TrustBill write endpoint requires an Idempotency-Key. For QBO, derive it from the QBO invoice ID (numeric, stable across QBO renumbering):
Idempotency-Key: qbo::{realm_id}::{invoice_id}Intuit's webhook service retries up to 5 times on non-200 responses — TrustBill returns the cached response for repeats, so retries never create duplicate FTA submissions.
QBO → PINT-AE Field Mapping
The connector translates QBO's JSON invoice shape (v3 API, minorversion 75+) into TrustBill's InvoiceCreateInput, which TrustBill then renders into PINT-AE XML.
Header-level mapping
| QBO Invoice field | TrustBill field | Notes |
|---|---|---|
DocNumber | number | 1–64 chars, unique per tenant + mode |
TxnDate | issueDate | ISO YYYY-MM-DD (QBO's native format) |
DueDate | dueDate | Optional |
CurrencyRef.value | currency | Must be AED; multi-currency invoices converted at ExchangeRate |
ExchangeRate | used to convert non-AED lines | Applied to Line.SalesItemLineDetail.UnitPrice |
CompanyInfo.CompanyName | seller.name | Fetched from /companyinfo/{realmId} |
CompanyInfo.TaxIdentifiers / PrimaryTaxIdentifier | seller.trn | 15-digit UAE TRN |
CustomerRef.value → Customer | buyer | Fetched from /customer/{id} |
Customer.DisplayName | buyer.name | — |
Customer.PrimaryTaxIdentifier | buyer.trn | 15-digit TRN; leave empty for B2C customers |
Customer.BillAddr | buyer.address.{line1,line2,city,country} | Country normalised to ISO 3166-1 alpha-2 |
GlobalTaxCalculation | reads inclusive/exclusive flag | TaxExcluded / TaxInclusive / NotApplicable |
PrivateNote / CustomerMemo.value | notes | Concatenated; visible in FTA-facing XML |
Id | Idempotency key + sellerInvoiceReference | Numeric QBO invoice ID |
MetaData.LastUpdatedTime | used for delta polling | Cursor for SDK-based sync |
Line-level mapping (Line[] with DetailType = SalesItemLineDetail)
| QBO field | TrustBill field | Notes |
|---|---|---|
Description | lines[].description | Non-empty; supports Arabic |
SalesItemLineDetail.Qty | lines[].quantity | Must be > 0 |
SalesItemLineDetail.UnitPrice | lines[].unitPrice | VAT-exclusive; connector strips VAT if GlobalTaxCalculation = TaxInclusive |
SalesItemLineDetail.ItemRef.name | lines[].sellerItemId | Preserved for traceability |
SalesItemLineDetail.TaxCodeRef.value | lines[].vatRate + lines[].taxCategory | Mapped via the QBO Tax Code table below |
SalesItemLineDetail.UnitPrice + DiscountLineDetail | lines[].discountAmount | Line-level discount (QBO uses a separate line of DetailType DiscountLineDetail — connector rolls it into the previous item line) |
SalesItemLineDetail.ServiceDate | lines[].periodStart / periodEnd | If populated, added to the PINT-AE service-period fields |
Totals are computed server-side
Do not send subtotal / vat_amount / TotalAmt. TrustBill re-computes totals from lines[] and returns them so QBO can reconcile. If QBO's TotalAmt differs from TrustBill's by more than ±0.01 AED (usually a QBO inclusive-tax rounding issue), the connector logs a variance and blocks submission until the invoice is corrected.
Create Invoice (draft)
Endpoint: POST /v1/invoices
A real QBO invoice mapped to the TrustBill payload. QBO invoice: DocNumber INV-1042 — Sale of accounting services to a Dubai buyer at 5% VAT.
Request body
{
"number": "INV-1042",
"issueDate": "2026-09-08",
"dueDate": "2026-10-08",
"currency": "AED",
"invoiceType": "sale",
"buyer": {
"name": "Dubai Consulting Group LLC",
"trn": "100112233400005",
"country": "AE",
"email": "ap@dcg.example",
"address": {
"line1": "Emaar Square, Building 3, Level 15",
"city": "Dubai",
"country": "AE"
}
},
"seller": {
"name": "QBO Accountants LLC",
"trn": "100100100100011",
"country": "AE"
},
"lines": [
{
"description": "Monthly bookkeeping — August 2026",
"sellerItemId": "SVC-BK-MO",
"quantity": 1,
"unit": "MON",
"unitPrice": 2500.00,
"vatRate": 0.05,
"taxCategory": "standard_5"
}
],
"sellerInvoiceReference": "QBO realm 4620816365000000, invoice_id 189",
"notes": "Payment due 30 days"
}Response (201 Created) — abbreviated:
{
"id": "f9c8b7a6-....-uuid",
"number": "INV-1042",
"status": "draft",
"invoiceType": "sale",
"totals": { "subtotal": 2500, "tax": 125, "total": 2625, "currency": "AED" },
"pipeline": [],
"errors": [],
"submissionMode": "sandbox",
"source": "quickbooks-online-app"
}Credit Memos & Vendor Credits
QBO has first-class Credit Memo (CreditMemo endpoint) and Vendor Credit (VendorCredit endpoint) documents. The connector maps both:
| QBO object | invoiceType | Required extra fields |
|---|---|---|
Credit Memo applied to a specific invoice (via LinkedTxn) | credit_note | referencedInvoiceNumber = original invoice's DocNumber, reasonCode |
Standalone Credit Memo (no LinkedTxn) | credit_note | reasonCode = OtherAdjustment |
| Vendor Credit (purchase side) | debit_note | referencedInvoiceNumber = original Bill's DocNumber, reasonCode |
Sign convention: QBO Credit Memos carry positive quantities and positive rates. Send the same to TrustBill — do not negate. The invoiceType tells TrustBill and the FTA that the document reverses the reference invoice; PINT-AE handles the sign in the XML.
Recurring Invoices
QBO Plus and Advanced support Recurring Transactions (RecurringTransaction endpoint). QBO generates a child Invoice from a template on a schedule — the connector treats each generated child as a fresh event:
- QBO webhook fires
Invoice.Createfor every generated child - Each child gets its own
Id— so a fresh Idempotency-Key, a fresh TrustBill draft, a fresh FTA submission - The recurring template itself is not pushed to TrustBill — only the concrete invoices it produces
- Pro-rated changes: keep them in the QBO line description (QBO does this by default)
Auto-submit tip: for recurring invoices, enable TrustBill's auto-submit on ingest. Otherwise every child sits as a draft in TrustBill waiting for a human to click Submit — defeats the purpose of a recurring schedule.
Submit Invoice(s) for Delivery
Creating a draft in TrustBill does not deliver the invoice to the FTA. Submission is an explicit second call so an accountant can review before sending.
Endpoint: POST /v1/invoices/submit
{ "ids": ["f9c8b7a6-....-uuid"] }Accepts 1–200 UUIDs per call. Non-draft invoices are silently skipped, so retry is safe.
App Store UX: the app adds a Send to FTA button to every QBO invoice screen. On QBO Advanced, the app also registers a Workflow → When invoice is Approved → Send to FTA template so batch invoicing goes through automatically.
Status Tracking & Custom Field Write-back
On install, the App Store app configures three write-back destinations depending on your edition:
| QBO edition | Write-back target | Notes |
|---|---|---|
| Simple Start / Essentials | Invoice PrivateNote | Prefixed with [TrustBill] so it doesn't confuse other automations |
| Plus | 3 CustomField slots (1, 2, 3) on Invoice | Auto-created on install if free slots exist; else falls back to PrivateNote |
| Advanced | 3 dedicated CustomField (12 slots available; app uses 3) | Recommended — supports column-view filtering by TrustBill status |
| TrustBill status | QBO write-back |
|---|---|
| draft | CustomField[1] = Draft |
| queued | CustomField[1] = Queued |
| validated | CustomField[1] = Validated |
| delivered | CustomField[1] = Delivered |
| acknowledged | CustomField[1] = Acknowledged, CustomField[2] = <FTA ack ref> |
| rejected | CustomField[1] = Rejected, CustomField[3] = <reject code> |
Bulk Migration from QuickBooks Online
To migrate historical QBO invoices (up to 12 months back):
- In QBO: Sales → Invoices → filter by date range → Export to Excel
- Run the TrustBill qbo-csv-normaliser script to remap QBO's column headers to the TrustBill schema below
- Upload in
testmode viaPOST /v1/invoices/bulk - Review the summary; repeat in
sandboxandlive
TrustBill CSV column headers
number,issueDate,dueDate,invoiceType,currency,sellerTrn,sellerName,buyerTrn,buyerName,buyerCountry,buyerAddressLine1,buyerCity,lineDescription,lineQty,lineUnit,lineUnitPrice,lineVatRate,lineTaxCategory,referencedInvoiceNumber,notes| Limit | Value |
|---|---|
| Max rows per file | 1,000 invoices |
| Max file size | 5 MB |
| Multiple lines per invoice | Repeat the number column |
| Partial success | Yes — bad rows reported without rolling back the batch |
QBO Sandbox vs Prod + TrustBill Modes
Two orthogonal switches to understand — Intuit's sandbox vs production, and TrustBill's test/sandbox/live.
Intuit side (QBO)
- Sandbox realm:
sandbox-quickbooks.api.intuit.com— free, seeded with sample data, no real accounting effect - Production realm:
quickbooks.api.intuit.com— real customer company - The App Store app registers separately for each realm; refresh tokens are realm-scoped
TrustBill side
| TrustBill mode | Purpose | Reaches FTA? |
|---|---|---|
test | Local integration testing — no ASP call | No |
sandbox | End-to-end dry run against the ASP sandbox | FTA sandbox only |
live | Real, legally binding e-invoicing | Yes — the FTA production network |
Recommended pairing during onboarding: QBO Sandbox realm + TrustBill sandbox mode. This lets you flow test invoices to the FTA sandbox without touching real books. Switch both to production together on go-live day.
QBO Tax Code Mapping (UAE)
QBO Global stores VAT as a Tax Code + Tax Rate. Set up the following tax codes in QBO under Taxes → Manage Tax Rates → New Tax Rate, and the connector will map them automatically:
| QBO Tax Code name | QBO Rate | TrustBill vatRate | TrustBill taxCategory |
|---|---|---|---|
| Standard 5% VAT | 5% | 0.05 | standard_5 |
| Zero-Rated Sales (Export) | 0% | 0 | zero_rated_export |
| Zero-Rated Sales (Healthcare) | 0% | 0 | zero_rated_healthcare |
| Zero-Rated Sales (Education) | 0% | 0 | zero_rated_education |
| Exempt Sales (Financial) | Exempt | 0 | exempt_financial |
| Exempt Sales (Residential Rent) | Exempt | 0 | exempt_residential_rent |
| Reverse Charge (RCM) — Designated Zone | 0% | 0 | reverse_charge_designated_zone |
| Out of Scope | Out of Scope | 0 | out_of_scope |
If your QBO has custom-named tax codes ("5% Output", "VAT-Export", etc.), add the QBO code → TrustBill category mapping in App Store app → Settings → Tax Code Mapping. Any unmapped code blocks submission with unknown_tax_code.
UAE-Specific Scenarios
Free Zone / Designated Zone sellers
QBO does not carry a "designated zone" flag natively. The App Store app adds a company-level checkbox TrustBill → Company Type = Designated Zone that flows through as seller.designatedZone: true. PINT-AE then emits the free-zone declaration.
Margin scheme (used cars, antiques, second-hand goods)
The App Store app adds an item-level checkbox Margin Scheme. When checked, the connector sends lines[].marginScheme: true and uses the item's Cost as the margin base — matching FTA rules for margin-scheme traders.
Reverse charge on imports
Purchase Bills from non-UAE vendors with the tax code Reverse Charge (RCM) are mapped to invoiceType: "purchase" + taxCategory: "reverse_charge_designated_zone". TrustBill emits the required ReverseCharge markers.
B2C simplified tax invoices
QBO customers with no PrimaryTaxIdentifier are treated as B2C. Invoices under 10,000 AED are simplified tax invoices under FTA rules; TrustBill emits the correct PINT-AE profile automatically.
Multi-company (multi-realm) accountants
Accountants managing many client QBO companies install the App Store app once per Intuit login. TrustBill stores the mapping realm_id → trustbill_tenant_id. Use TrustBill's Accounting Firm account type to see every client company on one dashboard.
Error Handling
TrustBill errors follow the shape { code, humanMessage, meta? }. The App Store app surfaces the humanMessage in the invoice sidebar and writes the code to CustomField[3] / PrivateNote.
| HTTP | Typical code | QBO root cause | Action |
|---|---|---|---|
| 400 | invalid_body | QBO customer missing PrimaryTaxIdentifier (TRN), or line missing TaxCodeRef | Fix in QBO; the app auto-resubmits |
| 400 | totals_mismatch | QBO inclusive-tax rounding vs TrustBill per-invoice rounding | In QBO: Account and Settings → Advanced → Automation → Automatically apply credits = OFF; recompute the invoice |
| 400 | unknown_tax_code | Custom-named QBO tax code not in the connector's map | Add the mapping in App Store app → Settings → Tax Code Mapping |
| 400 | region_not_supported | QBO realm is on US/CA/AU/IN edition (no VAT engine) | Migrate the QBO company to the Global edition |
| 401 | intuit_oauth_expired | Refresh token expired (100 days idle) or user revoked | Reconnect the App Store app in Apps → TrustBill → Reconnect |
| 401 | intuit_realm_mismatch | Webhook realm ID does not match the stored token | User probably reinstalled QBO or created a new realm — reconnect the app |
| 403 | kyb_required | TrustBill tenant not yet approved by compliance | Contact TrustBill support |
| 409 | invoice_mode_mismatch | QBO Production realm connected but TrustBill still in sandbox | Switch mode in TrustBill dashboard |
| 409 | invoice_number_duplicate | Two QBO realms pushed the same DocNumber | Use per-realm DocNumber prefixes in Account and Settings → Sales → Custom transaction numbers |
| 413 | bulk_payload_too_large | CSV export > 1,000 rows or > 5 MB | Split by month and re-upload |
| 429 | intuit_rate_limited | QBO 500 req/min realm cap hit | Automatic exponential backoff — no user action needed |
Setup Checklist
- Confirm QBO realm is on a VAT-capable edition (Global / UK / Ireland / South Africa)
- Enable VAT in Taxes → Set up VAT and add the UAE tax rates from the mapping table above
- Fill in the TRN under Account and Settings → Company → VAT / TRN
- Confirm all UAE customers have a
PrimaryTaxIdentifier(for B2B) and a billing country - Create your TrustBill SME account and complete KYB (trade licence + TRN certificate)
- Install the TrustBill App Store app from
appstore.intuit.com - Approve the OAuth scopes (must be a QBO Company Admin)
- Confirm custom fields / memo write-back is enabled (per your edition)
- Enable
sandboxmode in the TrustBill dashboard - Send a test invoice in QBO — mark it Send → confirm it reaches
acknowledgedin TrustBill within 3 minutes - Reconcile QBO's Taxes → VAT Return against TrustBill's "Delivered invoices" report
- Switch to
livemode when FTA registration is complete
Suggested test cases before go-live
- B2B invoice, single line, 5% VAT — expect
acknowledged - B2C invoice under 10,000 AED, no TRN — expect PINT-AE "simplified" profile
- Credit Memo linked to an earlier invoice via
LinkedTxn— expect matching pair - Vendor Credit against a Bill — expect
invoiceType: debit_note - Export sale (customer with country != AE, tax code Zero-Rated Export) — expect
zero_rated_export - Designated-zone customer — expect reverse-charge markers
- Multi-line invoice with mixed VAT (5% + 0%) — expect two
taxCategoryvalues - Recurring invoice child fired by QBO scheduler — expect fresh FTA submission per child
- Multi-currency invoice (USD → AED via QBO exchange rate) — expect conversion, matching totals
- Bulk upload of 500 historical invoices via CSV — expect partial success reported per row
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| App Store install fails with "Company not eligible" | QBO realm is on a non-VAT country (US/CA/AU/IN) | Migrate to QBO Global; retry install |
| Invoice sent in QBO, nothing in TrustBill | Intuit webhook not delivered (Intuit retries 5×, then gives up) | Check App Store → TrustBill → Sync History; re-trigger with the Sync Now button |
| Custom fields don't appear | You're on Simple Start / Essentials (no custom fields exist) | Status written to PrivateNote instead — check the memo |
Invoice stuck in queued | Insufficient TrustBill credit or KYB pending | Check the TrustBill dashboard banner; top up credit |
Invoice reaches rejected with "buyer_trn_invalid" | QBO customer TRN is 14 digits, has spaces, or wrong field | Fix in QBO: Customers → Edit → Tax info → Tax registration number. Connector auto-retries. |
totals_mismatch on inclusive-tax invoices | QBO per-line rounding vs TrustBill per-invoice | Re-save the invoice with Amounts are: Exclusive of Tax if possible; otherwise contact support to enable "match-QBO-rounding" mode |
Arabic descriptions render as ??? | Legacy Windows-1256 paste; QBO stores UTF-8 | Re-type or paste from a UTF-8 source |
| OAuth reconnect required weekly | Refresh token invalidated by Intuit's fraud/abuse system | Confirm the App Store app is not being used from multiple TrustBill tenants against the same realm |
| Duplicate FTA submissions after a network blip | Custom middleware forgot the Idempotency-Key | Use qbo::realm::invoice_id derivation |
| Status write-back not appearing on QBO invoice | OAuth scope missing accounting write, or user is Viewer-only | Reconnect as Company Admin |
Support & Contact
Technical Support
- WhatsApp: +971 52 260 9313
- Email: info@trustbill.ae
- Documentation hub: trustbill.ae/en/documentation
- Zoho integration: /documentation/zoho
- Tally integration: /documentation/tally
- Focus RT integration: /documentation/focus-rt
- ERP Partner API guide: /documentation/erp-partner-api
Escalation
For go-live escalations, include your TrustBill tenant ID, the QBO Realm ID + Invoice ID of the failing invoice, and the timestamp of the failed pipeline run. TrustBill support responds to QuickBooks-tagged tickets within one business hour during UAE working days.