Files
dukang/server/dukang-api/src/callbacks/wechat-refund.controller.ts
T
jacy 3328c52cb4 feat(ops): WeCom webhook alerts for pay/redeem anomalies
Add outbound group-bot alerts, rate/amount rules, stuck-order cron, HQ test button, and health db/redis checks.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-02 16:01:30 +08:00

57 lines
1.9 KiB
TypeScript

import { Controller, Headers, Post, Req, Res } from '@nestjs/common';
import type { Request, Response } from 'express';
import { PrismaService } from '../common/prisma/prisma.module';
import { AlertService } from '../common/alert/alert.service';
@Controller('callbacks/wechat')
export class WechatRefundCallbackController {
constructor(
private readonly prisma: PrismaService,
private readonly alert: AlertService,
) {}
@Post('refund')
async refundNotify(
@Req() req: Request,
@Headers() _headers: Record<string, string | string[] | undefined>,
@Res() res: Response,
) {
try {
const body = typeof req.body === 'object' ? req.body : {};
const outRefundNo = String((body as Record<string, unknown>).out_refund_no ?? '');
const refundId = String((body as Record<string, unknown>).refund_id ?? outRefundNo);
const existing = await this.prisma.logThirdParty.findFirst({
where: { provider: 'WECHAT_REFUND', externalNo: refundId, status: 'SUCCESS' },
});
if (existing) {
return res.status(200).json({ code: 'SUCCESS', message: '成功' });
}
await this.prisma.logThirdParty.create({
data: {
provider: 'WECHAT_REFUND',
scene: 'ORDER_REFUND_CALLBACK',
refType: 'TICKET',
refId: BigInt(0),
externalNo: refundId,
status: 'SUCCESS',
},
});
return res.status(200).json({ code: 'SUCCESS', message: '成功' });
} catch (err) {
const message = err instanceof Error ? err.message : '处理失败';
this.alert.notify({
level: 'P0',
category: 'pay',
title: '退款回调处理失败',
detail: message,
dedupeKey: `refund_callback_fail|${message.slice(0, 40)}`,
dedupeTtlSec: 120,
});
return res.status(500).json({ code: 'FAIL', message });
}
}
}