{"_id":"@atoapayments/atoa-cli","_rev":"4-394466a2c01f0efd2c317a1860be9c6d","name":"@atoapayments/atoa-cli","dist-tags":{"latest":"0.3.0"},"versions":{"0.1.0":{"name":"@atoapayments/atoa-cli","version":"0.1.0","license":"MIT","_id":"@atoapayments/atoa-cli@0.1.0","maintainers":[{"name":"shariqueatoa","email":"sharique@paywithatoa.co.uk"},{"name":"rvkrish","email":"vamsi@paywithatoa.co.uk"},{"name":"tushargupta224","email":"tushar@paywithatoa.co.uk"},{"name":"atoalicence","email":"licence@paywithatoa.co.uk"},{"name":"anandtanu","email":"tanushree@paywithatoa.co.uk"}],"homepage":"https://github.com/ATOAPaymentsLimited/atoa-cli#readme","bugs":{"url":"https://github.com/ATOAPaymentsLimited/atoa-cli/issues"},"bin":{"atoa":"bin/atoa.js"},"pkg":{"assets":["node_modules/@napi-rs/keyring-*/**/*.node"],"scripts":"dist/**/*.js"},"dist":{"shasum":"a1e73ab869171569eafac7a4152f63d0e301bbc2","tarball":"https://registry.npmjs.org/@atoapayments/atoa-cli/-/atoa-cli-0.1.0.tgz","fileCount":10,"integrity":"sha512-fWn0otvk7Sz2YWBPGVaDNtkR/kb0l938q5NDpGJYOf5c4WOIxKf2zhKETz3DIhAXGIFEcl2lMkpmsa8nIPcoHQ==","signatures":[{"sig":"MEUCIAZQrfxCEQZmchgdzLK2Q/pMQa3TTItX3Yahy197WblPAiEAga15I/btuIqdmD+ED2kD8znd5GxOL30+Wy7lQ70qn2U=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":782287},"main":"./dist/index.js","engines":{"node":">=20"},"gitHead":"dac8dd2cfe7677bc65ebde53487d6b4aa6bf6d4e","private":false,"scripts":{"dev":"tsx src/cli.ts","lint":"eslint \"src/**/*.ts\" \"test/**/*.ts\"","test":"vitest run --coverage","build":"tsup","clean":"rimraf dist","lint:fix":"eslint --fix \"src/**/*.ts\" \"test/**/*.ts\"","prettier":"prettier \"src/**/*.ts\" \"test/**/*.ts\" --write","test:e2e":"cross-env ATOA_CLI_E2E=1 vitest run test/integration","test:unit":"vitest run test/lib test/commands","build:release":"tsup","prepublishOnly":"npm run lint && npm run test:unit && npm run build","prettier:check":"prettier \"src/**/*.ts\" \"test/**/*.ts\" --check"},"_npmUser":{"name":"atoalicence","email":"licence@paywithatoa.co.uk"},"repository":{"url":"git+https://github.com/ATOAPaymentsLimited/atoa-cli.git","type":"git"},"_npmVersion":"10.8.2","description":"First-party CLI for the Atoa payment API.","directories":{},"_nodeVersion":"20.20.2","dependencies":{"citty":"^0.2.2","undici":"^6.19.0","js-yaml":"^4.1.0","cli-table3":"^0.6.5","@napi-rs/keyring":"^1.1.4","@inquirer/prompts":"^8.4.3"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.3.0","tsx":"^4.7.0","tsup":"^8.0.0","eslint":"^8.57.0","rimraf":"^5.0.5","vitest":"^4.1.6","prettier":"^3.4.0","cross-env":"^7.0.3","typescript":"^5.3.3","@types/node":"^20.10.0","@types/js-yaml":"^4.0.9","@vitest/coverage-v8":"^4.1.6","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.2.1","@typescript-eslint/parser":"^7.18.0","@typescript-eslint/eslint-plugin":"^7.18.0"},"_npmOperationalInternal":{"tmp":"tmp/atoa-cli_0.1.0_1780393871662_0.389956168234449","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@atoapayments/atoa-cli","version":"0.1.1","keywords":["atoa","atoa pay","cli","agentic payments"],"license":"MIT","_id":"@atoapayments/atoa-cli@0.1.1","maintainers":[{"name":"shariqueatoa","email":"sharique@paywithatoa.co.uk"},{"name":"rvkrish","email":"vamsi@paywithatoa.co.uk"},{"name":"tushargupta224","email":"tushar@paywithatoa.co.uk"},{"name":"atoalicence","email":"licence@paywithatoa.co.uk"},{"name":"anandtanu","email":"tanushree@paywithatoa.co.uk"}],"homepage":"https://github.com/ATOAPaymentsLimited/Atoa-CLI#readme","bugs":{"url":"https://github.com/ATOAPaymentsLimited/Atoa-CLI/issues","email":"vamsi@paywithatoa.co.uk"},"bin":{"atoa":"bin/atoa.js"},"pkg":{"assets":["node_modules/@napi-rs/keyring-*/**/*.node"],"scripts":"dist/**/*.js"},"dist":{"shasum":"800b0822ecae06a6004bc1c5693bf76d8cf336c4","tarball":"https://registry.npmjs.org/@atoapayments/atoa-cli/-/atoa-cli-0.1.1.tgz","fileCount":10,"integrity":"sha512-4cRJywSjv5AEycTZ7Tm8MGuP1v1e7Z1bVjh7JqF+Gh/0dx+U6Z3u2eP7tUoefr4PgiXgmFwXrfUALTculqdyVw==","signatures":[{"sig":"MEUCIG1sRhViNQZ34WYuB+zKgYAomaQkWIABEYvMS0Ojl4yaAiEAtL/7M2PU7kf2jxD5W2vMwojJVbjiz97eSr33AlfLsQk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":783977},"main":"./dist/index.js","engines":{"node":">=20"},"gitHead":"fe36cad74e4d2935cdba9ccce1f4af42dad4a175","private":false,"scripts":{"dev":"tsx src/cli.ts","lint":"eslint \"src/**/*.ts\" \"test/**/*.ts\"","test":"vitest run --coverage","build":"tsup","clean":"rimraf dist","lint:fix":"eslint --fix \"src/**/*.ts\" \"test/**/*.ts\"","prettier":"prettier \"src/**/*.ts\" \"test/**/*.ts\" --write","test:e2e":"cross-env ATOA_CLI_E2E=1 vitest run test/integration","test:unit":"vitest run test/lib test/commands","build:release":"tsup","prepublishOnly":"npm run lint && npm run test:unit && npm run build","prettier:check":"prettier \"src/**/*.ts\" \"test/**/*.ts\" --check"},"_npmUser":{"name":"atoalicence","email":"licence@paywithatoa.co.uk"},"repository":{"url":"git+https://github.com/ATOAPaymentsLimited/Atoa-CLI.git","type":"git"},"_npmVersion":"10.8.2","description":"First-party CLI for the Atoa payment API.","directories":{},"_nodeVersion":"20.20.2","dependencies":{"citty":"^0.2.2","undici":"^6.19.0","js-yaml":"^4.1.0","cli-table3":"^0.6.5","@napi-rs/keyring":"^1.1.4","@inquirer/prompts":"^8.4.3"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.3.0","tsx":"^4.7.0","tsup":"^8.0.0","eslint":"^8.57.0","rimraf":"^5.0.5","vitest":"^4.1.6","prettier":"^3.4.0","cross-env":"^7.0.3","typescript":"^5.3.3","@types/node":"^20.10.0","@types/js-yaml":"^4.0.9","@vitest/coverage-v8":"^4.1.6","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.2.1","@typescript-eslint/parser":"^7.18.0","@typescript-eslint/eslint-plugin":"^7.18.0"},"_npmOperationalInternal":{"tmp":"tmp/atoa-cli_0.1.1_1780396964507_0.37646334354360866","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@atoapayments/atoa-cli","version":"0.2.0","keywords":["atoa","atoa pay","cli","agentic payments"],"license":"MIT","_id":"@atoapayments/atoa-cli@0.2.0","maintainers":[{"name":"shariqueatoa","email":"sharique@paywithatoa.co.uk"},{"name":"rvkrish","email":"vamsi@paywithatoa.co.uk"},{"name":"tushargupta224","email":"tushar@paywithatoa.co.uk"},{"name":"atoalicence","email":"licence@paywithatoa.co.uk"},{"name":"anandtanu","email":"tanushree@paywithatoa.co.uk"}],"homepage":"https://github.com/ATOAPaymentsLimited/Atoa-CLI#readme","bugs":{"url":"https://github.com/ATOAPaymentsLimited/Atoa-CLI/issues","email":"vamsi@paywithatoa.co.uk"},"bin":{"atoa":"bin/atoa.js"},"pkg":{"scripts":"dist/**/*.js"},"dist":{"shasum":"1943ab50edda911655bd69990a1aff5c0b3d6f05","tarball":"https://registry.npmjs.org/@atoapayments/atoa-cli/-/atoa-cli-0.2.0.tgz","fileCount":10,"integrity":"sha512-yduf9CjW7NATuq2wGqb9vusBtsZqLBL/JlDDmrV3TOqMK6RDG6aFQH/K4AglJyUKuV6yfwgD7lGiqyNDWHnTQg==","signatures":[{"sig":"MEUCIHmwuoSqcp5Eri4J4220AH+yac5Nr3rJs0rKd4KCgYogAiEAjmH6kPjamQuEZAagFD4l4it5sIaqAClzAR8DFSR2rkk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2408952},"main":"./dist/index.js","engines":{"node":">=20"},"gitHead":"9f0f0f81705fc46f9fbd76b43262a87790485cd8","private":false,"scripts":{"dev":"tsx src/cli.ts","lint":"eslint \"src/**/*.ts\" \"test/**/*.ts\"","test":"vitest run --coverage","build":"npm run gen:logo && tsup","clean":"rimraf dist","gen:logo":"node scripts/gen-logo.mjs && prettier --write src/lib/atoa-logo.ts","lint:fix":"eslint --fix \"src/**/*.ts\" \"test/**/*.ts\"","prettier":"prettier \"src/**/*.ts\" \"test/**/*.ts\" --write","test:e2e":"cross-env ATOA_CLI_E2E=1 vitest run test/integration","dev:local":"cross-env ATOA_ALLOW_INSECURE=1 ATOA_BASE_URL=http://localhost:9090/server ATOA_DASHBOARD_URL=http://localhost:3000 tsx src/cli.ts","test:unit":"vitest run test/lib test/commands","build:release":"npm run gen:logo && tsup","prepublishOnly":"npm run lint && npm run test:unit && npm run build","prettier:check":"prettier \"src/**/*.ts\" \"test/**/*.ts\" --check"},"_npmUser":{"name":"atoalicence","email":"licence@paywithatoa.co.uk"},"repository":{"url":"git+https://github.com/ATOAPaymentsLimited/Atoa-CLI.git","type":"git"},"_npmVersion":"10.8.2","description":"First-party CLI for the Atoa payment API.","directories":{},"_nodeVersion":"20.20.2","dependencies":{"citty":"^0.2.2","undici":"^6.19.0","js-yaml":"^4.1.0","cli-table3":"^0.6.5","@inquirer/prompts":"^8.4.3"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.3.0","tsx":"^4.7.0","tsup":"^8.0.0","eslint":"^8.57.0","rimraf":"^5.0.5","vitest":"^4.1.6","prettier":"^3.4.0","cross-env":"^7.0.3","typescript":"^5.3.3","@types/node":"^20.10.0","@types/js-yaml":"^4.0.9","@vitest/coverage-v8":"^4.1.6","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.2.1","@typescript-eslint/parser":"^7.18.0","@typescript-eslint/eslint-plugin":"^7.18.0"},"_npmOperationalInternal":{"tmp":"tmp/atoa-cli_0.2.0_1783506628217_0.12612931912944947","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"_id":"@atoapayments/atoa-cli@0.3.0","bin":{"atoa":"bin/atoa.js"},"pkg":{"scripts":"dist/**/*.js"},"bugs":{"url":"https://github.com/ATOAPaymentsLimited/Atoa-CLI/issues","email":"vamsi@paywithatoa.co.uk"},"dist":{"shasum":"b2923ee6a22c9dfe25f46cf1b2408296849e174f","tarball":"https://registry.npmjs.org/@atoapayments/atoa-cli/-/atoa-cli-0.3.0.tgz","fileCount":10,"integrity":"sha512-aEVTBKCqtAYnDBOHs6blu47gJESKtUVSxGbvPJFe8+V/bmI3hD06piVyiWUTvqw6OKE6059QdrFKt3S/qf0wTQ==","signatures":[{"sig":"MEUCIAbS2Xw8JqBOxAfzWJ3c2dSD+6GniJ0zGI3EWr5rg4EgAiEA48hFHaivqYqZCeywxbLcEtcM1eAFU4BN5J5roY+ddSw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIEdvUuwM1YgIrtHWVCZOJ7Zuocddd7KnqOIx9fFqitwpAiBMiGZwcXQaHVf6OPjEgrYEeIRuOxZYyRUl0tVUNliaxQ=="}],"unpackedSize":3001745},"main":"./dist/index.js","name":"@atoapayments/atoa-cli","engines":{"node":">=20"},"gitHead":"2f590dec0050662cd996fc31d67408d158bf011f","license":"MIT","private":false,"scripts":{"dev":"tsx src/cli.ts","lint":"eslint \"src/**/*.ts\" \"test/**/*.ts\"","test":"vitest run --coverage","build":"npm run gen:logo && tsup","clean":"rimraf dist","gen:logo":"node scripts/gen-logo.mjs && prettier --write src/lib/atoa-logo.ts","lint:fix":"eslint --fix \"src/**/*.ts\" \"test/**/*.ts\"","prettier":"prettier \"src/**/*.ts\" \"test/**/*.ts\" --write","test:e2e":"cross-env ATOA_CLI_E2E=1 vitest run test/integration","dev:local":"cross-env ATOA_ALLOW_INSECURE=1 ATOA_BASE_URL=http://localhost:9090/server ATOA_DASHBOARD_URL=http://localhost:3000 tsx src/cli.ts","test:unit":"vitest run test/lib test/commands","build:release":"npm run gen:logo && tsup","prepublishOnly":"npm run lint && npm run test:unit && npm run build","prettier:check":"prettier \"src/**/*.ts\" \"test/**/*.ts\" --check"},"version":"0.3.0","_npmUser":{"name":"atoalicence","email":"licence@paywithatoa.co.uk"},"homepage":"https://github.com/ATOAPaymentsLimited/Atoa-CLI#readme","keywords":["atoa","atoa pay","cli","agentic payments"],"repository":{"url":"git+https://github.com/ATOAPaymentsLimited/Atoa-CLI.git","type":"git"},"_npmVersion":"10.8.2","description":"First-party CLI for the Atoa payment API.","directories":{},"maintainers":[{"name":"shariqueatoa","email":"sharique@paywithatoa.co.uk"},{"name":"rvkrish","email":"vamsi@paywithatoa.co.uk"},{"name":"tushargupta224","email":"tushar@paywithatoa.co.uk"},{"name":"atoalicence","email":"licence@paywithatoa.co.uk"},{"name":"anandtanu","email":"tanushree@paywithatoa.co.uk"}],"_nodeVersion":"20.20.2","dependencies":{"citty":"^0.2.2","undici":"^6.19.0","js-yaml":"^4.1.0","cli-table3":"^0.6.5","@inquirer/prompts":"^8.4.3"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.3.0","tsx":"^4.7.0","tsup":"^8.0.0","eslint":"^8.57.0","rimraf":"^5.0.5","vitest":"^4.1.6","prettier":"^3.4.0","cross-env":"^7.0.3","typescript":"^5.3.3","@types/node":"^20.10.0","@types/js-yaml":"^4.0.9","@vitest/coverage-v8":"^4.1.6","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.2.1","@typescript-eslint/parser":"^7.18.0","@typescript-eslint/eslint-plugin":"^7.18.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/atoa-cli_0.3.0_1788245092803_0.19839174239991264"}}},"time":{"created":"2026-06-02T09:51:11.512Z","modified":"2026-09-01T06:44:53.100Z","0.1.0":"2026-06-02T09:51:11.810Z","0.1.1":"2026-06-02T10:42:44.666Z","0.2.0":"2026-07-08T10:30:28.365Z","0.3.0":"2026-09-01T06:44:52.913Z"},"bugs":{"url":"https://github.com/ATOAPaymentsLimited/Atoa-CLI/issues","email":"vamsi@paywithatoa.co.uk"},"license":"MIT","homepage":"https://github.com/ATOAPaymentsLimited/Atoa-CLI#readme","keywords":["atoa","atoa pay","cli","agentic payments"],"repository":{"url":"git+https://github.com/ATOAPaymentsLimited/Atoa-CLI.git","type":"git"},"description":"First-party CLI for the Atoa payment API.","maintainers":[{"name":"shariqueatoa","email":"sharique@paywithatoa.co.uk"},{"name":"rvkrish","email":"vamsi@paywithatoa.co.uk"},{"name":"tushargupta224","email":"tushar@paywithatoa.co.uk"},{"name":"atoalicence","email":"licence@paywithatoa.co.uk"},{"name":"anandtanu","email":"tanushree@paywithatoa.co.uk"}],"readme":"# Atoa CLI\n\nFirst-party command-line interface for the [Atoa](https://paywithatoa.co.uk) payment API. Manage merchants, payments, refunds, webhooks, bank feeds, and payouts from your terminal — scriptable, secure, and consistent across `sandbox` and `production`.\n\n**Documentation:** [Atoa Docs](https://docs.atoa.me/cli)\n\n```bash\natoa login                                  # pair this machine with your Atoa account\natoa payments create --amount 10.05 --orderId order-001 --customerId cust_123\natoa webhooks trigger PAYMENTS_STATUS       # fire a fake event at your sandbox URL\n```\n\n---\n\n## Install\n\n```bash\nnpm install -g @atoapayments/atoa-cli\n```\n\n**Requires Node.js 20 or later** (`node --version`).\n\nVerify:\n\n```bash\natoa --version\n```\n\n### Sandbox vs production\n\nThe same binary talks to both `sandbox` and `production`. Pick which env a command targets via `--env`, or set a default per profile (`atoa profile set env=production`). Pairing a token to the wrong env surfaces as `401` on the first authenticated call — run `atoa whoami` to confirm which env you're authenticated against.\n\n---\n\n## Quick start\n\n```bash\n# 1. Log in via your browser (recommended)\natoa login\n\n# 2. Confirm\natoa whoami\n\n# 3. Try a real call\natoa stores list\natoa payments create --amount 10.05 --orderId test-001 --customerId cust_123 --redirectUrl https://example.com\n```\n\nCredentials are stored in owner-only (`0600`) JSON files under `~/.atoa/auth/` — JWT sessions in `session.json`, SDK API keys in `secret_key.json`. Plain files (no OS keychain, like the AWS/gcloud/Stripe CLIs) so automation and coding agents on the same machine can read them. **Credentials never touch a `.env` file or your shell history.**\n\n---\n\n## Profiles & environments\n\nA single machine can hold credentials for **many merchants** (profiles) **and** both environments (`sandbox` + `production`). The CLI keeps them isolated so production keys can't run during a test session by accident. Note: each binary talks to one server, so a credential's reachability still depends on which build you installed (see above).\n\n```bash\natoa profile list                  # see every profile + which envs are configured\natoa profile show                  # detailed metadata for the active profile\natoa profile use acme              # switch active profile\natoa profile set env=production    # set the default env for the active profile (prompts)\natoa profile rename acme acme-uk   # rename + move the stored credentials\natoa profile delete old-merchant   # remove profile + its JWT session and SDK keys\natoa whoami --env production       # query against a specific env without switching the default\n```\n\n> Browser login (`atoa login`) is **env-independent** — one JWT session per profile works for both\n> sandbox and production. `defaultEnv` only decides which env SDK/data commands target by default.\n\n---\n\n## Sign in\n\n### Browser flow (recommended)\n\n```bash\natoa login      # opens the Atoa dashboard grant page in your default browser\n```\n\n`atoa login` takes no `--env`: the browser grant authenticates against a single auth\nbackend, so the resulting JWT session works for both sandbox and production. The profile is not\nenv-scoped.\n\nWhat happens:\n\n1. The CLI generates a PKCE pair and a random state value, then starts a temporary localhost server on a random port.\n2. Your default browser opens the Atoa dashboard grant page (`/auth/extension-callback`).\n3. You approve the request in the browser.\n4. The dashboard redirects back to `http://127.0.0.1:<port>/callback` with a one-time code.\n5. The CLI exchanges the code for a JWT access token + refresh token (server-side PKCE verification).\n6. If your account belongs to multiple businesses, you are prompted to pick one (interactive terminals only; non-interactive logins complete and ask you to run `atoa business use <id>` afterwards).\n7. A profile is created (or updated) and the JWT pair is stored in `~/.atoa/auth/session.json` (owner-only, `0600`).\n\n`atoa login` requires an interactive terminal (TTY) and a desktop browser on the same machine — there is no headless/CI login path. For CI, provision credentials on a workstation and make the `~/.atoa/auth/` files available to the runner (see [CI / automation](#ci--automation)).\n\n### Minting an SDK key\n\nTo use the SDK/data commands (`payments`, `refunds`, …) you need an SDK API key. Create one\nexplicitly after logging in:\n\n```bash\natoa keys create --env sandbox    # mints a revocable SDK key, writes it to secret_key.json\n```\n\nThe `apiSecret` is shown **once** — save it immediately. Requires an admin role on the business.\n\n---\n\n## Dual-credential model\n\nThe CLI supports two independent credential types per profile and environment:\n\n```\natoa login (browser)\n      │\n      ├─► JWT access token  ──► account-management commands (v1 API)\n      │   JWT refresh token      business, sessions, keys, staff, roles,\n      │                          kyb, payment-links, bank, stores,\n      │                          addons, comms, custom-branding,\n      │                          custom-sms, direct-debit\n      │\n      └─► SDK API key (optional, via `atoa keys create`)\n              ──► payments/data commands (legacy API)\n                  payments, refunds, customers, card-on-file,\n                  webhooks, bank-feed, payouts, institutions,\n                  get, post, delete\n```\n\nA single `atoa login` always mints a JWT pair. The SDK key is optional and can be added at any time with `atoa keys create`.\n\nCredentials live in two owner-only (`0600`) JSON files under `~/.atoa/auth/`:\n\n| File | Content | Keyed by |\n|---|---|---|\n| `session.json` | JWT access + refresh tokens (browser login) | profile only — env-independent, since browser login hits one auth backend |\n| `secret_key.json` | SDK API keys (`atoa keys create`) | profile + env |\n\n### Which commands need which login\n\n| Auth required | Commands |\n|---|---|\n| **JWT (browser login)** | `business list/use`, `sessions list/revoke`, `keys create/list`, `kyb status/link`, `kyb card status/link`, `staff *`, `roles *`, `payment-links create/get/delete`, `bank list/get/add/delete`, `stores *`, `addons *`, `comms list/set`, `custom-branding get/set/reset`, `custom-sms list/set/delete`, `direct-debit status/setup` |\n| **SDK key** (`atoa keys create`) | `payments *`, `refunds *`, `customers *`, `payment-methods *`, `card-on-file *`, `webhooks *`, `bank-feed *`, `payouts *`, `institutions list`, `get`, `post`, `delete` |\n| **Either** | `whoami`, `keys revoke/regenerate` |\n| **None** (self-authenticating) | `signup` (creates the account + session itself), `completion`, `profile *`, `reset` |\n\nCommands that require JWT will error with a clear message when the active profile has only an SDK key and no JWT session. Run `atoa login` (browser) to gain a JWT session; mint an SDK key with `atoa keys create` when you need the SDK/data commands.\n\n---\n\n## New commands reference\n\n### Account management (`business`, `sessions`)\n\n```bash\natoa business list                      # list businesses on this account; marks the active one\natoa business use <businessId>          # switch the active business for /v1 API calls\natoa sessions list                      # list active CLI sessions for this account\natoa sessions revoke <deviceId>         # revoke a session (--yes to skip confirmation)\n```\n\n### SDK key management (`keys create`, `keys list`)\n\nThese extend the existing `keys revoke` / `keys regenerate` commands.\n\n```bash\natoa keys create                        # create a new SDK API key (jwt mode; prompts for a label)\natoa keys create --name \"CI server\"     # label the key non-interactively\natoa keys list                          # list SDK keys for this account (never shows secrets)\n```\n\n### KYB (`kyb`)\n\n```bash\natoa kyb status                         # get the KYB verification status for this business\natoa kyb link                           # open the KYB form in the browser (prints the URL too)\natoa kyb card status                    # card-payment application status + what blocks it\natoa kyb card link                      # open the card-payment application form\n```\n\n### Staff and roles (`staff`, `roles`)\n\n`staff add` and `staff invite` are the same command under two names. Omit the identifier on a\nTTY and the CLI prompts, prefilled with the record's current values.\n\n```bash\natoa staff list                         # list staff members for this business\natoa staff add \\\n  --firstName Alice --lastName Smith \\\n  --email alice@example.com \\\n  --role <roleId>                       # add a new staff member\natoa staff add … --store <storeId>      # restrict to one or more stores (repeatable flag)\natoa staff update <userId>              # edit name, email, phone, role or permitted stores\natoa staff delete <userId> --yes        # remove a staff member from the business\natoa roles list                         # list available roles for this business\natoa roles permissions                  # permission catalogue: id, name, category, requires\natoa roles add --name \"Shift lead\"      # create a role; prompts for permissions\natoa roles add --name \"Shift lead\" --permission <id>   # repeat --permission for several\natoa roles update <roleId>              # edit name, description or permissions\natoa roles delete <roleId> --yes        # delete a role\n```\n\n`--permission` takes permission **ids**, which `atoa roles permissions` lists — every other view\nshows only names. Permissions can depend on other permissions: selecting one automatically grants\nwhat it requires, and the CLI prints which extras it added.\n\n### Bank accounts (`bank`)\n\n```bash\natoa bank list                          # list bank accounts for the active business\natoa bank add                           # interactive: pick bank, enter details, verify via OTP\natoa bank add --sortCode 123456 --accountNumber 12345678 \\\n  --accountHolderName \"<account holder name>\"\n\n# Non-interactive. If a one-time code is required, the first run exits with code 9 having sent it:\natoa bank add --bankName \"<bank name>\" --sortCode 123456 \\\n  --accountNumber 12345678 --accountHolderName \"<account holder name>\" --output json\n#   → exit code 9: \"An OTP was sent to your registered contact. Re-run with --otp <code>\"\natoa bank add <same flags> --otp <code> --output json        # → exit code 0\natoa bank get <bankAccountId>           # get a bank account by id\natoa bank delete <bankAccountId> --yes  # remove a bank account\n```\n\nA business's first bank account becomes its primary automatically. `--setPrimary` switches which\naccount Atoa settles to and re-points every location already linked to one, so pass it only when\nyou mean to change the billing account.\n\n### Payment links (`payment-links`)\n\n`--amount` is in GBP (e.g. `10.50`), not pence. `--store-id` is required.\n\n```bash\natoa payment-links create --amount 10.50 --store-id <id>                  # create a link\natoa payment-links create --amount 10.50 --store-id <id> --notes \"Inv 42\" # notes max 30 chars\natoa payment-links get <linkId> --store-id <id>                           # fetch a link + status\natoa payment-links delete <linkId> --store-id <id>                        # delete a link\n```\n\n### Stores (`stores`)\n\n```bash\natoa stores list                        # list stores for this business\natoa stores get <storeId>               # get a store by ID\natoa stores add                         # interactive: name, address, postcode\natoa stores add --locationName \"Soho\" --addressLine1 \"12 Dean St\" \\\n  --cityOrTown London --addressPostalCode W1D3RP\natoa stores update <storeId>            # prompts with the store's current values prefilled\natoa stores link-bank <storeId> --bank <bankAccountId>  # link a bank account to a store\natoa stores image ./logo.png --storeId <storeId>        # upload/replace store logo (PNG/JPG, ≤6MB)\n```\n\n### Add-on plans (`addons`)\n\n```bash\natoa addons list                        # current plan, feature usage, available moves\natoa addons upgrade                     # pick a plan on a TTY, or pass a plan ID\natoa addons downgrade <planId>          # refused while usage exceeds the target plan\natoa addons cancel-downgrade            # cancel a downgrade that hasn't taken effect\n```\n\nA refused downgrade names the features that are over the target plan's limits, so you know\nwhat to reduce before retrying.\n\n### Direct Debit (`direct-debit`)\n\nA business can hold one mandate. Once it's active, `setup` refuses rather than creating a second.\n\n```bash\natoa direct-debit status                # whether a mandate exists, and its status\natoa direct-debit setup                 # interactive: bank details + billing address\n```\n\nInteractive setup prefills the account holder name, email and billing address already held on\nthe business, and masks the account number on file — press Enter to keep it.\n\n### Notification preferences (`comms`)\n\n```bash\natoa comms list                         # topics, with each channel's state\natoa comms set payouts --email off      # topic ID or display name\natoa comms set <topicId> --sms on --push off\n```\n\nEach channel reads `on`, `off`, or `unavailable` — Atoa doesn't send every channel for every\ntopic, and an unavailable channel can't be switched on.\n\n### Checkout branding and SMS sender name (`custom-branding`, `custom-sms`)\n\n```bash\natoa custom-branding get                # current checkout theme colour\natoa custom-branding set '#FF0000'      # 6-digit hex\natoa custom-branding reset              # restore the Atoa default\n\natoa custom-sms list                    # sender name and its review status\natoa custom-sms set AcmeLtd             # request a sender name (3-11 chars; letters, numbers, spaces)\natoa custom-sms delete --yes            # remove the custom sender name\n```\n\n### Merchant onboarding (`signup`)\n\n`atoa signup` needs **no prior login** — it creates the account (email + one-time code) and its JWT session, then runs the onboarding wizard.\n\n```bash\natoa signup                             # interactive: email + OTP, then guided onboarding\natoa signup --email you@example.com     # skip the email prompt\natoa signup --fromStep 2                # resume from step N (2-3); businessId must already be set\natoa signup --deviceName \"Work laptop\"  # label this device in your Atoa sessions\n```\n\nEvery prompted value also has a flag, so signup can run with no terminal at all. The one-time code\ngoes to your inbox, so it takes two runs:\n\n```bash\natoa signup --email you@example.com --output json\n#   → exit code 9: \"An OTP has been sent to you@example.com.\"\n\natoa signup --email you@example.com --otp 123456 --accept-terms \\\n  --business-name \"Acme Ltd\" --industry \"Retail - Other\" \\\n  --monthly-turnover \"Up to £10,000\" --business-structure \"Limited Company\" \\\n  --vat-number 123456789 --first-name Ada --last-name Lovelace \\\n  --postal-code \"SW1A 2AA\" --address-line1 \"10 Downing Street\" --output json\n```\n\n`--accept-terms` records acceptance of the [Privacy Policy](https://paywithatoa.co.uk/atoa-business-privacy-policy/)\nand [Terms of Service](https://paywithatoa.co.uk/terms/); `--marketing` is a separate opt-in.\n`--start-new` creates a second business rather than resuming an existing signup.\n\n`--business-structure` is `Limited Company` or `Charity`. `--industry` and `--monthly-turnover` are\nserver-defined lists that vary by environment, so the values above are illustrative — pass the\noption's name and, if it doesn't match, the CLI exits with code `3` listing every valid one to choose from.\n\n---\n\n## Idempotency-Key — duplicate-charge protection\n\nThe CLI auto-generates a fresh `Idempotency-Key: <uuidv4>` header on every POST/PUT/PATCH. The Atoa server uses it to deduplicate retries, so a network blip on the response never produces a doubly-charged customer.\n\nYou don't need to think about this for interactive use — it just works. For **CI / scripted retries**, where one logical operation spans multiple CLI invocations (e.g. the job restarts), pass `--idempotencyKey` so a re-run produces the same key and the server deduplicates:\n\n```bash\n# Auto-generated key (default — safe for interactive use)\natoa refunds create --paymentRequestId pr_abc --amount 5.00\n\n# Stable key (CI retry-safe — same key on every re-run of the same run)\natoa refunds create \\\n  --paymentRequestId pr_abc \\\n  --amount 5.00 \\\n  --idempotencyKey \"atoa-cli/refund/${RUN_ID}/${PAYMENT_ID}\"\n```\n\nAvailable on `atoa payments create`, `atoa refunds create`, `atoa card-on-file charge`, and the generic `atoa post`. For other POST endpoints, the auto-generated key is always sent — your retries are safe by default.\n\n---\n\n## Common workflows\n\n### Payments\n\n```bash\natoa payments create --amount 25.00 --orderId order-001 --customerId cust_123 --redirectUrl https://shop.example.com/return\natoa payments status pr_abc123 --poll\natoa payments cancel pr_abc123 --yes\natoa payments transactions --from 2026-01-01 --to 2026-01-31 --status COMPLETED\natoa payments transactions --pageAll --output json   # walk every page\n```\n\n### Customers & saved cards\n\n```bash\natoa customers create --fullName \"Jane Doe\" --email jane@example.com --type INDIVIDUAL\natoa customers list --search jane\natoa customers get cust_123\natoa customers update cust_123 --vatNumber GB123456789\natoa customers delete cust_123 --yes\natoa payment-methods list --customer cust_123\natoa payment-methods get card_456 --customer cust_123\natoa payment-methods delete card_456 --customer cust_123 --yes\n```\n\n### Card-on-file (saved card charging)\n\n```bash\natoa card-on-file charge --customerId cust_123 --paymentMethodId card_456 --amount 10.50 --orderId order-007\natoa card-on-file charge --customerId cust_123 --paymentMethodId card_456 --amount 10.50 --orderId order-007 --captureType MANUAL_CAPTURE\natoa card-on-file capture pr_abc123 --yes\natoa card-on-file cancel pr_abc123 --yes\n```\n\n### Refunds\n\n```bash\natoa refunds create --paymentRequestId pr_abc123 --amount 5.00 --currency GBP --notes \"duplicate charge\" --yes\natoa refunds list --paymentRequestId pr_abc123\natoa refunds cancel rf_xyz --yes\n```\n\n### Webhooks\n\n```bash\natoa webhooks create --url https://your-app.com/webhooks --event PAYMENTS_STATUS\natoa webhooks create --url https://your-app.com/webhooks --event PAYMENTS_STATUS \\\n  --authentication @./auth.json                              # OAuth/Basic secret from file (NOT inline — see below)\natoa webhooks list\natoa webhooks delete wh_123 --yes\n```\n\n> ⚠ Pass authentication secrets via `--authentication @path/to/auth.json` (or `--authentication -` for stdin). Inline JSON (`--authentication '{\"clientSecret\":\"...\"}'`) is accepted but **exposes the secret in `ps`, shell history, and audit logs** — avoid in scripted use.\n\n#### Webhook test trigger (sandbox only)\n\n`atoa webhooks trigger` fires a fake event at your registered sandbox webhook URL — same body shape and signature recipe as a production event, no real payment needed. Always uses the sandbox key, regardless of `--env`.\n\nSupported events: `PAYMENTS_STATUS`, `EXPIRED_STATUS`, `REFUND_STATUS`, `POS_PAYMENT_STATUS`.\n\n```bash\n# Defaults — fires a PAYMENTS_STATUS event with a generated orderId\natoa webhooks trigger PAYMENTS_STATUS\n\n# Override fields in the dispatched body\natoa webhooks trigger PAYMENTS_STATUS --paymentMethod CARD --status AUTHORIZED\natoa webhooks trigger PAYMENTS_STATUS --orderId order-001 --amount 25.00\natoa webhooks trigger REFUND_STATUS --status FAILED\n\n# POS_PAYMENT_STATUS has multiple body shapes — pick one via --type\natoa webhooks trigger POS_PAYMENT_STATUS --type PAYMENTS_STATUS\natoa webhooks trigger POS_PAYMENT_STATUS --type REFUND_STATUS --status COMPLETED\natoa webhooks trigger POS_PAYMENT_STATUS --type EXPIRED_STATUS\natoa webhooks trigger POS_PAYMENT_STATUS --type PAYMENTS_STATUS \\\n  --customFields '[{\"value\":\"CUST_001\",\"fieldName\":\"Customer ID\"}]'\n```\n\n| Flag | Use |\n|---|---|\n| `--orderId` | Override the dispatched body's `orderId` |\n| `--amount` | Override `paidAmount` in pounds (e.g. 10.05 for £10.05) |\n| `--paymentMethod` | `CARD` \\| `PAY_BY_BANK` |\n| `--status` | `COMPLETED` \\| `AUTHORIZED` \\| `FAILED` \\| `CANCELLED` \\| `EXPIRED` (per-event validation server-side) |\n| `--type` | `POS_PAYMENT_STATUS` only — body shape: `PAYMENTS_STATUS` (default) / `REFUND_STATUS` / `EXPIRED_STATUS` |\n| `--customFields` | `POS_PAYMENT_STATUS` only — JSON array of `{value, fieldName}` |\n\n### Bank feed (Open Banking)\n\n```bash\natoa bank-feed initiate --redirectUrl https://example.com/bank/return\natoa bank-feed accounts auth_999\natoa bank-feed account acct_111\natoa bank-feed balance acct_111\natoa bank-feed transactions acct_111 --from 2026-01-01 --before 2026-02-01\natoa bank-feed revoke --accountAuthId auth_999 --yes\n```\n\n### Stores, institutions, payouts\n\n```bash\natoa stores list\natoa institutions list\natoa payouts list --fromDate 2026-01-01 --status COMPLETED\natoa payouts transactions po_555 --pageAll\n```\n\n### Device keys (rotate / revoke)\n\n```bash\natoa keys revoke                              # interactive: picks env if profile has both\natoa keys revoke --env sandbox --yes          # non-interactive\natoa keys revoke <sdkAccessId> --yes          # revoke a specific key by id\natoa keys regenerate                          # rotate active env's key — new bearer shown ONCE\natoa keys regenerate --env production --yes\n```\n\n### Generic HTTP verbs (escape hatch)\n\nFor endpoints the CLI doesn't yet wrap, or when you want explicit control. These authenticate\nwith the **SDK key**, so `atoa keys create` must have been run first:\n\n```bash\natoa get /api/payments/stores\natoa get /api/customers -d page=0 -d size=20 --pageAll\natoa post /api/something --data @body.json\natoa post /api/something --data @body.json --idempotencyKey \"ci-${RUN_ID}\"\natoa delete /api/customers/cust_123 --yes\n```\n\n---\n\n## Common flags\n\n### Resource commands (payments, refunds, customers, …)\n\nAll resource commands accept the same six globals. Use them on any leaf command in the resource topics (`payments`, `refunds`, `customers`, `payment-methods`, `card-on-file`, `webhooks`, `bank-feed`, `payouts`, `stores`, `institutions`, `keys`, `whoami`, `get`/`post`/`delete`).\n\n| Flag | Use |\n|---|---|\n| `--env` | Override env (`sandbox` \\| `production`) for this single command |\n| `--output` | `json` \\| `table` \\| `yaml` (default: json) |\n| `--verbose` | Print method, URL, and redacted Authorization to stderr |\n| `--dryRun` | Resolve the request and print it without sending |\n| `--yes` | Skip confirmation prompts (required for destructive commands in CI) |\n| `--profile` | Operate against a specific profile (overrides `activeProfile`) |\n\n### Admin commands (login, logout, reset, profile/\\*)\n\nThese don't accept the resource-command globals — they have their own focused arg set. The most common ones:\n\n| Command | Key flags |\n|---|---|\n| `atoa login` | `--profile` |\n| `atoa logout` | `--env`, `--profile`, `--revoke`, `--yes`, `--dryRun` |\n| `atoa reset` | `--revoke`, `--yes`, `--dryRun` |\n| `atoa profile set` | `--profile`, `--yes`, `--dryRun` (and the `key=value` positional) |\n| `atoa profile delete` | `--yes`, `--dryRun` |\n| `atoa profile use` | `--dryRun` |\n| `atoa profile rename` | `--yes`, `--dryRun` |\n\nRun `atoa <command> --help` for the full per-command flag list.\n\n---\n\n## Output formats\n\n```bash\natoa payments transactions --output json   # default — JSON to stdout\natoa profile list --output table           # human-readable\natoa whoami --output yaml\n```\n\nJSON is the default whether or not stdout is a TTY, so piping to `jq` always works without explicit `--output json`.\n\n---\n\n## Shell completion\n\nThe CLI ships TAB-completion for command names, flag names, and dynamic values (live profile names, sdkAccessIds, `--env` values). One install per shell:\n\n```bash\natoa completion <bash|zsh|pwsh>\n```\n\n| Shell | One-line install |\n|---|---|\n| **bash** | `atoa completion bash >> ~/.bashrc && source ~/.bashrc` |\n| **zsh** | `atoa completion zsh > ~/.zsh/completions/_atoa` (ensure `fpath` includes that dir above `compinit`) |\n| **PowerShell** | `atoa completion pwsh \\| Out-String \\| Invoke-Expression` (append to `$PROFILE` to persist) |\n\nAfter installing, hit `<TAB>`:\n\n```\natoa <TAB>                       → login, keys, profile, payments, …\natoa keys revoke <TAB>           → your live sdkAccessIds\natoa profile use <TAB>           → your live profile names\natoa --env <TAB>                 → sandbox, production\n```\n\n**TAB falls back to file completion?** The wrapper didn't load. Verify the engine first:\n\n```bash\natoa --complete-bash \"atoa profile use \"\n```\n\nIf that prints candidates, the engine is healthy — re-run the install in a fresh terminal.\n\n---\n\n## Config / environment variables\n\n| Variable | Purpose |\n|---|---|\n| `ATOA_HOME` | Override the config + credentials location. Defaults to `$HOME`; credentials land in `$ATOA_HOME/.atoa/auth/`. Useful for Docker, sandboxed CI, ephemeral containers. |\n| `ATOA_PROFILE` | Default profile name. Equivalent to passing `--profile <name>` on every command; the explicit flag still wins. Useful for `export ATOA_PROFILE=ci && atoa …` long-running scripts. |\n| `ATOA_BASE_URL` | Unchanged — overrides the Atoa payment API base URL at runtime. |\n| `ATOA_DASHBOARD_URL` | Override the dashboard URL used for the browser login grant page (build define default: `https://dashboard.paywithatoa.co.uk`). Set at build time via the `DASHBOARD_URL` tsup define or at runtime via this variable. Useful for self-hosted or staging dashboard deployments. |\n\n---\n\n## Exit codes\n\nThe CLI uses POSIX-style exit codes so shell pipelines and CI systems can branch on the failure mode:\n\n| Code | Meaning | Trigger |\n|---:|---|---|\n| `0` | Success | Command completed without error |\n| `1` | Generic failure | Anything not classified below |\n| `2` | Auth / forbidden | HTTP 401 or 403 — token invalid / revoked / lacks permission |\n| `3` | Validation error | HTTP 400, or client-side input rejected (bad amount, bad JSON, bad enum) |\n| `4` | Not found | HTTP 404 — resource doesn't exist on this env |\n| `5` | Rate limited | HTTP 429, or a one-time-code / sign-in throttle — **stop and wait**; retrying extends the block |\n| `6` | Network / TLS / DNS | Couldn't reach the server (connection refused, DNS, cert expired, timeout) |\n| `7` | Business not selected | The account belongs to several businesses and none is active — run `atoa business use <id>` |\n| `8` | Plan limit | The add-on plan doesn't allow this — `atoa addons list` shows the limits |\n| `9` | One-time code sent | Not a failure: a code was sent and nothing was written. Re-run the same command with `--otp <code>` |\n\nExample CI pattern:\n\n```bash\nif ! atoa refunds create --paymentRequestId \"$PR\" --amount 5.00 --idempotencyKey \"$RUN_ID\" --yes ; then\n  case $? in\n    2) echo \"Token invalid — re-login required\" ;;\n    3) echo \"Bad input — fix the payload\" ;;\n    5) echo \"Throttled — wait it out; retrying extends the block\" ;;\n    6) echo \"Network blip — retry the same idempotency key is safe\" ;;\n    *) echo \"Unhandled error\" ;;\n  esac\n  exit 1\nfi\n```\n\n---\n\n## CI / automation\n\n`atoa login` needs an interactive browser, so a CI runner can't log in itself. Provision credentials on a workstation (`atoa login`, plus `atoa keys create` if the job hits SDK/data commands), then make the `~/.atoa/auth/` files available to the runner — point `ATOA_HOME` at the directory that holds them.\n\n```bash\n# 1. With credentials already provisioned (ATOA_HOME → the auth dir),\n#    target the CI profile with a stable idempotency key\natoa --profile ci payments create \\\n  --amount 10.00 --orderId \"$RUN_ID\" --customerId cust_123 --redirectUrl https://x \\\n  --idempotencyKey \"ci-payment/$RUN_ID\" --dryRun\n\n# 2. Read-only checks\natoa --profile ci payments transactions --output json --status COMPLETED\n\n# 3. Clean up (revokes the server-side key too; safe to share across machines)\natoa logout --profile ci --revoke --yes\n```\n\nKey patterns:\n\n- **`--profile ci`** scopes every command to a named credential bundle. Same flag form as `ATOA_PROFILE=ci`.\n- **`--idempotencyKey \"ci-…/$RUN_ID\"`** ensures a re-run of the same CI job doesn't create duplicate payments / refunds / charges.\n- **`--dryRun`** lets the CI step validate the resolved request body before going live.\n- **`--yes`** skips confirmation prompts — required on every destructive command in non-TTY contexts.\n\n---\n\n## Troubleshooting\n\n### `HTTP 401` after login\nYour session may have expired or been revoked (e.g. a later login on the same device evicted it). Run `atoa whoami` to check the active profile, then re-run `atoa login` to refresh the session.\n\n### `No profile is configured. Run \\`atoa login\\` to pair this device.`\nFirst-run state. Run `atoa login` to pair.\n\n### `Multiple profiles are configured (a, b, c). Run \\`atoa profile use <name>\\` …`\nYou have several merchants paired and haven't set a default. Either `atoa profile use <name>` once, or pass `--profile <name>` per command.\n\n### `Timed out acquiring lock on …/session.json.lock`\nAnother `atoa` process is mid-write. If no other process is running (e.g. one crashed), remove the lockfile manually:\n\n```bash\nrm ~/.atoa/auth/session.json.lock\n```\n\n### `Refusing to read …/session.json: insecure permissions` (POSIX only)\nThe session file got group/other read bits. Fix:\n\n```bash\nchmod 600 ~/.atoa/auth/session.json\n```\n\n### `Refusing to parse …/session.json: not valid JSON`\nThe file got corrupted. Recover with:\n\n```bash\natoa reset --yes && atoa login\n```\n\n---\n\n## Documentation\n\n- **Full docs:** [Atoa Docs](https://docs.atoa.me/cli)\n- **Built-in help:** `atoa --help`, `atoa <command> --help`, `atoa <command> <subcommand> --help` — full per-command flag list, always in sync with the binary you have installed.\n- **API reference:** see the doc site link from your Atoa Dashboard.\n\n---\n\n## Reset / uninstall\n\n```bash\natoa reset --yes                     # wipe local profiles + tokens (local only)\natoa reset --revoke --yes            # also revoke server-side keys (best-effort)\natoa reset --dryRun                  # preview what would be cleared without touching state\nnpm uninstall -g @atoapayments/atoa-cli   # remove the binary\n```\n\n---\n\n## Support\n\n`hello@paywithatoa.co.uk` or use chat on the [Dashboard](https://dashboard.paywithatoa.co.uk/).\n","readmeFilename":"README.md"}