提交 4c8005a9 编写于 作者: D devil_gong

wx pay debug

上级 0e087aca
......@@ -120,7 +120,8 @@ return array(
'common_platform_type' => array(
'pc' => array('value' => 'pc', 'name' => 'PC网站'),
'h5' => array('value' => 'h5', 'name' => 'H5手机网站'),
'app' => array('value' => 'app', 'name' => 'APP'),
'ios' => array('value' => 'ios', 'name' => '苹果APP'),
'android' => array('value' => 'android', 'name' => '安卓APP'),
'alipay' => array('value' => 'alipay', 'name' => '支付宝小程序'),
'weixin' => array('value' => 'weixin', 'name' => '微信小程序'),
'baidu' => array('value' => 'baidu', 'name' => '百度小程序'),
......
......@@ -850,7 +850,8 @@ class OrderAftersaleService
$pay_params = [
'order_no' => $order['order_no'],
'trade_no' => $pay_log['trade_no'],
'refund_amount' => $aftersale['price'],
'pay_price' => $order['pay_price'],
'refund_price' => $aftersale['price'],
'refund_reason' => $order['order_no'].'订单退款'.$aftersale['price'].'元',
];
$ret = (new $pay_name($payment[0]['config']))->Refund($pay_params);
......
......@@ -298,7 +298,7 @@ class Alipay
],
[
'checked_type' => 'empty',
'key_name' => 'refund_amount',
'key_name' => 'refund_price',
'error_msg' => '退款金额不能为空',
],
];
......@@ -309,7 +309,7 @@ class Alipay
}
// 退款原因
$refund_reason = empty($params['refund_reason']) ? $params['order_no'].'订单退款'.$params['refund_amount'].'元' : $params['refund_reason'];
$refund_reason = empty($params['refund_reason']) ? $params['order_no'].'订单退款'.$params['refund_price'].'元' : $params['refund_reason'];
// 退款参数
$parameter = array(
......@@ -324,7 +324,7 @@ class Alipay
$biz_content = array(
'out_trade_no' => $params['order_no'],
'trade_no' => $params['trade_no'],
'refund_amount' => $params['refund_amount'],
'refund_amount' => $params['refund_price'],
'refund_reason' => $refund_reason,
);
$parameter['biz_content'] = json_encode($biz_content, JSON_UNESCAPED_UNICODE);
......
......@@ -240,6 +240,94 @@ class AlipayMini
return $data;
}
/**
* 退款处理
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2019-05-28
* @desc description
* @param [array] $params [输入参数]
*/
public function Refund($params = [])
{
// 参数
$p = [
[
'checked_type' => 'empty',
'key_name' => 'order_no',
'error_msg' => '订单号不能为空',
],
[
'checked_type' => 'empty',
'key_name' => 'trade_no',
'error_msg' => '交易平台订单号不能为空',
],
[
'checked_type' => 'empty',
'key_name' => 'refund_price',
'error_msg' => '退款金额不能为空',
],
];
$ret = ParamsChecked($params, $p);
if($ret !== true)
{
return DataReturn($ret, -1);
}
// 退款原因
$refund_reason = empty($params['refund_reason']) ? $params['order_no'].'订单退款'.$params['refund_price'].'元' : $params['refund_reason'];
// 退款参数
$parameter = array(
'app_id' => $this->config['appid'],
'method' => 'alipay.trade.refund',
'format' => 'JSON',
'charset' => 'utf-8',
'sign_type' => 'RSA2',
'timestamp' => date('Y-m-d H:i:s'),
'version' => '1.0',
);
$biz_content = array(
'out_trade_no' => $params['order_no'],
'trade_no' => $params['trade_no'],
'refund_amount' => $params['refund_price'],
'refund_reason' => $refund_reason,
);
$parameter['biz_content'] = json_encode($biz_content, JSON_UNESCAPED_UNICODE);
// 生成签名参数+签名
$params = $this->GetParamSign($parameter);
$parameter['sign'] = $this->MyRsaSign($params['value']);
// 执行请求
$result = $this->HttpRequest('https://openapi.alipay.com/gateway.do', $parameter);
$key = str_replace('.', '_', $parameter['method']).'_response';
// 验证签名
if(!$this->SyncRsaVerify($result, $key))
{
return DataReturn('签名验证错误', -1);
}
// 状态
if(isset($result[$key]['code']) && $result[$key]['code'] == 10000)
{
// 统一返回格式
$data = [
'out_trade_no' => isset($result[$key]['out_trade_no']) ? $result[$key]['out_trade_no'] : '',
'trade_no' => isset($result[$key]['trade_no']) ? $result[$key]['trade_no'] : '',
'buyer_user' => isset($result[$key]['buyer_user_id']) ? $result[$key]['buyer_user_id'] : '',
'refund_price' => isset($result[$key]['refund_fee']) ? $result[$key]['refund_fee'] : 0.00,
'return_params' => $result[$key],
];
return DataReturn('退款成功', 0, $data);
}
// 直接返回支付信息
return DataReturn($result[$key]['sub_msg'].'['.$result[$key]['sub_code'].']', -1000);
}
/**
* [GetParamSign 生成参数和签名]
* @param [array] $data [待生成的参数]
......
......@@ -100,6 +100,24 @@ class Weixin
'is_required' => 0,
'message' => '请填写密钥',
],
[
'element' => 'textarea',
'name' => 'apiclient_cert',
'placeholder' => '证书(apiclient_cert.pem)',
'title' => '证书(apiclient_cert.pem)',
'is_required' => 0,
'rows' => 6,
'message' => '请填写证书(apiclient_cert.pem)',
],
[
'element' => 'textarea',
'name' => 'apiclient_key',
'placeholder' => '证书密钥(apiclient_key.pem)',
'title' => '证书密钥(apiclient_key.pem)',
'is_required' => 0,
'rows' => 6,
'message' => '请填写证书密钥(apiclient_key.pem)',
],
[
'element' => 'select',
'title' => '异步通知协议',
......@@ -107,7 +125,7 @@ class Weixin
'name' => 'agreement',
'is_multiple' => 0,
'element_data' => [
['value'=>1, 'name'=>'默认当前http协议'],
['value'=>1, 'name'=>'默认当前协议'],
['value'=>2, 'name'=>'强制https转http协议'],
],
],
......@@ -426,6 +444,92 @@ class Weixin
return $data;
}
/**
* 退款处理
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2019-05-28
* @desc description
* @param [array] $params [输入参数]
*/
public function Refund($params = [])
{
// 参数
$p = [
[
'checked_type' => 'empty',
'key_name' => 'order_no',
'error_msg' => '订单号不能为空',
],
[
'checked_type' => 'empty',
'key_name' => 'trade_no',
'error_msg' => '交易平台订单号不能为空',
],
[
'checked_type' => 'empty',
'key_name' => 'pay_price',
'error_msg' => '支付金额不能为空',
],
[
'checked_type' => 'empty',
'key_name' => 'refund_price',
'error_msg' => '退款金额不能为空',
],
];
$ret = ParamsChecked($params, $p);
if($ret !== true)
{
return DataReturn($ret, -1);
}
// 退款原因
$refund_reason = empty($params['refund_reason']) ? $params['order_no'].'订单退款'.$params['refund_price'].'元' : $params['refund_reason'];
// appid
$appid = (APPLICATION == 'app') ? $this->config['mini_appid'] : $this->config['appid'];
// 请求参数
$data = [
'appid' => $appid,
'mch_id' => $this->config['mch_id'],
'nonce_str' => md5(time().rand().$params['order_no']),
'sign_type' => 'MD5',
'transaction_id' => $params['trade_no'],
'out_trade_no' => $params['order_no'],
'out_refund_no' => $params['order_no'].GetNumberCode(6),
'total_fee' => intval($params['pay_price']*100),
'refund_fee' => intval($params['refund_price']*100),
'refund_desc' => $refund_reason,
];
$data['sign'] = $this->GetSign($data);
// xml
$xml = $this->ArrayToXml($data);
// echo $xml;die;
$result = $this->XmlToArray($this->HttpRequest('https://api.mch.weixin.qq.com/secapi/pay/refund', $xml, true));
if(!empty($result['return_code']) && $result['return_code'] == 'SUCCESS' && !empty($result['prepay_id']))
{
// 统一返回格式
$data = [
'out_trade_no' => isset($result['out_trade_no']) ? $result['out_trade_no'] : '',
'trade_no' => isset($result['transaction_id']) ? $result['transaction_id'] : '',
'buyer_user' => isset($result['refund_id']) ? $result['refund_id'] : '',
'refund_price' => isset($result['refund_fee']) ? $result['refund_fee'] : 0.00,
'return_params' => $result,
];
return DataReturn('退款成功', 0, $data);
}
$msg = empty($result['return_msg']) ? '退款异常' : $result['return_msg'];
if(!empty($result['err_code_des']))
{
$msg .= '-'.$result['err_code_des'];
}
return DataReturn($msg, -1);
}
/**
* 签名生成
* @author Devil
......@@ -533,13 +637,20 @@ class Weixin
if($use_cert == true)
{
// 退款 取消使用
$apiclient_cert = "-----BEGIN CERTIFICATE-----\n";
$apiclient_cert .= wordwrap($this->config['apiclient_cert'], 64, "\n", true);
$apiclient_cert .= "\n-----END CERTIFICATE-----";
$apiclient_key = "-----BEGIN PRIVATE KEY-----\n";
$apiclient_key .= wordwrap($this->config['apiclient_key'], 64, "\n", true);
$apiclient_key .= "\n-----END PRIVATE KEY-----";
//设置证书
//使用证书:cert 与 key 分别属于两个.pem文件
// $options[CURLOPT_SSLCERTTYPE] = 'PEM';
// $options[CURLOPT_SSLCERT] = WEB_ROOT.'cert/wechat_app_apiclient_cert.pem';
// $options[CURLOPT_SSLKEYTYPE] = 'PEM';
// $options[CURLOPT_SSLKEY] = WEB_ROOT.'cert/wechat_app_apiclient_key.pem';
$options[CURLOPT_SSLCERTTYPE] = 'PEM';
$options[CURLOPT_SSLCERT] = ROOT.'weixin-cert/apiclient_cert.pem';
$options[CURLOPT_SSLKEYTYPE] = 'PEM';
$options[CURLOPT_SSLKEY] = ROOT.'weixin-cert/apiclient_key.pem';
}
$ch = curl_init($url);
......
......@@ -174,7 +174,7 @@ App({
return (
this.data.request_url +
"index.php?s=/" + m + "/" + c + "/" + a +
"&application_client=default&&application=app&application_client_type=alipay&application_user_id=" +
"&application=app&application_client_type=alipay&application_user_id=" +
app_client_user_id +
"&user_id=" +
user_id +
......
......@@ -168,7 +168,7 @@ App({
return (
this.data.request_url +
"index.php?s=/" + m + "/" + c + "/" + a +
"&application_client=default&&application=app&application_client_type=weixin&application_user_id=" +
"&application=app&application_client_type=weixin&application_user_id=" +
app_client_user_id +
"&user_id=" +
user_id +
......
......@@ -48,13 +48,10 @@ define('ROOT', str_replace('public'.DS, '', ROOT_PATH));
// 定义应用目录
define('APP_PATH', ROOT.'application'.DS);
// 请求应用 [web, app] 默认web
// 请求应用 [web, app] 默认web(ios|android|小程序 均为app)
define('APPLICATION', empty($_REQUEST['application']) ? 'web' : trim($_REQUEST['application']));
// 请求客户端 [default, ...] 默认default
define('APPLICATION_CLIENT', empty($_REQUEST['application_client']) ? 'default' : trim($_REQUEST['application_client']));
// 请求客户端 [pc, h5, alipay, weixin, baidu] 默认pc
// 请求客户端 [pc, h5, ios, android, alipay, weixin, baidu] 默认pc(目前系统为自适应,h5需自行校验)
define('APPLICATION_CLIENT_TYPE', empty($_REQUEST['application_client_type']) ? 'pc' : trim($_REQUEST['application_client_type']));
// 是否ajax
......
-----BEGIN CERTIFICATE-----
MIIEaDCCA9GgAwIBAgIDas/LMA0GCSqGSIb3DQEBBQUAMIGKMQswCQYDVQQGEwJD
TjESMBAGA1UECBMJR3Vhbmdkb25nMREwDwYDVQQHEwhTaGVuemhlbjEQMA4GA1UE
ChMHVGVuY2VudDEMMAoGA1UECxMDV1hHMRMwEQYDVQQDEwpNbXBheW1jaENBMR8w
HQYJKoZIhvcNAQkBFhBtbXBheW1jaEB0ZW5jZW50MB4XDTE2MTIwMzA5NTIwN1oX
DTI2MTIwMTA5NTIwN1owgZgxCzAJBgNVBAYTAkNOMRIwEAYDVQQIEwlHdWFuZ2Rv
bmcxETAPBgNVBAcTCFNoZW56aGVuMRAwDgYDVQQKEwdUZW5jZW50MQ4wDAYDVQQL
EwVNTVBheTEtMCsGA1UEAxQk5LiK5rW35YyX5pav572R57uc56eR5oqA5pyJ6ZmQ
5YWs5Y+4MREwDwYDVQQEEwgxMDQyMzc1NjCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAMDA5gcWYofO1bp8xEuEMSa7i1WiPi4PuU02FWmDi3wSNIzpyrpP
qXmmCu8DRBry4dRf4/62WFgzh0HP9TRnmDsADAr4/Q2i/QQMlFnYyk1N8X7muirP
T4aU8BpR4zwBEQMsSybdmuJvyxxZMKR3/McMjXnuyqX6tFbUhCg5XBTZwBR6CNU/
Dx28VC6xWvBeWKzjELC59nyb263hjlHjdEy/8xufh3Oux/+nherHSTzQFHPgW9cB
25/o90pLq1zSJx66UcdkKMJP8JjOnMvn+nCZmFUDawJKD9SlOLW06DyE/WBDV/Uf
qgdm+I1kR5IwRyxGKFwWjP4yDaWqlCEzvpkCAwEAAaOCAUYwggFCMAkGA1UdEwQC
MAAwLAYJYIZIAYb4QgENBB8WHSJDRVMtQ0EgR2VuZXJhdGUgQ2VydGlmaWNhdGUi
MB0GA1UdDgQWBBTVt+c3x8Y9CT62eTuErS8U9yFJ2jCBvwYDVR0jBIG3MIG0gBQ+
BSb2ImK0FVuIzWR+sNRip+WGdKGBkKSBjTCBijELMAkGA1UEBhMCQ04xEjAQBgNV
BAgTCUd1YW5nZG9uZzERMA8GA1UEBxMIU2hlbnpoZW4xEDAOBgNVBAoTB1RlbmNl
bnQxDDAKBgNVBAsTA1dYRzETMBEGA1UEAxMKTW1wYXltY2hDQTEfMB0GCSqGSIb3
DQEJARYQbW1wYXltY2hAdGVuY2VudIIJALtUlyu8AOhXMA4GA1UdDwEB/wQEAwIG
wDAWBgNVHSUBAf8EDDAKBggrBgEFBQcDAjANBgkqhkiG9w0BAQUFAAOBgQAT1LPp
RghlBDmKjhFG596cZrYswQznfgahTOwb66nL1WXg6XlBb7sIqflKinAXzQOZJML4
iAsHCLq63y+ELJKMeh96tOmgH3pzQt9R6j2aL7kg6aXSSEiPlXiVKStiy2OWARWC
lwHc+cBmxiw8K7818NuCc0/WlYzrawPfPQat2g==
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDAwOYHFmKHztW6
fMRLhDEmu4tVoj4uD7lNNhVpg4t8EjSM6cq6T6l5pgrvA0Qa8uHUX+P+tlhYM4dB
z/U0Z5g7AAwK+P0Nov0EDJRZ2MpNTfF+5roqz0+GlPAaUeM8AREDLEsm3Zrib8sc
WTCkd/zHDI157sql+rRW1IQoOVwU2cAUegjVPw8dvFQusVrwXlis4xCwufZ8m9ut
4Y5R43RMv/Mbn4dzrsf/p4Xqx0k80BRz4FvXAduf6PdKS6tc0iceulHHZCjCT/CY
zpzL5/pwmZhVA2sCSg/UpTi1tOg8hP1gQ1f1H6oHZviNZEeSMEcsRihcFoz+Mg2l
qpQhM76ZAgMBAAECggEAQjtGDxNjAdVRXUX30Rb4KJ3yr5cTFJK0klJOIzZfHF/J
DM5cqY4r5q/mO+B8a2IftPDKD8CqNIxoInYJhFtAVK2cdby+fwwNMnH8G69BPDTX
EUrIl2MqqUzN/805bmnTZaq3nAAzczEEspX2/9x20BKBHm+t1ECD7P4S9xtWh5b+
H8IycTZLB5Y6R+0cTptpzkuUvp4kJDfXg9++QyHucEdG3+0jN26qSfog0KPbbeQZ
Odmvg8POsMqGcNhsa13OgP9mggQiKtsDQ2hyYbCIjNLK/Rs3JU/dLzJihXazfI12
VjIpBbT//Z7LddBnfZ1jfy0OW2jn7s4SObW2ds7ysQKBgQDeXoJvoVE+ZcjTv80t
woqXwNYO8Vo9n1fM+8V9kWELgMm1/H2PmEu1pmHUwWwYz4xmNan4NcA0m13MH2tx
WItE0GFpISYdCc3jXdU8toGU4YnxACh+GPRy4PHmX3DjA7xx1BX+O4NUKpgt5N9J
fxb9k1h4NuXW10qVAKJspTW4HQKBgQDd58GTF+6hjaicEUUZUm+VeejvZaVsVGSn
K0HixOU0JfeLWugLswgEB2TU84JFrULfRkjtMOx/5J6MeZFljD/E3VwtVMg2aIrN
x5/gRQWyPpfhcl1ZhFy2an3Ql/uMgA/75zU2/EMWV2qAKsQpd3std1Fem370bh1J
slJrqi0vrQKBgQDERfsveN3zC3hFnsgFme8mnyjRq6qRNbIT1i6s9MMJmjVwklpp
gm1g+mjjl45IH/m2xasu0JLEXFZgM2NselEC/kLcvkub2emGxG3Q1u5tcN2GgTM8
id5J/87EHn3Pgp60ghSff/wdMDN+XsPPZYPvcjzmbt5T0VedSSAUcYaG6QKBgQCd
i4oKZcZdWpan3zcAyF9Cb6AqPy9YHv6rFPIdDw9vm7kJbkwq6ju5qIo1CoGl+GHu
5Ranl8GA9459S14oC4/GtCZaZMQUpNpPSPhAIKDvsLLiM/EEug2c0TRsIUtNsCoo
/Tjxxd3Xgc6yGirVCeghGoJhueJDpd4TUZBkshiMrQKBgCJsFeRZGLpqIIF8nQDA
8ut6O5e7LRFguqcfp2pMHCSt7inzSJZNQsYq38dPPW2UYBmTO0C8kwNJCjVyYJt3
K6Aw9tjix1FU5dqNmC3GDwstz5VmXqmsyISRePgjiMYaIdysDFZYiw6gCRoDKN31
OvonqYebbxvzTfQGtUNmCdvW
-----END PRIVATE KEY-----
欢迎使用微信支付!
附件中的三份文件(证书pkcs12格式、证书pem格式、证书密钥pem格式),为接口中强制要求时需携带的证书文件。
证书属于敏感信息,请妥善保管不要泄露和被他人复制。
不同开发语言下的证书格式不同,以下为说明指引:
证书pkcs12格式(apiclient_cert.p12)
包含了私钥信息的证书文件,为p12(pfx)格式,由微信支付签发给您用来标识和界定您的身份
部分安全性要求较高的API需要使用该证书来确认您的调用身份
windows上可以直接双击导入系统,导入过程中会提示输入证书密码,证书密码默认为您的商户ID(如:10010000)
证书pem格式(apiclient_cert.pem)
从apiclient_cert.p12中导出证书部分的文件,为pem格式,请妥善保管不要泄漏和被他人复制
部分开发语言和环境,不能直接使用p12文件,而需要使用pem,所以为了方便您使用,已为您直接提供
您也可以使用openssl命令来自己导出:openssl pkcs12 -clcerts -nokeys -in apiclient_cert.p12 -out apiclient_cert.pem
证书密钥pem格式(apiclient_key.pem)
从apiclient_cert.p12中导出密钥部分的文件,为pem格式
部分开发语言和环境,不能直接使用p12文件,而需要使用pem,所以为了方便您使用,已为您直接提供
您也可以使用openssl命令来自己导出:openssl pkcs12 -nocerts -in apiclient_cert.p12 -out apiclient_key.pem
备注说明:
由于绝大部分操作系统已内置了微信支付服务器证书的根CA证书, 2018年3月6日后, 不再提供CA证书文件(rootca.pem)下载
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册