email service and template using resend

This commit is contained in:
2026-05-18 20:47:05 +07:00
parent f0ce22bbb8
commit bf5c97c442
16 changed files with 1152 additions and 2 deletions
+35
View File
@@ -11,6 +11,7 @@ import {
} from "@/lib/midtrans";
import { isTripDepartureDayPast } from "@/lib/trip-dates";
import { payoutService } from "@/server/services/payout.service";
import { emailService } from "@/lib/email/send";
const SERIAL_TX_ATTEMPTS = 6;
@@ -177,6 +178,12 @@ async function applyGatewayStatus(
});
const isConflict =
newStatus === "PAID" && finalBooking?.status !== "PAID";
// Notif email user kalau payment benar-benar berhasil di-apply ke booking.
if (newStatus === "PAID" && !isConflict) {
void notifyPaymentPaid(payment.id);
}
return {
ok: true,
status: isConflict ? "booking_conflict" : "updated",
@@ -469,6 +476,34 @@ export const paymentService = {
},
};
async function notifyPaymentPaid(paymentId: string) {
const payment = await prisma.payment.findUnique({
where: { id: paymentId },
include: {
booking: {
include: {
user: { select: { email: true, name: true } },
trip: { select: { id: true, title: true } },
},
},
},
});
if (!payment) return;
await emailService.send({
to: payment.booking.user.email,
idempotencyKey: `payment_paid-${payment.id}`,
template: {
template: "payment_paid",
data: {
userName: payment.booking.user.name,
tripTitle: payment.booking.trip.title,
tripId: payment.booking.trip.id,
amount: payment.amount,
},
},
});
}
// Re-export untuk testing langsung kalau perlu (tetap private dari modul lain).
export const _internal = { applyGatewayStatus };
export type { MidtransTransactionStatus };