94 lines
3.3 KiB
JavaScript
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();
|