feat: Add payment status endpoint with date filtering
Deploy Application / deploy (push) Successful in 31s
Details
Deploy Application / deploy (push) Successful in 31s
Details
This commit is contained in:
parent
2ad6c2759f
commit
766404ed8f
|
|
@ -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),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
if (fs.existsSync(candidate)) {
|
||||
existsFile = candidate;
|
||||
break;
|
||||
}
|
||||
} 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(candidate);
|
||||
mod = require(existsFile);
|
||||
} catch (reqErr) {
|
||||
// try dynamic import with file:// URL
|
||||
const url = pathToFileURL(candidate).href;
|
||||
const url = pathToFileURL(existsFile).href;
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
mod = await import(url);
|
||||
}
|
||||
|
||||
if (!mod || typeof mod.default !== "function") {
|
||||
throw new Error(
|
||||
`handler at ${candidate} not found or default export not a function`
|
||||
`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 });
|
||||
} catch (err) {
|
||||
lastErr = err;
|
||||
// try next candidate
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
throw lastErr || new Error("handler not found for gate");
|
||||
}
|
||||
|
||||
export default callGate;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue