z-getway
v1.1.7
Published
Zyro Gateway — real-time income sync, Express Checkout, and browser SDK
Maintainers
Readme
Install either package — same gateway:
npm install z-getway(recommended) ornpm install zyro-gateway
Zyro Gateway
Zyro Gateway is a framework-agnostic real-time sync layer for TypeScript and JavaScript. It moves payment and income events from mobile clients to web clients and systems over Socket.IO, with HTTP fallback when long-lived connections are unavailable. Pairing rooms, a REST surface, and a bundled browser SDK (Zyro.connect) ship in one npm package so you can integrate income sync without building transport, discovery, and fan-out yourself.
Why Zyro Gateway
Reliable delivery of transaction data across devices on a local network is rarely a single library—it is usually custom sockets, polling endpoints, and fragile “connected” states that diverge from what the server actually sees. Zyro Gateway treats that as one problem: authenticate a pairing code, register clients, broadcast income and notifications, and expose the same events to web and system consumers from a small Node process—hence, Zyro Gateway.
| Capability | Description |
|------------|-------------|
| Income sync | Push payment fields from mobile to gateway in real time |
| Dual transport | Socket.IO primary; HTTP register + POST when sockets drop |
| Isolated rooms | pairingCode scopes clients and event streams per deployment |
Table of contents
- Requirements
- Installation
- Quick start
- Architecture
- Configuration
- Phone app setup
- Browser client
- HTTP API
- Socket.IO protocol
- Programmatic server API
- CLI reference
- Project structure
- Development
- Publishing updates
- Troubleshooting
- Security
- License
Requirements
| Requirement | Notes |
|-------------|--------|
| Node.js 18+ | LTS recommended |
| Same LAN | Phone, PC, and browser clients must reach the gateway IP |
| Open port | Default 3001 (configurable); only one process per port |
| Pairing code | 4–12 alphanumeric characters, shared across all clients |
Installation
From npm (recommended)
npm install z-getwayGlobal CLI (optional)
npm install -g z-getway
z-getway --helpFrom source
git clone https://github.com/orod-codes/zyro-getway.git
cd zyro-getway
npm install
npm run config
npm startQuick start
1. Create config (in your project folder—not committed to git):
npm install zyro-gateway # or: z-getway
npx zyro-gateway config # creates zyro.config.js + zyro.data.js
# already have an old config?
npx zyro-gateway config --upgrade2. Edit zyro.config.js — set pairingCode, port, bank accounts, and checkout.orderApiUrl (your store API for customer + amount). See SETUP.md.
3. Start the gateway:
npx z-getway4. Terminal output (example):
Zyro Gateway
───────────────────────
Config /path/to/zyro.config.js
Pairing MYSTORE
App IP 192.168.1.10 port 3001
Connected: (waiting…)
Income: name · amount · sender · ref5. Phone app → Setup → Zyro Gateway → enter the same IP, port, and pairing code.
6. Express Checkout — http://YOUR_IP:PORT/checkout/?orderId=... (order data from your store API). See SETUP.md.
7. Website → load scripts from the gateway (see Browser client).
One-liner (no install)
npx z-getway@latest config
npx z-getway@latestGet the latest version (after you publish an update)
| How you installed | Update command |
|-------------------|----------------|
| In a project | npm update z-getway |
| One-off run | npx z-getway@latest |
| Global CLI | npm install -g z-getway@latest |
Architecture
flowchart LR
subgraph Phone["Mobile client"]
PAY[Income events]
end
subgraph Gateway["Zyro Gateway (Node.js)"]
HTTP[REST API]
WS[Socket.IO]
ROOM[Pairing rooms]
TERM[Terminal logs]
HTTP --> ROOM
WS --> ROOM
ROOM --> TERM
end
subgraph Clients["Clients"]
WEB[Website / Zyro.connect]
TTY[Developer terminal]
end
PAY -->|socket or HTTP| Gateway
WEB -->|socket| Gateway
ROOM --> WEB
TERM --> TTYData flow
- Phone joins room
pairing:MYSTORE(Socket.IO) or callsPOST /api/register+POST /api/income(HTTP). - Gateway stores transactions in memory (per pairing room), broadcasts to all web and system clients in that room.
- Terminal prints each income: amount, name, sender, reference.
- Web clients receive
income_transaction,dashboard_update, andpresenceevents.
Transport priority
| Client | Primary | Fallback |
|--------|---------|----------|
| Phone | Socket.IO (income_transaction) | POST /api/income, POST /api/register |
| Website | Socket.IO + Zyro.connect | HTTP polling (pollIntervalMs) |
| Web / system probe | GET /api/info | — |
Configuration
zyro.config.js fields
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| ip | string | '' | LAN IP shown to the phone. Empty = auto-detect. |
| port | number | 3000 | Listen port (example uses 3001). |
| pairingCode | string | '' | Room id (4–12 chars, A–Z, 0–9). Required for API unless sent per request. |
| deviceName | string | '' | Default label for web clients. |
| autoConnect | boolean | true | Browser client connects on load. |
| pollIntervalMs | number | 1500 | HTTP poll interval when sockets fail. |
| autoSave / dataFile | — | true / zyro.data.js | Auto-save income; rows include paymentMethod |
| checkout.orderApiUrl | string | demo URL in example | Store API: .../orders/{orderId} → customer, photo, amount |
| checkout.defaultOrderId | string | '' | Dev fallback when opening /checkout/ without ?orderId= |
| checkout.banks.* | object | — | Per-bank enabled, accountNumber, holderName |
Full walkthrough: SETUP.md.
Config file resolution order
ZYRO_CONFIG— absolute path via environment variable./zyro.config.js— current working directory (where you runnpx z-getway)- Package directory — fallback when running from
node_modules
Environment variables
| Variable | Effect |
|----------|--------|
| PORT | Overrides port in config |
| ZYRO_CONFIG | Path to a custom config file |
Example:
PORT=3002 ZYRO_CONFIG=/etc/zyro/prod.config.js npx z-getwayPhone app setup
Configure your mobile client under Setup → Zyro Gateway (or equivalent settings screen):
| Field | Value |
|-------|--------|
| IP | Terminal App IP (or 127.0.0.1 with USB reverse) |
| Port | Same as zyro.config.js |
| Pairing code | Exact match, case-insensitive (mystore → MYSTORE) |
Android USB debugging
Forward the gateway port to the device:
adb reverse tcp:3001 tcp:3001On the phone, use IP 127.0.0.1 and port 3001.
HTTP fallback
If Socket.IO cannot connect, the app should:
POST /api/register— appear in terminal Connected listPOST /api/income— push each transaction
Headers/query: X-Pairing: MYSTORE or ?pairing=MYSTORE.
Browser client
The gateway serves a bundled IIFE at /zyro/zyro.js (global Zyro).
HTML (vanilla)
<script src="http://192.168.1.10:3001/socket.io/socket.io.js"></script>
<script src="http://192.168.1.10:3001/zyro/zyro.js"></script>
<script>
const sync = Zyro.connect({
ip: '192.168.1.10',
port: 3001,
pairingCode: 'MYSTORE',
role: 'desktop',
deviceName: 'Front Desk',
});
sync.on('ready', () => console.log('Linked to gateway'));
sync.on('transaction', (tx) => {
console.log('Income', tx.amount, tx.name, tx.transactionNumber);
});
sync.on('notification', (note) => console.log('Push', note.title));
sync.on('dashboard', (d) => console.log('Today', d.stats.todayTotal));
sync.on('devices', (list) => console.log('Devices', list));
</script>ESM / Vite / Webpack
import { connect, EVENTS } from 'z-getway';
const sync = connect({
serverUrl: 'http://192.168.1.10:3001',
pairingCode: 'MYSTORE',
role: 'desktop',
});
sync.on(EVENTS.TRANSACTION, handler);Client events
| Event | When |
|-------|------|
| ready | Socket handshake complete |
| status | Connection state changed |
| error | Auth or network error |
| transaction | New income |
| notification | New notification |
| dashboard | Stats snapshot |
| presence / devices | Device list updated |
HTTP API
Base URL: http://<ip>:<port>
Pairing — required on protected routes unless set in config:
- Query:
?pairing=MYSTORE - Header:
X-Pairing: MYSTORE
Discovery
GET /
Service index and endpoint list.
GET /api/info
Server metadata for health checks and app probes.
{
"name": "Zyro Gateway",
"httpUrl": "http://192.168.1.10:3001",
"wsUrl": "ws://192.168.1.10:3001",
"pairingCode": "MYSTORE",
"features": ["transactions", "notifications", "dashboard", "devices"],
"reachable": true
}GET /api/config
Effective IP, port, and pairing from config (no secrets).
Data
GET /api/dashboard?pairing=MYSTORE
Today’s totals and recent activity.
GET /api/devices?pairing=MYSTORE
Connected mobile, web, and system clients in the room.
GET /api/transactions?pairing=MYSTORE&after=2026-05-17T08:00:00.000Z
| Query | Behavior |
|-------|----------|
| (none) | Last 50 transactions |
| after | ISO timestamp — only newer rows (polling) |
GET /api/notifications?pairing=MYSTORE
Same pattern as transactions.
Write (phone / integrations)
POST /api/register
Register a phone when using HTTP-only transport.
curl -X POST "http://127.0.0.1:3001/api/register?pairing=MYSTORE" \
-H "Content-Type: application/json" \
-d '{"deviceName":"Cashier Phone","platform":"android","deviceId":"pixel-7"}'POST /api/income
Push a transaction (same shape as socket income_transaction).
curl -X POST "http://127.0.0.1:3001/api/income?pairing=MYSTORE" \
-H "Content-Type: application/json" \
-d '{
"amount": 1500,
"name": "John Doe",
"sender": "2519****1234",
"transactionNumber": "FT260501234"
}'POST /api/notification
Push a notification payload.
Static assets
| Path | Description |
|------|-------------|
| /zyro/zyro.js | Browser client bundle |
| /socket.io/socket.io.js | Socket.IO client (served by Socket.IO) |
Socket.IO protocol
Connection URL
ws://<ip>:<port>/socket.io/?pairing=MYSTORE&role=phone&deviceName=My%20Phone| Query | Values |
|-------|--------|
| pairing | Required, 4–12 alphanumeric |
| role | phone (mobile) | desktop (web / system client) |
| deviceName | Optional display name |
Client → server
| Event | Payload |
|-------|---------|
| register | { deviceName, platform, ... } |
| income_transaction | Transaction object |
| notification_event | Notification object |
Server → client
| Event | Description |
|-------|-------------|
| sync_ready | Joined room successfully |
| sync_error | Invalid or missing pairing |
| history | Up to 50 recent transactions |
| notification_history | Up to 50 recent notifications |
| income_transaction | Live transaction |
| notification_event | Live notification |
| dashboard_update | Aggregated stats |
| presence | Client counts by role + device list |
| device_joined / device_left / device_updated | Device lifecycle |
Transaction payload (recommended fields)
| Field | Type | Description |
|-------|------|-------------|
| amount | number | Income amount |
| name | string | Payer / customer name |
| sender | string | Source address or account |
| transactionNumber | string | Provider / bank reference |
| timestamp | string | ISO time (optional) |
| smsAddress | string | Optional alias for sender (API field name) |
Programmatic server API
Embed the gateway in your own Node process:
const { createGateway } = require('z-getway/server');
async function main() {
const gateway = createGateway({
packageRoot: __dirname, // folder containing dist/ and zyro.config.js
});
const { url, port, pairingCode } = await gateway.start();
console.log(`Gateway at ${url} (pairing: ${pairingCode})`);
// gateway.app — Express instance
// gateway.io — Socket.IO server
// await gateway.stop();
}
main().catch(console.error);Useful for tests, Electron backends, or custom hosting.
CLI reference
| Command | Description |
|---------|-------------|
| z-getway | Start server (builds client if needed) |
| z-getway config | Create ./zyro.config.js + ./zyro.data.js |
| z-getway config --upgrade | Merge missing checkout / fields into existing config |
| z-getway help | Show usage |
npm scripts (repository)
| Script | Action |
|--------|--------|
| npm start | Build + run server.js |
| npm run dev | Run with --watch |
| npm run build | Bundle zyro/zyro.js → dist/zyro.js |
| npm run config | Init config in cwd |
Project structure
zyro-getway/
├── bin/z-getway.js # CLI entry (`zyro-gateway` alias)
├── src/
│ ├── config/ # load-config.js, pairing.js
│ ├── server/ # routes, socket, broadcast, terminal
│ ├── utils/ # network, formatting
│ └── index.js # createGateway(), start()
├── zyro/zyro.js # ESM browser client (source)
├── dist/zyro.js # IIFE bundle (published)
├── check-out/ # Express Checkout (built to check-out/dist)
├── scripts/ # build, init-config, demo-order-api
├── SETUP.md # Short setup guide
├── server.js # npm start shim
├── zyro.config.example.js
├── README.md
├── CHANGELOG.md
└── LICENSEDevelopment
git clone https://github.com/orod-codes/zyro-getway.git
cd zyro-getway
npm install
cp zyro.config.example.js zyro.config.js # or: npm run config
npm run devLink locally into another project
cd zyro-getway && npm link
cd ~/my-app && npm link z-getway
npx z-getwayRun tests manually
curl http://localhost:3001/api/info
curl "http://localhost:3001/api/dashboard?pairing=MYSTORE"Publishing updates (maintainers)
From the package root, after code changes:
npm run releaseBuilds SDK + checkout, bumps patch, publishes z-getway and zyro-gateway. Users: npm update z-getway or npx z-getway@latest.
See CHANGELOG.md · SETUP.md.
Troubleshooting
EADDRINUSE — port already in use
Another gateway (or app) is on that port.
# Find process
ss -tlnp | grep 3001
# Stop it (replace PID)
kill <PID>
# Or use another port
PORT=3002 npx z-getwayUpdate the phone app and zyro.config.js to match.
Phone shows “Connected” but terminal is empty
- Confirm pairing code matches exactly.
- Check gateway logs for
Connected [MYSTORE]. - If Socket.IO fails, ensure the app calls
POST /api/register.
Website not receiving events
- Same LAN and firewall allows inbound TCP on the gateway port.
- Use the PC’s LAN IP, not
localhost, unless the browser runs on the same machine. - Pairing query must match:
pairingCode: 'MYSTORE'.
npm whoami / publish auth errors
npm login
npm whoamiEnable 2FA on npm settings for publish.
Wrong config loaded
npx z-getway reads ./zyro.config.js in the current directory. Run npx z-getway config in each project, or set ZYRO_CONFIG.
Security
- LAN-only by design — do not expose the gateway directly to the public internet without a reverse proxy, TLS, and auth.
- Pairing codes are shared secrets; use unique codes per tenant.
- No persistence — transactions live in memory; restart clears history.
- CORS is open (
*) for local dashboards; tighten if you expose beyond LAN. - Never commit
zyro.config.js(see.gitignore).
Related projects
| Project | Role | |---------|------| | zyro-getway | This repository (server + browser client) | | Mobile monitor | Client that captures income and posts events to the gateway |
Contributing
- Fork the repo
- Create a branch:
git checkout -b feature/my-change - Commit with a clear message
- Open a PR against
main
Issues and feature requests: GitHub Issues.
Contribution
Zyro Gateway is free and open source under the MIT License. You are welcome to:
- Fork the repo and open pull requests
- Report bugs or request features
- Improve docs and examples
Security
Do not expose the gateway to the public internet without TLS and authentication. Pairing codes are shared secrets—rotate them per tenant. If you find a vulnerability, please open a private security advisory on GitHub.
