feat: Add payment status endpoint with date filtering
Deploy Application / deploy (push) Successful in 31s Details

This commit is contained in:
faisolavolut 2025-10-31 08:18:49 +07:00
parent 2ad6c2759f
commit 766404ed8f
4 changed files with 89 additions and 36 deletions

View File

@ -438,3 +438,60 @@ export async function MidsuitPaymentV2(req: Request, res: Response) {
return res.status(200).json(result);
}
}
export async function paymentStatus(req: Request, res: Response) {
try {
const { c_invoice_id, startdate, enddate } = req.query as any;
if (!c_invoice_id) {
return res.status(400).json({ error: "c_invoice_id is required" });
}
const where: any = { c_invoice_id: Number(c_invoice_id) };
if (startdate || enddate) {
where.created_at = {} as any;
if (startdate) {
const s = new Date(String(startdate));
where.created_at.gte = s;
}
if (enddate) {
const e = new Date(String(enddate));
// include the whole end day by setting to end of day if time not provided
if (!String(enddate).includes("T")) {
e.setHours(23, 59, 59, 999);
}
where.created_at.lte = e;
}
}
const rows = await db.transactions_lines.findMany({
where: {
...where,
not: {
c_invoice_id: null,
},
},
include: { transactions: true },
orderBy: { created_at: "desc" },
});
const result = rows.map((r: any) => ({
id: r.id,
transaction_id: r.transaction_id,
amount: r.amount,
documentno: r.documentno,
c_invoice_id: r.c_invoice_id,
created_at: r.created_at,
tenant_id: r.tenant_id,
transaction_status: r.transactions ? r.transactions.status : null,
transaction_reference: r.transactions ? r.transactions.referenceNo : null,
}));
return res.json({ count: result.length, data: result });
} catch (err) {
console.error("paymentStatus error", err);
return res.status(500).json({
error: "internal_error",
detail: err instanceof Error ? err.message : String(err),
});
}
}

View File

@ -58,8 +58,6 @@ export async function getPoolForDbId(db_id: string) {
max: 10,
idleTimeoutMillis: 30000,
});
// poolCache.set(db_id, { pool, lastUsed: Date.now() });
return pool;
}

View File

@ -1,5 +1,6 @@
import path from "path";
import { pathToFileURL } from "url";
import fs from "fs";
export async function callGate(opts: {
client: string;
@ -12,49 +13,42 @@ export async function callGate(opts: {
// candidate paths to try (dev and prod)
const candidates = [
// development / ts-node: src .ts
// path.join(process.cwd(), "src", "lib", "bank", client, `${action}.ts`),
// // compiled production: dist .js
// path.join(process.cwd(), "dist", "lib", "bank", client, `${action}.js`),
// // relative to this file (useful when running from dist/lib)
// path.join(__dirname, "bank", client, `${action}.ts`),
path.join(__dirname, "bank", client, `${action}.ts`),
path.join(__dirname, "bank", client, `${action}.js`),
// path.join(__dirname, "..", "lib", "bank", client, `${action}.js`),
];
let lastErr: any = null;
let existsFile = null as any;
for (const candidate of candidates) {
try {
// prefer require when available (CommonJS build)
// require expects a path without file://
// but dynamic import needs a file:// URL for absolute paths
let mod: any;
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
mod = require(candidate);
} catch (reqErr) {
// try dynamic import with file:// URL
const url = pathToFileURL(candidate).href;
// eslint-disable-next-line no-await-in-loop
mod = await import(url);
if (fs.existsSync(candidate)) {
existsFile = candidate;
break;
}
if (!mod || typeof mod.default !== "function") {
throw new Error(
`handler at ${candidate} not found or default export not a function`
);
}
// call the handler with (user, session, data)
return await mod.default({ user, session, data });
} catch (err) {
lastErr = err;
// try next candidate
continue;
}
} catch (ex) {}
}
if (!existsFile) {
throw new Error(`handler not found for gate: ${client}/${action}`);
}
let mod: any;
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
mod = require(existsFile);
} catch (reqErr) {
// try dynamic import with file:// URL
const url = pathToFileURL(existsFile).href;
// eslint-disable-next-line no-await-in-loop
mod = await import(url);
}
throw lastErr || new Error("handler not found for gate");
if (!mod || typeof mod.default !== "function") {
throw new Error(
`handler at ${existsFile} not found or default export not a function`
);
}
// call the handler with (user, session, data)
return await mod.default({ user, session, data });
}
export default callGate;

View File

@ -75,6 +75,10 @@ export const setRoutes = () => {
router.post("/api/transfer", authMiddleware, async (req, res) =>
transferController.MidsuitPayment(req, res)
);
// Payment status lookup by c_invoice_id (optionally limit by startdate/enddate)
router.get("/api/va/status", authMiddleware, async (req, res) =>
transferController.paymentStatus(req, res)
);
// Signature generation for testing (uses PRIVATE_KEY_PATH file)
router.post("/generate-signature", (req, res) =>
signController.generateSignature(req, res)