| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
Discuss (mail)
|
| Lines of code | 2002 |
| Technical Name |
eh_hero_base |
| License | OPL-1 |
| Website | https://www.erpheritage.com.au/ |
| Versions | 16.0 17.0 18.0 19.0 |
Employment Hero Connector
The transport and configuration core every Employment Hero module installs on: connections, dual auth, a data driven endpoint registry, encrypted OAuth2 and a redacting API audit log.
Why this module
Employment Hero Connector
Every endpoint is a record
API paths live in a registry, not in Python. Add a new read endpoint, set its pagination style and rate group from the user interface, and it is callable immediately with no module upgrade. The base catalogue ships fifteen read endpoints across the HR and Payroll product APIs.
One audited client for every call
A single transport carries every request with client side rate limiting, exponential backoff with jitter, retry of transient failures and 429 only, honored and clamped Retry-After, per request timing, and a redacting log hook. Credentials never touch the calling code.
Encrypted at rest, no plaintext fallback
OAuth tokens are sealed with Fernet keyed from an environment variable or a generated system parameter, tagged with a key fingerprint, and rotatable. There is deliberately no plaintext downgrade: if encryption is unavailable, storing a token is a hard error, not a silent leak.
Day in the life
From credentials to a working, audited link
An administrator creates a connection, picks the HR platform, and clicks Connect. The browser is sent to Employment Hero through an authorization code flow protected by PKCE and a CSRF state token. On return, the code is exchanged once (a replayed callback finds nothing to redeem) and the access and refresh tokens are encrypted into the database. From then on, sync jobs in the domain modules call connection.call or connection.paginate by endpoint code. The connection owns auth, rate limiting and logging: it lazily refreshes the access token under a single flight lock so two workers never race, meters requests against one cluster wide budget, retries transient failures with backoff, and writes a redacted row to the audit log for every call. A scheduled job refreshes tokens nearing expiry before a job ever sees an expired one, and a weekly job purges audit rows past the retention horizon.
Edge cases
The cases most modules quietly ignore.
In the shipped code today, each one a place where a cheaper module silently does the wrong thing.
An idempotency key is forwarded as an Idempotency-Key header and reused across every attempt of a call, so a retried create is deduplicated by the vendor instead of writing a second record.
Only 5xx, 429 and network timeouts are retried, with exponential backoff plus jitter. A 4xx such as 401 or 422 raises immediately rather than hammering the API with a request that will never succeed.
Refresh runs single flight: the token row is locked FOR UPDATE in an autonomous transaction and the expiry rechecked after the lock, so two workers cannot both POST the same rotating refresh token and leave a dead one behind.
The in flight authorization is claimed by a single DELETE RETURNING keyed on state, so a replayed or concurrent callback with the same state finds no row and cannot redeem the code a second time.
A database backed token bucket meters one shared budget per rate group against the database clock, so N workers draw from one cap. When the budget is exhausted it refuses to send rather than adding to the very 429 storm it exists to prevent.
A server supplied Retry-After is honored but clamped to five minutes, so a buggy or hostile header cannot park a worker for hours.
OData, page index and cursor paging each stop on a short or empty page, and a configurable page cap logs a loud warning when hit so truncated results are never returned silently as complete.
Each encrypted value carries an eight character key fingerprint. Decrypting under a different key fails with an actionable error naming the expected key rather than handing a corrupt string to the API as a live credential.
The audit log redacts sensitive keys, personal and financial identifiers (tax file, bank, super, national insurance and similar) by substring, and bearer or basic tokens inside raw string bodies, then truncates each body.
A 2xx body that parses to plain text (a maintenance or proxy page) is rejected during pagination instead of being yielded as a record.
What is inside
Built to do the job, end to end.
- Connections. One record per link to an Employment Hero product API, scoped per company, with a default per product that sync jobs fall back to. A Test Connection button probes a per product endpoint and records the result. Three products are supported: the HR platform over OAuth2 Bearer, Payroll over KeyPay API key Basic auth, and ATS over a static header token.
- Endpoint registry. A data driven catalogue where every API path, HTTP method, pagination style and rate group is a record. The base module ships fifteen read endpoints across HR and Payroll. Integrators add their own from the user interface with no Python and no upgrade.
- Resilient transport. A single client with client side rate limiting, exponential backoff with jitter, retry of transient failures and 429 only, honored and clamped Retry-After, configurable timeout and retry count, per request timing, and an Idempotency-Key header for safe retried writes.
- Pagination engine. OData skip and top, one based page index with configurable page and size parameters, and cursor following, all reading either a bare list or a wrapped envelope through dotted item and next paths, with a page cap that warns on truncation.
- OAuth2 with PKCE. Authorization code flow with an S256 PKCE challenge and a CSRF state token, single flight refresh under a row lock in an autonomous transaction, a scheduled job that refreshes tokens nearing expiry, and per attempt flow rows so concurrent authorizations do not collide.
- Encryption and key rotation. Fernet encryption at rest for access and refresh tokens, keyed from an environment variable or a generated system parameter, tagged with a key fingerprint, with a one call key rotation routine that re-encrypts every token atomically inside a savepoint.
- Cross worker rate limiting. A database backed token bucket meters one shared budget per rate group across all workers, the default for multi worker deployments, with a lighter in process bucket available for single worker hosts via a system parameter.
- Audit and retention. A redacting API call log that strips credentials and personal identifiers, truncates bodies, and is purged on a weekly cron at a configurable retention horizon, plus a separate append only PII access log for deliberate reveals of sensitive fields.
Honest about the edges
What this does not do, so nothing surprises you.
- This is a developer and integrator foundation. On its own it does not sync employees, leave, attendance or payroll into Odoo. The domain modules do that on top of the services exposed here.
- The shipped endpoint catalogue and the data flow are read and pull only (GET endpoints). The client supports POST, PUT and DELETE and forwards idempotency keys, but no write endpoints to Employment Hero are shipped in this base module.
- There is no webhook receiver, no real time push and no two way or conflict resolution in this module. Data movement is performed by the domain modules as scheduled or on demand pulls.
- OAuth2 connections require client credentials issued by Employment Hero for your integration, and at rest token encryption requires the Python cryptography package. Without it, storing a token is a hard error by design.
- Rate limits and pagination behaviour follow what the Employment Hero APIs document; the connector enforces a client side budget but cannot raise a server side cap.
- English only. The connector does not localize Employment Hero data; country specific fields are handled by the country modules in the suite.
Employment Hero connector Odoo, Employment Hero integration, KeyPay API Odoo, Employment Hero OAuth2, Odoo HR API connector, data driven endpoint registry, token bucket rate limiting Odoo, exponential backoff retry, Fernet token encryption Odoo, PKCE authorization code flow, encrypted OAuth tokens at rest, API audit log Odoo, multi company HR integration, Odoo 19 Employment Hero, payroll API connector
Need this fitted to the way you work?
ERP Heritage delivers end to end Odoo work: Odoo Implementation, Customization and Development, Integration, Migration, Consultation, Support and Training. We help teams put this module into production, shape it to their process, and keep it running.
We work with businesses across Australia (Melbourne, Sydney, Brisbane, Perth, Adelaide, Canberra) and the Middle East (Dubai, Abu Dhabi, Riyadh, Jeddah, Doha, Kuwait City, Muscat). Start a conversation at erpheritage.com.au or email info@erpheritage.com.au.
Languages
Available in 19 languages
The interface ships translated out of the box. Switch language in Odoo and the fields, menus, and messages follow.
Modules teams pair with this one.
Premium ERP Heritage modules that extend the same stack, each built to the same engineering bar.
Bring Employment Hero onboarding workflows, employee goals and contractor flags into Odoo Community as real recor...
End to end French B2B and B2G electronic invoicing for the DGFiP reform, generating Factur-X PDF/A-3 with embedde...
Accept ZainCash wallet payments in Iraq at your Odoo checkout, on the ZainCash Payment Gateway v2 with OAuth2, re...
Sync Employment Hero ATS recruitment job openings into the standard Odoo Recruitment app, mapping each opening on...
The Singapore country pack for the ERP Heritage Employment Hero integration
| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
Discuss (mail)
|
| Lines of code | 2002 |
| Technical Name |
eh_hero_base |
| License | OPL-1 |
| Website | https://www.erpheritage.com.au/ |
Odoo Proprietary License v1.0 This software and associated files (the "Software") may only be used (executed, modified, executed after modifications) if you have purchased a valid license from the authors, typically via Odoo Apps, or if you have received a written agreement from the authors of the Software (see the COPYRIGHT file). You may develop Odoo modules that use the Software as a library (typically by depending on it, importing it and using its resources), but without copying any source code or material from the Software. You may distribute those modules under the license of your choice, provided that this license is compatible with the terms of the Odoo Proprietary License (For example: LGPL, MIT, or proprietary licenses similar to this one). It is forbidden to publish, distribute, sublicense, or sell copies of the Software or modified copies of the Software. The above copyright notice and this permission notice must be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Please log in to comment on this module