Files
midtrans-gateway/app/modules/notification/services/notification.service.js
2026-02-18 16:03:43 +07:00

94 lines
3.3 KiB
JavaScript

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();