This document outlines the technical implementation details for the CM Finance integration (Between Salesforce and QuickBooks Online (QBO)). The integration enables bidirectional communication and synchronization of core accounting data such as Accounts, Customers, Invoices, Vendor, Products, Payments, Tax Rates, Journal Entry, Sales Receipt and Company Preferences.
QB_Connector_Workflow_Diagrams.pdf
1. Integrated QuickBooks Endpoints
We have integrated the following endpoints with QuickBooks:
|
QuickBooks Entity |
Supported Operations |
|---|---|
|
Account |
Query |
|
Company Info |
Query |
|
Customer |
Create, Query, Update |
|
Invoice |
Create, Query, Update, Get Invoice as PDF |
|
Sales Receipt |
Create, Query, Update, Get Sales Receipt as PDF |
|
Vendor |
Create, Query, Update |
|
Product (Item) |
Create, Query, Update |
|
Payment |
Create, Query, Get Payment Receipt as PDF |
|
Journal Entry |
Create |
|
Tax Rate |
Query |
|
Tax Code |
Query |
|
QB Class |
Query |
|
Preferences |
Query (Fetch and sync Custom Fields) |
|
Batch |
Send multiple API requests in a single API call |
2. Authentication Flow
To implement OAuth 2.0 authentication with QuickBooks:
-
A Visualforce (VF) Page is created in Salesforce.
-
This VF Page initiates a call to our middleware (Cloud Maven's Subscriber Org).
-
Middleware redirects the user to the Intuit Login Page for authentication.
-
Upon success or failure, the middleware processes the response and redirects back to the VF Page with the authentication result.
-
On success, the access token and refresh token are stored securely in a
cm_finance__Quickbooks_Credentials__ccustom setting record, keyed by the QuickBooks Realm Id.
This ensures a secure and compliant OAuth 2.0 authentication mechanism without exposing credentials at any point in the flow.
3. Methods for Entity Creation
Entities (Customers, Vendors, Products, Invoices, Payments, Journal Entries, Sales Receipt) in QuickBooks can be created or synced through four methods:
3.1 Manual Creation
Users can manually trigger entity creation or sync by interacting with the cmQBConnectorMaster Lightning Web Component, embedded on any Salesforce record page via a Lightning App Builder page layout. From this component, users can:
-
Push a Salesforce record to QuickBooks (create or update the corresponding QB entity)
-
Pull a QuickBooks record back into Salesforce (sync the latest QB state)
-
Create net-new QB entities (Customer, Vendor, Product, Invoice, Sales Receipt) with live field pre-fill from the source record
Invoices specifically are managed through the QBInvoiceController backed LWC with full line item, custom field, QB Class, and customer association support.
Sales Receipt are managed through the QBSalesReceiptController backed LWC with full line item, custom field, QB Class, and customer association support.
Journal Entries are handled through the standalone qbJournalLedger LWC, which enforces debit/credit balance constraints before any callout is made.
3.2 Automation (Flow / Apex)
Developers and admins can automate entity creation as part of business processes using the global InvocableAutomateQBService class:
-
Flow: Add an Apex Action named Call QB Service inside any Record-Triggered Flow. Set the
recordIdandrequestType(CustomerorProduct). No code required. -
Apex: Call
InvocableAutomateQBService.callQBService()for Customers and Products, orInvocableAutomateQBService.createQBInvoiceFromMapping()for Invoices andInvocableAutomateQBService.createQBSalesReceiptFromMapping()for Sales Receipt.
Routing logic:
-
Single record → dispatched as a real-time
QueueableJob(immediate HTTP callout to QBO) -
Multiple records → staged in Salesforce with a batch flag and processed asynchronously
3.3 Webhook-Driven Updates
QuickBooks sends inbound HTTP POST webhooks to the Webhook_QBChangeHandler REST endpoint (/getUpdatesQB/*) whenever an entity is created, updated, or voided in QuickBooks.
On receiving a webhook, the system:
-
Parses the payload and groups entity Ids by type
-
Dispatches one dedicated Apex Batch job per entity type
-
Each batch job queries QuickBooks for the current state of the changed entity
-
Creates or updates the corresponding Salesforce record to match
Supported webhook entities: Customer, Vendor, Account, Product (Item), Invoice, Payment, Sales Receipt and Payment Method
Each batch class also guards against duplicate concurrent executions — if a job of the same type is already Processing, the incoming batch exits immediately and returns an empty scope.
3.4 Full Sync (Bulk Batch Sync)
For initial setup or periodic reconciliation, dedicated batch classes perform a full sync by querying all records of a given entity type from QuickBooks and upserting them into Salesforce:
|
Batch Class |
Entity Synced |
|---|---|
|
|
Customers |
|
|
Accounts |
|
|
Invoices |
|
|
Payments |
|
|
Products (Items) |
|
|
Vendors |
|
|
QB Classes |
|
|
Payment Methods |
|
|
Sales Receipt |
4. Custom Field Mapping
We have implemented a Custom Field Mapping feature to enhance flexibility and eliminate hardcoding:
-
Users can map any Salesforce object (standard or custom) to a QuickBooks entity (Customer, Product, Invoice, Vendor, Sales Receipt).
-
Mappings can handle multiple source objects for a single QuickBooks entity type — for example, both
OpportunityandOrdercan independently map to QB Invoice or QB Sales Receipt. -
Custom and standard fields from both Salesforce and QuickBooks can be dynamically mapped without any codebase changes.
-
For Invoices and Sales Receipt, the mapping additionally supports:
-
Customer lookup field — specifies which field on the source object identifies the related QB Customer
-
Product pre-population mapping — auto-generates line items from child records with configurable quantity, unit price, description, and QB Class fields
-
QB Custom Fields mapping — maps Custom Field Definition Ids to source object fields
-
This mapping architecture ensures the integration is scalable, configurable, and easily adaptable to changing business requirements.
5. Multi-Company Support
The connector supports connecting a single Salesforce org to multiple QuickBooks companies simultaneously:
-
Each QB Company is represented as a
cm_finance__Quickbooks_Company__crecord with its own credentials (cm_finance__Quickbooks_Credentials__c), keyed by Realm Id. -
One company can be designated as the default company. All automation and manual operations fall back to this company when no specific company is provided.
-
Field mappings, custom fields, and synced records are all scoped to their respective company, preventing data cross-contamination across companies.
6. Notes
-
Batch API Usage: The Batch API allows sending multiple QuickBooks API requests in a single HTTP call, reducing API call overhead and increasing throughput. This is used internally when processing bulk entity operations.
-
PDF Fetching for Invoices, Sales Receipt and Payments: PDF documents can be fetched directly through the integration for both Invoices, Sales Receipt and Payment Receipts, enabling storage or sharing within Salesforce. The
QueueableGetQBPaymentReceiptPDFQueueable class handles asynchronous PDF retrieval and attachment. -
Scheduled Payments: The
BatchCaptureScheduledPaymentbatch class supports scheduled payment capture, enabling automated payment processing on a defined schedule via a cron-based Scheduled Apex job. -
QB Custom Fields: QB Custom Fields defined in QuickBooks Preferences are fetched using the
getCustomFieldsmethod and stored ascm_finance__Quickbooks_Custom_Field__crecords. These are then referenced in field mappings and persisted on Invoice and Sales Receipt records (cm_finance__Custom_Field_1/2/3__c). -
QB Classes: QuickBooks Classes are synced into
cm_finance__Quickbooks_Class__crecords and can be assigned to individual line items, enabling class-based accounting categorisation within QuickBooks from Salesforce.