const WalletTransactionModel = require('../models/WalletTransactionModel') const { getBucketBalance } = require('../controllers/application/wallet/walletController') /** * وقتی کاربر موقع خرید تیکِ «استفاده از موجودی کیف پول» رو می‌زنه (useWallet=true)، * تا هر مقدار که سبدِ «charged» (شارژِ دستیِ کیف پول، همون چیزی که کاربر خودش واریز * کرده — نه سبدهای درآمدیِ shop/academy/project/booking) پوشش بده از همونجا کسر * می‌شه و فقط باقی‌مونده (اگه چیزی مونده باشه) از درگاه زرین‌پال گرفته می‌شه. اگه * useWallet نباشه یا موجودی صفر باشه، دقیقاً مثلِ قبل کاملش از درگاه پرداخت می‌شه. * * عمداً همینجا چیزی کسر نمی‌کنه (فقط محاسبه) — کسرِ واقعی رو خودِ فراخوان، فقط لحظه‌ای * که پرداخت قطعاً موفق شده (یا کلاً از درگاه رد نشده، یعنی fullyCovered) صدا می‌زنه؛ * این‌طوری اگه کاربر پرداختِ درگاه رو نصفه ول کنه، هیچ مبلغی از کیف پول کم نشده که * لازم باشه برگردونده بشه */ // زرین‌پال حداقل مبلغِ درگاه رو ۱۵٬۰۰۰ ریال (۱٬۵۰۰ تومان) می‌خواد — اگه بعدِ کسرِ // کیف‌پول فقط یه باقی‌مونده‌ی مثبتِ کوچیک‌تر از این بمونه، کلِ درخواستِ initiate به // زرین‌پال با خطای 422 رد می‌شه (نه فقط همون بخشِ کوچیک) — این دقیقاً همون چیزی بود // که باعث می‌شد «ثبت درخواست» (و هر مسیرِ دیگه‌ای که از این تابع استفاده می‌کنه) با // بعضی ترکیب‌های قیمت/موجودیِ کیف‌پول روی سرور ارور بده const ZARINPAL_MIN_GATEWAY_TOMAN = 1500 async function resolveWalletSplit (userId, amount, useWallet) { if (!useWallet) { return { walletAmount: 0, gatewayAmount: amount, fullyCovered: false } } const balance = await getBucketBalance(userId, 'charged') if (!balance || balance <= 0) { return { walletAmount: 0, gatewayAmount: amount, fullyCovered: false } } let walletAmount = Math.min(balance, amount) let gatewayAmount = amount - walletAmount if (gatewayAmount > 0 && gatewayAmount < ZARINPAL_MIN_GATEWAY_TOMAN) { const neededWalletAmount = amount - ZARINPAL_MIN_GATEWAY_TOMAN if (neededWalletAmount >= 0 && balance >= neededWalletAmount) { // از کیف‌پول کمتر استفاده کن تا باقی‌مونده دقیقاً به حداقلِ مجازِ درگاه برسه walletAmount = neededWalletAmount gatewayAmount = ZARINPAL_MIN_GATEWAY_TOMAN } else { // یا کلِ مبلغ از حداقلِ درگاه کمتره، یا کیف‌پول برای رسوندنِ باقی‌مونده به اون // حداقل کافی نیست — اصلاً از کیف‌پول استفاده نکن، همه چیز از درگاه. این‌طوری // حداقل یه خطای واضحِ «حداقل مبلغ» از خودِ زرین‌پال می‌گیریم، نه یه 422ِ گنگ walletAmount = 0 gatewayAmount = amount } } return { walletAmount, gatewayAmount, fullyCovered: gatewayAmount <= 0 } } async function debitWalletForPurchase (userId, walletAmount, { referenceType, referenceId, description }) { if (!walletAmount || walletAmount <= 0) return await WalletTransactionModel.create({ user: userId, bucket: 'charged', type: 'debit', amount: walletAmount, referenceType, referenceId, description }) } module.exports = { resolveWalletSplit, debitWalletForPurchase }