Stripe Terminal and Card-Present Payments in QuickBooks
A card-present Stripe charge is the same object as an online one, which is why the sync needs no special path. The fee, the customer name and offline...
Every article about syncing Stripe to QuickBooks quietly assumes the same sale: a customer with an email address types a card into a checkout page, a receipt goes out, and a record with a name on it lands in your books.
Then you buy a card reader.
The charge that comes off a Stripe Terminal reader is the same object as the online one, and that fact does more work than anything else in this post. But three things around it are different, and each of them changes what shows up in QuickBooks: the fee is smaller and shaped differently, there is often no name attached to the sale at all, and the payment can be taken at a moment when Stripe does not yet know it happened.
If you would rather in-person and online Stripe revenue arrived in QuickBooks as one set of books instead of two, start a free trial.
The charge is the same object, and that is the good news
Stripe describes Terminal's whole premise as unification: you "accept in-person payments and manage them alongside your online payments in Stripe."
That is not marketing, it is the data model. A card-present sale produces a Charge, exactly like an online one. The difference lives in one nested hash. Where an online charge carries payment_method_details.card, a reader-collected charge carries payment_method_details.card_present, which Stripe documents as "a snapshot of the transaction specific details of the card_present payment method."
Everything downstream follows from that. The charge produces a balance transaction, the balance transaction settles into your Stripe balance, the balance pays out. There is no parallel in-person ledger.
For the sync, this means there is no separate in-person path either. Acodei's documented routing keys on the charge event, not on how the card was read: a successful charge becomes a QuickBooks sales receipt by default, deposited into the resolved holding account for that Stripe account and currency. The choice between writing a Sales Receipt and writing a standalone Payment is made by your account settings rather than by anything on the charge itself. The full record-type logic is covered in sales receipt vs payment, and this post will not restate it.
One consequence is worth stating plainly, because it is the answer to a question people ask in their first week of in-person sales: if your account is on daily summary rather than real-time sync, there is no per-charge record for a Terminal sale any more than there is for an online one. The day's charges aggregate into one receipt. Your reader does not change that.
The fee is smaller, and it lands in the same payout
Here is where the numbers stop being interchangeable. Stripe's published US pricing, as of this writing:
| Rate | |
|---|---|
| Online cards and wallets | 2.9% + 30¢ per successful transaction, domestic cards |
| In-person cards and wallets | 2.7% + 5¢ per successful transaction, domestic cards |
| International cards | + 1.5%, both channels |
| Tap to Pay | + $0.10 per authorization |
Run a $40 ticket through both. Online costs $1.46. On a reader it costs $1.13. On a Tap to Pay phone, $1.23. (Which reader, and what it costs to buy, is a separate question from what it costs to run, and one covered in the Terminal hardware comparison.) Nobody notices that on one sale. On four hundred sales a month it is $132 of difference, and it is the reason a business with a busy counter and a quiet web store can have a blended effective rate that matches neither published number.
The accounting question is what happens to those two different fees in the same payout, and the answer is that nothing separates them. Both are fees on a balance transaction, and both are handled by the same documented machinery. Acodei creates a QuickBooks product at onboarding, "Stripe Fees - Acodei", mapped to an account you choose, and routes fees to it. Where the fee appears is a Fee Management setting: a line item on the Sales Receipt, a line item on the Bank Deposit if you are on Undeposited Funds, or a separate Expense. The default on a real-time sales receipt is the line item, which nets the receipt down to what actually entered your Stripe balance.
Notice what is not on that list of levers: the channel. Acodei's advanced fee mapping resolves fees through your product-mapping rules, on dimensions like the description or the Stripe product. Nothing documented routes a fee by whether the card was present. So if you want in-person processing cost broken out separately in your P&L, the sync will not do it for you. The split is visible per balance transaction on Stripe's side, and the general mechanics of getting fees into QuickBooks correctly are covered in the fee reconciliation guide.
The name problem, which is the real one
This is the section that surprises people, and it is entirely a data problem rather than a sync problem.
Stripe documents card_present.cardholder_name with an important caveat: it is "the cardholder name as read from the card", and "cardholder name is typically not available on swipe or contactless payments, such as those made with Apple Pay and Google Pay."
Think about what fraction of counter sales that describes. Every tap. Every phone. Every watch. On those charges, Stripe has a last four, a brand, a fingerprint, an expiry, an issuer, and no human name whatsoever.
Now put that against how the customer actually gets resolved. Acodei's documented order is to take the name from the Stripe Customer object first, then fall back to charge.billing_details.name. A typical in-person charge has neither: there is no Customer object because nobody signed up, and billing details are not collected at a card reader. When neither is present, the documented fallback options are to build the customer from the email address, to use a static default name, or to leave it empty and land on QuickBooks' own "Unnamed Customer" placeholder.
At a counter there is usually no email either. So in-person revenue tends to collapse onto whatever static default name the account is configured with, and every tap for the rest of the year joins it.
That is not a bug, and for most retail it is the right answer. A coffee shop does not want four thousand QuickBooks customer records. But it is worth deciding on purpose rather than discovering in March, because the default name becomes a permanent bucket. Acodei's documentation is explicit that customer records are not updated after creation.
Does an in-person sale and an online sale reconcile as one customer?
Only if the names match, and match precisely. The documented matching rule is character-for-character identical on the display name, case-insensitive. "Jane Smith" matches "jane smith". It does not match "Jane A. Smith", and it certainly does not match a blank.
Which means the honest answer for most in-person setups is no. Your regular customer who orders online as "Jane Smith" and taps her phone at the counter produces one named QuickBooks customer and one anonymous sale in the default bucket. If unifying those matters to you, the fix is upstream: attach the Stripe Customer at the point of sale so the charge carries one. Stripe supports saving cards at the point of sale for exactly this reason, and the charge then carries card_present.generated_card, a card PaymentMethod that can be attached to a Customer for future transactions.
Location and reader: Stripe knows, QuickBooks does not ask
Stripe tracks in-person sales by physical place. Readers are registered to Locations "so Stripe can apply the right regional and payment method settings", and each Location object carries a display_name and a full address. Every card-present charge records both card_present.location and card_present.reader.
So the dimension you want for a multi-site business exists, and it exists on the charge.
It does not reach QuickBooks. Acodei's product documentation has no Terminal page, and nothing in it documents reading, mapping, or preserving Terminal locations, readers, or read_method on the QuickBooks record. Rather than guess at what happens to those fields, treat them as not carried.
The nearest QuickBooks-side dimension is a different thing that is easy to mistake for the same thing. Acodei documents a Location Tracking option, enabled by the Acodei team rather than self-serve, which adds a QuickBooks Location tag on every sales line. Read that carefully: every sales line, not the line's originating Stripe Location. It is a connection-level tag, so it can tell QuickBooks that this connection's revenue belongs to one entity. It will not split Tuesday's Downtown takings from Tuesday's Airport takings, because the Stripe Location never makes the trip. If per-store reporting matters, the practical lever is a separate Stripe account per site, since the holding account and the fee mapping both resolve per Stripe account. The QuickBooks-side concept is covered in location tracking.
Offline payments, and the sale that has no charge yet
This is the part with genuine month-end consequences, and it has no online equivalent at all.
Terminal readers can take payments with no internet connection. Stripe's own description of what that means:
When operating offline, payment information is collected at the time of sale, and authorization is only attempted after connectivity is restored and the payment is forwarded.
And the risk that comes with it, stated just as directly:
You, as the user, assume all decline and tamper-related risks associated with an offline transaction. If your tampered reader can't forward payments to Stripe, or the issuer declines the transaction, there's no way to recover the funds, and you might not receive payment from the customer for goods or services already provided.
Sit with the accounting shape of that. At 2pm on Tuesday you handed over goods and your POS said the payment succeeded. Stripe has never heard of it. There is no charge, no balance transaction, no payout line, and therefore nothing for any sync to write, because the sync is driven by charge events and the charge does not exist yet. When the reader reconnects, the payment forwards and the charge is created then. Stripe records card_present.offline.stored_at as the "time at which the payment was collected while offline", so the evidence of the gap is preserved on the charge, with offline.type set to deferred.
Two practical consequences:
Your close is exposed to the length of the outage. A Tuesday sale that forwards on Wednesday creates a Wednesday charge. If the outage straddles month end, that revenue lands in the wrong month from the till's point of view, and the only trace is a timestamp buried in a nested object. If you run offline mode at all, reconnect before you close.
Some of those sales may never become revenue. An issuer declining a forwarded payment is not a refund or a dispute. It is a sale that never happened, on goods that already walked out. Your POS totals and your Stripe totals will disagree by exactly that amount, and no reconciliation of Stripe against QuickBooks will surface it, because both agree there was no charge. The check is the one nobody builds: POS-reported sales against Stripe charges for the same day.
Stripe gives you the levers to bound the exposure. The SDK exposes offlinePaymentsCount and offlinePaymentAmountsByCurrency, and an offlineBehavior of REQUIRE_ONLINE fails a transaction rather than storing it. If your average ticket is large, that is worth configuring before the outage rather than during it.
Receipts, and the data that is not for you
One last card-present peculiarity, because it looks like an accounting field and is not.
A card-present charge can carry a card_present.receipt object, which Stripe describes as "a collection of fields required to be displayed on receipts. Only required for EMV transactions." Inside it are things like the Application Cryptogram, the Application Identifier, the authorization response code, and the terminal verification results. The same hash carries amount_authorized and, under manual capture, a capture_before timestamp, which is the in-person face of the authorization and capture split. These exist because card networks and local regulation require them printed on the customer's slip. They are compliance data, not bookkeeping data, and none of them belongs in QuickBooks.
The field that does matter by its absence is receipt_email, documented as "the email address that the receipt for this charge was sent to". Online, your checkout collected it. At a counter, usually nobody did. That is the same absence that drives the customer-naming behaviour above, showing up in a second place.
What to actually set up before your first busy day
- Decide the in-person customer name deliberately. Pick the static default and name it something you would be happy to see on a year of transactions, like "In-Person Sales", rather than discovering the placeholder.
- Check whether you are on real-time or daily summary sync. It decides whether you get four hundred receipts a month or thirty.
- Leave the fee product alone. In-person and online fees share it. If you need the split, take it from Stripe's side, not QuickBooks'.
- If you run more than one physical site, run more than one Stripe account. The Stripe Location will not reach your books.
- If offline mode is on, bound it. Set
REQUIRE_ONLINEabove a threshold, and never close a month with payments still stored on a reader. - Reconcile the till, not just the bank. POS sales versus Stripe charges for the same day is the only check that catches a forwarded payment that declined.
None of this is exotic. It is the ordinary consequence of taking money from someone standing in front of you, who has no account, gave you no email, and whose card told you a number instead of a name.
FAQ
Does Stripe Terminal need a different QuickBooks setup than online Stripe payments?
No. A card-present charge is still a Stripe Charge with its own balance transaction, and the documented sync routes it the same way as an online charge: a Sales Receipt by default, deposited to your resolved holding account, with the record type decided by your account settings rather than by how the card was read.
Why do my in-person Stripe sales have no customer name in QuickBooks?
Because the card usually does not supply one. Stripe documents that cardholder name is "typically not available on swipe or contactless payments, such as those made with Apple Pay and Google Pay". With no Stripe Customer and no billing details on the charge, the sync falls back to your configured option: an email-derived name, a static default name, or QuickBooks' "Unnamed Customer" placeholder.
Are Stripe Terminal fees different from online Stripe fees?
Yes. Stripe's published US rate for in-person cards and wallets is 2.7% + 5¢ per successful transaction on domestic cards, against 2.9% + 30¢ online, with Tap to Pay adding $0.10 per authorization. Both are handled by the same documented fee machinery in QuickBooks, and nothing documented routes a fee by whether the card was present, so the channel difference is visible in Stripe rather than in your books.
Does the Stripe Terminal location or reader appear in QuickBooks?
Not in any documented way. The charge carries card_present.location and card_present.reader, but nothing in Acodei's product documentation covers carrying those into QuickBooks, and there is no Terminal page in it at all. The QuickBooks Location Tracking option is a connection-level tag on every sales line, not a per-store dimension derived from the reader.
What happens in QuickBooks when a Terminal payment is taken offline?
Nothing, until it forwards. Stripe only attempts authorization "after connectivity is restored and the payment is forwarded", so no charge exists in the meantime and there is nothing for the sync to write. When it forwards, the charge is created then and the record follows the charge, not the moment at the till.
Can an offline Terminal payment fail after I have handed over the goods?
Yes, and Stripe says so plainly: you assume the decline risk, and if the issuer declines the forwarded transaction "there's no way to recover the funds". It is not a refund or a chargeback, so it leaves no trace in your books. The only way to catch it is comparing your POS-reported sales against Stripe charges for the same day.
Will an in-person sale and an online sale from the same person land on one QuickBooks customer?
Usually not. Customer matching is character-for-character on the display name, case-insensitive, and a contactless in-person charge typically carries no name to match with. Attaching a Stripe Customer at the point of sale is the upstream fix.
Do I need a separate Stripe account for each store?
If you want per-store revenue in QuickBooks today, effectively yes. Stripe's Location is registered per reader and recorded on the charge, but it is not documented as reaching QuickBooks, and the QuickBooks-side location tag applies to the whole connection rather than to individual sales.
In-person revenue is the case where the tidy online mental model quietly stops describing your books. The charge is the same, which is why the sync needs no special handling. The context around the charge is different, which is why your QuickBooks looks different. If you want Stripe sales, fees, refunds and payouts to arrive in QuickBooks already reconciled, whichever side of the counter they came from, start a free trial.
Automate your Stripe to QuickBooks sync
Save hours every month. Acodei automatically syncs your Stripe transactions, invoices, and payouts to QuickBooks Online.
How Acodei handles this in your stack
Stripe QuickBooks Integration
See how Acodei syncs Stripe payments, fees, refunds, invoices, and payouts into QuickBooks Online automatically.
Or go straight to a capability
Advanced Product Mapping
Map Stripe products to QuickBooks with rule-based logic on product ID, price ID, metadata, and account. Set rule priority and extend mapping to refunds and fees.
Automated Invoice Sync
Bring Stripe invoices into QuickBooks and auto-apply payments and credit memos, with numbering, invoice matching, and quantity tracking to cut double-entry.
Multi-Currency Mastery
Sync Stripe transactions across currencies with automatic exchange rate handling and currency-specific customer records. Our team enables multicurrency on request, and zero-decimal currencies such as JPY are not supported.
Class Mapping
Map Stripe products to QuickBooks classes for scalable categorization and multi-entity reporting. Class tracking requires QuickBooks Online Plus or Advanced.
Historical Data Import
Backfill historical Stripe data into QuickBooks by month range. Preview volume and cost before syncing so reporting starts from a complete baseline.
How to Connect Stripe to QuickBooks Online
Connect Stripe to QuickBooks Online in minutes. Acodei links both accounts with secure OAuth and syncs payments, fees, refunds, and payouts automatically.
Reconcile Stripe Payments in QuickBooks
Reconcile Stripe in QuickBooks Online automatically. Acodei splits out fees, matches payouts to deposits, and keeps every charge audit-ready.
Get more operational finance guides like this one
We will only send high-value product and finance content.