This commit is contained in:
payacom
2026-09-03 16:06:02 +03:30
parent 3f416a7a60
commit 90c5f94b57
31 changed files with 3968 additions and 4283 deletions

View File

@@ -13,6 +13,12 @@ function toDateOnlyString (date) {
return new Date(date).toISOString().slice(0, 10)
}
// درگاه قدیمیِ REST زرین‌پال (/pg/rest/WebGate) منسوخ شده — مبلغ به API نسخه‌ی v4
// باید به ریال ارسال بشه، نه تومان (برخلاف API قدیمی)
function toRial (tomanAmount) {
return Number(tomanAmount) * 10
}
/** Initiates the 30% deposit payment for a pending booking. */
const initiateBookingPayment = async (req, res) => {
try {
@@ -37,27 +43,27 @@ const initiateBookingPayment = async (req, res) => {
}
const response = await axios.post(
'https://www.zarinpal.com/pg/rest/WebGate/PaymentRequest.json',
'https://api.zarinpal.com/pg/v4/payment/request.json',
{
MerchantID: apiKey,
Amount: booking.depositAmount,
Description: `بیعانه رزرو خدمت ${booking.serviceTitle}`,
CallbackURL: `${callbackBase}/bookings/payment-callback/web?bookingId=${booking._id}`
merchant_id: apiKey,
amount: toRial(booking.depositAmount),
description: `بیعانه رزرو خدمت ${booking.serviceTitle}`,
callback_url: `${callbackBase}/bookings/payment-callback/web?bookingId=${booking._id}`
},
{ timeout: 20000 }
{ headers: { 'Content-Type': 'application/json' }, timeout: 20000 }
)
const data = response.data
if (data.Status === 100 && data.Authority) {
booking.paymentAuthority = data.Authority
const result = response.data?.data
if (result?.code === 100 && result?.authority) {
booking.paymentAuthority = result.authority
await booking.save()
return res.status(200).json({
authority: data.Authority,
paymentUrl: `https://www.zarinpal.com/pg/StartPay/${data.Authority}`
authority: result.authority,
paymentUrl: `https://www.zarinpal.com/pg/StartPay/${result.authority}`
})
}
console.error('initiateBookingPayment ZarinPal error:', data)
console.error('initiateBookingPayment ZarinPal error:', response.data)
return res.status(502).json({ error: true, message: 'درگاه پرداخت پاسخ نامعتبر داد. لطفاً دوباره تلاش کنید.' })
} catch (error) {
console.error('initiateBookingPayment error:', error?.response?.data || error?.message || error)
@@ -81,12 +87,13 @@ const handleBookingPaymentCallback = async (req, res) => {
}
const verificationResponse = await axios.post(
'https://www.zarinpal.com/pg/rest/WebGate/PaymentVerification.json',
{ MerchantID: apiKey, Authority, Amount: booking.depositAmount }
'https://api.zarinpal.com/pg/v4/payment/verify.json',
{ merchant_id: apiKey, authority: Authority, amount: toRial(booking.depositAmount) },
{ headers: { 'Content-Type': 'application/json' } }
)
const verificationData = verificationResponse.data
if (verificationData.Status !== 100 && verificationData.Status !== 101) {
const verificationData = verificationResponse.data?.data
if (verificationData?.code !== 100 && verificationData?.code !== 101) {
await PaymentModel.create({
amount: booking.depositAmount,
status: 'failed',