innobrain/laravel-onoffice-adapter
Laravel adapter for the onOffice API that makes it easy to connect your PHP application to onOffice CRM data, including real estate listings, contacts, and addresses, through a clean, framework-friendly integration layer.
Architecture fit
innobraingmbh/laravel-onoffice-adapter remains a thin, framework-native integration layer: a Laravel service provider, a publishable config file, and a client/facade abstraction over the onOffice API (the German real-estate CRM/ERP used by property agencies and portals). Architecturally it slots in where you would otherwise hand-roll an HTTP client against onOffice: as an outbound adapter at the edge of a domain boundary. That is the correct shape for this kind of dependency. Consume it behind your own repository or gateway interface, not directly from controllers or models, so onOffice's module/field vocabulary (estate, address, relation, activity, and their German field names) does not leak into your domain. Fits well in a Laravel monolith or modular monolith; fits less well in a polyglot or event-driven estate where a dedicated sync service would be more appropriate.
Integration feasibility
Feasible and unchanged in character. The hard parts remain upstream, not in the package: HMAC-signed requests (token + secret + timestamp), module/action semantics (get, read, create, modify, delete), filter and listlimit paging, and per-tenant field schemas that differ between customers. Credentials are config/env-driven and belong in a secret store. A read-only proof of concept is still a few days, most of it field mapping.
Technical risk
The dominant risk is still adoption, not code quality: five stars, effectively zero external dependents, single organisational maintainer. Treat it as an internal dependency with an external name. v2.8.0 is a small additive feature (estateIds() to read activities across several estates in one call) with no breaking changes — the release cadence (v2.7.1 → v2.8.0, one focused PR) is a mildly positive signal against abandonment but does not change the risk profile. Remaining risks: thin coverage of retries, throttling, and partial batch failures may be pushed onto the consumer; no published supported-version matrix; possible coupling to a specific onOffice API version underneath.
Notably, v2.8.0 partially answers the earlier module-coverage question: the package supports more than estate/address/relation, and it is growing convenience methods per onOffice module rather than exposing only a generic pass-through. That convenience is welcome, but it also means the API surface is shaped by the vendor's own client needs — verify method semantics against onOffice docs rather than assuming completeness.
Key questions
null/false? Is there an error-code taxonomy?listlimit/offset, and result-count handling out of the box, or must callers loop?Http::fake() works in tests) or Guzzle directly?estate, address, relation, activity, others)? Is raw/unsupported action pass-through available for gaps?estateIds() accept an array of IDs only, how does it map to onOffice's filter syntax, and what is the result shape — flat list, or grouped/attributed per estate? How does it interact with listlimit and result counts when the combined activity set exceeds one page, and is truncation detectable?Stack fit
Good fit for a Laravel-first team already integrating a real-estate CRM. The package is small and replaceable — its main virtue. Wrap it in an application-level OnOfficeGateway interface with a concrete adapter so upgrading, patching, or replacing it is a one-file change plus tests. Register the facade only inside the infrastructure layer. Where the new batch method is used, keep the batch boundary inside the adapter and expose a domain-shaped result to callers.
Migration path
If you already have a bespoke onOffice client, migrate incrementally: stand up the package behind your existing interface, run both implementations in shadow mode on read paths, diff outputs, then cut over reads before writes. Greenfield: reads first, hold writes until idempotency keys and reconciliation tooling exist. For activity ingestion specifically, v2.8.0 lets you replace a per-estate loop with a single batched read — a good first candidate for an A/B cutover, since it is read-only and easily diffed against the existing per-estate results.
Compatibility
Pin to an exact minor version and lock. With near-zero external dependents, version constraints are unlikely to have been battle-tested against your Laravel version — verify the illuminate/* constraints resolve before committing. v2.8.0 is additive and non-breaking, so it is a low-risk bump from v2.7.x, but still read the diff (one PR is easy to review) and confirm config file shape is unchanged. Watch for config key renames in future releases — a common breaking change in packages of this size.
Sequencing
read call succeeds end-to-end.estate and address; internal models and a sync cursor.estateIds() batching once result shape and pagination semantics are confirmed against a realistic multi-estate tenant.create/modify) with idempotency and a reconciliation job.Maintenance
Low code volume, non-zero ongoing attention: onOffice API changes, field-schema drift between tenants, and PHP/Laravel upgrades. Budget a small recurring allowance (a few days per quarter) rather than zero. v2.8.0 is evidence the maintainer is active and shipping reviewed, narrowly scoped PRs — treat that as encouraging, not as a guarantee. Mitigate bus factor by forking to a private VCS mirror or vendoring; MIT makes this cheap. Plan the fork as the explicit fallback.
Support
No commercial support and no meaningful community. Support is self-support: source reading plus onOffice's own documentation (largely German). One PR per release means changelogs are readable — low effort to review before upgrading. Internal runbooks for credential rotation and sync failures remain mandatory.
Scaling
onOffice is the bottleneck, not the package. Tenant volumes are usually low, but upstream throttling and per-tenant limits mean sync must be queued, chunked, and rate-limited on your side. Do not call onOffice synchronously from user requests; materialise into your own database. Horizontal worker scaling needs shared rate-limit coordination (Redis-backed limiter) across pods. The new batched activity read measurably improves the call budget for activity sync — fewer round trips, less throttle pressure — but only if pagination across the combined estate set is handled correctly; a batched call that silently truncates is worse than the loop it replaced.
Failure modes
create produce duplicates.estateIds() call) — needs per-record and per-estate result tracking, not all-or-nothing assumptions.Ramp-up
For a mid-level Laravel developer: half a day to install, configure, and make a first call; two to three days to be productive with onOffice's module/field semantics; one to two weeks to own a reliable two-way sync. The learning curve is domain (German real-estate data model), not framework. Recommendation is unchanged by v2.8.0: adopt with eyes open, wrap defensively, pin hard, and treat the package as a small replaceable component — not a strategic foundation.
How can I help you explore Laravel packages today?