写在前面:
微信官方文档
https://pay.weixin.qq.com/wiki/doc/api/allocation.php?chapter=27_3&index=4
SIGN值校验检查地址
https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=20_1
调试中可能遇到的问题
SIGN_ERROR : https://developers.weixin.qq.com/community/develop/doc/0002cc86c603b006fd4a4c65f59c00?highLine=SIGN_ERROR
SYSTEMERROR: https://developers.weixin.qq.com/community/develop/doc/0006eec6274db8ddd619cf6105bc00
直接上代码
<?php
namespace app\admin\lib\weixin;
use think\Controller;
class Weixin extends Controller
{
private $add_divide_accounts_url;
private $add_divide_accounts_type;
private $add_divide_accounts_relation_type;
private $mch_id;
private $appid;
private $mch_secrect;
function __construct()
{
$this->add_divide_accounts_url = 'https://api.mch.weixin.qq.com/pay/profitsharingaddreceiver';
$this->add_divide_accounts_type = 'PERSONAL_OPENID';
$this->add_divide_accounts_relation_type = 'PARTNER';
$this->mch_id = config('wechat.pay_config.mch_id');
$this->appid = config('wechat.pay_config.app_id');
$this->mch_secrect = config('wechat.pay_config.key');
}
public function addDivideAccountsReceiver($openid)
{
$tmp_receive_data = [
'mch_id' => $this->mch_id,
'appid' => $this->appid,
'nonce_str' => $this->getNonceStr(),
'sign_type' => 'HMAC-SHA256',
'receiver' => $this->receiver($openid)
];
$tmp_receive_data['sign'] = $this->makeSign($tmp_receive_data, $this->mch_secrect);
$xml = $this->arrayToXml($tmp_receive_data);
$curl_arr = $this->postXmlCurl($xml, $this->add_divide_accounts_url);
$result = $this->xmlToArray($curl_arr);
return $result;
}
private function receiverInfo($openid)
{
$tmp_receiver_arr = [
'type' => 'PERSONAL_OPENID',
'account' => $openid,
'relation_type' => $this->add_divide_accounts_relation_type,
];
return json_encode($tmp_receiver_arr);
}
private function getNonceStr($length = 32)
{
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str = "";
for ($i = 0; $i < $length; $i++) {
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
return $str;
}
private function makeSign($arr, $secret)
{
ksort($arr);
$str = $this->toUrlParams($arr);
$str = $str . "&key=" . $secret;
$str = hash_hmac('sha256', $str, $this->mch_secrect);
$result = strtoupper($str);
return $result;
}
private function toUrlParams($arr)
{
$str = "";
foreach ($arr as $k => $v) {
if (!empty($v) && ($k != 'sign')) {
$str .= "$k" . "=" . $v . "&";
}
}
$str = rtrim($str, "&");
return $str;
}
private function arrayToXml($arr){
$xml = '<?xml version="1.0" encoding="UTF-8"?><xml>';
foreach ($arr as $key => $val) {
$xml.="<".$key.">$val</".$key.">";
}
$xml.="</xml>";
return $xml;
}
private function xmlToArray($xml){
libxml_disable_entity_loader(true);
$arr= json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $arr;
}
private function postXmlCurl($xml, $url, $second = 30){
$ch = curl_init();
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
$data = curl_exec($ch);
if($data){
curl_close($ch);
return $data;
}else{
$error = curl_errno($ch);
echo "curl出错,错误码:$error"."<br>";
echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>";
curl_close($ch);
return false;
}
}
}