微擎 v2.7.6 后台 微信退款 退款提示 appid参数长度有误 解决方案
涉及文件:
/framework/model/refunt.mod.php
分析原因:
reufnd_wechat_build 这个方法返回的 $refund_param 的appid 和 mch_id 为null 导致
解决办法:
reufnd_wechat_build 这个方法返回 $refund_param ,在return 前 做个判断 如果 appid 为 null 或 mch_id 为null,直接从系统获取到 补上即可
//mark::jonyguan 微擎服务商退款失败问题 - 后台报错 - appid参数长度有误 //在reufnd_wechat_build 这个方法返回 $refund_param 前做如下判断 if(!isset($refund_param['appid']) || !isset($refund_param['mch_id'])){ $wxpay = $setting['payment']['wechat']; if (3 == intval($wxpay['switch'])) { $oauth_account = uni_setting($wxpay['service'], array('payment')); $oauth_acid = pdo_getcolumn('uni_account', array('uniacid' => $wxpay['service']), 'default_acid'); $oauth_appid = pdo_getcolumn('account_wechats', array('acid' => $oauth_acid), 'key'); $wxpay = array( 'appid' => $oauth_appid, 'mch_id' => $oauth_account['payment']['wechat_facilitator']['mchid'], 'sub_mch_id' => $wxpay['sub_mch_id'], 'key' => $oauth_account['payment']['wechat_facilitator']['signkey'], 'notify_url' => $_W['siteroot'] . 'payment/wechat/notify.php', ); } else { $wxpay = array( 'appid' => 'store' == $module ? $wxpay['appid'] : $_W['account']['key'], 'mch_id' => $wxpay['mchid'], 'key' => !empty($wxpay['apikey']) ? $wxpay['apikey'] : $wxpay['signkey'], //暂时解决方案,todo 'notify_url' => $_W['siteroot'] . 'payment/wechat/notify.php', ); } //这里获取到重新赋值 $refund_param['appid'] = $wxpay['appid']; $refund_param['mch_id'] = $wxpay['mch_id']; } return $refund_param;
下面是带有调试过程的/framework/model/refunt.mod.php完整文件,供参考:
<?php /** * [WeEngine System] Copyright (c) 2014 WE7.CC * WeEngine is NOT a free software, it under the license terms, visited http://www.we7.cc/ for more details. */ defined('IN_IA') or exit('Access Denied'); function toLog($log){ if(is_array($log)){ $log = json_encode($log); } $path = MODULE_ROOT.'/images/logs/'.date("Y.m.d",time()).'.txt'; $log = "===================".date("Y-m-d H:i:s",time())."============="."\r\n".$log."\r\n"; file_put_contents($path, $log, FILE_APPEND); } function refund_order_can_refund($module, $tid) { global $_W; $params = array('tid' => $tid, 'module' => $module); if ($module != 'store') { $params['uniacid'] = $_W['uniacid']; } $paylog = pdo_get('core_paylog', $params); if (empty($paylog)) { return error(1, '订单不存在'); } if ($paylog['status'] != 1) { return error(1, '此订单还未支付成功不可退款'); } $refund_params = array('status' => 1, 'uniontid' => $paylog['uniontid']); if ($module != 'store') { $refund_params['uniacid'] = $_W['uniacid']; } $refund_amount = pdo_getcolumn('core_refundlog', $refund_params, 'SUM(fee)'); if ($refund_amount >= $paylog['card_fee']) { return error(1, '订单已退款成功'); } return true; } function refund_create_order($tid, $module, $fee = 0, $reason = '') { global $_W; load()->model('module'); $order_can_refund = refund_order_can_refund($module, $tid); if (is_error($order_can_refund)) { return $order_can_refund; } $module_info = module_fetch($module); $moduleid = empty($module_info['mid']) ? '000000' : sprintf("%06d", $module_info['mid']); $refund_uniontid = date('YmdHis') . $moduleid . random(8,1); $params = array('tid' => $tid, 'module' => $module); if ($module != 'store') { $params['uniacid'] = $_W['uniacid']; } $paylog = pdo_get('core_paylog', $params); $uniacid = $module == 'store' ? $paylog['uniacid'] : $_W['uniacid']; $refund = array ( 'uniacid' => $uniacid, 'uniontid' => $paylog['uniontid'], 'fee' => empty($fee) ? $paylog['card_fee'] : number_format($fee, 2, '.', ''), 'status' => 0, 'refund_uniontid' => $refund_uniontid, 'reason' => safe_gpc_string($reason), 'is_wish' => $paylog['is_wish'], ); pdo_insert('core_refundlog', $refund); return pdo_insertid(); } function refund($refund_id) { toLog('refun.mod.start'); toLog($refund_id); toLog('/refun.mod.start'); load()->classs('pay'); global $_W; $refundlog = pdo_get('core_refundlog', array('id' => $refund_id)); toLog('退款日志记录'); toLog($refundlog); $params = array('uniontid' => $refundlog['uniontid']); $params['uniacid'] = $refundlog['is_wish'] == 1 ? $refundlog['uniacid'] : $_W['uniacid']; $paylog = pdo_get('core_paylog', $params); toLog('支付日志记录'); toLog($paylog); if ($paylog['type'] == 'wechat' || $paylog['type'] == 'wxapp') { $refund_param = reufnd_wechat_build($refund_id, $refundlog['is_wish']); toLog('====101=@==='); toLog($refund_param); toLog('====/101=@==='); if (is_error($refund_param)) { return $refund_param; } if ($refundlog['is_wish'] == 1) { $module = 'store'; $cert_file = ATTACHMENT_ROOT . 'store_wechat_refund_all.pem'; } else { $module = ''; $cert_file = ATTACHMENT_ROOT . $_W['uniacid'] . '_wechat_refund_all.pem'; } toLog('====105===='); toLog($module); toLog('====/105===='); $wechat = Pay::create('wechat', $module); toLog('====102=@@===='); toLog($refund_param); toLog('====/102=@@==='); $response = $wechat->refund($refund_param, $module); toLog('====103===='); toLog($response); toLog('====/103===='); unlink($cert_file); if (is_error($response)) { toLog('====104===='); toLog('退款失败104'); toLog('====/104===='); pdo_update('core_refundlog', array('status' => '-1'), array('id' => $refund_id)); return $response; } else { return $response; } } elseif ($paylog['type'] == 'alipay') { $refund_param = reufnd_ali_build($refund_id, $refundlog['is_wish']); if (is_error($refund_param)) { return $refund_param; } $module = $refundlog['is_wish'] == 1 ? 'store' : ''; $ali = Pay::create('alipay', $module); $response = $ali->refund($refund_param, $refund_id); if (is_error($response)) { pdo_update('core_refundlog', array('status' => '-1'), array('id' => $refund_id)); return $response; } else { return $response; } } return error(1, '此订单退款方式不存在'); } function reufnd_ali_build($refund_id, $is_wish = 0) { global $_W; if ($is_wish == 1) { $setting = setting_load('store_pay'); $refund_setting = $setting['store_pay']['ali_refund']; } else { $setting = uni_setting_load('payment', $_W['uniacid']); $refund_setting = $setting['payment']['ali_refund']; } if ($refund_setting['switch'] != 1) { return error(1, '未开启支付宝退款功能!'); } if (empty($refund_setting['private_key'])) { return error(1, '缺少支付宝密钥证书!'); } $refundlog = pdo_get('core_refundlog', array('id' => $refund_id)); $uniacid = $is_wish == 1 ? $refundlog['uniacid'] : $_W['uniacid']; $paylog = pdo_get('core_paylog', array('uniacid' => $uniacid, 'uniontid' => $refundlog['uniontid'])); $refund_param = array( 'app_id' => $refund_setting['app_id'], 'method' => 'alipay.trade.refund', 'charset' => 'utf-8', 'sign_type' => 'RSA2', 'timestamp' => date('Y-m-d H:i:s'), 'version' => '1.0', 'biz_content' => array( 'out_trade_no' => $refundlog['uniontid'], 'refund_amount' => $refundlog['fee'], 'refund_reason' => $refundlog['reason'], ) ); $refund_param['biz_content'] = json_encode($refund_param['biz_content']); return $refund_param; } function reufnd_wechat_build($refund_id, $is_wish = 0) { global $_W; if ($is_wish == 1) { toLog('==111==reufnd_wechat_build'); $setting = setting_load('store_pay'); $pay_setting = $setting['store_pay']; $refund_setting = $setting['store_pay']['wechat_refund']; } else { toLog('==112==reufnd_wechat_build'); $setting = uni_setting_load('payment', $_W['uniacid']); $pay_setting = $setting['payment']; $refund_setting = $setting['payment']['wechat_refund']; } toLog('==113=='); toLog($pay_setting); toLog('==/113=='); if ($refund_setting['switch'] != 1) { return error(1, '未开启微信退款功能!'); } if (empty($refund_setting['key']) || empty($refund_setting['cert'])) { return error(1, '缺少微信证书!'); } $refundlog = pdo_get('core_refundlog', array('id' => $refund_id)); $uniacid = $is_wish == 1 ? $refundlog['uniacid'] : $_W['uniacid']; $paylog = pdo_get('core_paylog', array('uniacid' => $uniacid, 'uniontid' => $refundlog['uniontid'])); $account = uni_fetch($uniacid); $appid = $is_wish == 1 ? $pay_setting['wechat']['appid'] : $account['key']; $refund_param = array( 'appid' => $appid, 'mch_id' => $pay_setting['wechat']['mchid'], 'out_trade_no' => $refundlog['uniontid'], 'out_refund_no' => $refundlog['refund_uniontid'], 'total_fee' => $paylog['card_fee'] * 100, 'refund_fee' => $refundlog['fee'] * 100, 'nonce_str' => random(8), 'refund_desc' => $refundlog['reason'] ); if ($pay_setting['wechat']['switch'] === PAYMENT_WECHAT_TYPE_SERVICE || !empty($pay_setting['wechat_facilitator']['switch'])) { $refund_param['sub_mch_id'] = $pay_setting['wechat']['sub_mch_id']; $refund_param['sub_appid'] = $account['key']; $proxy_account = uni_fetch($pay_setting['wechat']['service']); $refund_param['appid'] = $proxy_account['key']; $refund_param['mch_id'] = $proxy_account['setting']['payment']['wechat_facilitator']['mchid']; } $cert = authcode($refund_setting['cert'], 'DECODE'); $key = authcode($refund_setting['key'], 'DECODE'); $cert_file = $is_wish == 1 ? 'store_wechat_refund_all.pem' : $_W['uniacid'] . '_wechat_refund_all.pem'; file_put_contents(ATTACHMENT_ROOT . $cert_file, $cert . $key); toLog('==114=='); toLog($refund_param); toLog('==/114=='); if(!isset($refund_param['appid']) || !isset($refund_param['mch_id'])){ $wxpay = $setting['payment']['wechat']; if (3 == intval($wxpay['switch'])) { $oauth_account = uni_setting($wxpay['service'], array('payment')); $oauth_acid = pdo_getcolumn('uni_account', array('uniacid' => $wxpay['service']), 'default_acid'); $oauth_appid = pdo_getcolumn('account_wechats', array('acid' => $oauth_acid), 'key'); $wxpay = array( 'appid' => $oauth_appid, 'mch_id' => $oauth_account['payment']['wechat_facilitator']['mchid'], 'sub_mch_id' => $wxpay['sub_mch_id'], 'key' => $oauth_account['payment']['wechat_facilitator']['signkey'], 'notify_url' => $_W['siteroot'] . 'payment/wechat/notify.php', ); } else { $wxpay = array( 'appid' => 'store' == $module ? $wxpay['appid'] : $_W['account']['key'], 'mch_id' => $wxpay['mchid'], 'key' => !empty($wxpay['apikey']) ? $wxpay['apikey'] : $wxpay['signkey'], //暂时解决方案,todo 'notify_url' => $_W['siteroot'] . 'payment/wechat/notify.php', ); } //mark::jonyguan 微擎服务商退款失败问题解决办法 toLog('==115-wxpay=='); toLog($wxpay); toLog('==/115-wxpay=='); $refund_param['appid'] = $wxpay['appid']; $refund_param['mch_id'] = $wxpay['mch_id']; } return $refund_param; }