Problem: GST portal's public taxpayer search (services.gst.gov.in/
searchtp) now requires human CAPTCHA verification but no login.
The BIG-IP WAF blocks direct Node.js HTTP clients via TLS
fingerprinting; Playwright (real Chromium) bypasses it successfully.
Confirmed working: GSTIN 27AAHCP5787B1Z6 → full PELAGIA MARINE
SERVICES data including address, jurisdiction, filing status.
GstService/ (new standalone microservice):
- src/index.ts: Express + Playwright singleton browser
GET /health → { ok: true }
GET /captcha → launches browser, loads GST portal, fetches
CAPTCHA image from same origin (sets CaptchaCookie),
stores BrowserContext in session map (3 min TTL)
→ { sessionId, captchaBase64 }
POST /search → { sessionId, gstin, captcha } → submits form
via page.evaluate fetch() using live browser session,
closes context, returns parsed taxpayer data
- package.json, tsconfig.json, npm install
- src/test-lookup.ts: interactive CLI test (prompted user for captcha)
App changes:
- Remove playwright dep from Next.js app (was incorrectly added)
- Remove lib/gst-lookup.ts (sandbox.co.in placeholder — unused)
- Remove lib/gst-browser.ts (Playwright singleton — moved to service)
- app/api/gst/captcha/route.ts: thin proxy → GST_SERVICE_URL/captcha
- app/api/gst/route.ts: thin proxy POST → GST_SERVICE_URL/search
- vendor-form.tsx: two-step captcha UI
Step 1: "Look up" → calls /api/gst/captcha → shows PNG inline
Step 2: user types 6 digits → "Verify" → calls /api/gst → fills
form (name, address, lat/lng from Nominatim geocoding)
Wrong captcha → SWEB_9034 error with retry option
- .env.example: GST_SERVICE_URL=http://localhost:3002
Start the microservice: cd GstService && npm run dev
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
18 lines
702 B
TypeScript
18 lines
702 B
TypeScript
import { auth } from "@/auth";
|
|
import { NextResponse } from "next/server";
|
|
|
|
const GST_SERVICE = process.env.GST_SERVICE_URL ?? "http://localhost:3002";
|
|
|
|
/** Proxy: load GST portal page + fetch CAPTCHA → { sessionId, captchaBase64 } */
|
|
export async function GET() {
|
|
const session = await auth();
|
|
if (!session?.user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
|
|
try {
|
|
const res = await fetch(`${GST_SERVICE}/captcha`, { cache: "no-store" });
|
|
const data = await res.json();
|
|
return NextResponse.json(data, { status: res.ok ? 200 : 502 });
|
|
} catch (e) {
|
|
return NextResponse.json({ error: `GST service unavailable: ${String(e)}` }, { status: 502 });
|
|
}
|
|
}
|