Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Xero Laravel Package

supplycart/xero

A Laravel integration for the Xero accounting API by Supplycart, providing a simple way to connect your application to Xero for syncing invoices, contacts, payments, and other accounting data through an expressive, framework-friendly interface.

View on GitHub
Deep Wiki
Context7

Getting Started

This package manages Laravel-side "connections" that hold OAuth credentials and refresh tokens on your behalf. The 0.3.23 release is a small but behaviorally meaningful patch: when a token refresh fails, the connection's enabled status is now reset, so the connection stops being treated as usable instead of silently continuing with a stale/expired token.

Minimal steps to get productive:

  1. Read the connection model/migration first. Look for the table backing connections and confirm the enabled column (and any last_refreshed_at/error columns). This is the state the release note changes — everything else in the package orbits it.
  2. Trace the refresh path. Find the service/job that calls the refresh endpoint and the exception handling around it. 0.3.23 means failures now write enabled = false (or equivalent) before rethrowing/logging. Confirm whether the exception still propagates or is swallowed.
  3. First use case: wire up one connection end-to-end — authorize, store tokens, run a scheduled job that uses the connection, then deliberately corrupt the refresh token and observe the connection flip to disabled. That single loop teaches you the package's whole failure model.
  4. Check your scheduler. If you iterate connections in a scheduled command, filter on enabled before attempting work; after 0.3.23 that filter becomes load-bearing rather than cosmetic.

Implementation Patterns

Gate work on enabled, not on token presence. The pre-0.3.23 pattern of "try the call, catch the 401, move on" now produces different state than it used to. Prefer:

Connection::query()->where('enabled', true)->each(fn ($c) => $c->refreshIfNeeded());

so refresh failures are handled once, at the boundary, rather than inside every consumer.

Refresh-then-use, with a single retry. Wrap outbound API calls so a refresh failure disables the connection and does not get retried in a loop. The reset is a signal, not a transient error — retrying an already-disabled connection wastes quota and can trigger provider lockouts.

Re-enable only through re-authorization. Build a "reconnect" flow (redirect to the provider's consent screen) and, on success, explicitly set enabled = true. Treat enabled as user-visible: surface disabled connections in your settings UI with a "Reconnect" button and a reason string if the package stores one.

Isolate connection health from feature code. A small ConnectionHealth service that returns usable / needs_reauth / disabled keeps the enabled flag out of controllers and jobs, and gives you one place to change when the package's semantics shift again (they just did).

Test with a fake token endpoint. Use Http::fake() to return a 400 invalid_grant for the refresh call and assert two things: the connection is now disabled, and your job recorded a skip rather than a hard failure. This is the exact regression surface of 0.3.23.

Multi-tenant care. If connections are per-user or per-team, make sure the disable happens on the specific connection row, not globally, and that a tenant's disabled connection doesn't silently drop them from a sync fan-out — emit an event or notification so it's visible.

Gotchas and Tips

  • The reset is sticky. Once disabled, nothing in normal operation re-enables the connection. If your app assumes connections self-heal after a provider outage, it now won't — you need an explicit re-auth path or an admin action.
  • Silent skips look like data loss. After upgrading, jobs that filter on enabled will just... do nothing. Add logging/alerting when a connection is skipped so a wave of disabled connections doesn't masquerade as "no new records."
  • Distinguish revocation from transient failure. A 5xx from the token endpoint is not a revoked grant. If the package disables on any refresh failure, add your own guard (or check the package's exception types) so a provider blip doesn't force every user to reconnect.
  • Check what "reset" means in your version. It may set enabled = false, or clear a previously-set enabled = true default. Read the diff against your migration; if the column is nullable, false vs null may behave differently in your scopes.
  • Queued jobs hold stale models. A connection hydrated before the refresh failure will still report enabled = true in memory. Re-query, or check wasChanged(), before acting.
  • Backfill your observability. Log refresh failures with connection ID and provider error code, and add a metric for "connections disabled in the last 24h" — that graph is the fastest way to spot a credential-wide breakage.
  • Extension point to watch: if the package exposes events around refresh (e.g. a TokenRefreshFailed event), listen to it to notify users proactively. That's a better hook than overriding the connection class.
  • Pin your version carefully. 0.3.23 changes runtime state on failure. If you deploy in a rolling fashion, older workers will leave connections enabled while newer ones disable them — expect brief inconsistency, and don't run a "repair connections" script mid-deploy.
  • Upgrade test: snapshot a connection with a valid-looking but revoked refresh token, run your scheduled sync, and assert the connection is disabled and the user is notified exactly once.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package