botttaStart project

Stripe and Xero Integration: A Guide That Actually Reconciles

Ugo Charles
Illustration for Stripe and Xero Integration: A Guide That Actually Reconciles

You connect the Stripe feed in Xero, watch a few bank lines turn green on their own, and think the reconciliation problem is solved. Then a payout comes in short because of a refund, a customer paid through a checkout link instead of a Xero invoice, and a chargeback from last month drags a deposit under the sales behind it. The green lines stop, and you are back to matching Stripe deposits by hand. The native feed is real and it does more than QuickBooks offers out of the box, but it auto-matches one clean path and leaves everything else on your desk.

This guide is for the operator who takes card payments through Stripe and keeps the books in Xero, and wants the deposits to tie out without a manual session every few days. Most of the work is not connecting the feed, which takes minutes. It is building the account structure underneath it so a payout proves out instead of just appearing. Whether Stripe is your checkout or just the way customers pay invoices, the same reconciliation logic decides whether your books are right or merely full.

Know what Xero's native Stripe feed does, and where it stops

Unlike QuickBooks Online, which has no first-party Stripe sync, Xero ships a native Stripe direct feed. Per Xero Central's guide to reconciling Stripe payments, when a customer pays a Xero online invoice through Stripe, the feed groups the related charge and its fee into the single payout line and auto-matches it for you. That is genuinely useful, and it is more than the QuickBooks side gets natively, which we covered in the QuickBooks Stripe integration build guide.

The catch is the word "invoice". The auto-match only fires for payments made against an invoice issued from Xero. Three common things fall outside it:

  • Charges taken outside Xero. A Stripe Checkout session, a payment link, or a subscription billed in Stripe never touched a Xero invoice, so there is no invoice line to match against.
  • Refunds and chargebacks. Xero's own documentation notes that refunds, chargebacks, and manual payouts do not auto-match. They reduce a later payout, and you reconcile them by hand.
  • Fees on third-party payments. If Stripe is set as a payment gateway on some other app or website rather than a Xero invoice, the automatic fee handling does not apply.

There is also no sync of Stripe's own invoices into Xero. Stripe's support docs are explicit that there is no integration between Stripe invoices and Xero. So the native feed is excellent at exactly one job and silent on the rest. Design for the rest.

Decide where your Stripe money actually comes in

Before touching any settings, answer one question, because it decides everything downstream: how do customers actually pay you through Stripe?

There are two patterns, and most teams run some mix of both.

  1. They pay a Xero invoice by card. You raise the invoice in Xero, attach Stripe as the payment service, and the customer clicks pay. This is the path the native feed handles well. The payment applies to the open invoice, the fee posts separately, and nothing double-counts.
  2. They pay outside Xero. Checkout pages, payment links, in-app purchases, or Stripe-billed subscriptions. Revenue is created in Stripe with no Xero invoice behind it. The native feed brings the payout into your bank feed, but there is nothing for it to auto-match, so you record the income yourself or lean on a connector.

If you are pattern one and only pattern one, the native feed plus a clean clearing account gets you most of the way. If any real share of your money comes in through pattern two, the native feed alone will leave a growing pile of unreconciled deposits, and a connector or a build earns its keep. Be honest about the split before you architect anything. A team that thinks it is "mostly invoices" but takes 40% of revenue through a subscription product is going to fight Xero every month.

Set up the Stripe clearing account before you reconcile a single payout

The account structure is what makes payouts reconcile, and it is the step most tutorials skip. A Stripe payout is a batch: many charges, minus fees, minus refunds, netted into one deposit. If that deposit posts straight to your checking account in Xero, gross and net never separate, and every reconciliation is manual matching. Build three accounts first.

  • A Stripe clearing account. Set this up as the bank-style account the Stripe direct feed reports into. Charges land here as they happen. When Stripe pays out to your real bank, that payout draws the balance down. Reconciling becomes watching this account trend toward zero, not reverse-engineering a bank deposit.
  • A Stripe fees expense account. A real "Merchant fees" or "Stripe fees" expense, not a generic bucket. Stripe's standard US online card rate is 2.9% plus $0.30 per successful charge, and that comes out of every payout. Rates differ by country, so check your own region's Stripe pricing, but wherever you are, that cut needs its own line or your income is overstated.
  • An income account for the revenue itself, mapped to how you already report sales and any tax.

The reason the clearing account matters so much in Xero specifically: the gross customer payment goes into the clearing account, the Stripe fee posts to the fee expense, and the net payout reduces the clearing balance. Whatever is left in that account at any moment represents timing, fees, or an unreconciled item, which is exactly the signal you want. Skip it, and the difference between what customers paid and what Stripe deposited has nowhere clean to live. Our account reconciliation software guide goes deeper on this structure when you are reconciling more than one payment source.

Connect the feed and map fees so payouts net out

With the accounts in place, connect the Stripe feed from your Stripe account settings into Xero, pointed at the clearing account. Two setup facts change how this behaves, and both come straight from Stripe's docs.

First, auto-reconciliation only works if Stripe is set to automatic payouts, and the same Stripe account is not connected to more than one Xero organisation. Per Stripe's payout and reconciliation support article, the feed also imports transactions starting from your most recent payout only. So if you switch this on mid-year expecting it to backfill January, it will not. Plan the cutover for a clean payout boundary and reconcile the history separately.

Second, the fee handling. For invoice payments, Xero groups the charge and the fee into the payout line automatically. For everything else, you map the fee yourself to the fees expense account so your net matches the deposit. The test is simple: after a payout reconciles, gross sales minus fees minus refunds for that batch should equal the deposit that hit your bank. If it does not, one of the three accounts is mapped wrong.

This is also where volume starts to matter. Pushing every individual charge into Xero as its own line bloats the ledger and, if you are driving anything custom off the API, burns through call limits fast. For most teams a per-payout summary reads cleaner than a thousand charge lines nobody opens.

Reconcile the payout: prove net equals gross minus fees minus refunds

Reconciliation is not "click the green button". It is proving the deposit is correct and having Xero show it that way. With the clearing account live, the flow runs like this.

Each Stripe charge lands in the clearing account as income. Each fee posts to the fees expense. When the payout arrives in your real bank feed, you match it against the drawdown from the clearing account. For invoice payments, Xero does this grouping for you. For the rest, use Find and Match to tie the payout to the underlying charges and fees. Your bank shows one deposit, your clearing account shows the matching reduction, and they agree.

Two things reliably break this, and both are timing or adjustment problems rather than tooling failures:

  • Payout timing at month-end. A charge on the 30th may not pay out until the 2nd. At cutoff you will have revenue sitting in the clearing account that has not been deposited yet. That is correct, not an error, and the clearing account is what makes the cutoff obvious instead of a mystery.
  • Refunds and chargebacks. These do not auto-match, and they reduce a later payout. A deposit that comes in smaller than the sales behind it looks like missing money until you post the refund. Handle them by hand in Xero, promptly, or they compound into a reconciliation you dread.

If you have ever stared at a Stripe deposit in Xero that would not match anything, the fix is almost always the clearing account plus deliberate handling of refunds, not a broken feed. For the wider pattern across payment sources, our guide to reconciling payments covers the same logic beyond Stripe.

Common mistakes that leave Stripe unreconciled in Xero

  • No clearing account. Payouts post straight to checking, gross and net never separate, and every month-end is manual matching. The single most common cause of "the Stripe feed does not reconcile".
  • Assuming auto-match covers everything. It covers Xero invoice payments. Checkout, links, and subscriptions taken outside Xero do not auto-match and need their own handling.
  • Ignoring refunds and chargebacks. They never auto-match and they quietly shrink later payouts. Left unrecorded, they read as missing revenue.
  • Fees lumped into income. If fees are not split into their own expense, your revenue is overstated by roughly the processing rate on your card volume and your margins look better than they are.
  • Multi-currency on autopilot. If Stripe settles in more than one currency, Xero's default conversion and rounding rarely match how you want it reported. This is usually the point where the native feed stops being enough.

When to go past the native feed, and where bottta fits

For a lean team whose Stripe money mostly arrives through Xero invoices in one currency, the native feed plus a proper clearing account is the honest answer, and it beats paying for anything heavier. Recommend that setup to yourself first.

You outgrow it when the shape of your business breaks the feed's one clean assumption. That is where working with bottta changes the math. We design and build the Stripe-to-Xero sync around your actual books rather than around what auto-matches, which is our Integrations work. In practice that means driving the flow off Stripe webhooks so entries post as events happen, handling refunds, chargebacks, subscriptions, and multi-currency deliberately instead of leaving them to fall out of the feed, and respecting Xero's API limits so a naive per-charge sync does not stall. Xero caps the Accounting API at 60 calls per minute and 5,000 per day per organisation, with a Starter-tier developer app dropping to 1,000 per day and a concurrent ceiling of five calls, which is exactly the wall a per-charge sync hits at volume.

A build like this usually lands as our $4K fixed-scope project, integrations and 30-day post-launch support included. If Stripe is one of several systems that keep drifting out of Xero, the $3K per month retainer covers ongoing monitoring so a silent failure surfaces as an alert, not as a reconciliation gap you find two weeks later. The deciding question is not whether the feed can move data. It can. It is whether your books stay right without someone babysitting the reconciliation. Our build vs buy vs hire breakdown walks that call across tools, and the broader accounting automation guide covers the stack Stripe and Xero plug into, including invoice automation on the accounts-receivable side, and WooCommerce to Xero if that is your checkout.

Most teams call us at the point where the manual Xero session has crept from ten minutes to half a day and nobody trusts the numbers at month-end. You do not have to wait for that. A Stripe-to-Xero build that handles the checkout charges, refunds, and multi-currency the native feed leaves behind is a fixed-scope project, not a standing chore. Book a call with bottta.

Frequently asked questions

Does Xero integrate with Stripe natively?

Yes. Xero has a native Stripe direct feed, unlike QuickBooks Online. When a customer pays a Xero online invoice through Stripe, the feed groups the charge and its fee into the payout line and auto-matches it. Payments taken outside Xero, along with refunds and chargebacks, do not auto-match and need manual handling.

Why does my Stripe payout not match anything in Xero?

Because a payout is a batch of charges net of fees and refunds, and without a clearing account there is nowhere to hold the gross-versus-net difference. Set up a Stripe clearing account, post fees to their own expense, and record refunds as they happen. The payout then reconciles against the sales behind it instead of looking like missing money.

How are Stripe fees recorded in Xero?

For invoice payments, Xero groups the fee into the payout line automatically. For other charges you map the fee to a dedicated fees expense account. Stripe's standard US online card rate is 2.9% plus $0.30 per successful charge and comes out of every payout, so keeping fees in their own account is what keeps your revenue and margins accurate.

Does the Stripe feed in Xero import historical transactions?

No. Per Stripe's documentation, the feed imports from your most recent payout only when you connect it, and auto-reconciliation requires Stripe to be set to automatic payouts. Plan the cutover on a clean payout boundary and reconcile any earlier history separately.

Do I need a connector or a custom build instead of the native feed?

Not if your Stripe money mostly arrives through Xero invoices in one currency. You outgrow the native feed when you take significant revenue outside Xero, run subscriptions, settle in multiple currencies, or need custom mapping the feed cannot express. At that point a paid sync tool or a custom build reconciles far more reliably than the feed alone.

More from the Journal