更新项目配置,调整 .next 目录的清理脚本以支持多个子目录的删除,优化提现功能的环境变量配置,确保与现有支付配置一致。同时,增强 API 日志记录以便于调试,更新文档以反映新的环境变量使用方式,提升系统的可维护性和用户体验。
This commit is contained in:
@@ -18,13 +18,34 @@ export interface WechatTransferConfig {
|
||||
certSerialNo: string
|
||||
}
|
||||
|
||||
// 与小程序支付、lib/payment/config 保持一致,复用同一套 env
|
||||
const DEFAULT_MCH_ID = '1318592501'
|
||||
const DEFAULT_APP_ID = 'wxb8bbb2b10dec74aa'
|
||||
|
||||
/** 从 apiclient_cert.pem 读取证书序列号(与 lib/payment 的 WECHAT_CERT_PATH 复用) */
|
||||
function getCertSerialNoFromPath(certPath: string): string {
|
||||
const p = path.isAbsolute(certPath) ? certPath : path.join(process.cwd(), certPath)
|
||||
const pem = fs.readFileSync(p, 'utf8')
|
||||
const cert = new crypto.X509Certificate(pem)
|
||||
const raw = (cert.serialNumber || '').replace(/:/g, '').replace(/^0+/, '') || ''
|
||||
return raw.toUpperCase()
|
||||
}
|
||||
|
||||
function getConfig(): WechatTransferConfig {
|
||||
const mchId = process.env.WECHAT_MCH_ID || process.env.WECHAT_MCHID || ''
|
||||
const appId = process.env.WECHAT_APP_ID || process.env.WECHAT_APPID || 'wxb8bbb2b10dec74aa'
|
||||
const mchId = process.env.WECHAT_MCH_ID || process.env.WECHAT_MCHID || DEFAULT_MCH_ID
|
||||
const appId = process.env.WECHAT_APP_ID || process.env.WECHAT_APPID || DEFAULT_APP_ID
|
||||
const apiV3Key = process.env.WECHAT_API_V3_KEY || process.env.WECHAT_MCH_KEY || ''
|
||||
const keyPath = process.env.WECHAT_KEY_PATH || process.env.WECHAT_MCH_PRIVATE_KEY_PATH || ''
|
||||
const keyContent = process.env.WECHAT_MCH_PRIVATE_KEY || ''
|
||||
const certSerialNo = process.env.WECHAT_MCH_CERT_SERIAL_NO || ''
|
||||
let certSerialNo = process.env.WECHAT_MCH_CERT_SERIAL_NO || ''
|
||||
const certPath = process.env.WECHAT_CERT_PATH || ''
|
||||
if (!certSerialNo && certPath) {
|
||||
try {
|
||||
certSerialNo = getCertSerialNoFromPath(certPath)
|
||||
} catch (e) {
|
||||
console.warn('[wechat-transfer] 从证书文件读取序列号失败:', (e as Error).message)
|
||||
}
|
||||
}
|
||||
return {
|
||||
mchId,
|
||||
appId,
|
||||
@@ -193,8 +214,24 @@ export async function createTransferUserConfirm(
|
||||
params: CreateTransferUserConfirmParams
|
||||
): Promise<CreateTransferUserConfirmResult> {
|
||||
const cfg = getConfig()
|
||||
if (!cfg.mchId || !cfg.appId || !cfg.certSerialNo) {
|
||||
return { success: false, errorCode: 'CONFIG_ERROR', errorMessage: '微信转账配置不完整' }
|
||||
if (!cfg.mchId || !cfg.appId) {
|
||||
return { success: false, errorCode: 'CONFIG_ERROR', errorMessage: '微信转账配置不完整:缺少商户号或 AppID' }
|
||||
}
|
||||
if (!cfg.certSerialNo) {
|
||||
const certPath = process.env.WECHAT_CERT_PATH || ''
|
||||
const hint = certPath
|
||||
? `已配置 WECHAT_CERT_PATH=${certPath} 但读取序列号失败,请检查文件存在且为有效 PEM。或直接在 .env 配置 WECHAT_MCH_CERT_SERIAL_NO(openssl x509 -in apiclient_cert.pem -noout -serial 获取)`
|
||||
: '请在 .env 中配置 WECHAT_CERT_PATH(apiclient_cert.pem 路径),或配置 WECHAT_MCH_CERT_SERIAL_NO(证书序列号)'
|
||||
return { success: false, errorCode: 'CONFIG_ERROR', errorMessage: `微信转账配置不完整:缺少证书序列号。${hint}` }
|
||||
}
|
||||
try {
|
||||
getPrivateKey()
|
||||
} catch (e) {
|
||||
return {
|
||||
success: false,
|
||||
errorCode: 'CONFIG_ERROR',
|
||||
errorMessage: `微信转账配置不完整:商户私钥未配置。请在 .env 中配置 WECHAT_KEY_PATH(apiclient_key.pem 路径)或 WECHAT_MCH_PRIVATE_KEY`,
|
||||
}
|
||||
}
|
||||
|
||||
const urlPath = '/v3/fund-app/mch-transfer/transfer-bills'
|
||||
@@ -218,6 +255,14 @@ export async function createTransferUserConfirm(
|
||||
const signature = buildSignature('POST', urlPath, timestamp, nonce, bodyStr)
|
||||
const authorization = buildAuthorization(timestamp, nonce, signature)
|
||||
|
||||
// 发起请求前打印:便于区分是请求微信缺参,还是管理端审核传参问题
|
||||
console.log('[wechat-transfer] ========== 请求微信支付(用户确认模式)==========')
|
||||
console.log('[wechat-transfer] URL:', `${BASE_URL}${urlPath}`)
|
||||
console.log('[wechat-transfer] 请求体 body:', JSON.stringify(body, null, 2))
|
||||
console.log('[wechat-transfer] 当前配置: mchId=', cfg.mchId, 'appId=', cfg.appId, 'certSerialNo=', cfg.certSerialNo ? `${cfg.certSerialNo.slice(0, 8)}...` : '(空)')
|
||||
console.log('[wechat-transfer] notify_url:', body.notify_url)
|
||||
console.log('[wechat-transfer] ========================================')
|
||||
|
||||
const res = await fetch(`${BASE_URL}${urlPath}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
@@ -229,6 +274,7 @@ export async function createTransferUserConfirm(
|
||||
body: bodyStr,
|
||||
})
|
||||
const data = (await res.json()) as Record<string, unknown>
|
||||
console.log('[wechat-transfer] 微信响应 status=', res.status, 'body=', JSON.stringify(data, null, 2))
|
||||
if (res.ok && res.status >= 200 && res.status < 300) {
|
||||
const state = (data.state as string) || ''
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user