admin roadmap trips ops and payment ops

This commit is contained in:
2026-05-18 19:25:32 +07:00
parent e1966b69f1
commit 4bcb93e283
22 changed files with 1586 additions and 188 deletions
+43
View File
@@ -381,6 +381,49 @@ export const paymentService = {
* Auth: caller harus pastikan `userId` adalah owner booking; kita verifikasi
* di sini lewat lookup payment → booking.userId.
*/
/**
* Admin variant `reconcileFromGateway` — skip ownership check (admin bypass).
* Dipakai dari `/admin/bookings/[id]` saat user lapor "sudah bayar tapi
* status belum update". Idempotent: aman dipanggil berulang.
*/
async adminReconcile(
orderId: string
): Promise<
| {
ok: true;
status:
| "updated"
| "skipped"
| "ignored"
| "booking_conflict"
| "not_found";
}
| { ok: false; reason: "amount_mismatch" | "not_found" }
> {
const payment = await prisma.payment.findUnique({
where: { externalOrderId: orderId },
select: { id: true },
});
if (!payment) {
return { ok: false, reason: "not_found" };
}
const status = await fetchMidtransTransactionStatus(orderId);
if (!status) {
return { ok: true, status: "not_found" };
}
return applyGatewayStatus({
order_id: status.order_id,
gross_amount: status.gross_amount,
transaction_status: status.transaction_status,
fraud_status: status.fraud_status ?? null,
transaction_id: status.transaction_id,
payment_type: status.payment_type,
rawSource: status as unknown as Prisma.InputJsonValue,
});
},
async reconcileFromGateway(
orderId: string,
userId: string