مرکز ابزارها، افزونه ها و مثال های اتصال

در این صفحه بسته های آماده برای اتصال به سرویس پرداخت، افزونه های کمکی و مثال های اجرایی را مثل یک ریپازیتوری مرور می کنید: فایل ها را می بینید، README را می خوانید و کل بسته را با یک دانلود می گیرید.

CONTROLLED RELEASE

انتشار کنترل شده از پنل رسمی

هر بسته از مسیر مدیریتی رسمی پی اکسا منتشر می شود و قبل از دانلود، اطلاعات کلیدی آن به صورت شفاف نمایش داده می شود.

PRE-DOWNLOAD VISIBILITY

شفافیت محتوا پیش از دریافت

پیش نمایش README، مرور ساختار فایل و نمایش متادیتای بسته کمک می کند قبل از دانلود، ارزیابی دقیق تری از محتوا داشته باشید.

TRUST PROFILE

نمای رسمی تر برای انتخاب ابزار

صفحه بر پایه شفافیت انتشار، نمایش منبع README، تاریخ بروزرسانی و آمار دانلود چیده شده تا حس ارزیابی حرفه ای تری منتقل کند.

مرجع حقوقی و هویتی کنار دسترس

ساختار صفحه طوری چیده شده که اطلاعات انتشار، محتوای فایل ها و جزئیات هر بسته بدون شلوغی اضافه در دسترس باشند.

مثال repository / wallet-top-up-node-js

شارژ كيف پول

نمونه پياده سازي جريان شارژ کيف پول با Payexa در Node.js.

دانلود بسته
8 فایل payexa-nodejs-express.zip README: README.md

دانلود ثبت شده

114

آخرین بروزرسانی

2026-09-25

حجم بسته

17.0 KB

منتشرکننده

مدیر ارشد سامانه

وضعیت نمایش

عمومی و فعال

پیش نمایش فایل

nodejs-express/app.js

const express = require("express"); const dotenv = require("dotenv"); const axios = require("axios"); const crypto = require("crypto"); const path = require("path"); dotenv.config({ path: path.join(__dirname, ".env") }); const app = express(); app.set("view engine", "ejs"); app.use(express.urlencoded({ extended: true })); app.use(express.json()); const cfg = { baseUrl: (process.env.PAYEXA_BASE_URL || "https://sandbox.pexn.ir").replace(/\/$/, ""), apiKey: process.env.PAYEXA_API_KEY || "", startPayPath: process.env.PAYEXA_STARTPAY_PATH || "/startPay", requestEndpoint: process.env.PAYEXA_REQUEST_ENDPOINT || "/v1/payment/request", verifyEndpoint: process.env.PAYEXA_VERIFY_ENDPOINT || "/v1/payment/verify", callbackPath: process.env.PAYEXA_CALLBACK_PATH || "/payments/callback", timeoutMs: Number(process.env.PAYEXA_TIMEOUT_MS || 12000), badgeScriptUrl: process.env.PAYEXA_BADGE_SCRIPT_URL || "", port: Number(process.env.PORT || 5051), }; const wallet = { ownerName: "Demo User", balance: 0 }; const orders = []; function buildStartPayUrl(authority) { const path = cfg.startPayPath.startsWith("/") ? cfg.startPayPath : `/${cfg.startPayPath}`; return `${cfg.baseUrl}${path}?authority=${encodeURIComponent(authority)}`; } function genOrderRef() { return `TOPUP-${crypto.randomBytes(6).toString("hex").toUpperCase()}`; } function gatewayHeaders() { return { "Content-Type": "application/json", "X-API-KEY": cfg.apiKey, }; } async function requestPayment(amount, callbackUrl, orderRef) { const url = `${cfg.baseUrl}${cfg.requestEndpoint}`; const payload = { amount, callback_url: callbackUrl, meta: { order_ref: orderRef } }; const response = await axios.post(url, payload, { headers: gatewayHeaders(), timeout: cfg.timeoutMs, validateStatus: () => true, }); return { statusCode: response.status, data: response.data || {} }; } async function verifyPayment(orderId, token) { const url = `${cfg.baseUrl}${cfg.verifyEndpoint}`; const payload = { order_id: orderId, token }; const response = await axios.post(url, payload, { headers: gatewayHeaders(), timeout: cfg.timeoutMs, validateStatus: () => true, }); return { statusCode: response.status, data: response.data || {} }; } app.get("/", (req, res) => { const flash = req.query.msg || ""; res.render("index", { wallet, orders: [...orders].reverse().slice(0, 15), badgeScriptUrl: cfg.badgeScriptUrl, flash, }); }); app.post("/wallet/charge", async (req, res) => { const amount = Number(req.body.amount || 0); if (!Number.isInteger(amount) || amount <= 0) { return res.redirect("/?msg=" + encodeURIComponent("مبلغ نامعتبر است.")); } const orderRef = genOrderRef(); const order = { orderRef, amount, status: "pending", credited: false, authority: "", gatewayOrderId: "", gatewayToken: "", callbackPayload: null, verifyResponse: null, createdAt: new Date().toISOString(), }; orders.push(order); const callbackUrl = `${req.protocol}://${req.get("host")}${cfg.callbackPath}`; try { const r = await requestPayment(amount, callbackUrl, orderRef); if (r.statusCode !== 200 && r.statusCode !== 201) { order.status = "request_failed"; order.verifyResponse = r.data; return res.redirect("/?msg=" + encodeURIComponent(`خطا در ايجاد پرداخت (${r.statusCode})`)); } order.authority = String(r.data.authority || "").trim(); order.gatewayOrderId = String(r.data.order_id || "").trim(); if (r.data.amount_unique !== undefined && r.data.amount_unique !== null) { order.gatewayToken = String(r.data.amount_unique); } order.status = "requested"; if (!order.authority) { order.status = "request_invalid_response"; return res.redirect("/?msg=" + encodeURIComponent("پاسخ درگاه authority نداشت.")); } return res.redirect(buildStartPayUrl(order.authority)); } catch (err) { order.status = "request_failed"; return res.redirect("/?msg=" + encodeURIComponent("خطا در ارتباط با درگاه")); } }); app.all(cfg.callbackPath, async (req, res) => { const payload = Object.keys(req.body || {}).length ? req.body : req.query; const callbackStatus = String(payload.status || "").toUpperCase().trim(); const authority = String(payload.authority || "").trim(); const orderId = String(payload.order_id || "").trim(); const token = String(payload.token || "").trim(); const successStatuses = new Set(["OK", "SUCCESS"]); if (callbackStatus && !successStatuses.has(callbackStatus)) { return res.render("payment_result", { ok: false, title: "پرداخت ناموفق يا لغو شده", message: `وضعيت بازگشتي درگاه: ${callbackStatus}`, payload, wallet, }); } let order = null; if (orderId) order = orders.find((x) => x.gatewayOrderId === orderId) || null; if (!order && authority) order = orders.find((x) => x.authority === authority) || null; if (!order) { return res.render("payment_result", { ok: false, title: "سفارش پيدا نشد", message: "سفارش مرتبط با callback يافت نشد.", payload, wallet, }); } order.callbackPayload = payload; if (token) order.gatewayToken = token; if (order.credited) { return res.render("payment_result", { ok: true, title: "پرداخت قبلا ثبت شده", message: "اين سفارش قبلا وريفاي و به کيف پول اضافه شده است.", payload, wallet, }); } const finalOrderId = orderId || order.gatewayOrderId; const finalToken = token || order.gatewayToken; if (!finalOrderId || !finalToken) { order.status = "callback_invalid"; return res.render("payment_result", { ok: false, title: "callback ناقص", message: "order_id يا token موجود نيست.", payload, wallet, }); } try { const vr = await verifyPayment(finalOrderId, finalToken); order.verifyResponse = vr.data; if (vr.statusCode === 200 && !order.credited) { order.status = "verified"; order.credited = true; wallet.balance += order.amount; return res.render("payment_result", { ok: true, title: "شارژ موفق کيف پول", message: `مبلغ ${order.amount.toLocaleString("fa-IR")} با موفقيت اضافه شد.`, payload: vr.data, wallet, }); } if (vr.statusCode === 201) { order.status = "already_verified"; return res.render("payment_result", { ok: true, title: "قبلا وريفاي شده", message: "اين پرداخت قبلا وريفاي شده است.", payload: vr.data, wallet, }); } order.status = "verify_failed"; return res.render("payment_result", { ok: false, title: "وريفاي ناموفق", message: `verify failed: ${vr.statusCode}`, payload: vr.data, wallet, }); } catch (_err) { order.status = "verify_failed"; return res.render("payment_result", { ok: false, title: "وريفاي ناموفق", message: "خطا در ارتباط با درگاه هنگام وريفاي پرداخت", payload, wallet, }); } }); app.get("/orders/:orderRef", (req, res) => { const order = orders.find((x) => x.orderRef === req.params.orderRef); if (!order) return res.status(404).send("Order not found"); return res.render("order_status", { order, wallet }); }); app.listen(cfg.port, () => { console.log(`Node demo running on http://127.0.0.1:${cfg.port}`); });

README / توضیحات

منبع: README.md

Payexa Wallet Demo - Node.js (Express)

نمونه پياده سازي جريان شارژ کيف پول با Payexa در Node.js.

هدف اين مثال، نمايش جريان کامل پرداخت (request -> redirect -> callback -> verify) به شکل ساده و قابل تست است.

راه اندازي

cd examples/nodejs-express
cp .env.example .env
npm install
npm start

آدرس پيش فرض:

http://127.0.0.1:5051/

تنظيمات محيطي مهم

فايل نمونه: .env.example

متغيرهاي مهم:

  • PAYEXA_BASE_URL براي sandbox/production
  • PAYEXA_API_KEY کليد مرچنت
  • PAYEXA_STARTPAY_PATH مسير startPay
  • PAYEXA_REQUEST_ENDPOINT و PAYEXA_VERIFY_ENDPOINT
  • PAYEXA_CALLBACK_PATH مسير callback

نکته تست:

  • براي sandbox مي تواني موقتا از PAYEXA به عنوان API key استفاده کني.

نکات

  • افزايش موجودي فقط بعد از verify موفق انجام مي شود.
  • براي جلوگيري از شارژ تکراري از credited استفاده شده است.
  • داده ها در اين نمونه در حافظه نگهداري مي شوند (demo mode).
PAYEXA ASSISTANT

من دستیار پی اکسا هستم، شما را در تمام مسیر راهنمایی می‌کنم و اگر به من نیازی ندارید با ۲ بار کلیک خاموش می‌شوم.