import { createHash } from "crypto"; const XORPAY_AID = process.env.XORPAY_AID || "8220"; const XORPAY_SECRET = process.env.XORPAY_SECRET || "afcacd99570945f88de62624aaa3578e"; const XORPAY_QUERY_URL = process.env.XORPAY_QUERY_URL || "https://xorpay.com/api/query2"; const XORPAY_QUERY_TIMEOUT_MS = Number( process.env.XORPAY_QUERY_TIMEOUT_MS || 5000 ); export type XorPayStatusResult = { ok: boolean; paid: boolean; status?: string; error?: string; url: string; }; function buildXorPaySign(orderId: string): string { return createHash("md5") .update(`${orderId}${XORPAY_SECRET}`, "utf8") .digest("hex") .toLowerCase(); } export async function queryXorPayOrderStatus( orderId: string, timeoutMs = XORPAY_QUERY_TIMEOUT_MS ): Promise { const normalizedOrderId = orderId.trim(); if (!normalizedOrderId || !XORPAY_AID || !XORPAY_SECRET) { return null; } const url = new URL( `${XORPAY_QUERY_URL.replace(/\/$/, "")}/${encodeURIComponent(XORPAY_AID)}` ); url.searchParams.set("order_id", normalizedOrderId); url.searchParams.set("sign", buildXorPaySign(normalizedOrderId)); try { const res = await fetch(url.toString(), { cache: "no-store", signal: AbortSignal.timeout(timeoutMs), }); const data = await res.json().catch(() => ({})); const status = String(data?.status || "") .trim() .toLowerCase(); return { ok: res.ok, paid: res.ok && (status === "payed" || status === "success"), status, url: url.toString(), error: res.ok ? undefined : `status=${res.status}`, }; } catch (error) { return { ok: false, paid: false, url: url.toString(), error: error instanceof Error ? error.message : String(error), }; } }