Browse Source

refactor: 退款请求复用 PaymentClient 直连支付平台

Co-authored-by: Cursor <cursoragent@cursor.com>
Pchen. 5 days ago
parent
commit
c312e1072a
2 changed files with 55 additions and 72 deletions
  1. 1 71
      lib/OrderRefundService.js
  2. 54 1
      lib/PaymentClient.js

+ 1 - 71
lib/OrderRefundService.js

@@ -1,7 +1,6 @@
-const axios = require('axios')
-const config = require('../config.json')
 const db = require('../plugin/DataBase/db')
 const db = require('../plugin/DataBase/db')
 const { insertLedgerRecord } = require('./Lepao/CountLedger')
 const { insertLedgerRecord } = require('./Lepao/CountLedger')
+const { requestPaymentRefund } = require('./PaymentClient')
 
 
 const REFUND_WINDOW_MS = 7 * 24 * 60 * 60 * 1000
 const REFUND_WINDOW_MS = 7 * 24 * 60 * 60 * 1000
 const ORDER_STATE_COMPLETED = 2
 const ORDER_STATE_COMPLETED = 2
@@ -36,75 +35,6 @@ function evaluateRefundEligibility({
     return { canRefund: true, reason: '' }
     return { canRefund: true, reason: '' }
 }
 }
 
 
-function parsePaymentResponseBody(data) {
-    if (data && typeof data === 'object') return data
-    if (typeof data !== 'string') return null
-    const text = data.trim()
-    if (!text) return null
-    try {
-        return JSON.parse(text)
-    } catch (_) {
-        return null
-    }
-}
-
-function formatPaymentRefundError(response, fallbackMessage) {
-    const status = Number(response?.status || 0)
-    const parsed = parsePaymentResponseBody(response?.data)
-
-    if (parsed?.msg) return String(parsed.msg)
-    if (status === 503) return '支付平台暂时不可用,请稍后重试'
-    if (status >= 500) return `支付平台异常(${status}),请稍后重试`
-    if (status >= 400) return `支付平台拒绝退款(${status})`
-    return fallbackMessage || '支付平台退款失败'
-}
-
-async function requestPaymentRefund({ orderId, tradeNo, money, logger }) {
-    const paymentConfig = config.pay || {}
-    if (!paymentConfig.url || !paymentConfig.pid || !paymentConfig.key) {
-        throw new Error('支付配置错误')
-    }
-
-    const params = new URLSearchParams()
-    params.append('pid', String(paymentConfig.pid))
-    params.append('key', paymentConfig.key)
-    if (tradeNo) {
-        params.append('trade_no', tradeNo)
-    } else {
-        params.append('out_trade_no', orderId)
-    }
-    params.append('money', String(money))
-
-    const refundUrl = `${paymentConfig.url}/api.php?act=refund`
-    let response
-    try {
-        response = await axios.post(refundUrl, params.toString(), {
-            headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
-            timeout: 30000,
-            validateStatus: () => true
-        })
-    } catch (error) {
-        logger?.error?.(`易支付退款请求失败 订单号:${orderId}:${error.stack || error}`)
-        if (error.code === 'ECONNABORTED') {
-            throw new Error('支付平台响应超时,请稍后重试')
-        }
-        throw new Error('无法连接支付平台,请稍后重试')
-    }
-
-    const result = parsePaymentResponseBody(response.data)
-    logger?.info?.(`易支付退款响应 订单号:${orderId},HTTP ${response.status},结果:${JSON.stringify(result ?? response.data)}`)
-
-    if (response.status >= 400) {
-        throw new Error(formatPaymentRefundError(response, '支付平台退款失败'))
-    }
-
-    if (!result || Number(result.code) !== 1) {
-        throw new Error(result?.msg || '支付平台退款失败')
-    }
-
-    return result
-}
-
 async function loadRefundContext(orderId) {
 async function loadRefundContext(orderId) {
     const rows = await db.query(
     const rows = await db.query(
         `SELECT
         `SELECT

+ 54 - 1
lib/PaymentClient.js

@@ -92,11 +92,64 @@ async function queryPaymentOrder(orderId, logger) {
     return result
     return result
 }
 }
 
 
+function formatPaymentRefundError(response, fallbackMessage) {
+    return formatPaymentHttpError({ response }, fallbackMessage || '支付平台退款失败')
+}
+
+async function requestPaymentRefund({ orderId, tradeNo, money, logger }) {
+    const paymentConfig = getPaymentConfig()
+    if (!paymentConfig.url || !paymentConfig.pid || !paymentConfig.key) {
+        throw new Error('支付配置错误')
+    }
+
+    const refundUrl = buildPaymentApiUrl('refund')
+    const params = new URLSearchParams()
+    params.append('pid', String(paymentConfig.pid))
+    params.append('key', paymentConfig.key)
+    if (tradeNo) {
+        params.append('trade_no', tradeNo)
+    } else {
+        params.append('out_trade_no', orderId)
+    }
+    params.append('money', String(money))
+
+    let response
+    try {
+        response = await axios.post(
+            refundUrl,
+            params.toString(),
+            getAxiosPaymentOptions({
+                timeout: 30000,
+                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+                validateStatus: () => true
+            })
+        )
+    } catch (error) {
+        logger?.error?.(`易支付退款请求失败 订单号:${orderId}:${error.stack || error}`)
+        throw new Error(formatPaymentHttpError(error, '无法连接支付平台,请稍后重试'))
+    }
+
+    const result = parsePaymentResponseBody(response.data)
+    logger?.info?.(`易支付退款响应 订单号:${orderId},HTTP ${response.status},结果:${JSON.stringify(result ?? response.data)}`)
+
+    if (response.status >= 400) {
+        throw new Error(formatPaymentRefundError(response, '支付平台退款失败'))
+    }
+
+    if (!result || Number(result.code) !== 1) {
+        throw new Error(result?.msg || '支付平台退款失败')
+    }
+
+    return result
+}
+
 module.exports = {
 module.exports = {
     normalizePayBaseUrl,
     normalizePayBaseUrl,
     buildPaymentApiUrl,
     buildPaymentApiUrl,
     getAxiosPaymentOptions,
     getAxiosPaymentOptions,
     formatPaymentHttpError,
     formatPaymentHttpError,
+    formatPaymentRefundError,
     parsePaymentResponseBody,
     parsePaymentResponseBody,
-    queryPaymentOrder
+    queryPaymentOrder,
+    requestPaymentRefund
 }
 }