Agentic Trading Lab
Talk to agents, and test trading ideas. Try AI trading agents on real market data with no code required.
AI translation
ETAX files every sales invoice with FBR Digital Invoicing in real time and sends every point-of-sale sale to PRA, with the official invoice number and QR on the receipt. Annual plans from Rs. 12,000 a
FinanceJavaScript · HTMLGitHub @mohisn-bhattiOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
ETAX files every sales invoice with FBR Digital Invoicing in real time and sends every point-of-sale sale to PRA, with the official invoice number and QR on the receipt. Annual plans from Rs. 12,000 a year, the same price for FBR and PRA.
Taken from the repository README
Loading the full README.
Read the full README ↗Start here: docs/GUIDE.md covers what's done, how to use the app and what's left.
Website: / landing page, /contact contact form (enquiries appear for the super admin under Website enquiries), /app the application.
Set CONTACT_WHATSAPP, CONTACT_PHONE, CONTACT_EMAIL, CONTACT_CITY in .env to show contact details (empty = hidden).
Multi-tenant web app that files invoices with FBR through the PRAL Digital Invoicing (DI) API v1.12
(spec: docs/FBR-DI-API-Technical-Spec-v1.12.pdf).
Flow per invoice: calculate tax → save → validateinvoicedata → postinvoicedata → store the FBR invoice number → print receipt with QR.
npm install
cp .env.example .env
npm run gen:keys # paste JWT_SECRET and ENCRYPTION_KEY into .env
npm run db:local # local Postgres in Docker (localhost:54329) — development uses this
npm run db:deploy # create tables from prisma/migrations
npm run seed # super admin + first tenant user + HS codes
npm run dev # http://localhost:3000 (website) · http://localhost:3000/app (app)
npm test # tax engine + FBR response handling
Supabase is only updated when you decide: put its URLs in SUPABASE_DATABASE_URL / SUPABASE_DIRECT_URL and run
npm run supabase:deploy (migrations + seed).
Keep FBR_MOCK=true until the IP is whitelisted; invoices get a fake FBR number so you can test the UI.
| Super admin (CA firm) | Client |
|---|---|
| Create clients; per client Manage: FBR settings (NTN, STRN, token, environment, business nature/sector, further tax %), HS sync | New invoices, receipts, retry / debit note / mark cancelled / "found in IRIS" |
| Go-live checklist; sandbox scenario tests via "Open workspace" (works inside the client screen; logged under the admin) | Bulk import (Excel/CSV) |
| Annex-C report per client; activity log for all clients | Saved products & buyers |
Clients can't change FBR settings or see the activity log, checklist or Annex-C. While a client is in Sandbox the client can't file invoices (the screen says it is being tested); invoicing opens when the admin switches it to Production.
FBR_MOCK=false. Open workspace, and for each assigned scenario (see the checklist) pick it in the Sandbox scenario dropdown and submit a matching invoice.| Status | Meaning | What you can do |
|---|---|---|
| SUBMITTED | Filed; FBR invoice number received | Receipt |
| FAILED | FBR definitely did not record it (validation error, rejected token, nothing sent) | Retry |
| UNCERTAIN | Connection broke after sending — FBR may have it | Check IRIS → "Found in IRIS" (enter its number) or "Not in IRIS — resubmit" |
| QUEUED | Waiting for the background sender: FBR was unreachable (auto-retry after 30s, 2m, 10m, 30m, 2h, then FAILED) or from a bulk import | "Send now", or "Stop" |
| SUBMITTING | Being sent right now (acts as a lock) | Wait; shows as UNCERTAIN if stuck > 3 min |
| CANCELLED | Was filed, then cancelled in IRIS and recorded here | Left out of reports |
Each invoice form carries a clientRequestId; resending the same form (double-click, network retry) returns the
existing invoice instead of filing again. Only one submission per invoice can run at a time.
Test the failure screens with FBR_MOCK=true FBR_MOCK_RESULT=invalid or FBR_MOCK_RESULT=uncertain.
Bulk import → Download template → fill one row per item (rows with the same Invoice Ref form one invoice) → choose the file → preview shows every invoice as Ready / Error (with the reason) / Already imported → Send to FBR. Valid invoices are queued and filed one by one in the background; Recent imports shows progress.
The invoice popup switches between an 80mm thermal receipt and an A4 tax invoice. The A4 version has a letterhead, a buyer block, an item table with HS codes, totals, the amount in words (lakh/crore), the FBR number, the QR code and logo, "Integrated with FBR" and a signature line. The chosen format is remembered on each device.
On the Stock page (Owner/Accountant) record opening balances, local purchases, imports (GD) and adjustments. Sales come automatically from invoices filed with FBR: taxable, exempt and zero-rated are counted separately, and debit notes count as returns. Reports → Annex-H1 (super admin) gives the HS-code-wise stock statement for a month: opening → purchased → adjustments → supplies → closing, with a CSV download. Quantities are exact. Supplies are valued at sale value, and opening/closing stock at weighted average cost. Confirm this valuation with the CA.
npm run backup writes an encrypted dump of Supabase. See docs/backups.md for restore checks and
daily scheduling.
Every important action is recorded with user, IP and time:
Background-sender actions show as system. Clients see their own log, and the super admin sees everyone's. Both can filter,
search and download a CSV. The AuditLog table is append-only: a database trigger rejects UPDATE, DELETE and TRUNCATE,
so entries can't be changed through the app or through SQL.
reason / reasonRemarks payload field names are not in the v1.12
sample JSON — confirm in sandbox.IRIS_EDIT_WINDOW_HOURS in server.js) a note is optional;
after that, a Commissioner approval reference is required. Invoices with debit notes can't be cancelled.Annex-C report → pick month + environment → Show (totals + first 50 lines) or Download Excel (CSV): one row per item of every invoice filed with FBR, same columns as the IRIS Annex-C, for reconciling with the sales tax return.
The item form searches HS/PCT codes by code or words (e.g. laptop, 0101).
npm run seed.itemdesccode list. FBR codes are shown first and are never
overwritten by the PCT import.HS_UOM) which units are valid for it and sets the UOM — a wrong UOM is a common FBR rejection.Receipts are 80mm with a 1×1 inch QR (v2, 25×25) of the FBR invoice number, per spec §6.
The official FBR Digital Invoicing System logo is included as public/fbr-di-logo.jpg, taken from the DI API v1.12 spec §6 (page 35). It prints next to the QR.
Browser ──► Vercel (public/ static) ──/api/* rewrite──► Render (Express API) ──► Supabase Postgres
│
└─► static-IP proxy ──► gw.fbr.gov.pk
?pgbouncer=true) into DATABASE_URL
and the Session pooler URL (port 5432) into DIRECT_URL. (The "direct" host is IPv6-only; Render needs the pooler.).env, then
npm run db:deploy && npm run seed.plan: free); fill the sync: false env vars.
Use the same ENCRYPTION_KEY as your local .env. Migrations run in the build step.public/ and forwards /api/*
to Render — edit the destination if your Render URL differs from digital-invoicing.onrender.com.https://<render-url>/healthz every 10 minutes during shop hours.public/, so just use the Render URL).pg_dump with DIRECT_URL).Every change to prisma/schema.prisma needs a migration: npm run db:migrate -- --name what_changed, commit the new folder.
See src/tax.js:
valueSalesExcludingST = qty × unit price − discount