Setup guide · Xero payroll journals · Early access
Set up Xero payroll journals: step by step
This guide is for two people working together: your Xero administrator, who knows your chart of accounts, creates your company's Xero app and approves the connection, and the person who runs payroll in AhlanHamad, who connects Xero and maps the accounts. Follow it in order. Every AhlanHamad label below is the one you will see on screen.
Updated 12 October 2026
1. Before you start
Early access. Posting payroll journals to Xero is switched on one company at a time, when you ask us. It is not open to every company yet. Until it is on for your company, the Field Mapping tab says “Posting payroll journals to Xero isn't switched on for your workspace yet.”
| Check | What you need |
|---|---|
| Xero organisation | A Xero organisation where you can add manual journals: open Accounting → Manual journals. Xero's help ties manual journals to the user's role (administrator, or standard with manual journals) rather than to a plan (Xero Central). |
| Where it stands | Tested end to end on a Xero trial organisation (base currency KWD): manual journals posted, and the reversal of a deleted run. It has not yet posted to a customer's live Xero organisation, so check your first journals closely and tell us if anything looks wrong. |
| Currency and decimals | Manual journals are always in the organisation's base currency. Xero keeps 2 decimals on journal lines, so for KWD, BHD or OMR each line is rounded to 2 decimals and can differ from AhlanHamad's ledger by up to 0.005; the difference goes on the largest line and the journal still balances. |
| Your own Xero app | AhlanHamad connects through a Web app your company creates on developer.xero.com (section 2). Xero's free Starter plan is enough: it allows 5 connected organisations per app and you need one (Xero: app plans). Xero has no separate test keys: test with the Xero Demo Company or a trial organisation first, then connect your real organisation with the same app. |
| A Xero user | Creates the Xero app and signs in to Xero to approve the connection. Use an administrator of the organisation you keep payroll in. |
| In AhlanHamad | A company admin who can manage settings (to connect Xero and save the mapping), and the person who finalizes and pays payroll. Your accountant should help with the mapping. |
Only totals are sent to Xero: one line per account, never a line per employee. Names, IDs and individual salaries stay in AhlanHamad (the journal's description carries the number of employees in the run, nothing more).
Salary payment journals start switched off for Xero. Xero doesn't allow bank accounts in manual journals, so by default AhlanHamad sends the payroll accrual and the monthly end-of-service journal, and you reconcile the salary payment in your bank feed against Net salaries payable. You can switch payment journals on to a salary clearing account instead (section 5).
2. In Xero: create your own Xero app
AhlanHamad connects to Xero through an app your company creates on Xero's developer site and uses only for itself. It takes a few minutes and no review by Xero for one organisation (Xero: getting started).
- Go to
developer.xero.comand log in with your Xero login, then open My Apps (My Apps) and click New app. - Name the app something you will recognise, for example
AhlanHamad payroll, and choose the integration type Web app. - Company or application URL: your company's website.
- Redirect URI: enter
https://ahlanhamad.com/auth/xero/callbackexactly as written: https, same casing, no slash at the end. AhlanHamad shows the same address on the Connection tab under “Redirect URI to register on your app”, with a Copy button. - Accept Xero's developer terms and click Create app.
- On the app's Configuration page, copy the Client id, then click Generate a secret and copy the Client secret straight away; Xero shows it only once. Keep it private; you paste both in section 4 and AhlanHamad stores them encrypted.
Plans and scopes. A new Xero app starts on the free Starter plan: 5 connected organisations per app and 1,000 API calls per organisation per day (Xero: app plans). Payroll journals use a few calls per run, and your app connects one organisation. You don't pick scopes on the app: AhlanHamad asks for them when you connect, and Xero lists them on its consent screen: accounting.manualjournals (post and look up manual journals), accounting.settings.read (read your chart of accounts and organisation details), plus openid, profile, email and offline_access so the connection stays signed in (Xero: scopes).
3. In Xero: get your chart of accounts ready
Xero refuses some accounts in manual journals: system accounts (such as Wages Payable, Accounts Payable and Accounts Receivable), bank accounts, and accounts without a code. AhlanHamad greys them out, so create the accounts you need first. In Xero, go to Accounting → Chart of accounts → Add Account.
- Check every account you will map has a Code. Add one to any that doesn't.
- If you have no ordinary liability for net salaries, add one: type Current Liability, a code, name for example
Salaries payable. Xero's own Wages Payable is a system account and can't take manual journals. - Do the same for social insurance payable (and, if used, deductions withheld and DIFC DEWS payable): Current Liability accounts with codes.
- Add the end-of-service provision as a Non-current Liability with a code, if you don't have one.
- Only if you will switch salary payment journals on: add a Current Liability account such as
Salary clearing, with a code. It stands between payroll and the bank.
Expenses (salaries, housing, transport, employer social insurance, end-of-service, bank charges) go to ordinary Expense accounts with codes; most charts already have them.
4. In AhlanHamad: connect Xero
Go to Integrations, open Xero and stay on the Connection tab. The card starts with Connect with your own Xero app, with a link to this guide.
- Check the address under Redirect URI to register on your app is the one you entered in section 2.
- Client ID and Client Secret: paste the values from section 2. Under the secret it says “Stored encrypted on the server. Never shown again and never sent to the browser.”
- Click the blue Connect to Xero button (Xero's own button). AhlanHamad says “Taking you to Xero to sign in…”.
- Sign in to Xero. In Xero's organisation select window, choose one organisation, the one you keep payroll in, and allow access (Xero: the auth flow).
- You come back to a page that says Connected to Xero, then to the Xero page. The card shows Connected to Xero, Organisation: with its name, “Connected through your own app”, and the Tenant ID (Xero's number for the organisation).
Your app's Client ID and Secret stay saved. If you connect again later, the card says “Your app credentials are saved. Click Connect to sign in with them — no need to enter them again.” To use another app, click Replace credentials.
From test to live. Tested with the Xero Demo Company or a trial organisation? Disconnect, then connect again with the same app and choose your real organisation in Xero's organisation select window. That is a different organisation, so load your accounts and save the mapping again (section 5).
Or one click with Ahlan Hamad's app (when available)
AhlanHamad also has its own Xero app. Where it is switched on for your workspace, the Connection tab shows Or connect with Ahlan Hamad's app under the form: you sign in to Xero and approve access, with no app or keys of your own. It lists What Ahlan Hamad will access (your chart of accounts and organisation settings, read; manual journals; your organisation name and base currency), and the card then says “Connected through Ahlan Hamad's app”. Your own app stays the main way to connect.
Already sending payroll to another accounting system? If another one is connected and receiving payroll, AhlanHamad asks first: “Connect a second accounting system?” If you connect Xero too, every payroll run is posted to both and your payroll costs are booked twice. If you are moving to Xero, click Cancel, disconnect the other system first, then connect Xero.
5. Choose the organisation, then map your accounts
- Open the Field Mapping tab. The card is called Post payroll journals to Xero.
- Click Load my accounts. This reads your chart of accounts, organisation name and base currency from Xero.
- If your Xero sign-in can reach more than one organisation, the card asks you to Choose the organisation: “Your Xero sign-in can reach more than one organisation. Pick the one payroll journals go to.” The card then shows Posting to that organisation and its Base currency.
- Decide on Post salary payment journals (below). Leave it off unless you created a salary clearing account in section 3.
- Map each Ahlan Hamad account to a Xero account (table below). Some are pre-selected and marked Suggested when the match is clear; check every one with your accountant.
- Click Save mapping. When nothing is missing the card says Mapping complete. Until then it says “Posting is on hold until every required account is mapped.”
- If you pay any payroll in a currency other than your Xero base currency, decide on Post runs in other currencies (section 6).
Salary payment journals: off or on
| Post salary payment journals | What happens |
|---|---|
| Off (the default) | Only the payroll accrual and the end-of-service journals are sent. The payment and bank-charge lines on the run card say Not needed. When the salary payment appears in your Xero bank feed, reconcile it against your Net salaries payable account (code the statement line to that liability with Create, Xero: reconcile). The 1101 row says “Not used — salary payment journals are off.” |
| On | Payment and bank-charge journals are sent too. Map 1101 Bank account salaries are paid from to your salary clearing account (not a bank account), then reconcile the bank-feed payment against that clearing account. AhlanHamad's hint: “Xero doesn't allow bank accounts in manual journals. Pick a salary clearing account — then match the bank-feed payment against it — or leave payment journals off and reconcile the bank feed against Net salaries payable.” |
Which Xero account for each payroll account
| Code | Ahlan Hamad account | Needed | Typical Xero account type |
|---|---|---|---|
| 5100 | Salaries — basic, other allowances, overtime & additions | Required | Expense |
| 5400 | Housing allowance | Required | Expense |
| 5500 | Transport allowance | Required | Expense |
| 5200 | Employer social-insurance contribution | Required | Expense |
| 5300 | End-of-service expense | Required | Expense |
| 2100 | Net salaries payable | Required | Current Liability (not Wages Payable) |
| 2200 | Social insurance payable (employee + employer) | Required | Current Liability |
| 2300 | End-of-service provision | Required | Non-current Liability |
| 1101 | Bank account salaries are paid from | Only if payment journals are on | Payment journals on: a Current Liability salary clearing account. Never a Bank account. |
| 2700 | Deductions withheld (loans, penalties, unpaid leave) | Only if used | Current Liability |
| 5810 | Bank transfer charges on salaries | Only if used | Expense |
| 5310 | DIFC DEWS employer contribution | Only if used | Expense |
| 2310 | DIFC DEWS payable | Only if used | Current Liability |
| 5900 | Foreign-exchange gain/loss on payroll (only if a run in another currency is paid at a different rate) | Only if used | Your foreign currency gains and losses account |
- Costs go to Expense accounts, what you owe to Current Liability accounts; the end-of-service provision is the one Non-current Liability.
- Some accounts are greyed out. AhlanHamad says why: “Some accounts are greyed out: Xero refuses system accounts (such as Wages Payable, Accounts Payable and Accounts Receivable), bank accounts and accounts without a code in manual journals. Pick an ordinary liability or clearing account that has a code.” Each carries a tag such as “System account — not allowed in journals”, “Bank account — not allowed in journals” or “No account code — add one first”.
- Added an account in Xero after loading? Click Reload accounts to see it.
End-of-service is not on the payroll journal. It is its own journal each month (5300 End-of-service expense / 2300 End-of-service provision).
6. What gets posted, and when
| When this happens in AhlanHamad | Xero receives | Dated |
|---|---|---|
| A payroll run is finalized (Finalize) | Payroll accrual: salaries and allowances, employer social insurance and the payables they create (debits 5100–5500, credits 2100, 2200 and, if used, 2700) | The last day of the payroll month |
| The run is paid (Mark as Paid, or CEO Sign-off & Pay) | Salary payment: debit 2100 Net salaries payable, credit 1101 — only with Post salary payment journals switched on (off by default; section 5). Off, the line says Not needed and you reconcile the bank feed instead. | The day the run was signed off and paid |
| Bank transfer charges are recorded on a paid run | Bank charges: debit 5810, credit 1101 — only with payment journals switched on, like the salary payment | The pay day |
| A month ends | End-of-service accrual: debit 5300, credit 2300 — sent automatically on the 1st of the next month. You can also run it by hand for a finished month with Run Monthly Accrual on the Finance page. | The last day of that month |
| A run is deleted, or a posted journal is corrected | A reversal: a new manual journal with the same lines, debit and credit swapped. Xero does not link the two; the reversal's narration starts with “Reversal of” and the reference it reverses. A corrected run is then posted again as a new manual journal. | The day of the change |
- Each journal is one manual journal in Xero, saved as Posted (not a draft), with no tax and one line per account. Its Narration (called Journal title in Xero's newer screens, Xero Central) starts with the description and AhlanHamad's reference and ends with our marker in square brackets, for example
[AH1F2E3D4C5B6A]. - We never edit or delete a journal in Xero. Corrections are always new journals: the reversal first, then the corrected run as a new journal.
- Each journal is sent once. If a send is cut off halfway, the next try looks the journal up by its marker instead of creating a second one.
- Amounts are in your Xero base currency. A run in another currency is held unless you switch on Post runs in other currencies; then it is converted at AhlanHamad's daily exchange rate, and the rate is written on the journal.
- Runs finalized or paid before you saved the mapping are not sent on their own. Open each run and press Send this run's journals. The mapping card lists them under “Earlier runs not sent to Xero yet”.
- End-of-service months booked before you connected are listed on the mapping card. Press Send them, check the list of months and amounts, and confirm. They go oldest first, each dated at its own month end.
Every journal's description starts with what it is and AhlanHamad's own reference for it: PAY-KW-2026-10 for the October 2026 Kuwait payroll accrual, PAY-KW-2026-10-PMT for its salary payment, PAY-KW-2026-10-FEES for its bank charges, IND-KW-2026-10 for that month's end-of-service accrual (the country code is the run's own). A reversal's description starts with “Reversal of” and the reference it reverses. Each journal also carries a marker: AH followed by 12 letters and digits.
7. Check your first payroll in Xero
- In AhlanHamad, open the payroll run. The Xero journals card lists each journal (Payroll accrual, End-of-service accrual, …) with its status. Posted means Xero has it; the card shows Xero's own id for it (a long code).
- In Xero, go to Accounting → Manual journals and open the Posted tab (Xero Central).
- Find the journal by its date (the last day of the payroll month for the accrual) and its narration or title, which starts with what it is and the reference, for example
Payroll journal entry for 2026-10 — KW…PAY-KW-2026-10, and ends with[AH…]. - Open it and check: the date, the status Posted, one line per mapped account, and totals that match the payroll run in AhlanHamad (to 2 decimals).
- When the salary payment reaches your bank feed, reconcile it as described in section 5.
Statuses on the run card: Queued and Sending (on its way), Waiting (another journal must reach Xero first), Retrying (Xero or the network was busy; we try again automatically), Posted, On hold (needs you; the reason is shown), Failed (Xero refused it; the reason is shown), Not needed (nothing to send; the reason is shown).
8. Troubleshooting
Company admins who can manage settings, and finance managers, also get an in-app notice and an email when Xero journals are held or fail: one per problem, a reminder after three days, and a short note when it clears. No amounts, names or Xero errors are put in the email; open the payroll run to see the reason.
When connecting (Connection tab and the return page)
| What you see | What to do |
|---|---|
| Enter your app's Client ID and Client Secret to connect. | Paste both values from your app (own-app connection only), then click Connect. |
| Enter both the Client ID and the Client Secret to replace the saved credentials. | You started replacing the saved credentials: fill in both fields, or click Keep saved credentials. |
| Connecting isn't available yet: this workspace's app address isn't configured. Contact support and we'll set it up. | Contact us. Nothing on your side is wrong. |
| Couldn't connect Xero — with “No authorization code was returned. The connection was cancelled or the link is invalid.” | You cancelled or declined on the Xero screen, or the link was opened twice. Start again from the Connection tab. |
| You were signed out before the connection finished. Sign in again, then reconnect from the integration settings. | Sign in to AhlanHamad, then click Connect again. Use the same browser for the whole flow. |
| This connection link is invalid, expired or already used. Start the connection again from the integration's settings page. | Each connect link works once and for a short time. Click Connect again on the Connection tab. |
| Token exchange failed: … | Xero refused to hand over the connection: usually the Client Secret is wrong, or the redirect URI on your app does not match exactly. Check both (own-app connection), then connect again. |
| No stored Xero credentials for this company. Run Connect first. | Your own app's keys were not saved. Open the Connection tab, paste the Client ID and Client Secret again, and click Connect to Xero. |
| Xero shows an error instead of the sign-in, mentioning the redirect URI (“Invalid redirect_uri”) | The redirect URI on your Xero app does not match. On the app's Configuration page, add https://ahlanhamad.com/auth/xero/callback exactly as written, save, then connect again. |
| Could not tell which Xero organisation was connected. Connect again and approve exactly one organisation. | In Xero's organisation select window you chose more than one organisation, or none. Connect again and choose only the organisation you keep payroll in. |
| Xero needs to be reconnected — with “Xero no longer accepts the saved connection: access was revoked or has expired. Journals are held, not lost. Connect again below and sign in, and the held journals are sent automatically.” | Click Reconnect and sign in again. Held journals are sent by themselves once you are back. |
When loading your accounts (Field Mapping tab)
| What you see | What to do |
|---|---|
| Choose which Xero organisation payroll journals go to. | Pick the organisation in Choose the organisation that appears below the message. |
| Could not list your Xero organisations (…). | Xero didn't answer. Try again in a minute; if it keeps happening, reconnect Xero. |
| Xero no longer accepts this connection (refresh …). Reconnect Xero. | Click Reconnect on the Connection tab and sign in to Xero again. |
| The connected company changed, so the old mapping was cleared. Map the accounts again. | You connected or chose a different organisation. Map the accounts again and save. |
On the payroll run: On hold
A held journal is waiting, not lost. Fix the reason and it goes, either by itself or when you press Retry on the run card.
| What you see | What to do |
|---|---|
| Map these accounts first: 5400, 5500. | Map the listed account codes on the Field Mapping tab and click Save mapping, then Retry. |
| Load your accounts and save the mapping on the integration page first. | On the Field Mapping tab, click Load my accounts (choose the organisation if asked), save the mapping, then Retry. |
| … mapped to an account that can't be used in a journal (Accounts Payable or Receivable, a system or bank account, or an account with no code). Pick another account on the integration page. | In Xero terms: a system account (such as Wages Payable), a bank account, an account without a code, or Accounts Payable / Receivable. Map those codes to an ordinary Current Liability account with a code (section 3), save, then Retry. |
| This run's currency differs from your books. Allow other-currency posting to send it. | Switch on Post runs in other currencies on the Field Mapping tab, then Retry. Or keep that run out of Xero. |
| The connection needs to be renewed. Reconnect and try again. | Xero stopped accepting the connection: the organisation was disconnected from AhlanHamad in Xero, the user who approved it lost access, or the access expired. Click Reconnect on the Connection tab and sign in again, choosing the same organisation. Journals held for this reason are sent automatically once you reconnect. |
| Not connected, or posting is switched off. | Connect Xero again on the Connection tab. Held journals are sent automatically once you reconnect. If Xero is connected and you still see this, ask us: posting may have been switched off for your company. |
On the payroll run: Failed
These come back from Xero, in English, with Xero's own words added after ours. Fix the cause in Xero or in the mapping, then press Retry. A retry never creates a second journal.
| What you see | What to do |
|---|---|
| Xero rejected the journal (400). followed by Xero's own message | Read Xero's message after ours. A common one: the date is before a lock date (Accounting → Accounting settings → Financial settings → Lock Dates, Xero Central). Ask your adviser to move the lock date, or reverse and correct the run in AhlanHamad. |
| Xero could not find the company or an account this journal points at (404). Check the account mapping belongs to the connected company. | A mapped account was deleted or archived in Xero. Click Reload accounts, fix the mapping, save, then Retry. |
| This run's payroll accrual journal did not reach Xero. Retry the accrual first, then retry this payment, so it clears exactly the salaries payable the accrual booked. | Retry the Payroll accrual line first, then the Salary payment line. |
| No exchange rate from … to … is available. | Try again later, or contact us. |
| … — gave up after 6 attempts. | Xero or the network kept failing. Check Xero opens normally, then press Retry. |
On the payroll run: Not needed
| What you see | What it means |
|---|---|
| Salary payment and bank-charge journals are off for Xero: Xero doesn't allow bank accounts in manual journals. Reconcile the bank-feed payment against Net salaries payable, or switch payment journals on and map a salary clearing account. | Salary payment journals are off (the default). Nothing is wrong: reconcile the bank-feed payment against Net salaries payable, or switch them on (section 5). |
| Reversed in Ahlan Hamad before it reached Xero; the pair nets to zero. | Nothing to do: the journal and its reversal cancel out, so neither is sent to Xero. |
| Reverses an entry that never reached Xero, so there is nothing to reverse there. | Nothing to do. |
Two accounting systems
If the Xero page or the payroll run says “Payroll is being posted to …” with more than one system, every run is booked in each of them. If you keep your books only in Xero, disconnect the others so payroll costs aren't counted twice.
9. Disconnecting
- In AhlanHamad, go to Integrations → Xero → Connection and click the blue Disconnect button (Xero's own button). AhlanHamad deletes the stored connection and also removes the connection in Xero.
- If you won't use your Xero app again, you can delete it under My Apps on developer.xero.com too.
- Journals already in Xero stay there. We never delete or change them.
- While Xero is disconnected, new payroll journals are not sent. The run card says “Xero is not connected, so new journals are not being sent.”
- If you connect again later, open each payroll run from that time and press Send this run's journals, and send any end-of-service months listed on the mapping card.
Xero sources used in this guide
- Xero Developer: getting started, app plans, the OAuth 2.0 auth flow, scopes.
- Xero Central: manual journals, changes to manual journals, lock dates, reconciling your bank account.
- Xero is a trademark of Xero Limited. AhlanHamad is not affiliated with Xero.