Shopify and QuickBooks
Shopify QuickBooks integration
Shopify orders, refunds and payouts booked in QuickBooks Online as sales receipts, invoices and deposits that match the bank. Tax as Shopify charged it, one item per variant, customers without name conflicts. Built to your chart of accounts, then hosted and run for you.
What moves between Shopify and QuickBooks
Shopify takes the order and the money. QuickBooks Online keeps the books, and on the Plus and Advanced plans it can count stock. Most of the flow goes one way: from Shopify into QuickBooks.
| Flow | Direction | Shopify | QuickBooks Online |
|---|---|---|---|
| Paid orders | to QuickBooks | Order with transactions |
SalesReceipt |
| B2B orders on payment terms | to QuickBooks | order with net terms | Invoice with a Term, later a Payment |
| Refunds | to QuickBooks | refund | RefundReceipt or CreditMemo |
| Payouts | to QuickBooks | Shopify Payments payout and its balance transactions | Deposit from Undeposited Funds |
| Customers | to QuickBooks | customer, company | Customer, sub-customer |
| Products | either way, set once | product and variants | Item, one per variant |
| Stock | from the system that counts it | inventory level | Item.QtyOnHand |
A sales receipt records sale and payment together. It fits a card or wallet payment at checkout. An invoice fits a B2B order on 30-day terms: it stays open until the payment arrives and is applied to it.
Which system owns what
| Data | System of record | Direction | Sync behavior |
|---|---|---|---|
| Orders and order numbers | Shopify | Shopify to QuickBooks | per order or as a daily summary |
| Tax charged | Shopify | Shopify to QuickBooks | written as an override, not recalculated |
| Payouts and fees | Shopify Payments | Shopify to QuickBooks | one deposit per payout |
| Chart of accounts, classes, locations | QuickBooks | stays in QuickBooks | read for the mapping |
| Items and SKUs | Shopify, or QuickBooks when it buys stock | one way, set once | one item per variant |
| Stock quantity | Shopify or a WMS; QuickBooks on Plus and Advanced | from the counting system | changed quantities only |
| Customers | Shopify for web buyers, QuickBooks for accounts | Shopify to QuickBooks | matched on email, then name |
What Shopify and QuickBooks store differently
Variants and items
QuickBooks has no variants. A Shopify product with 3 colors and 4 sizes is 12 items in QuickBooks. Item Name is required, at most 100 characters, and unique across all items; Sku is optional, also 100 characters. Two products both called Classic Tee with a variant Black / M would produce the same name, so the integration builds names from a rule that cannot collide and keeps a map of Shopify variant ID to QuickBooks item ID. A product renamed in Shopify does not create a new item.
Customers and names
DisplayName must be unique across all customers, vendors and employees. A web buyer called Jane Miller cannot be created when Jane Miller is already a vendor; QuickBooks answers with error 6240, Duplicate Name Exists. The integration matches on email first, then creates the customer with a suffix when the name is taken. Company buyers become customers, their locations sub-customers, up to four levels under a parent. More in duplicate customers and orders.
Sales tax
US companies created after November 10, 2017 use automated sales tax. QuickBooks then calculates tax from the company's legal address and the transaction's ship-to address, and replaces tax codes an app assigns. Shopify calculated tax at checkout with its own rules. A local pickup order without a shipping address is taxed by QuickBooks at the company address; Shopify may have charged something else. So the integration supplies TxnTaxDetail.TotalTax and TxnTaxCodeRef at creation, which QuickBooks honors and spreads over the rates of that tax code. US transaction lines are always tax-exclusive; sending GlobalTaxCalculation on a US company is an error. Outside the US the same field is required, with TaxExcluded or TaxInclusive.
Rounding is the second difference. QuickBooks keeps UnitPrice to 7 decimals and rounds the line to 2. Intuit's own example at 12 percent: a unit price of 37.37499999 gives a line of 37.38 and tax of 4.49; the line entered as 37.37 gives tax of 4.48. The integration sends line amounts exactly as Shopify charged them. Background in money, tax and rounding.
Numbers, addresses, locations
DocNumber holds 21 characters; a prefix such as SHOP- leaves room for Shopify's order numbers and keeps them apart from invoices typed by hand. A number that is already used returns 6140, Duplicate Doc Num. Countries go in as ISO alpha-3 or a full name, so Shopify's US becomes USA. A QuickBooks location is a Department: a tag for reporting by store or region, not a place where stock is kept.
The technical reality of this pair
| Limit | Shopify | QuickBooks Online |
|---|---|---|
| Rate | 100 to 2,000 cost points per second by plan | 500 requests per minute per company; 10 per second per company and app |
| Over the limit | THROTTLED inside an HTTP 200 |
HTTP 429; wait 60 seconds |
| Batch | 250 items per input array | 30 payloads per batch request recommended; 40 batch requests a minute |
| Long requests | query cost cap of 1,000 points | timeout after 120 seconds |
| Change feed | webhooks, 8 retries over 4 hours | webhooks retried from 10 seconds to every 6 hours; cdc up to 30 days back, 1,000 objects |
| Access | app token | access token 60 minutes; refresh token 100 days, rolling, at most 5 years |
Payout, worked through. A payout covers three orders of 120.00, 85.00 and 45.00. Fees on the three charges are 3.62, 2.77 and 1.61, together 8.00. The bank receives 250.00 minus 8.00, which is 242.00. In QuickBooks the three sales receipts sit in Undeposited Funds at 250.00. The deposit links all three and adds a line of minus 8.00 on the merchant fees account, so it totals 242.00, the bank line to the cent:
{
"DepositToAccountRef": { "value": "35", "name": "Checking" },
"Line": [
{ "Amount": 120.00, "LinkedTxn": [{ "TxnId": "1501", "TxnType": "SalesReceipt", "TxnLineId": "0" }] },
{ "Amount": 85.00, "LinkedTxn": [{ "TxnId": "1502", "TxnType": "SalesReceipt", "TxnLineId": "0" }] },
{ "Amount": 45.00, "LinkedTxn": [{ "TxnId": "1503", "TxnType": "SalesReceipt", "TxnLineId": "0" }] },
{ "Amount": -8.00, "DetailType": "DepositLineDetail",
"DepositLineDetail": { "AccountRef": { "value": "92", "name": "Merchant fees" } } }
]
}
The figures come from the payout's balance transactions, which carry amount, fee and net for each charge and refund. Refunds and adjustments in a payout are handled the same way, as further lines. Reading them needs the view_payouts permission.
Volume. 2,000 orders on a sale day, each with a customer lookup and a sales receipt, are 4,000 requests. At 10 per second that is under 7 minutes of API time. The QuickBooks limit is not the problem. A token is: the refresh token changes value every 24 hours and expires after 100 days without use, after which someone has to authorize the app again. The integration stores every new value and refreshes on schedule.
Webhooks and polling. QuickBooks expects an answer within 3 seconds and may deliver events out of order. Intuit's own advice is a cdc call back to the last processed event, plus a daily one. We do both. The Shopify side is in Shopify API rate limits.
Where standard connectors stop
Standard connectors and iPaaS templates post orders into QuickBooks with fixed settings. The data model above shows where those settings run out:
- Tax recalculated. Without
TotalTaxin the request, automated sales tax recalculates every order, and pickup orders and tax-exempt customers come out different from Shopify. - Payouts. Gross receipts without a deposit built from the payout leave a bank line that matches nothing.
- Names. Variant names that collide, and buyers whose name is already a vendor, stop on 6240 one by one.
- Desktop. For QuickBooks Desktop the Web Connector decides when data moves: on its schedule, and only while the machine runs. See integrating a system without an API.
A built integration follows your chart of accounts and your accountant's choices: per order or per day, which account takes fees, which class takes which channel.
When it goes wrong
| What fails | What the integration does | What you see |
|---|---|---|
| QuickBooks answers 429 | waits 60 seconds, continues | nothing |
| 6240 Duplicate Name Exists | creates the customer with a suffix, links it to the email | a line in the run diff |
| 6140 Duplicate Doc Num | stops that order: the number exists already | the order and the existing document |
| 5010 Stale Object | reads the record again with its new SyncToken, retries |
nothing |
| Refresh token expired or revoked | stops writing, keeps the queue | an alert: reconnect QuickBooks |
| Deposit does not equal the payout | holds the deposit | the payout and the difference |
| Shopify webhook subscription deleted | reconciliation finds the orders | an alert with the time |
Writes carry a request ID, so a retry after a timeout is recognized as the same request instead of a second sales receipt. A record that still fails is kept with its payload and sent again once the cause is fixed. Before go-live the integration runs as a dry run against a QuickBooks sandbox company and shows the receipts, invoices and deposits it would create; after that every run leaves a diff per record. This is part of every e-commerce ERP integration we build. QuickBooks itself is covered on the QuickBooks page and Shopify on the Shopify page; for a full ERP behind Shopify see Shopify ERP integration and Shopify Acumatica integration. Tell us how your accountant wants Shopify booked.
Frequently asked questions
Does this work with QuickBooks Desktop?
Yes, by a different route. QuickBooks Desktop has no cloud API: the QuickBooks Web Connector, a Windows program on the same machine or network, polls a web service on a schedule and passes qbXML both ways. The machine has to be running for orders to arrive. The mapping on this page applies to both; the limits and error codes are those of QuickBooks Online.
One entry per order or a daily summary?
Your accountant decides. Per order gives a sales receipt per Shopify order, so every refund and every customer question can be traced to a document. A daily summary is one sales receipt per day and payment method, which keeps the item list and the customer list small. Payouts reconcile either way, as long as the deposit is built from the same receipts.
Why does the deposit in QuickBooks not match the payout?
Because a Shopify Payments payout is net of fees and refunds, while sales receipts are gross. The integration reads the balance transactions of each payout, with amount, fee and net per transaction, and builds one deposit: the receipts from Undeposited Funds plus a negative line for fees. The deposit total then equals the bank line.
Do we need QuickBooks Online Plus or Advanced?
Only if QuickBooks should count stock. Inventory items with quantity on hand are available on Plus and Advanced. On Simple Start and Essentials the integration books sales against non-inventory items and Shopify stays the place where stock is counted. Plus allows 40 classes and locations for reporting by channel; Advanced has no limit.
Will QuickBooks recalculate the sales tax?
Not when the integration sends it. US companies on automated sales tax have QuickBooks calculate tax from the company address and the ship-to address. The integration writes Shopify's tax amount and tax code with the transaction, which QuickBooks honors, so the books show what the customer paid.
Can stock from QuickBooks go to Shopify?
Yes, if QuickBooks is where purchases are received. An item holds one QtyOnHand and no location, so the quantity goes to one Shopify location, or is split by a rule you set. Most stores keep stock in Shopify or a WMS and let QuickBooks follow through the sales and purchase documents.
Tell us what you need
Tell us which systems you use and what needs to work better. We reply personally within one working day. We help you define the work, then agree the price and timing before you commit.
- You know the price and the timeline before you commit to anything
- We work out the connection that takes the work off your hands
- We handle the build, hosting, monitoring and maintenance
- Your team has less information to retype and fewer discrepancies to chase