diff --git a/src/lib/wxpay/client.ts b/src/lib/wxpay/client.ts index 8ecd5f0..f3d96a6 100644 --- a/src/lib/wxpay/client.ts +++ b/src/lib/wxpay/client.ts @@ -1,4 +1,5 @@ import WxPay from 'wechatpay-node-v3'; +import crypto from 'crypto'; import { getEnv } from '@/lib/config'; import type { WxpayPcOrderParams, WxpayH5OrderParams, WxpayRefundParams } from './types'; @@ -144,12 +145,14 @@ export async function verifyNotifySign(params: { serial: string; signature: string; }): Promise { - const pay = getPayInstance(); - return pay.verifySign({ - timestamp: params.timestamp, - nonce: params.nonce, - body: params.body, - serial: params.serial, - signature: params.signature, - }); + const env = getEnv(); + if (!env.WXPAY_PUBLIC_KEY) { + throw new Error('WXPAY_PUBLIC_KEY is required for signature verification'); + } + + // 微信支付公钥模式:直接用公钥验签,不拉取平台证书 + const message = `${params.timestamp}\n${params.nonce}\n${params.body}\n`; + const verify = crypto.createVerify('RSA-SHA256'); + verify.update(message); + return verify.verify(env.WXPAY_PUBLIC_KEY, params.signature, 'base64'); } diff --git a/src/lib/wxpay/provider.ts b/src/lib/wxpay/provider.ts index e6572c7..82decfb 100644 --- a/src/lib/wxpay/provider.ts +++ b/src/lib/wxpay/provider.ts @@ -107,6 +107,12 @@ export class WxpayProvider implements PaymentProvider { if (!timestamp || !nonce || !signature || !serial) { throw new Error('Missing required Wechatpay signature headers'); } + + // 验证 serial 匹配我们配置的公钥 ID + if (env.WXPAY_PUBLIC_KEY_ID && serial !== env.WXPAY_PUBLIC_KEY_ID) { + throw new Error(`Wxpay serial mismatch: expected ${env.WXPAY_PUBLIC_KEY_ID}, got ${serial}`); + } + const valid = await verifyNotifySign({ timestamp, nonce, body, serial, signature }); if (!valid) { throw new Error('Wxpay notification signature verification failed');