feat: 集成微信支付直连(Native + H5)及金融级安全修复

- 新增 wxpay provider(wechatpay-node-v3 SDK),支持 Native 扫码和 H5 跳转
- 新增 /api/wxpay/notify 回调路由,AES-256-GCM 解密 + RSA 签名验证
- 修复 confirmPayment count=0 静默成功、充值失败返回 true 等 P0 问题
- 修复 notifyUrl 硬编码 easypay、回调金额覆盖订单金额等 P1 问题
- 手续费计算改用 Prisma.Decimal 精确运算,消除浮点误差
- 支付宝 provider 移除冗余 paramsForVerify,fetch 添加超时
- 补充 .env.example 配置文档和 CLAUDE.md 支付渠道说明
This commit is contained in:
erio
2026-03-06 13:57:52 +08:00
parent e9e164babc
commit 937f54dec2
17 changed files with 728 additions and 28 deletions

View File

@@ -3,6 +3,7 @@ import type { PaymentType } from './types';
import { EasyPayProvider } from '@/lib/easy-pay/provider';
import { StripeProvider } from '@/lib/stripe/provider';
import { AlipayProvider } from '@/lib/alipay/provider';
import { WxpayProvider } from '@/lib/wxpay/provider';
import { getEnv } from '@/lib/config';
export { paymentRegistry } from './registry';
@@ -33,12 +34,31 @@ export function initPaymentProviders(): void {
}
if (providers.includes('alipay')) {
if (!env.ALIPAY_APP_ID || !env.ALIPAY_PRIVATE_KEY) {
throw new Error('PAYMENT_PROVIDERS 含 alipay但缺少 ALIPAY_APP_ID 或 ALIPAY_PRIVATE_KEY');
if (!env.ALIPAY_APP_ID || !env.ALIPAY_PRIVATE_KEY || !env.ALIPAY_NOTIFY_URL) {
throw new Error(
'PAYMENT_PROVIDERS includes alipay but required env vars are missing: ALIPAY_APP_ID, ALIPAY_PRIVATE_KEY, ALIPAY_NOTIFY_URL',
);
}
paymentRegistry.register(new AlipayProvider());
}
if (providers.includes('wxpay')) {
if (
!env.WXPAY_APP_ID ||
!env.WXPAY_MCH_ID ||
!env.WXPAY_PRIVATE_KEY ||
!env.WXPAY_API_V3_KEY ||
!env.WXPAY_PUBLIC_KEY ||
!env.WXPAY_CERT_SERIAL ||
!env.WXPAY_NOTIFY_URL
) {
throw new Error(
'PAYMENT_PROVIDERS includes wxpay but required env vars are missing: WXPAY_APP_ID, WXPAY_MCH_ID, WXPAY_PRIVATE_KEY, WXPAY_API_V3_KEY, WXPAY_PUBLIC_KEY, WXPAY_CERT_SERIAL, WXPAY_NOTIFY_URL',
);
}
paymentRegistry.register(new WxpayProvider());
}
if (providers.includes('stripe')) {
if (!env.STRIPE_SECRET_KEY) {
throw new Error('PAYMENT_PROVIDERS 含 stripe但缺少 STRIPE_SECRET_KEY');