add: gui sep requests
This commit is contained in:
133
index.js
133
index.js
@@ -855,7 +855,7 @@ app.post("/sep-pay-request", async (req, res) => {
|
|||||||
action: "token",
|
action: "token",
|
||||||
TerminalId: SEP_TERMINAL_ID,
|
TerminalId: SEP_TERMINAL_ID,
|
||||||
Amount: parsedAmount,
|
Amount: parsedAmount,
|
||||||
ResNum,
|
ResNum: resNum,
|
||||||
RedirectUrl: redirectUrl,
|
RedirectUrl: redirectUrl,
|
||||||
CellNumber: phone,
|
CellNumber: phone,
|
||||||
SettlementIBANInfo: wages,
|
SettlementIBANInfo: wages,
|
||||||
@@ -961,16 +961,8 @@ app.post("/sepverify", async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get("/sep-pay-requests/gui", async (req, res) => {
|
// all-payments: list of saved SEP pay requests (from MongoDB)
|
||||||
const basePath =
|
app.get("/all-payments", async (req, res) => {
|
||||||
(req.baseUrl || "").replace(/\/sep-pay-requests\/gui$/, "") || "";
|
|
||||||
const listPath = basePath
|
|
||||||
? basePath + "/sep-pay-requests"
|
|
||||||
: "/sep-pay-requests";
|
|
||||||
const submitPathPrefix = basePath
|
|
||||||
? basePath + "/sep-pay-request/"
|
|
||||||
: "/sep-pay-request/";
|
|
||||||
|
|
||||||
let list = [];
|
let list = [];
|
||||||
try {
|
try {
|
||||||
const coll = await getSepPayCollection();
|
const coll = await getSepPayCollection();
|
||||||
@@ -984,7 +976,7 @@ app.get("/sep-pay-requests/gui", async (req, res) => {
|
|||||||
_id: doc._id ? doc._id.toString() : doc._id,
|
_id: doc._id ? doc._id.toString() : doc._id,
|
||||||
}));
|
}));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("sep-pay-requests gui list error", err);
|
console.error("all-payments list error", err);
|
||||||
}
|
}
|
||||||
|
|
||||||
const listJson = JSON.stringify(list)
|
const listJson = JSON.stringify(list)
|
||||||
@@ -1000,75 +992,33 @@ app.get("/sep-pay-requests/gui", async (req, res) => {
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title>SEP Pay Requests</title>
|
<title>همه پرداختها</title>
|
||||||
<style>
|
<style>
|
||||||
* { box-sizing: border-box; }
|
* { box-sizing: border-box; }
|
||||||
body { font-family: Tahoma, Arial, sans-serif; margin: 0; padding: 16px; background: #f5f5f5; }
|
body { font-family: Tahoma, Arial, sans-serif; margin: 0; padding: 16px; background: #f5f5f5; }
|
||||||
h1 { color: #333; margin-bottom: 16px; }
|
h1 { color: #333; margin-bottom: 16px; }
|
||||||
.card { background: #fff; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); padding: 16px; margin-bottom: 12px; }
|
table { width: 100%; border-collapse: collapse; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,0.1); border-radius: 8px; overflow: hidden; }
|
||||||
.row { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; align-items: center; }
|
th, td { padding: 10px 12px; text-align: right; border-bottom: 1px solid #eee; }
|
||||||
.label { font-weight: bold; color: #555; min-width: 90px; }
|
th { background: #fafafa; font-weight: bold; color: #555; }
|
||||||
.value { color: #333; }
|
tr:hover { background: #f9f9f9; }
|
||||||
button { background: #1976d2; color: #fff; border: none; padding: 8px 16px; border-radius: 6px; cursor: pointer; font-size: 14px; margin-top: 8px; }
|
|
||||||
button:hover { background: #1565c0; }
|
|
||||||
.msg { margin-top: 8px; padding: 8px; border-radius: 6px; font-size: 14px; }
|
|
||||||
.msg.success { background: #e8f5e9; color: #2e7d32; }
|
|
||||||
.msg.error { background: #ffebee; color: #c62828; }
|
|
||||||
input { padding: 6px 8px; border: 1px solid #ccc; border-radius: 4px; width: 180px; }
|
|
||||||
#list { margin-top: 16px; }
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>درخواستهای پرداخت SEP</h1>
|
<h1>همه پرداختها</h1>
|
||||||
<p><a href="${listPath}">API لیست (JSON)</a></p>
|
|
||||||
<div id="list"></div>
|
<div id="list"></div>
|
||||||
<script>
|
<script>
|
||||||
(function() {
|
(function() {
|
||||||
const list = JSON.parse("${listJson}");
|
var list = JSON.parse("${listJson}");
|
||||||
const submitPathPrefix = ${JSON.stringify(submitPathPrefix)};
|
var listEl = document.getElementById('list');
|
||||||
const submitPath = function(id) { return submitPathPrefix + id + '/submit'; };
|
|
||||||
|
|
||||||
const listEl = document.getElementById('list');
|
|
||||||
if (!list || list.length === 0) {
|
if (!list || list.length === 0) {
|
||||||
listEl.innerHTML = '<p>موردی یافت نشد.</p>';
|
listEl.innerHTML = '<p>موردی یافت نشد.</p>';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
var rows = list.map(function(item) {
|
||||||
listEl.innerHTML = list.map(function(item) {
|
var createdAt = item.createdAt ? new Date(item.createdAt).toLocaleString('fa-IR') : '-';
|
||||||
const id = item._id;
|
return '<tr><td>' + (item.amountRaw || item.amount) + '</td><td>' + (item.provincecode || '-') + '</td><td>' + (item.isLink ? 'بله' : 'خیر') + '</td><td>' + (item.phone || '-') + '</td><td>' + createdAt + '</td></tr>';
|
||||||
const token = (item.token || '').toString();
|
|
||||||
const traceNo = (item.traceNo || '').toString();
|
|
||||||
const securePan = (item.securePan || '').toString();
|
|
||||||
const createdAt = item.createdAt ? new Date(item.createdAt).toLocaleString('fa-IR') : '-';
|
|
||||||
return '<div class="card" data-id="' + id + '">' +
|
|
||||||
'<div class="row"><span class="label">مبلغ:</span><span class="value">' + (item.amountRaw || item.amount) + '</span></div>' +
|
|
||||||
'<div class="row"><span class="label">استان:</span><span class="value">' + (item.provincecode || '-') + '</span></div>' +
|
|
||||||
'<div class="row"><span class="label">لینک:</span><span class="value">' + (item.isLink ? 'بله' : 'خیر') + '</span></div>' +
|
|
||||||
'<div class="row"><span class="label">Token:</span><span class="value">' + (token ? token.substring(0, 20) + '...' : '-') + '</span></div>' +
|
|
||||||
'<div class="row"><span class="label">RefId (TraceNo):</span><input type="text" id="ref-' + id + '" value="' + traceNo.replace(/"/g, '"') + '" placeholder="اختیاری" /></div>' +
|
|
||||||
'<div class="row"><span class="label">CardPan:</span><input type="text" id="pan-' + id + '" value="' + securePan.replace(/"/g, '"') + '" placeholder="اختیاری" /></div>' +
|
|
||||||
'<div class="row"><span class="label">تاریخ:</span><span class="value">' + createdAt + '</span></div>' +
|
|
||||||
'<button type="button" onclick="window.submitToTaavon(\\'' + id + '\\', this)">ارسال به تعاون (تراکنش موفق)</button>' +
|
|
||||||
'<div class="msg" id="msg-' + id + '"></div>' +
|
|
||||||
'</div>';
|
|
||||||
}).join('');
|
}).join('');
|
||||||
|
listEl.innerHTML = '<table><thead><tr><th>مبلغ</th><th>استان</th><th>لینک</th><th>موبایل</th><th>تاریخ</th></tr></thead><tbody>' + rows + '</tbody></table>';
|
||||||
window.submitToTaavon = async function(id, btn) {
|
|
||||||
const msgEl = document.getElementById('msg-' + id);
|
|
||||||
if (msgEl) { msgEl.textContent = ''; msgEl.className = 'msg'; }
|
|
||||||
btn.disabled = true;
|
|
||||||
var refId = (document.getElementById('ref-' + id) || {}).value || '';
|
|
||||||
var cardPan = (document.getElementById('pan-' + id) || {}).value || '';
|
|
||||||
var body = JSON.stringify({ refId: refId || undefined, cardHolderPan: cardPan || undefined });
|
|
||||||
try {
|
|
||||||
var r = await fetch(submitPath(id), { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: body });
|
|
||||||
var j = await r.json();
|
|
||||||
if (msgEl) { msgEl.textContent = j.error || (j.message || 'ارسال شد'); msgEl.className = 'msg ' + (j.error ? 'error' : 'success'); }
|
|
||||||
} catch (e) {
|
|
||||||
if (msgEl) { msgEl.textContent = e.message; msgEl.className = 'msg error'; }
|
|
||||||
}
|
|
||||||
btn.disabled = false;
|
|
||||||
};
|
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
@@ -1077,57 +1027,6 @@ app.get("/sep-pay-requests/gui", async (req, res) => {
|
|||||||
res.send(html);
|
res.send(html);
|
||||||
});
|
});
|
||||||
|
|
||||||
// List all SEP pay requests (API)
|
|
||||||
app.get("/sep-pay-requests", async (req, res) => {
|
|
||||||
try {
|
|
||||||
const coll = await getSepPayCollection();
|
|
||||||
const list = await coll
|
|
||||||
.find({})
|
|
||||||
.sort({ createdAt: -1 })
|
|
||||||
.limit(500)
|
|
||||||
.toArray();
|
|
||||||
// Ensure _id is string for GUI
|
|
||||||
const listWithIds = list.map((doc) => ({
|
|
||||||
...doc,
|
|
||||||
_id: doc._id ? doc._id.toString() : doc._id,
|
|
||||||
}));
|
|
||||||
return res.json(listWithIds);
|
|
||||||
} catch (err) {
|
|
||||||
console.error("sep-pay-requests list error", err);
|
|
||||||
return res.status(500).json({ error: err.message });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Manual submit to Taavon (like sepverify does) - use stored or body: authority, refId, cardHolderPan
|
|
||||||
app.post("/sep-pay-request/:id/submit", async (req, res) => {
|
|
||||||
const id = req.params.id;
|
|
||||||
const { authority, refId, cardHolderPan } = req.body;
|
|
||||||
try {
|
|
||||||
const coll = await getSepPayCollection();
|
|
||||||
const doc = await coll.findOne({ _id: new ObjectId(id) });
|
|
||||||
if (!doc) {
|
|
||||||
return res.status(404).json({ error: "Record not found" });
|
|
||||||
}
|
|
||||||
const province = (doc.provincecode || "").toString().substring(0, 2);
|
|
||||||
const isLink =
|
|
||||||
doc.isLink === true || doc.isLink === "true" || doc.isLink === "1";
|
|
||||||
const data = {
|
|
||||||
authority: authority ?? doc.token,
|
|
||||||
refId: refId ?? doc.traceNo,
|
|
||||||
cardHolderPan: cardHolderPan ?? doc.securePan,
|
|
||||||
};
|
|
||||||
if (isLink) {
|
|
||||||
await taavonSendDataZarinPalLink(province, data);
|
|
||||||
} else {
|
|
||||||
await taavonSendDataZarinPal(province, data);
|
|
||||||
}
|
|
||||||
return res.json({ ok: true, message: "Submitted to Taavon" });
|
|
||||||
} catch (err) {
|
|
||||||
console.error("sep-pay-request submit error", err);
|
|
||||||
return res.status(500).json({ error: err.message });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
//end sep ---------------------------------------------------------------------------------------------
|
//end sep ---------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// samasat crack
|
// samasat crack
|
||||||
|
|||||||
Reference in New Issue
Block a user