From 2888d620374f07d486dd4870c4ded37658e7b6a3 Mon Sep 17 00:00:00 2001 From: tikkhun Date: Thu, 8 Jan 2026 20:54:45 +0800 Subject: [PATCH] =?UTF-8?q?refactor(webhook):=20=E9=87=8D=E6=9E=84webhook?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E5=99=A8=E9=80=BB=E8=BE=91=EF=BC=8C=E4=BD=BF?= =?UTF-8?q?=E7=94=A8siteApiService=E9=80=82=E9=85=8D=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除对UnifiedOrderDTO的直接使用,改为通过适配器转换订单数据 - 统一处理woocommerce和shoppy的webhook验证逻辑 - 清理冗余代码和注释 --- src/controller/webhook.controller.ts | 97 ++++++++++++---------------- 1 file changed, 43 insertions(+), 54 deletions(-) diff --git a/src/controller/webhook.controller.ts b/src/controller/webhook.controller.ts index 41ef422..6132182 100644 --- a/src/controller/webhook.controller.ts +++ b/src/controller/webhook.controller.ts @@ -9,13 +9,10 @@ import { } from '@midwayjs/decorator'; import { Context } from '@midwayjs/koa'; import * as crypto from 'crypto'; - + import { SiteService } from '../service/site.service'; import { OrderService } from '../service/order.service'; - -import { - UnifiedOrderDTO, -} from '../dto/site-api.dto'; +import { SiteApiService } from '../service/site-api.service'; @Controller('/webhook') export class WebhookController { @@ -31,9 +28,11 @@ export class WebhookController { @Logger() logger: ILogger; - + @Inject() private readonly siteService: SiteService; + @Inject() + private readonly siteApiService: SiteApiService; // 移除配置中的站点数组,来源统一改为数据库 @@ -49,7 +48,7 @@ export class WebhookController { @Query('siteId') siteIdStr: string, @Headers() header: any ) { - console.log(`webhook woocommerce`, siteIdStr, body,header) + console.log(`webhook woocommerce`, siteIdStr, body, header) const signature = header['x-wc-webhook-signature']; const topic = header['x-wc-webhook-topic']; const source = header['x-wc-webhook-source']; @@ -79,43 +78,44 @@ export class WebhookController { .update(rawBody) .digest('base64'); try { - if (hash === signature) { - switch (topic) { - case 'product.created': - case 'product.updated': - // 不再写入本地,平台事件仅确认接收 - break; - case 'product.deleted': - // 不再写入本地,平台事件仅确认接收 - break; - case 'order.created': - case 'order.updated': - await this.orderService.syncSingleOrder(siteId, body); - break; - case 'order.deleted': - break; - case 'customer.created': - break; - case 'customer.updated': - break; - case 'customer.deleted': - break; - default: - console.log('Unhandled event:', body.event); - } - - return { - code: 200, - success: true, - message: 'Webhook processed successfully', - }; - } else { + if (hash !== signature) { return { code: 403, success: false, message: 'Webhook verification failed', }; } + const adapter = await this.siteApiService.getAdapter(siteId); + switch (topic) { + case 'product.created': + case 'product.updated': + // 不再写入本地,平台事件仅确认接收 + break; + case 'product.deleted': + // 不再写入本地,平台事件仅确认接收 + break; + case 'order.created': + case 'order.updated': + const order = adapter.mapPlatformToUnifiedOrder(body) + await this.orderService.syncSingleOrder(siteId, order); + break; + case 'order.deleted': + break; + case 'customer.created': + break; + case 'customer.updated': + break; + case 'customer.deleted': + break; + default: + console.log('Unhandled event:', body.event); + + return { + code: 200, + success: true, + message: 'Webhook processed successfully', + }; + } } catch (error) { console.log(error); } @@ -130,23 +130,10 @@ export class WebhookController { @Query('signature') signature: string, @Headers() header: any ) { + console.log(`webhook shoppy`, siteIdStr, body, header) const topic = header['x-oemsaas-event-type']; - // const source = header['x-oemsaas-shop-domain']; + // const source = header['x-oemsaas-shop-domain']; const siteId = Number(siteIdStr); - const bodys = new UnifiedOrderDTO(); - Object.assign(bodys, body); - // 从数据库获取站点配置 - const site = await this.siteService.get(siteId, true); - - // if (!site || !source?.includes(site.websiteUrl)) { - if (!site) { - console.log('domain not match'); - return { - code: HttpStatus.BAD_REQUEST, - success: false, - message: 'domain not match', - }; - } if (!signature) { return { @@ -162,6 +149,7 @@ export class WebhookController { // .createHmac('sha256', this.secret) // .update(rawBody) // .digest('base64'); + const adapter = await this.siteApiService.getAdapter(siteId); try { if (this.secret === signature) { switch (topic) { @@ -174,7 +162,8 @@ export class WebhookController { break; case 'orders/create': case 'orders/update': - await this.orderService.syncSingleOrder(siteId, bodys); + const order = adapter.mapPlatformToUnifiedOrder(body) + await this.orderService.syncSingleOrder(siteId, order); break; case 'orders/delete': break;