Files

2779 lines
94 KiB
JavaScript
Raw Permalink Normal View History

2026-01-27 12:07:39 +03:30
// app.js
const express = require("express");
const moment = require("moment");
const cors = require("cors");
const app = express();
const port = 3000;
const bodyParser = require("body-parser");
const axios = require("axios");
const { toJalaali, toGregorian } = require("jalaali-js");
moment.locale("en");
const CryptoJS = require("crypto-js");
// app.options("*", cors);
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const {
config,
encrypt,
decrypt,
encryptWS,
decryptWS,
} = require("./lib/asan-pardakht-config");
// Middleware to parse JSON requests
app.use(express.json());
app.use(cors());
const querystring = require("querystring");
const https = require("https");
2026-02-01 10:26:22 +03:30
const cookieParser = require("cookie-parser");
const crypto = require("crypto");
app.use(cookieParser());
2026-01-27 12:07:39 +03:30
// const mellat = new mellatCheckout({
// terminalId: "7269507",
// username: "7269507",
// password: "66506956",
// timeout: 10000,
// apiUrl: "https://bpm.shaparak.ir/pgwchannel/services/pgw?wsdl",
// });
// const apiUrl = "https://bpm.shaparak.ir/pgwchannel/services/pgw?wsdl";
// function _interopRequireDefault(obj) {
// return obj && obj.__esModule ? obj : { default: obj };
// }
// var _soap = require("soap");
// const soap = require("soap");
const { bpReversalRequest } = require("./lib/bp-reversal-request");
const { bpInquiryRequest } = require("./lib/bp-inquiry-request");
const { bpVerifyRequest } = require("./lib/bp-verify-request");
const { bpPayRequest } = require("./lib/bp-pay-request");
const { bpSettleRequest } = require("./lib/bp-settle-request");
const {
bpCumulativeDynamicPayRequest,
} = require("./lib/bp-cumulative-dynamic-pay-request");
const {
taavonSendData,
taavonSendDataZarinPal,
taavonSendDataZarinPalLink,
} = require("./lib/taavon-send-data");
const { getAllCities } = require("./lib/getAllCities");
const { getAllProvinces } = require("./lib/getAllProvinces");
2026-02-01 08:32:36 +03:30
const { MongoClient, ObjectId } = require("mongodb");
const MONGODB_URI =
process.env.MONGODB_URI ||
"mongodb://root:2pCCFs4wrsLDsO1pjQVA9jORT2WCjLNO5uauS6FUUaGLXCcfjw28IJmAO8RxlEJN@31.7.78.133:14365/?authSource=admin";
const SEP_DB_NAME = "rasadyar";
const SEP_COLLECTION = "sepPayRequests";
let mongoClient = null;
async function getMongoClient() {
if (!mongoClient) {
mongoClient = new MongoClient(MONGODB_URI);
await mongoClient.connect();
}
return mongoClient;
}
async function getSepPayCollection() {
const client = await getMongoClient();
return client.db(SEP_DB_NAME).collection(SEP_COLLECTION);
}
2026-01-27 12:07:39 +03:30
// var _soap2 = _interopRequireDefault(_soap);
// var behpardakhtClient;
// _soap2.default.createClient(
// apiUrl,
// {
// overrideRootElement: {
// namespace: "ns1",
// },
// },
// function (error, client) {
// if (error) {
// // return callback(error);
// console.log("error", error);
// }
// console.log("Behpardakht Client Is Ready!");
// behpardakhtClient = client;
// // return callback(null);
// return null;
// }
// );
app.post("/cumulative-dynamic-pay-request", async (req, res) => {
// const orderId = moment().valueOf();
const orderId = req.body.orderId;
const amount = req.body.amount;
const additionalData = req.body.additionalData;
// let payRequestResult = await bpPayRequest(
// parseInt(orderId),
// 10000,
// "ok",
// "https://rasadyar.net/verify-payment"
// );
// additionalData: "9700383709,10000,0;1031990414,10000,0;",
let payRequestResult = await bpCumulativeDynamicPayRequest(
parseInt(orderId),
amount,
additionalData,
2026-02-01 08:32:36 +03:30
"https://rasadyar.net/verify-payment",
2026-01-27 12:07:39 +03:30
);
const payRequestRes = payRequestResult.return.split(",");
const responseCode = payRequestRes[0];
const refId = payRequestRes[1];
if (parseInt(responseCode) === 0) {
return res.json({ refId });
}
console.log("error: ", payRequestResult);
return res
.status(400)
.json({ error: desribtionStatusCode(parseInt(payRequestResult)) });
// var now = new Date();
// const bpPayRequestCallback = function (error, result) {
// console.log(result, "gggggg");
// if (error) {
// console.log("error", error);
// }
// var parsed = result.return.split(",");
// if (parsed.length < 2) {
// return {
// resCode: Number(parsed[0]),
// rawResCode: parsed[0],
// refId: null,
// };
// }
// var refId = parsed[1];
// // const redirectUrl = `https://bpm.shaparak.ir/pgwchannel/startpay.mellat?RefId=${refId}`;
// // // Redirect the user to the constructed URL
// // res.set('Referrer', 'https://rasadyar.net'); // Set the Referrer header
// // res.redirect(redirectUrl);
// return res.json({
// resCode: 0,
// rawResCode: "0",
// refId: refId,
// });
// };
// const localDate = moment().format("YYYYMMDD");
// const localTime = moment().format("HHmmss");
// const orderId = moment().valueOf();
// behpardakhtClient.bpPayRequest(
// {
// terminalId: 7269507,
// userName: "7269507",
// userPassword: "66506956",
// orderId: parseInt(orderId),
// amount: 10000,
// localDate: localDate,
// localTime: localTime,
// additionalData: "",
// payerId: 0,
// callBackUrl: "https://rasadyar.net/verify-payment", // Payment Callback URL
// },
// bpPayRequestCallback
// );
});
async function reversePay(orderId, saleOrderId, saleReferenceId) {
let resultReversePay = await bpReversalRequest(
orderId,
saleOrderId,
2026-02-01 08:32:36 +03:30
saleReferenceId,
2026-01-27 12:07:39 +03:30
);
resultReversePay = resultReversePay.return;
console.log(resultReversePay);
}
function desribtionStatusCode(statusCode) {
switch (statusCode) {
case 0:
return "ﺗﺮاﻛﻨﺶ_ﺑ_ﻣﻮﻓﻘﻴﺖ_اﻧﺠم_ﺷﺪ";
case 11:
return "ﺷﻤره_ﻛرت_ﻧﻣﻌﺘﺒﺮ_اﺳﺖ";
case 12:
return "ﻣﻮﺟﻮدي_ﻛﻓﻲ_ﻧﻴﺴﺖ";
case 13:
return "رﻣﺰ_ﻧدرﺳﺖ_اﺳﺖ";
case 14:
return "ﺗﻌﺪاد_دﻓﻌت_وارد_ﻛﺮدن_رﻣﺰ_ﺑﻴﺶ_از_ﺣﺪ_ﻣﺠز_اﺳﺖ";
case 15:
return "ﻛرت_ﻧﻣﻌﺘﺒﺮ_اﺳﺖ";
case 16:
return "دﻓﻌت_ﺑﺮداﺷﺖ_وﺟ_ﺑﻴﺶ_از_ﺣﺪ_ﻣﺠز_اﺳﺖ";
case 17:
return "ﻛرﺑﺮ_از_اﻧﺠم_ﺗﺮاﻛﻨﺶ_ﻣﻨﺼﺮف_ﺷﺪه_اﺳﺖ";
case 18:
return "ﺗرﻳﺦ_اﻧﻘﻀي_ﻛرت_ﮔﺬﺷﺘ_اﺳﺖ";
case 19:
return "ﻣﺒﻠﻎ_ﺑﺮداﺷﺖ_وﺟ_ﺑﻴﺶ_از_ﺣﺪ_ﻣﺠز_اﺳﺖ";
case 111:
return "ﺻدر_ﻛﻨﻨﺪه_ﻛرت_ﻧﻣﻌﺘﺒﺮ_اﺳﺖ";
case 112:
return "ﺧﻄي_ﺳﻮﻳﻴﭻ_ﺻدر_ﻛﻨﻨﺪه_ﻛرت";
case 113:
return "ﭘﺳﺨﻲ_از_ﺻدر_ﻛﻨﻨﺪه_ﻛرت_درﻳﻓﺖ_ﻧﺸﺪ";
case 114:
return ارﻧﺪه_ﻛرت_ﻣﺠز_ﺑ_اﻧﺠم_اﻳﻦ_ﺗﺮاﻛﻨﺶ_ﻧﻴﺴﺖ";
case 21:
return "ﭘﺬﻳﺮﻧﺪه_ﻧﻣﻌﺘﺒﺮ_اﺳﺖ";
case 23:
return "ﺧﻄي_اﻣﻨﻴﺘﻲ_رخ_داده_اﺳﺖ";
case 24:
return "اﻃﻼﻋت_ﻛرﺑﺮي_ﭘﺬﻳﺮﻧﺪه_ﻧﻣﻌﺘﺒﺮ_اﺳﺖ";
case 25:
return "ﻣﺒﻠﻎ_ﻧﻣﻌﺘﺒﺮ_اﺳﺖ";
case 31:
return "ﭘﺳﺦ_ﻧﻣﻌﺘﺒﺮ_اﺳﺖ";
case 32:
return "ﻓﺮﻣﺖ_اﻃﻼﻋت_وارد_ﺷﺪه_ﺻﺤﻴﺢ_ﻧﻤﻲ_ﺑﺷﺪ";
case 33:
return "ﺣﺴب_ﻧﻣﻌﺘﺒﺮ_اﺳﺖ";
case 34:
return "ﺧﻄي_ﺳﻴﺴﺘﻤﻲ";
case 35:
return "ﺗرﻳﺦ_ﻧﻣﻌﺘﺒﺮ_اﺳﺖ";
case 41:
return "ﺷﻤره_درﺧﻮاﺳﺖ_ﺗﻜﺮاري_اﺳﺖ";
case 42:
return "ﺗﺮاﻛﻨﺶ_Sale_یافت_نشد_";
case 43:
return "ﻗﺒﻼ_Verify_درﺧﻮاﺳﺖ_داده_ﺷﺪه_اﺳﺖ";
case 44:
return "درخواست_verify_یافت_نشد";
case 45:
return "ﺗﺮاﻛﻨﺶ_Settle_ﺷﺪه_اﺳﺖ";
case 46:
return "ﺗﺮاﻛﻨﺶ_Settle_نشده_اﺳﺖ";
case 47:
return "ﺗﺮاﻛﻨﺶ_Settle_یافت_نشد";
case 48:
return "تراکنش_Reverse_شده_است";
case 49:
return "تراکنش_Refund_یافت_نشد";
case 412:
return "شناسه_قبض_نادرست_است";
case 413:
return "ﺷﻨ_ﭘﺮداﺧﺖ_ﻧدرﺳﺖ_اﺳﺖ";
case 414:
return ازﻣن_ﺻدر_ﻛﻨﻨﺪه_ﻗﺒﺾ_ﻧﻣﻌﺘﺒﺮ_اﺳﺖ";
case 415:
return "زﻣن_ﺟﻠﺴ_ﻛري_ﺑ_ﭘن_رسیده_است";
case 416:
return "ﺧﻄ_در_ﺛﺒﺖ_اﻃﻼﻋت";
case 417:
return "ﺷﻨ_ﭘﺮداﺧﺖ_ﻛﻨﻨﺪه_ﻧﻣﻌﺘﺒﺮ_اﺳﺖ";
case 418:
return "اﺷﻜل_در_ﺗﻌﺮﻳﻒ_اﻃﻼﻋت_ﻣﺸﺘﺮي";
case 419:
return "ﺗﻌﺪاد_دﻓﻌت_ورود_اﻃﻼﻋت_از_ﺣﺪ_ﻣﺠز_ﮔﺬﺷﺘ_اﺳﺖ";
case 421:
return "IP_نامعتبر_است";
case 51:
return "ﺗﺮاﻛﻨﺶ_ﺗﻜﺮاري_اﺳﺖ";
case 54:
return "ﺗﺮاﻛﻨﺶ_ﻣﺮﺟﻊ_ﻣﻮﺟﻮد_ﻧﻴﺴﺖ";
case 55:
return "ﺗﺮاﻛﻨﺶ_ﻧﻣﻌﺘﺒﺮ_اﺳﺖ";
case 61:
return "ﺧﻄ_در_واریز";
}
return "";
}
app.post("/verify-payment", async (req, res) => {
let Run_bpReversalRequest = false;
let saleReferenceId = -999;
let saleOrderId = -999;
let resultCode_bpPayRequest;
if (
req.body === null ||
req.body?.ResCode === null ||
req.body?.SaleOrderId === null ||
req.body?.SaleReferenceId === null ||
req.body?.CardHolderPan === null
) {
return res
.status(422)
.json({ error: "پارامترهای لازم از طرف بانک ارسال نشد." });
}
saleReferenceId = parseInt(req.body.SaleReferenceId, 10);
saleOrderId = parseInt(req.body.SaleOrderId, 10);
resultCode_bpPayRequest = parseInt(req.body.ResCode);
const finalAmount = req.body.FinalAmount;
const refId = req.body.RefId;
const cardHolderPan = req.body.CardHolderPan;
//Result Code
let resultCode_bpinquiryRequest = "-9999";
let resultCode_bpSettleRequest = "-9999";
let resultCode_bpVerifyRequest = "-9999";
let redirectUrlError = "";
const provinceCode = saleOrderId.toString().substring(0, 2);
if (provinceCode === "10") {
redirectUrlError = `https://check.rasadyar.net/payment?error=`;
} else if (provinceCode === "15") {
redirectUrlError = `https://sha.rasadyar.net/payment?error=`;
} else if (provinceCode === "18") {
redirectUrlError = `https://ha.rasadyar.net/payment?error=`;
} else if (provinceCode === "91") {
redirectUrlError = `https://ar.rasadyar.net/payment?error=`;
} else if (provinceCode === "47") {
redirectUrlError = `https://ma.rasadyar.net/payment?error=`;
}
if (parseInt(resultCode_bpPayRequest) === 17) {
const error = desribtionStatusCode(parseInt(resultCode_bpPayRequest));
console.log("uwuwuwuwuwuwu", error);
await taavonSendData(saleOrderId, { error, refId });
return res.redirect(redirectUrlError + "کاربر از انجام تراکنش منصرف شد!");
}
if (resultCode_bpPayRequest === 0) {
//verify request
resultCode_bpVerifyRequest = await bpVerifyRequest(
saleOrderId,
saleOrderId,
2026-02-01 08:32:36 +03:30
saleReferenceId,
2026-01-27 12:07:39 +03:30
);
resultCode_bpVerifyRequest = resultCode_bpVerifyRequest.return;
console.log("bpVerifyRequest:" + resultCode_bpVerifyRequest);
if (
resultCode_bpVerifyRequest === null ||
resultCode_bpVerifyRequest.length === 0
) {
//Inquiry Request
resultCode_bpinquiryRequest = await bpInquiryRequest(
saleOrderId,
saleOrderId,
2026-02-01 08:32:36 +03:30
saleReferenceId,
2026-01-27 12:07:39 +03:30
);
resultCode_bpinquiryRequest = parseInt(
2026-02-01 08:32:36 +03:30
resultCode_bpinquiryRequest.return,
2026-01-27 12:07:39 +03:30
);
console.log("bpinquiryRequest" + resultCode_bpinquiryRequest);
if (resultCode_bpinquiryRequest !== 0) {
reversePay(saleOrderId, saleOrderId, saleReferenceId);
const error = desribtionStatusCode(resultCode_bpinquiryRequest);
await taavonSendData(saleOrderId, { error, refId });
return res.json({ error });
}
}
if (
parseInt(resultCode_bpVerifyRequest) === 0 ||
resultCode_bpinquiryRequest === 0
) {
//SettleRequest
resultCode_bpSettleRequest = await bpSettleRequest(
saleOrderId,
saleOrderId,
2026-02-01 08:32:36 +03:30
saleReferenceId,
2026-01-27 12:07:39 +03:30
);
resultCode_bpSettleRequest = parseInt(resultCode_bpSettleRequest.return);
//ﺗﺮاﻛﻨﺶ_Settle_ﺷﺪه_اﺳﺖ
//ﺗﺮاﻛﻨﺶ_ﺑ_ﻣﻮﻓﻘﻴﺖ_اﻧﺠم_ﺷﺪ
if (
resultCode_bpSettleRequest === 0 ||
resultCode_bpSettleRequest === 45
) {
//success payment
const data = {
saleReferenceId,
saleOrderId,
cardHolderPan,
date: new Date(),
finalAmount,
refId,
};
let redirectUrl = "";
let subDomain = "test";
const provinceCode = saleOrderId.toString().substring(0, 2);
console.log({ data, provinceCode });
if (provinceCode === "10") {
subDomain = "test";
redirectUrl = `https://check.rasadyar.net/payment?finalAmount=${finalAmount}&saleOrderId=${saleOrderId}&cardHolderPan=${cardHolderPan}&date=${data.date}&saleReferenceId=${saleReferenceId}`;
} else if (provinceCode === "15") {
subDomain = "sha";
redirectUrl = `https://sha.rasadyar.net/payment?finalAmount=${finalAmount}&saleOrderId=${saleOrderId}&cardHolderPan=${cardHolderPan}&date=${data.date}&saleReferenceId=${saleReferenceId}`;
} else if (provinceCode === "18") {
subDomain = "ha";
redirectUrl = `https://ha.rasadyar.net/payment?finalAmount=${finalAmount}&saleOrderId=${saleOrderId}&cardHolderPan=${cardHolderPan}&date=${data.date}&saleReferenceId=${saleReferenceId}`;
} else if (provinceCode === "91") {
subDomain = "ar";
redirectUrl = `https://ar.rasadyar.net/payment?finalAmount=${finalAmount}&saleOrderId=${saleOrderId}&cardHolderPan=${cardHolderPan}&date=${data.date}&saleReferenceId=${saleReferenceId}`;
} else if (provinceCode === "47") {
subDomain = "ma";
redirectUrl = `https://ma.rasadyar.net/payment?finalAmount=${finalAmount}&saleOrderId=${saleOrderId}&cardHolderPan=${cardHolderPan}&date=${data.date}&saleReferenceId=${saleReferenceId}`;
}
//save success payment into db
const url = `https://${subDomain}backend.rasadyar.com/wage_payment_final_step/`;
const options = {
method: "POST",
body: JSON.stringify(data),
headers: {
"Content-Type": "application/json",
},
};
try {
const r = await fetch(url, options);
} catch (error) {
return res.json({ error: "اطلاعات پرداخت ذخیره نشد!" });
}
return res.redirect(redirectUrl);
}
} else {
if (saleOrderId != -999 && saleReferenceId != -999) {
if (resultCode_bpPayRequest !== 17)
reversePay(saleOrderId, saleOrderId, saleReferenceId);
}
const error = desribtionStatusCode(resultCode_bpVerifyRequest);
try {
await taavonSendData(saleOrderId, { error, refId });
} catch (error) {
return res.json({ error: "اطلاعات پرداخت ذخیره نشد!" });
}
return res.json({ error });
}
} else {
if (saleOrderId != -999 && saleReferenceId != -999) {
if (resultCode_bpPayRequest !== 17)
reversePay(saleOrderId, saleOrderId, saleReferenceId);
const error = desribtionStatusCode(resultCode_bpPayRequest);
try {
taavonSendData(saleOrderId, { error, refId });
} catch (error) {
return res.json({ error: "اطلاعات پرداخت ذخیره نشد!" });
}
return res.json({ error });
}
}
});
//zarinpal ---------------------------------------------------------------------------------------------------
const MERCHANT_ID = "7ad4aa9d-a153-4b94-b850-552ecf690a4a";
const ZARINPAL_API = "https://api.zarinpal.com/pg/v4/payment/request.json";
const ZARINPAL_API_VERIFY =
"https://api.zarinpal.com/pg/v4/payment/verify.json";
app.post("/zarinpay", async (req, res) => {
const { amount, description, provincecode, wages, isLink } = req.body;
if (!amount || !description) {
return res.status(400).send("Invalid request parameters");
}
const parsedAmount = parseInt(amount);
if (isNaN(parsedAmount)) {
return res.status(400).send("Invalid amount");
}
try {
const response = await axios.post(
ZARINPAL_API,
{
merchant_id: MERCHANT_ID,
amount: parsedAmount,
description: description,
callback_url: `https://pay.rasadyar.com/zarinverify/?amount=${amount}&province=${provincecode}&isLink=${isLink}`,
wages: wages,
},
{
headers: {
"Content-Type": "application/json",
accept: "application/json",
},
2026-02-01 08:32:36 +03:30
},
2026-01-27 12:07:39 +03:30
);
if (response.data.data.authority) {
return res.status(201).json(response.data.data);
} else {
return res
.status(500)
.json({ error: "Error Init Payment", data: response.data.errors });
}
console.log("Verification response: ", response.data);
} catch (error) {
return res
.status(500)
.json({ error: "Error in accessing ZarinPal", data: error });
}
});
app.get("/zarinverify", async (req, res) => {
const { Authority, Status, amount, province, isLink } = req.query;
if (!Authority || !Status || !amount || !province) {
return res.status(400).send("Invalid request parameters");
}
if (Status === "OK") {
try {
const response = await axios.post(
ZARINPAL_API_VERIFY,
{
merchant_id: MERCHANT_ID,
authority: Authority,
amount: amount,
},
{
headers: {
"Content-Type": "application/json",
accept: "application/json",
},
2026-02-01 08:32:36 +03:30
},
2026-01-27 12:07:39 +03:30
);
console.log("Verification response in verify: ", response.data);
if (response.data.data.code === 100 || response.data.data.code === 101) {
let redirectUrl = `https://rasadyar.net/payment?finalAmount=${amount}&cardHolderPan=${
response.data.data.card_pan
}&date=${new Date()}&saleReferenceId=${response.data.data.ref_id}`;
let subDomain = "";
// if (province.substring(0, 2) === "10") {
// subDomain = "test";
// redirectUrl = `https://check.rasadyar.net/payment?finalAmount=${amount}&cardHolderPan=${
// response.data.data.card_pan
// }&date=${new Date()}&saleReferenceId=${response.data.data.ref_id}`;
// } else if (province.substring(0, 2) === "15") {
// subDomain = "sha";
// redirectUrl = `https://sha.rasadyar.net/payment?finalAmount=${amount}&cardHolderPan=${
// response.data.data.card_pan
// }&date=${new Date()}&saleReferenceId=${response.data.data.ref_id}`;
// } else if (province.substring(0, 2) === "18") {
// subDomain = "ha";
// redirectUrl = `https://ha.rasadyar.net/payment?finalAmount=${amount}&cardHolderPan=${
// response.data.data.card_pan
// }&date=${new Date()}&saleReferenceId=${response.data.data.ref_id}`;
// } else if (province.substring(0, 2) === "91") {
// subDomain = "ar";
// redirectUrl = `https://ar.rasadyar.net/payment?finalAmount=${amount}&cardHolderPan=${
// response.data.data.card_pan
// }&date=${new Date()}&saleReferenceId=${response.data.data.ref_id}`;
// } else if (province.substring(0, 2) === "47") {
// subDomain = "ma";
// redirectUrl = `https://ma.rasadyar.net/payment?finalAmount=${amount}&cardHolderPan=${
// response.data.data.card_pan
// }&date=${new Date()}&saleReferenceId=${response.data.data.ref_id}`;
// }
if (isLink) {
await taavonSendDataZarinPalLink(province, {
authority: Authority,
refId: response.data.data.ref_id,
cardHolderPan: response.data.data.card_pan,
});
} else {
await taavonSendDataZarinPal(province, {
authority: Authority,
refId: response.data.data.ref_id,
cardHolderPan: response.data.data.card_pan,
});
}
return res.redirect(redirectUrl);
}
} catch (error) {
res.status(400).send("Payment was not successful.");
}
} else {
let redirectUrlError = `https://rasadyar.net/payment?error=`;
// if (province.substring(0, 2) === "10") {
// redirectUrlError = `https://check.rasadyar.net/payment?error=`;
// } else if (province.substring(0, 2) === "15") {
// redirectUrlError = `https://sha.rasadyar.net/payment?error=`;
// } else if (province.substring(0, 2) === "18") {
// redirectUrlError = `https://ha.rasadyar.net/payment?error=`;
// } else if (province.substring(0, 2) === "91") {
// redirectUrlError = `https://ar.rasadyar.net/payment?error=`;
// } else if (province.substring(0, 2) === "47") {
// redirectUrlError = `https://ma.rasadyar.net/payment?error=`;
// }
await taavonSendDataZarinPal(province, {
error: "کاربر از انجام تراکنش منصرف شد!",
authority: Authority,
});
return res.redirect(redirectUrlError + "کاربر از انجام تراکنش منصرف شد!");
}
});
//sadad ---------------------------------------------------------------------------------------------------
const encrypt_pkcs7 = (data, key) => {
const keyHex = CryptoJS.enc.Base64.parse(key);
const encrypted = CryptoJS.TripleDES.encrypt(data, keyHex, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7,
});
return encrypted.toString();
};
app.post("/sadad-get-token", async (req, res) => {
const { data } = req.body;
try {
const response = await axios.post(
"https://sadad.shaparak.ir/api/v0/Request/PaymentRequest",
data,
{
headers: {
"Content-Type": "application/json",
Referer: "https://rasadyar.net/",
},
2026-02-01 08:32:36 +03:30
},
2026-01-27 12:07:39 +03:30
);
res.status(201).send(response.data);
} catch (error) {
res.status(500).send(error.message);
}
});
app.post("/sadad-request-payment", async (req, res) => {
const now = new Date();
const { OrderId, Amount, province } = req.body;
const month = String(now.getMonth() + 1).padStart(2, "0");
const day = String(now.getDate()).padStart(2, "0");
const year = now.getFullYear();
const hours = now.getHours();
const minutes = String(now.getMinutes()).padStart(2, "0");
const seconds = String(now.getSeconds()).padStart(2, "0");
const ampm = hours >= 12 ? "pm" : "am";
const formattedHours = hours % 12 || 12;
const key = "H8eOhSGAeKol46gNfb39dqbMFn0VJKbe";
const MerchantId = "000000140345422";
const TerminalId = "24107875";
const LocalDateTime = `${month}/${day}/${year} ${formattedHours}:${minutes}:${seconds} ${ampm}`;
const ReturnUrl = `https://rasadyar.net/sadad-verify?province=${province}&Amount=${Amount}`;
const dataToEncrypt = `${TerminalId};${OrderId};${Amount}`;
// Encrypt the data
const SignData = encrypt_pkcs7(dataToEncrypt, key);
const data = {
Amount: Amount,
OrderId: OrderId,
LocalDateTime: LocalDateTime,
ReturnUrl: ReturnUrl,
SignData: SignData,
TerminalId: TerminalId,
MerchantId: MerchantId,
};
console.log("Request Data:", data);
try {
const response = await axios.post(
"https://rasadyar.net/sadad-get-token",
{ data: data },
{
headers: {
"Content-Type": "application/json",
Referer: "https://rasadyar.net/",
},
2026-02-01 08:32:36 +03:30
},
2026-01-27 12:07:39 +03:30
);
const responseData = response.data;
if (responseData.ResCode === 0) {
res.status(201).send(responseData);
} else {
res.status(400).send(responseData);
}
} catch (error) {
res.status(500).send(error.message);
}
});
//asanpardakht ---------------------------------------------------------------------------------------------
app.post("/asanpay", async (req, res) => {
const { price } = req.body;
const orderId = Math.floor(Math.random() * 1000000);
const localDate = new Date()
.toISOString()
.replace(/T/, " ")
.replace(/\..+/, "");
const additionalData = "";
const callBackUrl = "https://rasadyar.net/asanverify";
const reqString = `1,${config.username},${config.password},${orderId},${price},${localDate},${additionalData},${callBackUrl},0`;
const encryptedRequest = await encryptWS(reqString);
const soapClient = await soap.createClientAsync(config.WebServiceUrl);
const args = {
merchantConfigurationID: config.merchantConfigurationID,
encryptedRequest: encryptedRequest,
};
soapClient.RequestOperation(args, (err, result) => {
if (err) {
res.status(500).send("خطا در فراخوانی وب‌سرویس.");
} else {
const response = result.RequestOperationResult;
if (response.startsWith("0,")) {
const refId = response.slice(2);
res.redirect(`https://asan.shaparak.ir/?RefId=${refId}`);
} else {
res.status(400).send(`خطای شماره: ${response}`);
}
}
});
});
app.post("/asanverify", async (req, res) => {
const { ReturningParams } = req.body;
const decryptedParams = await decryptWS(ReturningParams);
const params = decryptedParams.split(",");
if (params[3] !== "0" && params[3] !== "00") {
return res.status(400).send(`تراکنش ناموفق<br>خطای شماره: ${params[3]}`);
}
const encryptedCredintials = await encryptWS(
2026-02-01 08:32:36 +03:30
`${config.username},${config.password}`,
2026-01-27 12:07:39 +03:30
);
const soapClient = await soap.createClientAsync(config.WebServiceUrl);
const verifyArgs = {
merchantConfigurationID: config.merchantConfigurationID,
encryptedCredentials: encryptedCredintials,
payGateTranID: params[5],
};
soapClient.RequestVerification(verifyArgs, (err, verifyResult) => {
if (err || verifyResult.RequestVerificationResult !== "500") {
return res
.status(500)
.send(
2026-02-01 08:32:36 +03:30
`خطای شماره: ${verifyResult.RequestVerificationResult} در هنگام Verify`,
2026-01-27 12:07:39 +03:30
);
}
soapClient.RequestReconciliation(verifyArgs, (err, settlementResult) => {
if (err || settlementResult.RequestReconciliationResult !== "600") {
return res
.status(500)
.send(
2026-02-01 08:32:36 +03:30
`خطای شماره: ${settlementResult.RequestReconciliationResult} در هنگام Settlement`,
2026-01-27 12:07:39 +03:30
);
}
res.send(
2026-02-01 08:32:36 +03:30
'<div style="width:250px; margin:100px auto; direction:rtl; font:bold 14px Tahoma">تراکنش با موفقیت انجام پذیرفت.</div>',
2026-01-27 12:07:39 +03:30
);
});
});
});
//sep -------------------------------------------------------------------------------------------------
function generateRandomString() {
const numbers = "0123456789";
const lowerCase = "abcdefghijklmnopqrstuvwxyz";
const upperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const specialChars = "!@#$%^&*()_+-=[]{}|;:,.<>?";
const getRandomChar = (chars) =>
chars[Math.floor(Math.random() * chars.length)];
const num = getRandomChar(numbers);
const lower = getRandomChar(lowerCase);
const upper = getRandomChar(upperCase);
const special = getRandomChar(specialChars);
const combined = [num, lower, special, upper].join("");
return combined
.split("")
.sort(() => Math.random() - 0.5)
.join("");
}
const SEP_TERMINAL_ID = 21608844;
const SEP_TERMINAL_PASS = 9238787;
const SEP_API = "https://sep.shaparak.ir/onlinepg/onlinepg";
const SEP_API_VERIFY =
"https://sep.shaparak.ir/verifyTxnRandomSessionkey/ipg/VerifyTransaction";
app.post("/sep-pay-request", async (req, res) => {
const { amount, phone, provincecode, isLink, wages } = req.body;
if (!amount) {
return res.status(400).send("Invalid request parameters");
}
const parsedAmount = parseInt(amount);
if (isNaN(parsedAmount)) {
return res.status(400).send("Invalid amount");
}
2026-02-01 08:32:36 +03:30
const resNum = generateRandomString();
const redirectUrl = `https://pay.rasadyar.net/sepverify/?Amount=${amount}&province=${provincecode}&isLink=${isLink}`;
2026-01-27 12:07:39 +03:30
try {
const response = await axios.post(
SEP_API,
{
action: "token",
TerminalId: SEP_TERMINAL_ID,
Amount: parsedAmount,
2026-02-01 09:43:51 +03:30
ResNum: resNum,
2026-02-01 08:32:36 +03:30
RedirectUrl: redirectUrl,
2026-01-27 12:07:39 +03:30
CellNumber: phone,
SettlementIBANInfo: wages,
// TranType: "Government",
},
{
headers: {
"Content-Type": "application/json",
accept: "application/json",
},
2026-02-01 08:32:36 +03:30
},
2026-01-27 12:07:39 +03:30
);
2026-02-01 08:32:36 +03:30
try {
const coll = await getSepPayCollection();
const token = response.data?.Token ?? response.data?.token ?? null;
await coll.insertOne({
amount: parsedAmount,
amountRaw: amount,
phone: phone || null,
provincecode: provincecode || null,
isLink: isLink || null,
wages: wages || null,
resNum,
redirectUrl,
token,
rawResponse: response.data,
verified: false,
refNum: null,
traceNo: null,
securePan: null,
createdAt: new Date(),
updatedAt: new Date(),
});
} catch (dbErr) {
console.error("SEP pay request: failed to save to DB", dbErr);
}
2026-01-27 12:07:39 +03:30
return res.status(201).json(response.data);
} catch (error) {
return res
.status(500)
.json({ error: "Error in accessing SEP", data: error });
}
});
app.post("/sepverify", async (req, res) => {
const { State, Amount, RefNum, Token, TraceNo, SecurePan } = req.body;
const { province, isLink } = req.query;
if (!State || !Amount || !Token || !province || !isLink) {
return res.status(400).send("Missing required parameters");
}
if (State === "OK") {
try {
const response = await axios.post(
SEP_API_VERIFY,
{ RefNum: RefNum, TerminalNumber: SEP_TERMINAL_ID },
{
headers: {
"Content-Type": "application/json",
accept: "application/json",
},
2026-02-01 08:32:36 +03:30
},
2026-01-27 12:07:39 +03:30
);
if (response.data.ResultCode === 0) {
let redirectUrl = `https://rasadyar.net/payment?finalAmount=${Amount}&cardHolderPan=${SecurePan}&date=${new Date()}&saleReferenceId=${TraceNo}`;
2026-02-01 08:32:36 +03:30
2026-01-27 12:07:39 +03:30
if (isLink) {
await taavonSendDataZarinPalLink(province, {
authority: Token,
refId: TraceNo,
cardHolderPan: SecurePan,
});
} else {
await taavonSendDataZarinPal(province, {
authority: Token,
refId: TraceNo,
cardHolderPan: SecurePan,
});
}
return res.redirect(redirectUrl);
}
} catch (error) {
await taavonSendDataZarinPal(province, {
error: "تراکنش نامشخص!",
authority: Token,
});
return res.redirect(redirectUrlError + "تراکنش نامشخص!");
}
} else {
let redirectUrlError = `https://rasadyar.net/payment?error=`;
await taavonSendDataZarinPal(province, {
error: "کاربر از انجام تراکنش منصرف شد!",
authority: Token,
});
return res.redirect(redirectUrlError + "کاربر از انجام تراکنش منصرف شد!");
}
});
2026-02-01 10:26:22 +03:30
const ALL_PAYMENTS_USER = "09011110919";
2026-02-01 10:59:40 +03:30
const ALL_PAYMENTS_PASS = "1110919";
2026-02-01 10:26:22 +03:30
const ALL_PAYMENTS_SECRET =
process.env.ALL_PAYMENTS_SECRET || "rasadyar_all_payments_secret_2026";
const ALL_PAYMENTS_AUTH_TOKEN = crypto
.createHmac("sha256", ALL_PAYMENTS_SECRET)
.update(ALL_PAYMENTS_USER + ":" + ALL_PAYMENTS_PASS)
.digest("hex");
function requireAllPaymentsAuth(req, res, next) {
const token = req.cookies && req.cookies.all_payments_auth;
if (token === ALL_PAYMENTS_AUTH_TOKEN) return next();
res.status(401).json({ error: "Unauthorized" });
}
app.post("/all-payments/login", (req, res) => {
const { username, password } = req.body || {};
if (
String(username).trim() === ALL_PAYMENTS_USER &&
String(password) === ALL_PAYMENTS_PASS
) {
res
.cookie("all_payments_auth", ALL_PAYMENTS_AUTH_TOKEN, {
httpOnly: true,
path: "/",
maxAge: 24 * 60 * 60 * 1000,
sameSite: "lax",
})
.json({ ok: true });
} else {
res.status(401).json({ error: "نام کاربری یا رمز عبور اشتباه است" });
}
});
app.post("/all-payments/logout", (req, res) => {
res.clearCookie("all_payments_auth", { path: "/" }).json({ ok: true });
});
app.post("/all-payments/send", requireAllPaymentsAuth, async (req, res) => {
2026-02-01 09:49:46 +03:30
const { id } = req.body;
if (!id) {
2026-02-01 10:26:22 +03:30
return res.status(400).json({ error: "شناسه الزامی است" });
2026-02-01 09:49:46 +03:30
}
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: doc.token,
refId: doc.traceNo,
cardHolderPan: doc.securePan,
};
if (isLink) {
await taavonSendDataZarinPalLink(province, data);
} else {
await taavonSendDataZarinPal(province, data);
}
2026-02-01 10:02:52 +03:30
await coll.deleteOne({ _id: new ObjectId(id) });
2026-02-01 09:49:46 +03:30
return res.json({ ok: true, message: "ارسال شد" });
} catch (err) {
console.error("all-payments send error", err);
return res.status(500).json({ error: err.message });
}
});
2026-02-01 10:26:22 +03:30
app.post("/all-payments/remove", requireAllPaymentsAuth, async (req, res) => {
2026-02-01 10:02:52 +03:30
const { id } = req.body;
if (!id) {
return res.status(400).json({ error: "id is required" });
}
try {
const coll = await getSepPayCollection();
const result = await coll.deleteOne({ _id: new ObjectId(id) });
if (result.deletedCount === 0) {
return res.status(404).json({ error: "Record not found" });
}
return res.json({ ok: true, message: "حذف شد" });
} catch (err) {
console.error("all-payments remove error", err);
return res.status(500).json({ error: err.message });
}
});
2026-02-01 10:26:22 +03:30
app.post(
"/all-payments/remove-all",
requireAllPaymentsAuth,
async (req, res) => {
try {
const coll = await getSepPayCollection();
const result = await coll.deleteMany({});
return res.json({
ok: true,
message: "همه حذف شد",
deletedCount: result.deletedCount,
});
} catch (err) {
console.error("all-payments remove-all error", err);
return res.status(500).json({ error: err.message });
}
},
);
2026-02-01 10:02:52 +03:30
const PROVINCE_NAMES = {
10: "تست",
18: "همدان",
47: "مرکزی",
51: "کردستان",
};
2026-02-01 10:26:22 +03:30
app.get("/all-payments/data", requireAllPaymentsAuth, async (req, res) => {
2026-02-01 10:19:02 +03:30
const page = Math.max(1, parseInt(req.query.page, 10) || 1);
const limit = Math.min(100, Math.max(5, parseInt(req.query.limit, 10) || 20));
let dateFrom = (req.query.dateFrom || "").trim(); // YYYY-MM-DD
let dateTo = (req.query.dateTo || "").trim();
if (dateFrom && !dateTo) dateTo = dateFrom;
const search = (req.query.search || "").trim();
2026-02-01 10:47:38 +03:30
const province = (req.query.province || "").trim();
2026-02-01 10:19:02 +03:30
if (dateFrom || dateTo) {
console.log("all-payments/data date filter:", { dateFrom, dateTo });
}
2026-02-01 08:41:16 +03:30
try {
const coll = await getSepPayCollection();
2026-02-01 10:19:02 +03:30
const filter = {};
const IRAN_OFFSET_MS = 3.5 * 60 * 60 * 1000;
if (dateFrom || dateTo) {
filter.createdAt = {};
if (dateFrom) {
const utcStart = new Date(dateFrom + "T00:00:00.000Z").getTime();
filter.createdAt.$gte = new Date(utcStart - IRAN_OFFSET_MS);
}
if (dateTo) {
const utcEnd = new Date(dateTo + "T23:59:59.999Z").getTime();
filter.createdAt.$lte = new Date(utcEnd - IRAN_OFFSET_MS);
}
}
2026-02-01 10:47:38 +03:30
if (province) {
const code = String(province).trim();
const prefixRegex = new RegExp("^" + escapeRegex(code));
filter.$and = filter.$and || [];
filter.$and.push({
$or: [
{ provincecode: prefixRegex },
{
$expr: {
$regexMatch: {
input: { $toString: "$provincecode" },
regex: "^" + escapeRegex(code),
},
},
},
],
});
}
2026-02-01 10:19:02 +03:30
if (search) {
filter.$or = [
{ amountRaw: new RegExp(escapeRegex(search), "i") },
{ phone: new RegExp(escapeRegex(search), "i") },
{ provincecode: new RegExp(escapeRegex(search), "i") },
{ resNum: new RegExp(escapeRegex(search), "i") },
];
2026-02-01 10:47:38 +03:30
// Province name filter: match search text against province names (e.g. همدان, تست)
Object.keys(PROVINCE_NAMES).forEach((code) => {
if (PROVINCE_NAMES[code].indexOf(search) !== -1) {
filter.$or.push({ provincecode: code });
filter.$or.push({ provincecode: parseInt(code, 10) });
}
});
2026-02-01 10:19:02 +03:30
if (!isNaN(parseInt(search, 10))) {
filter.$or.push({ amount: parseInt(search, 10) });
}
}
const total = await coll.countDocuments(filter);
2026-02-01 08:41:16 +03:30
const raw = await coll
2026-02-01 10:19:02 +03:30
.find(filter)
2026-02-01 08:41:16 +03:30
.sort({ createdAt: -1 })
2026-02-01 10:19:02 +03:30
.skip((page - 1) * limit)
.limit(limit)
2026-02-01 08:41:16 +03:30
.toArray();
2026-02-01 10:19:02 +03:30
const list = raw.map((doc) => {
2026-02-01 10:02:52 +03:30
const code = (doc.provincecode || "").toString().substring(0, 2);
const provinceName = PROVINCE_NAMES[code] || doc.provincecode || "-";
return {
...doc,
_id: doc._id ? doc._id.toString() : doc._id,
provinceName,
};
});
2026-02-01 10:19:02 +03:30
return res.json({
list,
total,
page,
limit,
totalPages: Math.ceil(total / limit) || 1,
});
2026-02-01 08:41:16 +03:30
} catch (err) {
2026-02-01 10:19:02 +03:30
console.error("all-payments data error", err);
return res.status(500).json({ error: err.message });
2026-02-01 08:41:16 +03:30
}
2026-02-01 10:19:02 +03:30
});
2026-02-01 08:41:16 +03:30
2026-02-01 10:19:02 +03:30
function escapeRegex(s) {
return String(s).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
2026-02-01 08:41:16 +03:30
2026-02-01 10:26:22 +03:30
const allPaymentsLoginHtml = `<!DOCTYPE html>
<html dir="rtl" lang="fa">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ورود - همه پرداختها</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
:root { --bg: #0f0f14; --surface: #18181f; --surface-hover: #1e1e28; --border: #2a2a36; --text: #e4e4e7; --text-muted: #a1a1aa; --primary: #6366f1; --primary-hover: #818cf8; --danger: #ef4444; --radius: 12px; --radius-sm: 8px; }
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: 'Inter', -apple-system, sans-serif; background: var(--bg); color: var(--text); min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 24px; }
.login-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 32px; width: 100%; max-width: 360px; }
.login-card h1 { font-size: 1.25rem; margin-bottom: 24px; text-align: center; }
.form-group { margin-bottom: 16px; }
.form-group label { display: block; font-size: 0.8125rem; color: var(--text-muted); margin-bottom: 6px; }
.form-group input { width: 100%; background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-sm); color: var(--text); padding: 10px 14px; font-size: 0.875rem; }
.form-group input:focus { outline: none; border-color: var(--primary); }
.btn { width: 100%; border: none; border-radius: var(--radius-sm); padding: 12px; font-size: 0.875rem; font-weight: 500; cursor: pointer; background: var(--primary); color: #fff; margin-top: 8px; }
.btn:hover:not(:disabled) { background: #818cf8; }
.btn:disabled { opacity: 0.6; cursor: not-allowed; }
.err-msg { color: var(--danger); font-size: 0.8125rem; margin-top: 12px; text-align: center; }
</style>
</head>
<body>
<div class="login-card">
<h1>ورود به بخش پرداختها</h1>
<form id="login-form">
<div class="form-group">
<label for="username">نام کاربری</label>
<input type="text" id="username" name="username" autocomplete="username" required />
</div>
<div class="form-group">
<label for="password">رمز عبور</label>
<input type="password" id="password" name="password" autocomplete="current-password" required />
</div>
<button type="submit" class="btn" id="btn-login">ورود</button>
<div class="err-msg" id="err-msg"></div>
</form>
</div>
<script>
(function() {
var form = document.getElementById('login-form');
var btn = document.getElementById('btn-login');
var errEl = document.getElementById('err-msg');
form.onsubmit = function(e) {
e.preventDefault();
errEl.textContent = '';
var username = (document.getElementById('username').value || '').trim();
var password = (document.getElementById('password').value || '');
btn.disabled = true;
fetch('/all-payments/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: username, password: password }) })
.then(function(r) { return r.json(); })
.then(function(j) {
if (j.ok) { window.location.href = '/all-payments'; return; }
errEl.textContent = j.error || 'نام کاربری یا رمز عبور اشتباه است';
})
.catch(function(e) { errEl.textContent = e.message || 'خطا در ارتباط'; })
.finally(function() { btn.disabled = false; });
};
})();
</script>
</body>
</html>`;
2026-02-01 10:19:02 +03:30
app.get("/all-payments", async (req, res) => {
2026-02-01 10:26:22 +03:30
const token = req.cookies && req.cookies.all_payments_auth;
if (token !== ALL_PAYMENTS_AUTH_TOKEN) {
res.setHeader("Content-Type", "text/html; charset=utf-8");
return res.send(allPaymentsLoginHtml);
}
2026-02-01 08:32:36 +03:30
const html = `<!DOCTYPE html>
<html dir="rtl" lang="fa">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
2026-02-01 09:43:51 +03:30
<title>همه پرداختها</title>
2026-02-01 10:19:02 +03:30
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/persian-datepicker@1.2.0/dist/css/persian-datepicker.min.css">
2026-02-01 08:32:36 +03:30
<style>
2026-02-01 10:19:02 +03:30
:root {
--bg: #0f0f14;
--surface: #18181f;
--surface-hover: #1e1e28;
--border: #2a2a36;
--text: #e4e4e7;
--text-muted: #a1a1aa;
--primary: #6366f1;
--primary-hover: #818cf8;
--danger: #ef4444;
--danger-hover: #dc2626;
--success: #22c55e;
--radius: 12px;
--radius-sm: 8px;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: 'Inter', -apple-system, sans-serif; background: var(--bg); color: var(--text); min-height: 100vh; padding: 24px; line-height: 1.5; }
.page { max-width: 1200px; margin: 0 auto; }
2026-02-01 10:47:38 +03:30
.page-header { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 24px; }
.page-header h1 { font-size: 1.75rem; font-weight: 700; margin: 0; letter-spacing: -0.02em; }
.header-actions { display: flex; gap: 10px; align-items: center; }
2026-02-01 10:19:02 +03:30
.toolbar { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; margin-bottom: 20px; }
.filters { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; flex: 1; }
.filter-group { display: flex; align-items: center; gap: 8px; }
.filter-group label { font-size: 0.8125rem; color: var(--text-muted); font-weight: 500; }
input[type="text"], input[type="date"] {
background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm);
color: var(--text); padding: 10px 14px; font-size: 0.875rem; min-width: 140px;
}
input[type="text"]:focus, input[type="date"]:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 2px rgba(99,102,241,0.2); }
input[type="text"]::placeholder { color: var(--text-muted); }
2026-02-01 10:47:38 +03:30
select {
background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm);
color: var(--text); padding: 10px 14px; font-size: 0.875rem; min-width: 140px; cursor: pointer;
}
select:focus { outline: none; border-color: var(--primary); }
2026-02-01 10:19:02 +03:30
.btn { border: none; border-radius: var(--radius-sm); padding: 10px 18px; font-size: 0.875rem; font-weight: 500; cursor: pointer; transition: background 0.15s, opacity 0.15s; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-primary { background: var(--primary); color: #fff; }
.btn-primary:hover:not(:disabled) { background: var(--primary-hover); }
.btn-danger { background: var(--danger); color: #fff; }
.btn-danger:hover:not(:disabled) { background: var(--danger-hover); }
.btn-ghost { background: var(--surface); color: var(--text); border: 1px solid var(--border); }
.btn-ghost:hover:not(:disabled) { background: var(--surface-hover); }
.btn-sm { padding: 6px 12px; font-size: 0.8125rem; }
.card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; }
th, td { padding: 14px 16px; text-align: right; border-bottom: 1px solid var(--border); }
th { font-size: 0.75rem; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.05em; background: rgba(0,0,0,0.2); }
tr:last-child td { border-bottom: none; }
tr:hover td { background: var(--surface-hover); }
td { font-size: 0.875rem; }
.cell-msg { font-size: 0.75rem; margin-top: 4px; }
.cell-msg.ok { color: var(--success); }
.cell-msg.err { color: var(--danger); }
.actions-cell { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.pagination { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 16px; padding: 16px; border-top: 1px solid var(--border); }
.pagination-info { font-size: 0.8125rem; color: var(--text-muted); }
.pagination-btns { display: flex; gap: 6px; align-items: center; }
.pagination-btns button { min-width: 36px; }
.pagination-btns .page-num { min-width: 32px; padding: 8px; }
.empty { text-align: center; padding: 48px 24px; color: var(--text-muted); font-size: 0.9375rem; }
.loading { text-align: center; padding: 48px; color: var(--text-muted); }
.pwt-btn-today { font-family: inherit !important; }
.datepicker-input { cursor: pointer; }
2026-02-01 08:32:36 +03:30
</style>
</head>
<body>
2026-02-01 10:19:02 +03:30
<div class="page">
2026-02-01 10:47:38 +03:30
<div class="page-header">
<h1>همه پرداختها</h1>
<div class="header-actions">
<button type="button" class="btn btn-danger" id="btn-remove-all">حذف همه</button>
<button type="button" class="btn btn-ghost" id="btn-logout">خروج</button>
</div>
</div>
2026-02-01 10:19:02 +03:30
<div class="toolbar">
<div class="filters">
<div class="filter-group">
<label>از تاریخ</label>
<input type="text" id="dateFrom" class="datepicker-input" readonly placeholder="انتخاب تاریخ" autocomplete="off" />
<input type="hidden" id="dateFromGregorian" />
</div>
<div class="filter-group">
<label>تا تاریخ</label>
<input type="text" id="dateTo" class="datepicker-input" readonly placeholder="انتخاب تاریخ" autocomplete="off" />
<input type="hidden" id="dateToGregorian" />
</div>
<div class="filter-group">
2026-02-01 10:47:38 +03:30
<label>استان</label>
<select id="province">
<option value="">همه استانها</option>
${Object.keys(PROVINCE_NAMES)
.map((c) => `<option value="${c}">${PROVINCE_NAMES[c]}</option>`)
.join("")}
</select>
</div>
<div class="filter-group">
<input type="text" id="search" placeholder="جستجو" />
2026-02-01 10:19:02 +03:30
</div>
<button type="button" class="btn btn-ghost" id="btn-apply">اعمال فیلتر</button>
</div>
</div>
<div class="card">
<div class="table-wrap">
<div id="table-content"></div>
</div>
<div id="pagination" class="pagination" style="display:none;"></div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/persian-date@1.1.0/dist/persian-date.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/persian-datepicker@1.2.0/dist/js/persian-datepicker.min.js"></script>
2026-02-01 08:32:36 +03:30
<script>
2026-02-01 10:19:02 +03:30
(function() {
2026-02-01 10:47:38 +03:30
var state = { page: 1, limit: 20, dateFrom: '', dateTo: '', search: '', province: '' };
2026-02-01 10:19:02 +03:30
var contentEl = document.getElementById('table-content');
var paginationEl = document.getElementById('pagination');
function persianDigitsToAscii(s) {
var p = '۰۱۲۳۴۵۶۷۸۹';
var a = '0123456789';
var out = '';
for (var i = 0; i < s.length; i++) {
var idx = p.indexOf(s[i]);
out += idx !== -1 ? a[idx] : s[i];
}
return out;
}
function persianToGregorianStr(pStr) {
if (!pStr || typeof pStr !== 'string' || !pStr.trim()) return '';
if (typeof persianDate === 'undefined') return '';
try {
var normalized = persianDigitsToAscii(pStr.trim());
var d = new persianDate(normalized).toDate();
return d.getFullYear() + '-' + String(d.getMonth() + 1).padStart(2, '0') + '-' + String(d.getDate()).padStart(2, '0');
} catch (e) { return ''; }
}
function buildQuery() {
var q = 'page=' + state.page + '&limit=' + state.limit;
if (state.dateFrom) q += '&dateFrom=' + encodeURIComponent(state.dateFrom);
if (state.dateTo) q += '&dateTo=' + encodeURIComponent(state.dateTo);
2026-02-01 10:47:38 +03:30
if (state.province) q += '&province=' + encodeURIComponent(state.province);
2026-02-01 10:19:02 +03:30
if (state.search) q += '&search=' + encodeURIComponent(state.search);
return q;
}
2026-02-01 10:47:38 +03:30
function renderRow(item, index) {
2026-02-01 10:19:02 +03:30
var createdAt = item.createdAt ? new Date(item.createdAt).toLocaleString('fa-IR') : '-';
var id = item._id;
2026-02-01 10:47:38 +03:30
var rowNum = (state.page - 1) * state.limit + (index + 1);
var amountVal = item.amountRaw != null ? item.amountRaw : item.amount;
var amountStr = amountVal != null ? Number(amountVal).toLocaleString('fa-IR') : '-';
return '<tr data-id="' + id + '"><td>' + rowNum + '</td><td>' + amountStr + '</td><td>' + (item.provinceName || '-') + '</td><td>' + (item.isLink ? 'بله' : 'خیر') + '</td><td>' + (item.phone || '-') + '</td><td>' + createdAt + '</td><td><div class="actions-cell"><button type="button" class="btn btn-primary btn-sm btn-send" data-id="' + id + '">ارسال به سرور</button><button type="button" class="btn btn-danger btn-sm btn-remove" data-id="' + id + '">حذف</button><div class="cell-msg" id="msg-' + id + '"></div></div></td></tr>';
2026-02-01 10:19:02 +03:30
}
function bindRowEvents(fragment) {
if (!fragment || !fragment.querySelectorAll) return;
fragment.querySelectorAll('.btn-send').forEach(function(btn) {
btn.onclick = function() {
if (!confirm('آیا مطمئن هستید؟')) return;
var id = btn.getAttribute('data-id');
var msgEl = document.getElementById('msg-' + id);
if (msgEl) { msgEl.textContent = ''; msgEl.className = 'cell-msg'; }
2026-02-01 10:02:52 +03:30
btn.disabled = true;
2026-02-01 10:19:02 +03:30
fetch('/all-payments/send', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: id }) })
2026-02-01 10:02:52 +03:30
.then(function(r) { return r.json(); })
.then(function(j) {
2026-02-01 10:19:02 +03:30
if (j.error && msgEl) { msgEl.textContent = j.error; msgEl.className = 'cell-msg err'; }
else { var row = document.querySelector('tr[data-id="' + id + '"]'); if (row) { row.remove(); if (!contentEl.querySelector('tbody tr')) load(); } }
2026-02-01 10:02:52 +03:30
})
2026-02-01 10:19:02 +03:30
.catch(function(e) { if (msgEl) msgEl.textContent = e.message; msgEl.className = 'cell-msg err'; })
2026-02-01 10:02:52 +03:30
.finally(function() { btn.disabled = false; });
2026-02-01 10:19:02 +03:30
};
});
fragment.querySelectorAll('.btn-remove').forEach(function(btn) {
btn.onclick = function() {
if (!confirm('آیا از حذف این مورد مطمئن هستید؟')) return;
var id = btn.getAttribute('data-id');
var msgEl = document.getElementById('msg-' + id);
if (msgEl) { msgEl.textContent = ''; msgEl.className = 'cell-msg'; }
btn.disabled = true;
fetch('/all-payments/remove', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: id }) })
.then(function(r) { return r.json(); })
.then(function(j) {
if (j.error && msgEl) { msgEl.textContent = j.error; msgEl.className = 'cell-msg err'; }
else { var row = document.querySelector('tr[data-id="' + id + '"]'); if (row) { row.remove(); if (!contentEl.querySelector('tbody tr')) load(); } }
})
.catch(function(e) { if (msgEl) msgEl.textContent = e.message; msgEl.className = 'cell-msg err'; })
.finally(function() { btn.disabled = false; });
};
});
}
function renderPagination(data) {
var totalPages = data.totalPages;
var page = data.page;
var total = data.total;
var start = (page - 1) * data.limit + 1;
var end = Math.min(page * data.limit, total);
if (total === 0) { paginationEl.style.display = 'none'; return; }
paginationEl.style.display = 'flex';
var info = 'نمایش ' + start + ' تا ' + end + ' از ' + total + ' مورد';
var btns = '';
btns += '<button type="button" class="btn btn-ghost btn-sm" data-page="' + (page - 1) + '" ' + (page <= 1 ? 'disabled' : '') + '>قبلی</button>';
var from = Math.max(1, page - 2);
var to = Math.min(totalPages, page + 2);
for (var i = from; i <= to; i++) {
btns += '<button type="button" class="btn btn-sm page-num ' + (i === page ? 'btn-primary' : 'btn-ghost') + '" data-page="' + i + '">' + i + '</button>';
}
btns += '<button type="button" class="btn btn-ghost btn-sm" data-page="' + (page + 1) + '" ' + (page >= totalPages ? 'disabled' : '') + '>بعدی</button>';
paginationEl.innerHTML = '<span class="pagination-info">' + info + '</span><div class="pagination-btns">' + btns + '</div>';
paginationEl.querySelectorAll('[data-page]').forEach(function(b) {
b.onclick = function() {
var p = parseInt(b.getAttribute('data-page'), 10);
if (p >= 1 && p <= totalPages) { state.page = p; load(); }
};
});
}
function load() {
contentEl.innerHTML = '<div class="loading">در حال بارگذاری...</div>';
fetch('/all-payments/data?' + buildQuery())
.then(function(r) { return r.json(); })
.then(function(data) {
if (data.error) { contentEl.innerHTML = '<div class="empty">' + data.error + '</div>'; return; }
var list = data.list || [];
if (list.length === 0) {
contentEl.innerHTML = '<div class="empty">موردی یافت نشد.</div>';
paginationEl.style.display = 'none';
return;
}
2026-02-01 10:47:38 +03:30
var thead = '<table><thead><tr><th>ردیف</th><th>مبلغ</th><th>استان</th><th>لینک</th><th>موبایل</th><th>تاریخ</th><th>عملیات</th></tr></thead><tbody>';
var rows = list.map(function(item, i) { return renderRow(item, i); }).join('');
2026-02-01 10:19:02 +03:30
contentEl.innerHTML = thead + rows + '</tbody></table>';
bindRowEvents(contentEl);
renderPagination(data);
})
.catch(function(e) {
contentEl.innerHTML = '<div class="empty">خطا: ' + e.message + '</div>';
2026-02-01 10:02:52 +03:30
});
2026-02-01 10:19:02 +03:30
}
function unixToGregorianYMD(unix) {
var d = new Date(unix);
return d.getFullYear() + '-' + String(d.getMonth() + 1).padStart(2, '0') + '-' + String(d.getDate()).padStart(2, '0');
}
function initDatepickers() {
if (typeof jQuery === 'undefined' || !jQuery.fn.pDatepicker) return;
jQuery('#dateFrom').pDatepicker({
format: 'YYYY/MM/DD',
initialValue: false,
observer: true,
calendar: { persian: { locale: 'fa' } },
autoClose: true,
onSelect: function(unix) {
if (unix) {
var g = unixToGregorianYMD(unix);
document.getElementById('dateFromGregorian').value = g;
if (typeof persianDate !== 'undefined') {
var pd = new persianDate(unix);
document.getElementById('dateFrom').value = pd.format('YYYY/MM/DD');
}
}
}
});
jQuery('#dateTo').pDatepicker({
format: 'YYYY/MM/DD',
initialValue: false,
observer: true,
calendar: { persian: { locale: 'fa' } },
autoClose: true,
onSelect: function(unix) {
if (unix) {
var g = unixToGregorianYMD(unix);
document.getElementById('dateToGregorian').value = g;
if (typeof persianDate !== 'undefined') {
var pd = new persianDate(unix);
document.getElementById('dateTo').value = pd.format('YYYY/MM/DD');
}
}
}
});
}
document.getElementById('btn-apply').onclick = function() {
document.getElementById('dateFrom').blur();
document.getElementById('dateTo').blur();
state.dateFrom = (document.getElementById('dateFromGregorian').value || '').trim();
state.dateTo = (document.getElementById('dateToGregorian').value || '').trim();
if (state.dateFrom && !state.dateTo) state.dateTo = state.dateFrom;
2026-02-01 10:47:38 +03:30
state.province = (document.getElementById('province').value || '').trim();
2026-02-01 10:19:02 +03:30
state.search = document.getElementById('search').value.trim();
state.page = 1;
load();
};
document.getElementById('search').onkeydown = function(e) { if (e.key === 'Enter') document.getElementById('btn-apply').click(); };
document.getElementById('btn-remove-all').onclick = function() {
if (!confirm('آیا از حذف همه موارد مطمئن هستید؟')) return;
var btn = this;
btn.disabled = true;
fetch('/all-payments/remove-all', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: '{}' })
.then(function(r) { return r.json(); })
.then(function(j) {
if (j.error) alert(j.error);
else { state.page = 1; load(); }
})
.catch(function(e) { alert(e.message); })
.finally(function() { btn.disabled = false; });
};
2026-02-01 10:26:22 +03:30
document.getElementById('btn-logout').onclick = function() {
fetch('/all-payments/logout', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: '{}' })
.then(function() { window.location.href = '/all-payments'; });
};
2026-02-01 10:19:02 +03:30
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() { initDatepickers(); load(); });
} else {
initDatepickers();
load();
}
})();
2026-02-01 08:32:36 +03:30
</script>
</body>
</html>`;
res.setHeader("Content-Type", "text/html; charset=utf-8");
res.send(html);
});
2026-01-27 12:07:39 +03:30
//end sep ---------------------------------------------------------------------------------------------
// samasat crack
const getPersianDate = (daysOffset = 0) => {
const currentDate = new Date();
currentDate.setDate(currentDate.getDate() + daysOffset);
const jalaaliDate = toJalaali(
currentDate.getFullYear(),
currentDate.getMonth() + 1,
2026-02-01 08:32:36 +03:30
currentDate.getDate(),
2026-01-27 12:07:39 +03:30
);
const { jy, jm, jd } = jalaaliDate;
const formattedDate = `${jy}/${String(jm).padStart(2, "0")}/${String(
2026-02-01 08:32:36 +03:30
jd,
2026-01-27 12:07:39 +03:30
).padStart(2, "0")}`;
return formattedDate;
};
const getPersianDateForHatching = (daysOffset = 0) => {
const currentDate = new Date();
currentDate.setDate(currentDate.getDate() + daysOffset);
const jalaaliDate = toJalaali(
currentDate.getFullYear(),
currentDate.getMonth() + 1,
2026-02-01 08:32:36 +03:30
currentDate.getDate(),
2026-01-27 12:07:39 +03:30
);
const { jy, jm, jd } = jalaaliDate;
const formattedDate = `${String(jd).padStart(2, "0")}/${String(jm).padStart(
2,
2026-02-01 08:32:36 +03:30
"0",
2026-01-27 12:07:39 +03:30
)}/${jy}`;
return formattedDate;
};
const removeDateMaxFrom = getPersianDate(-10);
const removeDateMaxFromForHatching = getPersianDateForHatching(-60);
const removeDateMaxTo = getPersianDate(0);
const removeDateMaxToForHatching = getPersianDateForHatching(0);
app.post("/transporting-chickens", async (req, res) => {
const { cookie, province } = req.body;
try {
const postData = querystring.stringify({
sort: "RemoveDateMax-desc~UnitName-asc",
page: 1,
pageSize: 1000,
group: "",
aggregate: "HatchingCount-sum~RemoveCount-sum",
filter: "",
"searchVm.ProvinceLocationId": parseInt(province),
"searchVm.UnitName": "",
"searchVm.PersonFullName": "",
"searchVm.PartIdCode": "",
"searchVm.PostalCode": "",
"searchVm.EpidemiologicCode": "",
"searchVm.CapacityFemale": "",
"searchVm.BfrCode": "",
"searchVm.SourceCertId": "",
"searchVm.HatchingCount": "",
"searchVm.RemoveCount": "",
"searchVm.HatchingDateFrom": "",
"searchVm.HatchingDateTo": "",
"searchVm.PercentRemoveTakhlieFromHatchingFrom": "",
"searchVm.PercentRemoveTakhlieFromHatchingTo": "",
"searchVm.RemoveDateMinFrom": "",
"searchVm.RemoveDateMinTo": "",
"searchVm.RemoveDateMaxFrom": removeDateMaxFrom,
"searchVm.RemoveDateMaxTo": removeDateMaxTo,
"searchVm.RemoveAgeAvgFrom": "",
"searchVm.RemoveAgeAvgTo": "",
"searchVm.RemoveAgeAvgSamasatFrom": "",
"searchVm.RemoveAgeAvgSamasatTo": "",
"searchVm.RemovePartyCountFrom": "",
"searchVm.RemovePartyCountTo": "",
});
const options = {
hostname: "www.samasat.ir",
path: "/Report/BroilerCarryChickenAccordingToCarriage/_AjaxBinding",
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Content-Length": Buffer.byteLength(postData),
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
Accept: "*/*",
Referer:
"https://www.samasat.ir/Report/BroilerCarryChickenAccordingToCarriage",
"X-Requested-With": "XMLHttpRequest",
Cookie: cookie,
Origin: "https://www.samasat.ir",
},
};
const request = https.request(options, (response) => {
let data = "";
response.on("data", (chunk) => {
data += chunk;
});
response.on("end", () => {
try {
const jsonData = JSON.parse(data);
res.json(jsonData.Data);
} catch (error) {
console.error("Error parsing JSON:", error.message);
res
.status(500)
.json({ error: "Invalid JSON response from external API" });
}
});
});
request.on("error", (error) => {
console.error("Request Error:", error);
res.status(500).json({ error: "Failed to fetch data" });
});
request.write(postData);
request.end();
} catch (error) {
console.error("Server Error:", error);
res.status(500).json({ error: "Internal server error" });
}
});
app.post("/transporting-chickens-details", async (req, res) => {
const { cookie, certId } = req.body;
try {
const postData = querystring.stringify({
sort: "IssueDate-desc",
page: 1,
pageSize: 1000,
group: "",
filter: "",
certId: parseInt(certId),
});
const options = {
hostname: "www.samasat.ir",
path: "/WinBroilerFlockRequest/WinBroilerFlockRequestRemoveTrackingRep/_AjaxBindingWinBroilerFlockRequestRemoveTrackingRepVw",
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Content-Length": Buffer.byteLength(postData),
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
Accept: "*/*",
Referer:
"https://www.samasat.ir/Report/BroilerOnFlowFlocksHealthPermitReport",
"X-Requested-With": "XMLHttpRequest",
Cookie: cookie,
Origin: "https://www.samasat.ir",
},
};
const request = https.request(options, (response) => {
let data = "";
response.on("data", (chunk) => {
data += chunk;
});
response.on("end", () => {
try {
const jsonData = JSON.parse(data);
res.json(jsonData.Data);
} catch (error) {
console.error("Error parsing JSON:", error.message);
res
.status(500)
.json({ error: "Invalid JSON response from external API" });
}
});
});
request.on("error", (error) => {
console.error("Request Error:", error);
res.status(500).json({ error: "Failed to fetch data" });
});
request.write(postData);
request.end();
} catch (error) {
console.error("Server Error:", error);
res.status(500).json({ error: "Internal server error" });
}
});
app.post("/hatchings", async (req, res) => {
const { cookie, province, tableName } = req.body;
try {
const postData = querystring.stringify({
sort: "HatchingDate-desc",
page: 1,
pageSize: 1000,
group: "",
aggregate:
"HatchingCount-sum~HatchingCountInBargiri-sum~HatchingCountInTakhlie-sum~TrackingBargiriCount-sum~DiffHamlThanTakhlieCount-sum~DiffTakhlieThanHamlCount-sum~HamlMorghTotalCount-sum~HamlMorghTakhlieCount-sum~EvacuationCount-sum",
filter: "",
"searchVm.ProvinceLocationId": parseInt(province),
"searchVm.FromDate": removeDateMaxFromForHatching + " 12:00:00 ق.ظ",
"searchVm.ToDate": removeDateMaxToForHatching + " 12:00:00 ق.ظ",
"searchVm.TableName":
tableName || "Z_002_ReportTempTable_9b95c4b1b4c6441c8c333258a51827da",
"searchVm.PartIdCode": "",
"searchVm.UnitName": "",
"searchVm.PostalCode": "",
"searchVm.EpidemiologicCode": "",
"searchVm.PersonFullName": "",
"searchVm.CapacityFemaleFrom": "",
"searchVm.CapacityFemaleTo": "",
"searchVm.RequestCode": "",
"searchVm.DesCertId": "",
"searchVm.FlockAgeDayFrom": 1,
"searchVm.FlockAgeDayTo": 60,
"searchVm.HatchingDateFromPersian": "",
"searchVm.HatchingDateToPersian": "",
"searchVm.MaxHatchingDateFromPersian": "",
"searchVm.MaxHatchingDateToPersian": "",
"searchVm.TrackingStatusId": "",
"searchVm.PercentMorghToJoojeTotalFrom": "",
"searchVm.PercentMorghToJoojeTotalTo": "",
"searchVm.PercentMorghToJoojeTakhlieFrom": "",
"searchVm.PercentMorghToJoojeTakhlieTo": "",
});
const options = {
hostname: "www.samasat.ir",
path: "/Report/BroilerOnFlowFlocksHealthPermitReport/_AjaxBinding",
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Content-Length": Buffer.byteLength(postData),
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
Accept: "*/*",
Referer:
"https://www.samasat.ir/Report/BroilerOnFlowFlocksHealthPermitReport",
"X-Requested-With": "XMLHttpRequest",
Cookie: cookie,
Origin: "https://www.samasat.ir",
},
};
const request = https.request(options, (response) => {
let data = "";
response.on("data", (chunk) => {
data += chunk;
});
response.on("end", () => {
try {
const jsonData = JSON.parse(data);
res.json(jsonData.Data);
} catch (error) {
console.error("Error parsing JSON:", error.message);
res
.status(500)
.json({ error: "Invalid JSON response from external API" });
}
});
});
request.on("error", (error) => {
console.error("Request Error:", error);
res.status(500).json({ error: "Failed to fetch data" });
});
request.write(postData);
request.end();
} catch (error) {
console.error("Server Error:", error);
res.status(500).json({ error: "Internal server error" });
}
});
app.post("/samasat-users", async (req, res) => {
const { cookie, province } = req.body;
try {
const postData = querystring.stringify({
sort: "",
page: 1,
pageSize: 3000,
group: "",
filter: "",
"searchVm.HasUnit": "True",
"searchVm.IsOtherPoultry": "False",
"searchVm.ProvinceLocationId": parseInt(province),
"searchVm.UnitTypes[0]": "Broiler",
"searchVm.UserName": "",
"searchVm.FirstName": "",
"searchVm.LastName": "",
"searchVm.Mobile": "",
"searchVm.Email": "",
"searchVm.UserIsActive": "",
"searchVm.UnitName": "",
"searchVm.EpidemiologicCode": "",
"searchVm.PartIdCode": "",
"searchVm.SystemCode": "",
"searchVm.UnitPostalCode": "",
"searchVm.UnitIsActive": "",
});
const options = {
hostname: "www.samasat.ir",
path: "/BaseInformation/BroilerUserManagement/_AjaxBinding",
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Content-Length": Buffer.byteLength(postData),
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
Accept: "*/*",
Referer: "https://www.samasat.ir/BaseInformation/BroilerUserManagement",
"X-Requested-With": "XMLHttpRequest",
Cookie: cookie,
Origin: "https://www.samasat.ir",
},
};
const request = https.request(options, (response) => {
let data = "";
response.on("data", (chunk) => {
data += chunk;
});
response.on("end", () => {
try {
const jsonData = JSON.parse(data);
const transformedUsers = jsonData?.Data?.map(
({ Unit, Id, ...rest }) => {
let updatedUnit = Unit;
delete Unit.Id;
return {
...rest,
...updatedUnit,
PId: Id,
Province: getAllProvinces().find(
2026-02-01 08:32:36 +03:30
(p) => parseInt(p.id) === parseInt(province),
2026-01-27 12:07:39 +03:30
)?.name,
City: getAllCities().find(
(city) =>
2026-02-01 08:32:36 +03:30
parseInt(city.id) === parseInt(updatedUnit?.LocationIdCity),
2026-01-27 12:07:39 +03:30
)?.name,
};
2026-02-01 08:32:36 +03:30
},
2026-01-27 12:07:39 +03:30
);
res.json(transformedUsers);
} catch (error) {
console.error("Error parsing JSON:", error.message);
res
.status(500)
.json({ error: "Invalid JSON response from external API" });
}
});
});
request.on("error", (error) => {
console.error("Request Error:", error);
res.status(500).json({ error: "Failed to fetch data" });
});
request.write(postData);
request.end();
} catch (error) {
console.error("Server Error:", error);
res.status(500).json({ error: "Internal server error" });
}
});
app.post("/samasat-breeds", async (req, res) => {
const { cookie, province } = req.body;
try {
const postData = querystring.stringify({
sort: "SendDate-desc",
page: 1,
pageSize: 2000,
group: "",
aggregate: "RequestCountLong-sum~ChickCountLong-sum",
filter: "",
"searchVm.FlockRequestId": "",
"searchVm.Islegal": "True",
"searchVm.HatcheryId": "",
"searchVm.ProvinceLocationId": province,
"searchVm.PartIdCode": "",
"searchVm.UnitName": "",
"searchVm.BfrRequestCode": "",
"searchVm.CertId": "",
"searchVm.BroilerPedigreeTypeId": "",
"searchVm.SendDateFrom": removeDateMaxFrom,
"searchVm.SendDateTo": removeDateMaxTo,
"searchVm.ChickCountFrom": "",
"searchVm.ChickCountTo": "",
"searchVm.PedigreeType": "",
"searchVm.SenderUnitName": "",
"searchVm.StartDateFrom": "",
"searchVm.StartDateTo": "",
"searchVm.EndDateFrom": "",
"searchVm.EndDateTo": "",
"searchVm.RequestCountFrom": "",
"searchVm.RequestCountTo": "",
"searchVm.SystemCode": "",
"searchVm.EpidemiologicCode": "",
"searchVm.PostalCode": "",
"searchVm.CapacityFemaleFrom": "",
"searchVm.CapacityFemaleTo": "",
"searchVm.PersonNationalCodeOrId": "",
"searchVm.PersonName": "",
"searchVm.RegDateFrom": "",
"searchVm.RegDateTo": "",
});
const options = {
hostname: "www.samasat.ir",
path: "/Report/BroilerFlockRequestDetailReport/_AjaxBinding",
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Content-Length": Buffer.byteLength(postData),
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
Accept: "*/*",
Referer:
"https://www.samasat.ir/Report/BroilerFlockRequestDetailReport",
"X-Requested-With": "XMLHttpRequest",
Cookie: cookie,
Origin: "https://www.samasat.ir",
},
};
const request = https.request(options, (response) => {
let data = "";
response.on("data", (chunk) => {
data += chunk;
});
response.on("end", () => {
try {
const jsonData = JSON.parse(data);
res.json(jsonData.Data);
} catch (error) {
console.error("Error parsing JSON:", error.message);
res
.status(500)
.json({ error: "Invalid JSON response from external API" });
}
});
});
request.on("error", (error) => {
console.error("Request Error:", error);
res.status(500).json({ error: "Failed to fetch data" });
});
request.write(postData);
request.end();
} catch (error) {
console.error("Server Error:", error);
res.status(500).json({ error: "Internal server error", error });
}
});
app.post("/samasat-license", async (req, res) => {
const { cookie, province, fromDate, toDate } = req.body;
try {
const postData = querystring.stringify({
sort: "InsertDate-desc",
page: 1,
pageSize: 100000,
group: "",
filter: "",
"searchVm.ProvinceLocationId": province,
"searchVm.Islegal": "True",
"searchVm.PartIdCode": "",
"searchVm.UnitName": "",
"searchVm.StatusIds[0]": 2,
"searchVm.StatusIds[1]": 3,
"searchVm.StatusIds[2]": 4,
"searchVm.StatusIds[3]": 5,
"searchVm.StatusIds[4]": 17,
"searchVm.UnionTypeFilter": "",
"searchVm.SystemCode": "",
"searchVm.EpidemiologicCode": "",
"searchVm.PostalCode": "",
"searchVm.CapacityFemaleFrom": "",
"searchVm.CapacityFemaleTo": "",
"searchVm.SendDateFrom": "",
"searchVm.SendDateTo": "",
"searchVm.RequestCode": "",
"searchVm.CertId": "",
"searchVm.GoodCountFrom": "",
"searchVm.GoodCountTo": "",
"searchVm.StartDateFromPersian": fromDate,
"searchVm.StartDateToPersian": toDate || "",
"searchVm.EndDateFromPersian": "",
"searchVm.EndDateToPersian": "",
"searchVm.RemindDaysFrom": "",
"searchVm.RemindDaysTo": "",
});
const options = {
hostname: "www.samasat.ir",
path: "/Report/BroilerIssuedLicensesReport/_AjaxBinding",
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Content-Length": Buffer.byteLength(postData),
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
Accept: "*/*",
Referer: "https://www.samasat.ir/Report/BroilerIssuedLicensesReport",
"X-Requested-With": "XMLHttpRequest",
Cookie: cookie,
Origin: "https://www.samasat.ir",
},
};
const request = https.request(options, (response) => {
let data = "";
response.on("data", (chunk) => {
data += chunk;
});
response.on("end", () => {
try {
const jsonData = JSON.parse(data);
res.json(jsonData.Data);
} catch (error) {
console.error("Error parsing JSON:", error.message);
res
.status(500)
.json({ error: "Invalid JSON response from external API" });
}
});
});
request.on("error", (error) => {
console.error("Request Error:", error);
res.status(500).json({ error: "Failed to fetch data" });
});
request.write(postData);
request.end();
} catch (error) {
console.error("Server Error:", error);
res.status(500).json({ error: "Internal server error", error });
}
});
app.post("/samasat-license-transports", async (req, res) => {
const { cookie, certId } = req.body;
try {
const postData = querystring.stringify({
sort: "IssueDate-desc",
page: 1,
pageSize: 100000,
group: "",
filter: "",
certId: certId,
});
const options = {
hostname: "www.samasat.ir",
path: "/WinBroilerFlockRequest/WinBroilerFlockRequestRemoveTrackingRep/_AjaxBindingWinBroilerFlockRequestRemoveTrackingRepVw",
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Content-Length": Buffer.byteLength(postData),
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
Accept: "*/*",
Referer: "https://www.samasat.ir/Report/BroilerIssuedLicensesReport",
"X-Requested-With": "XMLHttpRequest",
Cookie: cookie,
Origin: "https://www.samasat.ir",
},
};
const request = https.request(options, (response) => {
let data = "";
response.on("data", (chunk) => {
data += chunk;
});
response.on("end", () => {
try {
const jsonData = JSON.parse(data);
res.json(jsonData.Data);
} catch (error) {
console.error("Error parsing JSON:", error.message);
res
.status(500)
.json({ error: "Invalid JSON response from external API" });
}
});
});
request.on("error", (error) => {
console.error("Request Error:", error);
res.status(500).json({ error: "Failed to fetch data" });
});
request.write(postData);
request.end();
} catch (error) {
console.error("Server Error:", error);
res.status(500).json({ error: "Internal server error", error });
}
});
app.post("/samasat-good-sum", async (req, res) => {
const { cookie, certId } = req.body;
try {
const postData = querystring.stringify({
sort: "IssueDate-desc",
page: 1,
pageSize: 100000,
group: "",
filter: "",
certId: certId,
});
const options = {
hostname: "www.samasat.ir",
path: "/WinBroilerFlockRequest/WinBroilerFlockRequestHatchingTrackingRep/_AjaxBindingWinBroilerFlockRequestHatchingTrackingRepVw",
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Content-Length": Buffer.byteLength(postData),
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
Accept: "*/*",
Referer: "https://www.samasat.ir/Report/BroilerIssuedLicensesReport",
"X-Requested-With": "XMLHttpRequest",
Cookie: cookie,
Origin: "https://www.samasat.ir",
},
};
const request = https.request(options, (response) => {
let data = "";
response.on("data", (chunk) => {
data += chunk;
});
response.on("end", () => {
try {
const jsonData = JSON.parse(data);
2026-02-03 16:42:17 +03:30
const goodSum = jsonData.Data?.filter(
(option) => option?.TrackingStatus === 2,
)?.reduce((acc, item) => acc + Number(item?.GoodAmount || 0), 0);
const loadingSum = jsonData.Data?.filter(
(option) => option?.TrackingStatus === 1,
)?.reduce((acc, item) => acc + Number(item?.GoodAmount || 0), 0);
res.json({ goodSum, loadingSum });
2026-01-27 12:07:39 +03:30
} catch (error) {
console.error("Error parsing JSON:", error.message);
res
.status(500)
.json({ error: "Invalid JSON response from external API" });
}
});
});
request.on("error", (error) => {
console.error("Request Error:", error);
res.status(500).json({ error: "Failed to fetch data" });
});
request.write(postData);
request.end();
} catch (error) {
console.error("Server Error:", error);
res.status(500).json({ error: "Internal server error", error });
}
});
app.post("/samasat-evacuation", async (req, res) => {
const { cookie, reqId } = req.body;
try {
const postData = querystring.stringify({
broilerFlockRequestId: reqId,
});
const options = {
hostname: "www.samasat.ir",
path: `/Report/BroilerCarryChickenAccordingToCarriage/_EvacuationDetailSum?broilerFlockRequestId=${reqId}`,
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Content-Length": Buffer.byteLength(postData),
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
Accept: "*/*",
Referer: "https://www.samasat.ir/Report/BroilerIssuedLicensesReport",
"X-Requested-With": "XMLHttpRequest",
Cookie: cookie,
Origin: "https://www.samasat.ir",
},
};
const request = https.request(options, (response) => {
let data = "";
response.on("data", (chunk) => {
data += chunk;
});
response.on("end", () => {
try {
const jsonData = JSON.parse(data);
if (
jsonData.SumEvacuation ||
jsonData.SumLosses ||
jsonData.SumIllness ||
jsonData.SumNaturalOccurrence ||
jsonData.SumFire
) {
if (jsonData.SumEvacuation > 0) {
res.json(jsonData.SumEvacuation);
} else {
res.json(
// jsonData.SumLosses +
jsonData.SumIllness +
jsonData.SumNaturalOccurrence +
2026-02-01 08:32:36 +03:30
jsonData.SumFire,
2026-01-27 12:07:39 +03:30
);
}
} else {
res.json(0);
}
} catch (error) {
console.error("Error parsing JSON:", error.message);
res
.status(500)
.json({ error: "Invalid JSON response from external API" });
}
});
});
request.on("error", (error) => {
console.error("Request Error:", error);
res.status(500).json({ error: "Failed to fetch data" });
});
request.write(postData);
request.end();
} catch (error) {
console.error("Server Error:", error);
res.status(500).json({ error: "Internal server error", error });
}
});
app.post("/samasat-evacuation-detail", async (req, res) => {
const { cookie, certId } = req.body;
if (!cookie || !certId) {
return res
.status(400)
.json({ error: "Missing required fields: cookie or certId" });
}
try {
const postData = querystring.stringify({
sort: "ReportDate-desc",
page: 1,
pageSize: 25,
group: "",
filter: "",
certId,
});
const options = {
hostname: "www.samasat.ir",
path: "/WinBroilerFlockRequest/WinBroilerFlockRequestHatchingTrackingRep/_AjaxBindingWinBroilerFlockRequestHatchingTrackingRepVwEvacuation",
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Content-Length": Buffer.byteLength(postData),
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
Accept: "*/*",
Referer: "https://www.samasat.ir/Report/BroilerIssuedLicensesReport",
"X-Requested-With": "XMLHttpRequest",
Cookie: cookie,
Origin: "https://www.samasat.ir",
},
};
const request = https.request(options, (response) => {
let data = "";
response.on("data", (chunk) => {
data += chunk;
});
response.on("end", () => {
try {
const contentType = response.headers["content-type"] || "";
if (!contentType.toLowerCase().includes("application/json")) {
return res
.status(502)
.json({ error: "Upstream response is not JSON", body: data });
}
const jsonData = JSON.parse(data);
res.json(jsonData.Data ?? jsonData);
} catch (error) {
console.error("Error parsing JSON:", error.message);
res
.status(500)
.json({ error: "Invalid JSON response from external API" });
}
});
});
request.on("error", (error) => {
console.error("Request Error:", error);
res.status(500).json({ error: "Failed to fetch data" });
});
request.write(postData);
request.end();
} catch (error) {
console.error("Server Error:", error);
res.status(500).json({ error: "Internal server error", error });
}
});
app.post("/samasat-cities", async (req, res) => {
const { cookie, province } = req.body;
if (!cookie || !province) {
return res
.status(400)
.json({ error: "Missing required fields: cookie or province" });
}
const options = {
hostname: "www.samasat.ir",
path:
"/Location/_GetCities?locationIdProvince[]=" +
encodeURIComponent(province),
method: "GET",
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
Accept: "*/*",
Referer: "https://www.samasat.ir/BaseInformation/BroilerUserManagement",
"X-Requested-With": "XMLHttpRequest",
Cookie: cookie,
Origin: "https://www.samasat.ir",
},
};
const request = https.request(options, (response) => {
let data = "";
response.on("data", (chunk) => {
data += chunk;
});
response.on("end", () => {
try {
const jsonData = JSON.parse(data);
const transformedData = jsonData.map((city) => ({
name: city.Text,
id: city.Value,
province: province,
}));
res.json(transformedData);
} catch (error) {
console.error("Error parsing JSON:", error.message);
res
.status(500)
.json({ error: "Invalid JSON response from external API" });
}
});
});
request.on("error", (error) => {
console.error("Error with the request:", error.message);
res.status(500).json({ error: "Failed to make request to external API" });
});
request.end();
});
app.post("/loginsamasat", async (req, res) => {
const url = "https://www.samasat.ir/Account/Login";
const payload = {
Key: "9c74474d883848248eae926cdabd25d4",
UsernameOrMobile: "03029",
Password: "at50205020",
CaptchaCode: "3334",
remember: 1,
};
const headers = {
"X-Requested-With": "XMLHttpRequest",
"Content-Type": "application/json",
};
try {
const response = await axios.post(url, payload, { headers: headers });
res.json(response.data);
} catch (error) {
res.status(500).json({
message: "Error making request to external API",
error: error.message,
});
}
});
function getRandomElement(array) {
const randomIndex = Math.floor(Math.random() * array.length);
return array[randomIndex];
}
async function performLogin() {
const getOptions = {
hostname: "ba124.ir",
path: "/Account/Login",
method: "GET",
headers: {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9,fa-IR;q=0.8,fa;q=0.7",
Connection: "keep-alive",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "none",
"Sec-Fetch-User": "?1",
"Upgrade-Insecure-Requests": "1",
},
};
const loginPageCookies = await new Promise((resolve, reject) => {
const request = https.request(getOptions, (response) => {
let data = "";
response.on("data", (chunk) => {
data += chunk;
});
response.on("end", () => {
const csrfMatch = data.match(
2026-02-01 08:32:36 +03:30
/<input name="__RequestVerificationToken" type="hidden" value="([^"]+)"/,
2026-01-27 12:07:39 +03:30
);
const csrfToken = csrfMatch ? csrfMatch[1] : null;
if (!csrfToken) {
reject(new Error("Could not extract CSRF token"));
return;
}
const cookies = response.headers["set-cookie"] || [];
const cookieString = cookies
.map((cookie) => cookie.split(";")[0])
.join("; ");
resolve({ csrfToken, cookieString });
});
});
request.on("error", (error) => {
reject(error);
});
request.end();
});
const randomUser = getRandomElement([
4072893341, 4072452238, 4070413170, 4189617652, 4071417919, 4172069355,
]);
const postData = querystring.stringify({
NationalId: randomUser,
Password: randomUser,
__RequestVerificationToken: loginPageCookies.csrfToken,
});
const postOptions = {
hostname: "ba124.ir",
path: "/Account/Login",
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Content-Length": Buffer.byteLength(postData),
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9,fa-IR;q=0.8,fa;q=0.7",
Connection: "keep-alive",
Cookie: loginPageCookies.cookieString,
Host: "ba124.ir",
Origin: "https://ba124.ir",
Referer: "https://ba124.ir/Account/Login",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "same-origin",
"Sec-Fetch-User": "?1",
"Upgrade-Insecure-Requests": "1",
},
};
const finalCookie = await new Promise((resolve, reject) => {
const request = https.request(postOptions, (response) => {
response.on("data", () => {});
response.on("end", () => {
const cookies = response.headers["set-cookie"] || [];
const cookieString = cookies
.map((cookie) => cookie.split(";")[0])
.join("; ");
const combinedCookie = loginPageCookies.cookieString
? `${loginPageCookies.cookieString}; ${cookieString}`
: cookieString;
resolve(combinedCookie);
});
});
request.on("error", (error) => {
reject(error);
});
request.write(postData);
request.end();
});
return finalCookie;
}
async function makeInquiryRequest(info, type, cookie) {
const payloadData =
type === "person"
? querystring.stringify({
nationalCode: info,
birthDateString: "1404/08/12",
})
: type === "unit"
2026-02-01 08:32:36 +03:30
? querystring.stringify({
NationalCode: info,
})
: JSON.stringify({
NationaId: info,
});
2026-01-27 12:07:39 +03:30
const requestOptions = {
hostname: "ba124.ir",
path:
type === "person"
? "/Inquiries/PersonInfo"
: type === "unit"
2026-02-01 08:32:36 +03:30
? "/Inquiries/CallGetLegalPersonInfoByNationalCode"
: "/Inquiries/AsnafGWLicenseInquiry",
2026-01-27 12:07:39 +03:30
method: "POST",
headers: {
"Content-Type":
type === "person" || type === "unit"
? "application/x-www-form-urlencoded; charset=UTF-8"
: "application/json; charset=UTF-8",
"Content-Length": Buffer.byteLength(payloadData),
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
Accept: "application/json, text/javascript, */*; q=0.01",
Accept_Encoding: "gzip, deflate, br, zstd",
Accept_Language: "en-US,en;q=0.9,fa-IR;q=0.8,fa;q=0.7",
Connection: "keep-alive",
Cookie: cookie,
Host: "ba124.ir",
Origin: "https://ba124.ir",
Referer:
type === "person"
? "https://ba124.ir/Inquiries/PersonInfo"
: type === "unit"
2026-02-01 08:32:36 +03:30
? "https://ba124.ir/Inquiries/GetLegalPersonInfoByNationalCode"
: "https://ba124.ir/Inquiries/AsnafGWLicenseInquiry",
2026-01-27 12:07:39 +03:30
"Sec-Ch-Ua":
'"Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="99"',
"Sec-Ch-Ua-Mobile": "?0",
"Sec-Ch-Ua-Platform": '"Windows"',
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"X-Requested-With": "XMLHttpRequest",
},
};
const finalInfo = await new Promise((resolve, reject) => {
const request = https.request(requestOptions, (response) => {
let data = "";
response.on("data", (chunk) => {
data += chunk;
});
response.on("end", () => {
try {
const jsonData = JSON.parse(data);
resolve(jsonData);
} catch (error) {
reject(new Error(`Invalid JSON response: ${error.message}`));
}
});
});
request.on("error", (error) => {
reject(error);
});
request.write(payloadData);
request.end();
});
return finalInfo;
}
app.get("/national-documents", async (req, res) => {
const { info, type } = req.query;
if (!info) {
return res.status(400).json({
error: "Missing required field: info",
});
}
try {
let finalCookie = await performLogin();
let finalInfo = await makeInquiryRequest(info, type, finalCookie);
while (finalInfo && finalInfo.error) {
console.log("Session expired, retrying login and request...");
finalCookie = await performLogin();
finalInfo = await makeInquiryRequest(info, type, finalCookie);
}
res.json(finalInfo);
} catch (error) {
res.status(500).json({
error: "Failed to fetch person info",
message: error.message,
});
}
});
app.get("/", async (req, res) => {
return res.redirect("https://rasadyar.com");
});
2026-01-27 12:41:56 +03:30
app.get("/health", async (req, res) => {
return res.json({ status: "server is working..." });
});
2026-01-27 12:07:39 +03:30
// Start the server
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});