Troubleshooting
Not an error, just a question?
See the FAQ — it explains how suppliers, taxes, payments and timing are meant to work.
Almost every issue comes down to one of six things. Find your symptom in the table below — each row has the likely cause and the fix. When in doubt, start with the Health check: it tells you which side is failing before you dig any further. For what each setting does, see the sync options reference.
Run the Health check first
Open your company → Health check. It validates both the Payhawk and Odoo connections and the sync settings, and points at the failing side in one click. The company's live log of runs shows what happened on each sync.
Quick answers
| Symptom | Likely cause | Fix |
|---|---|---|
| Odoo connection won't validate — "bad credentials" | Wrong Database name; the API key isn't a full-access integration user with Accountant access; Odoo isn't reachable over HTTPS; or you pasted a password instead of an API key | Re-check the four Odoo fields, create a proper API key (see below), then re-run the Health check |
| Nothing imported — expenses still draft in Payhawk | Only reviewed / ready expenses import; drafts are skipped by design | Move the expense through review in Payhawk — it then flows in (instantly with webhooks, or click Run sync now) |
| A bill has no tax / is stuck in draft | The Payhawk tax code didn't match an Odoo purchase tax by name | Fix the tax mapping and re-run Sync tax rates so the names line up, then re-review the expense |
| Payment shows up in the wrong place | By design — payments post to a dedicated Payhawk journal, never your real bank journal | Reconcile from the Payhawk journal to your bank as usual — nothing to change |
| Expense imported but not posted | Auto-post is off, or the tax couldn't be resolved (unresolved tax is always left as a draft) | Turn on Auto-post bills, or resolve the tax and post the draft manually |
| Webhooks seem slow | The scheduled sync is only a safety net; Real-time webhooks may be off, or the expense isn't reviewed yet | Confirm Real-time webhooks is ON, check the expense is reviewed, and use Run sync now to pull immediately |
"Bad credentials" on the Odoo connection
The API key goes in the credential field — never a password
The Odoo API key is used instead of a password, because PLANA enforces two-factor and Odoo blocks password logins over the API. Create the key under Preferences → Account Security → New API Key on a dedicated integration user with Accountant access — not a person's login. Also double-check the exact Database name and that your Odoo answers over HTTPS from the public internet.
Why a bill stays a draft (this is on purpose)
No tax posted is better than a wrong tax posted
We map each Payhawk line's tax to the matching Odoo purchase tax by its name — we never compute the tax ourselves. When you post the bill, Odoo recomputes the full tax accounting (the accounts behind each tax, the VAT-return boxes, reverse-charge, non-deductible, and so on). If a tax code can't be matched, the line is left untaxed and the bill stays a draft with a warning, so nothing incorrect is ever auto-posted. The fix is always the same: make the tax names match and re-run Sync tax rates, then re-review the expense.
I corrected an expense in Payhawk and Odoo did not follow
A bill is created once. A correction you make in Payhawk afterwards, even if you re-review the expense, reaches the bill only when one of these options is on:
- Apply Payhawk corrections to draft bills copies only the fields you changed in Payhawk, while the bill is an unpaid draft, and keeps what your team edited in Odoo. This is the one we recommend.
- Refresh a draft bill before paying it rebuilds the whole bill, clearing and recreating every line, once Payhawk marks the expense paid. It replaces anything your team has edited on that draft.
Neither one changes bills that differed from Payhawk before it was switched on.
You no longer have to guess what happened. When an expense is re-reviewed in Payhawk and its bill is left untouched, the run log says so once and names the reason, for example that the option is off, or that the bill is already posted. Open the run in History and look for the expense id.
A posted bill is never changed and never reset to draft by the connector. Correct it in Odoo, or reset it to draft yourself and the next full sync, within a day, copies the correction.
Payments always land in the Payhawk journal
This is intentional
Card and reimbursement movements post to a dedicated Payhawk journal, never your real bank journal — that keeps them from colliding with your bank feed. Reconcile from the Payhawk journal to your bank exactly as you would any other statement.
Still stuck after a Health check and a manual Run sync now? Note the run in the live log — that is the fastest way for us to see what the sync saw.
Next → Back to the guide overview