fix: 平台微信退款改用俱乐部收款配置(付呗/直连分路,不动支付宝)
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -918,84 +918,29 @@ class KefuPlatformRefundView(APIView):
|
||||
|
||||
def call_wechat_refund(self, dingdan_id, jine, transaction_id=None):
|
||||
"""
|
||||
调用微信支付退款接口
|
||||
:param dingdan_id: 商户订单号(我们的订单ID)
|
||||
:param jine: 退款金额
|
||||
:param transaction_id: 微信支付订单号(优先使用)
|
||||
:return: {'code': 0, 'msg': '成功', 'refund_id': 'xxx'} 或 {'code': 非0, 'msg': '错误信息'}
|
||||
平台订单退款:付呗单走付呗;微信直连单按订单 Club 的「收款」配置 V2 退款(不用全局 settings、不用提现 V3)。
|
||||
不处理支付宝。
|
||||
"""
|
||||
from jituan.services.pay_refund_router import try_fubei_refund
|
||||
from jituan.services.wechat_pay import club_id_from_order
|
||||
from jituan.services.wechat_v2_refund import refund_wechat_v2_by_club
|
||||
|
||||
club_id = club_id_from_order(dingdan_id)
|
||||
fb = try_fubei_refund(
|
||||
out_trade_no=dingdan_id,
|
||||
amount_yuan=jine,
|
||||
club_id=club_id_from_order(dingdan_id),
|
||||
club_id=club_id,
|
||||
)
|
||||
if fb is not None:
|
||||
return fb
|
||||
|
||||
# 获取配置
|
||||
appid = getattr(settings, 'WEIXIN_APPID', '')
|
||||
mch_id = getattr(settings, 'WEIXIN_MCHID', '')
|
||||
key = getattr(settings, 'WEIXIN_SHANGHUMIYAO', '')
|
||||
cert_path = getattr(settings, 'WEIXIN_CERT_PATH', '')
|
||||
key_path = getattr(settings, 'WEIXIN_KEY_PATH', '')
|
||||
|
||||
if not all([appid, mch_id, key, cert_path, key_path]):
|
||||
missing = [k for k, v in {'appid': appid, 'mch_id': mch_id, 'key': key, 'cert_path': cert_path, 'key_path': key_path}.items() if not v]
|
||||
logger.error(f"微信支付配置缺失: {missing}")
|
||||
return {'code': 500, 'msg': f'系统支付配置缺失: {missing}'}
|
||||
|
||||
# 生成退款单号
|
||||
out_refund_no = self.generate_refund_no(dingdan_id)
|
||||
total_fee = yuan_to_fen(jine)
|
||||
refund_fee = total_fee
|
||||
refund_desc = '客服退款'
|
||||
|
||||
# 构造请求参数
|
||||
params = {
|
||||
'appid': appid,
|
||||
'mch_id': mch_id,
|
||||
'nonce_str': self.generate_nonce_str(),
|
||||
'out_refund_no': out_refund_no,
|
||||
'total_fee': total_fee,
|
||||
'refund_fee': refund_fee,
|
||||
'refund_desc': refund_desc,
|
||||
}
|
||||
if transaction_id:
|
||||
params['transaction_id'] = transaction_id
|
||||
else:
|
||||
params['out_trade_no'] = dingdan_id # 使用订单ID作为商户订单号
|
||||
|
||||
# 生成签名
|
||||
sorted_keys = sorted(params.keys())
|
||||
stringA = '&'.join([f"{k}={params[k]}" for k in sorted_keys])
|
||||
stringSignTemp = f"{stringA}&key={key}"
|
||||
sign = hashlib.md5(stringSignTemp.encode('utf-8')).hexdigest().upper()
|
||||
params['sign'] = sign
|
||||
|
||||
xml_data = self.dict_to_xml(params)
|
||||
url = 'https://api.mch.weixin.qq.com/secapi/pay/refund'
|
||||
|
||||
try:
|
||||
response = requests.post(
|
||||
url,
|
||||
data=xml_data,
|
||||
cert=(cert_path, key_path),
|
||||
timeout=10
|
||||
)
|
||||
result = xmltodict.parse(response.content)['xml']
|
||||
logger.info(f"微信退款响应: {result}")
|
||||
except Exception as e:
|
||||
logger.error(f"微信退款请求异常: {str(e)}", exc_info=True)
|
||||
return {'code': 500, 'msg': '微信退款请求异常'}
|
||||
|
||||
if result.get('return_code') == 'SUCCESS' and result.get('result_code') == 'SUCCESS':
|
||||
return {'code': 0, 'msg': 'success', 'refund_id': out_refund_no}
|
||||
else:
|
||||
err_msg = result.get('err_code_des', result.get('return_msg', '未知错误'))
|
||||
logger.warning(f"微信退款失败: {err_msg}")
|
||||
return {'code': 400, 'msg': err_msg}
|
||||
return refund_wechat_v2_by_club(
|
||||
out_trade_no=dingdan_id,
|
||||
amount_yuan=jine,
|
||||
club_id=club_id,
|
||||
transaction_id=transaction_id,
|
||||
reason='客服退款',
|
||||
)
|
||||
|
||||
def generate_nonce_str(self):
|
||||
return ''.join(random.choices(string.ascii_letters + string.digits, k=32))
|
||||
|
||||
Reference in New Issue
Block a user