fix: add HTTP timeout and cert cache error recovery in wxpay

- httpsRequest: 15s timeout, prevents hanging on WeChat API outage
- fetchPlatformCertificates: keeps old certs if refresh fails,
  only throws if no certs at all (first time failure)
这个提交包含在:
Guoguo
2026-05-18 05:35:17 -07:00
父节点 2e63213e60
当前提交 46cc225fe8
+19 -11
查看文件
@@ -80,6 +80,7 @@ function httpsRequest(method, path, body) {
} }
}) })
}) })
req.setTimeout(15000, () => { req.destroy(new Error('wxpay request timeout (15s)')) })
req.on('error', reject) req.on('error', reject)
if (bodyStr) req.write(bodyStr) if (bodyStr) req.write(bodyStr)
req.end() req.end()
@@ -117,18 +118,25 @@ let _platformCertsExpiry = 0
async function fetchPlatformCertificates() { async function fetchPlatformCertificates() {
if (_platformCertsExpiry > Date.now()) return _platformCerts if (_platformCertsExpiry > Date.now()) return _platformCerts
const path = '/v3/certificates' try {
const result = await httpsRequest('GET', path) const path = '/v3/certificates'
const certs = {} const result = await httpsRequest('GET', path)
for (const item of (result.data || [])) { const certs = {}
const resource = item.encrypt_certificate for (const item of (result.data || [])) {
if (!resource) continue const resource = item.encrypt_certificate
const certPem = decryptResource(resource) if (!resource) continue
certs[item.serial_no] = certPem const certPem = decryptResource(resource)
certs[item.serial_no] = certPem
}
if (Object.keys(certs).length > 0) {
_platformCerts = certs
_platformCertsExpiry = Date.now() + 12 * 3600 * 1000
}
} catch (err) {
console.error('[WXPAY] cert refresh failed, keeping old certs:', err.message)
if (Object.keys(_platformCerts).length === 0) throw err
} }
_platformCerts = certs return _platformCerts
_platformCertsExpiry = Date.now() + 12 * 3600 * 1000
return certs
} }
async function verifyNotifySignature(headers, rawBody) { async function verifyNotifySignature(headers, rawBody) {