const crypto = require('crypto'); const db = require('../../../../models/migration'); require('dotenv').config(); class NotificationService { verifySignature(payload) { const { order_id, status_code, gross_amount, signature_key } = payload; const serverKey = process.env.MIDTRANS_SERVER_KEY; const data = order_id + status_code + gross_amount + serverKey; const hash = crypto.createHash('sha512').update(data).digest('hex'); return hash === signature_key; } async processNotification(payload) { const { order_id, transaction_status, fraud_status } = payload; console.log(`[Notification] Processing Order ${order_id}: status=${transaction_status}, fraud=${fraud_status}`); try { let payment = await db.Payment.findOne({ where: { external_id: order_id }, order: [['created_at', 'DESC']] }); let order = null; if (payment) { order = await db.Order.findByPk(payment.order_id); } else { order = await db.Order.findOne({ where: { orderID: order_id } }); if (!order) { order = await db.Order.findByPk(order_id); } } if (!order) { console.warn(`[Notification] Data Order/Payment untuk ID ${order_id} tidak ditemukan.`); return; } let orderPaymentStatus = 'PENDING'; let orderStatus = order.status; let paymentRecordStatus = 'PENDING'; if (transaction_status === 'settlement' || (transaction_status === 'capture' && fraud_status === 'accept')) { orderPaymentStatus = 'PAID'; orderStatus = 'COMPLETED'; paymentRecordStatus = 'SUCCESS'; } else if (['deny', 'cancel', 'expire'].includes(transaction_status)) { orderPaymentStatus = 'REJECT'; orderStatus = 'FAILED'; paymentRecordStatus = 'FAILED'; } else if (transaction_status === 'pending') { orderPaymentStatus = 'PENDING'; paymentRecordStatus = 'PENDING'; } if (order.payment_status === orderPaymentStatus && order.status === orderStatus) { console.log(`[Notification] Order ${order.id} sudah sinkron. Skip update.`); return; } await order.update({ payment_status: orderPaymentStatus, status: orderStatus }); if (!payment) { payment = await db.Payment.findOne({ where: { order_id: order.id }, order: [['created_at', 'DESC']] }); } if (payment) { await payment.update({ status: paymentRecordStatus, response_data: JSON.stringify(payload) }); } console.log(`[Notification] SUCCESS: Order ${order.id} updated to ${orderStatus}, Payment updated to ${paymentRecordStatus}`); } catch (error) { console.error(`[Notification] Error: ${error.message}`); throw error; } } } module.exports = new NotificationService();