QuickBooks Desktop and Stripe integration
QuickBooks Desktop holds your company's invoices, customers, and payment records on premises. Stripe accepts your online payments in the cloud. Connecting them keeps your invoices and customers in sync between both systems and posts every Stripe charge into QuickBooks Desktop as a received payment, eliminating manual entry and reconciliation gaps. ml-connector handles the SOAP Web Connector protocol that QuickBooks Desktop requires and the Stripe webhook format in the same session.
What moves between them
The main flow runs from QuickBooks Desktop outward and from Stripe back in. Customer records and invoices flow from QuickBooks Desktop into Stripe so customers appear in the Stripe dashboard and invoices can be linked to the right Stripe customer. When Stripe records a successful charge or payment, ml-connector receives that event via webhook and writes it back into QuickBooks Desktop as a ReceivePayment transaction, matched to the original invoice and customer. The mapping is deterministic: Stripe customer.id is stored in the QuickBooks Desktop customer record (in a memo or custom field), so when a Stripe payment arrives, ml-connector can find the corresponding QB customer and invoice without manual lookup.
How ml-connector handles it
ml-connector maintains two concurrent polling loops. On the QuickBooks Desktop side, it opens a SOAP session authenticated with the Web Connector credentials (username and password), receives a session ticket, then uses that ticket to send QBXML queries for new and modified customers and invoices based on the ModifiedDateRangeFilter timestamp from the last run. When customers or invoices are found, ml-connector pushes them to Stripe via the Stripe API, storing the Stripe customer.id in a memo field on the QB customer record so the reverse link is available. On the Stripe side, ml-connector listens for webhooks on a registered endpoint and validates the HMAC-SHA256 signature in the Stripe-Signature header against the webhook signing secret. When a charge.succeeded or payment_intent.succeeded event arrives, ml-connector looks up the associated Stripe customer, finds the QuickBooks Desktop customer via the stored customer.id, queries QB for the matching invoice, and posts a ReceivePayment transaction to QB that links to that invoice. The QBXML ReceivePayment requires the current EditSequence (version counter) of the invoice, so ml-connector re-queries the invoice before modifying it to avoid version conflicts. QuickBooks Desktop imposes a 60-second timeout per QBXML request and processes requests sequentially, so large customer or invoice queries must be paginated. Stripe rate limits are handled with exponential backoff. All transactions are recorded in the audit trail with their Stripe event ID and QB transaction ID so any failed payment can be replayed.
A real-world example
A mid-sized ecommerce company runs QuickBooks Desktop on premises for accounting and invoicing and uses Stripe to accept online payments from customers. Before the integration, the finance team exported payment confirmations from Stripe at the end of each day and manually entered them into QuickBooks as received payments, a process that took two hours daily and introduced entry errors. Customer data was kept only loosely in sync between the two systems. With QuickBooks Desktop and Stripe connected, each Stripe charge automatically creates a corresponding QuickBooks Desktop received payment linked to the original invoice, and customer records sync automatically from QB to Stripe. The manual data entry step is eliminated, and month-end reconciliation is faster because Stripe transactions already appear in the QB books.
What you can do
- Automatically sync customers from QuickBooks Desktop to Stripe and back, keeping both systems aligned.
- Post Stripe successful charges into QuickBooks Desktop as ReceivePayment transactions against the matching invoice.
- Handle the SOAP Web Connector authentication handshake and QBXML XML formatting on the QuickBooks Desktop side.
- Validate Stripe webhook signatures with HMAC-SHA256 and handle at-least-once webhook delivery by re-fetching current state from the API.
- Poll QuickBooks Desktop on a configurable interval (minimum one minute) and detect changes using ModifiedDateRangeFilter, with retries and full audit trail.
Questions
- How does ml-connector link a Stripe payment back to the original QuickBooks Desktop invoice?
- When a customer record is synced from QuickBooks Desktop to Stripe, ml-connector stores the Stripe customer.id in a memo field on the QB customer record. When a Stripe charge succeeds, ml-connector uses that stored ID to find the QB customer, queries for matching invoices, and posts a ReceivePayment transaction to the correct invoice. The Stripe event ID and QB transaction ID are both stored in the audit trail for full traceability.
- Does ml-connector require QuickBooks Desktop to be open at all times?
- Yes. QuickBooks Desktop must be running and logged into the company file on the customer's Windows machine for the Web Connector to process requests. ml-connector cannot directly access QuickBooks Desktop; all access is through the Web Connector agent that the customer configures and runs. If QB closes or the user logs out, the next polling cycle will fail until QB is reopened.
- How does ml-connector handle conflicts when QuickBooks Desktop and Stripe data changes at the same time?
- ml-connector re-queries the QB invoice before posting a ReceivePayment to get the current EditSequence (version counter), which prevents concurrent edit conflicts. For Stripe, webhook delivery is not ordered, so ml-connector always re-fetches the current state from the Stripe API before writing anything into QB, ensuring both systems reflect the latest data.
Related integrations
More QuickBooks Desktop integrations
Other systems that connect to Stripe
Connect QuickBooks Desktop and Stripe
Free to use. Add your credentials, ping your real systems, and see if we fit.
Get started