尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
Assist with mapping Xero expenses to clients.
翻譯準備中
正在載入完整 README。
檢視完整 README ↗A Laravel app that connects to Xero so your team can link organisations (tenants), sync bank spend and accounts-payable lines, and review expenses in the browser—with Sign in with Xero and organisation-scoped roles.
Stack: Laravel 13, PHP 8.3, Laravel Breeze (Livewire + Volt), Tailwind CSS, Vite.
SyncXeroOrganisationJob), with authorization re-checked when the job runs.composer install
npm install
cp .env.example .env
php artisan key:generate
# Create database/database.sqlite if using SQLite, then:
php artisan migrate
npm run build
For a scripted first-time setup (deps, .env, key, migrate, build): composer run setup.
Set DB_* in .env. SQLite is the default; create database/database.sqlite if it does not exist.
In the Xero developer portal, register one redirect URL used for both OpenID sign-in and accounting OAuth. It must match .env exactly (scheme, host, path):
${APP_URL}/xero/callback — same value as XERO_REDIRECT_URI (see .env.example).| Variable | Purpose |
|---|---|
XERO_CLIENT_ID / XERO_CLIENT_SECRET | Shared by SSO and Connect Xero |
XERO_REDIRECT_URI | Callback for both flows |
XERO_ALLOW_OPEN_SIGNUP | Default false: blocks self-serve sign-up unless the DB has no users yet or the user has a valid invitation. Set true only if you want a public, self-serve app. |
XERO_SSO_SCOPES | OpenID (default openid profile email) |
XERO_SCOPES | Accounting API scopes for sync (offline_access, transactions, contacts, settings, etc.) |
Invitations are sent from the dashboard. Configure MAIL_* in .env. For local dev, MAIL_MAILER=log writes messages to the log.
| Command | Use |
|---|---|
composer run dev | HTTP server, queue worker, log tail, and Vite (recommended) |
php artisan serve | App only |
npm run dev | Vite watch mode |
Use QUEUE_CONNECTION=database (default in .env.example) so sync jobs can run; composer run dev includes queue:listen.
/ or go to /login and Sign in with Xero./orgs/{public_id}/expenses). Route keys use an opaque public_id (ULID), not the internal numeric id.SyncXeroOrganisationJob always includes an initiating user id; handle() verifies that user is still a member of the organisation before calling Xero.php artisan xero:sync {public_id-or-slug} — pass --acting-user={id} with a user who belongs to that org. Optional: --from=YYYY-MM-DD, --to=YYYY-MM-DD, --queue to dispatch instead of running inline.APP_DEBUG=false, APP_URL to your real HTTPS origin, and SESSION_SECURE_COOKIE=true behind TLS.XERO_ALLOW_OPEN_SIGNUP=false unless you intentionally allow anyone to create an account via Xero.CACHE_STORE=database or Redis) for every web server and queue worker. Xero token refreshes and the one-Xero-job-per-organisation lock depend on it.retry_after above the sync job timeout (900s). The default is 960s; lowering it lets a long sync be picked up by a second worker.php artisan queue:restart after each deploy so workers load the new code.Set SEED_TEST_USER=true in .env, then php artisan db:seed. This creates [email protected] (password password) for local/testing only. Normal browser sign-in still uses Xero unless you authenticate in tests with actingAs.
composer run test
Laravel exposes GET /up for load balancers and uptime monitors.
This project is open source under the MIT license. Laravel is MIT licensed as well.