import { Controller, Headers, Inject, Post, Req, Res } from '@nestjs/common'; import type { Request, Response } from 'express'; import { TradeService } from '../modules/trade/trade.service'; import { WECHAT_PROVIDER } from '../integrations/integrations.constants'; import type { IWechatProvider } from '../integrations/wechat/wechat.interface'; import { AlertService } from '../common/alert/alert.service'; type RawBodyRequest = Request & { body: Buffer }; @Controller('callbacks/wechat') export class WechatRefundCallbackController { constructor( private readonly tradeService: TradeService, @Inject(WECHAT_PROVIDER) private readonly wechat: IWechatProvider, private readonly alert: AlertService, ) {} @Post('refund') async refundNotify( @Req() req: RawBodyRequest, @Headers() headers: Record, @Res() res: Response, ) { let outRefundNo: string | undefined; try { const rawBody = (req as Request & { rawBody?: Buffer }).rawBody?.toString('utf8') ?? (typeof req.body === 'string' ? req.body : JSON.stringify(req.body ?? {})); const notify = await this.wechat.parseRefundNotification(headers, rawBody); outRefundNo = notify.outRefundNo; await this.tradeService.handleRefundSuccess({ outRefundNo: notify.outRefundNo, refundId: notify.refundId, amountFen: notify.amountFen, remark: '微信退款回调确认', actorType: 'WECHAT_REFUND', }); 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: `${outRefundNo ? `退款单 ${outRefundNo}\n` : ''}${message}`, dedupeKey: `refund_callback_fail|${outRefundNo ?? message.slice(0, 40)}`, dedupeTtlSec: 120, }); return res.status(500).json({ code: 'FAIL', message }); } } }