共计 5407 个字符,预计需要花费 14 分钟才能阅读完成。
服务分帐功能实现
1、开通服务商分帐功能
2、添加子商户
3、开始分账 需要先添加可分账用户才能分
注意点:
1、在支付的时候添加 profit_sharing = 'Y'
2、签名和请求参数的签名类型为 HMAC-SHA256
3、需要证书
* 服务商分账功能
*
*/
class wxDivideAccount
{
protected $CertPem = '/home/wwwroot/xixxxxm/comxxxmon/mch/apiclient_cert.pem';
protected $KeyPem = '/home/wwwroot/xixxxxm/comxxxmon/mch/apiclient_key.pem';
protected $key = 'lwLyC2AWYPwwewewt4ddkX2vhO5q'; // 支付密钥 key
/*
服务商分账
*/
public function divideMoney()
{$params = array();
$params['mch_id'] = '1406xx6102'; // 服务商 mch_id
$params['sub_mch_id'] = '1553xx6371'; // 特约商户 mch_id
$params['appid'] = 'wx18dbxxx55773c05'; // 服务商对就的 appid
$params['sub_appid'] = 'wx7814xxaddbeb8'; // 对应的子 appid
$params['nonce_str'] = $this->createNoncestr();
$params['sign_type'] = 'HMAC-SHA256';
$params['transaction_id'] = '4200000450201910195680876190'; // 微信支付订单号
$params['out_order_no'] = '157146517126_580624809017106007'; // 交易订单号
$receivers = array([
'type' => 'PERSONAL_SUB_OPENID',
'account' => 'owf034yN-8MdAFNgaNm4qbxDw', //sub_openid
'amount' => 20,
'description' => '分给推广员'
]);
$params['receivers'] = json_encode($receivers);
$params['sign'] = $this->createSign($params);
// 把数组转化成 xml 格式
$xmlData = $this->arrayToXml($params);
$resXml = $this->postXmlCurl('https://api.mch.weixin.qq.com/secapi/pay/profitsharing',$xmlData,true);
$resXml = $this->xmlSafeStr(html_entity_decode($resXml));
$resData = json_decode(json_encode(simplexml_load_string($resXml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
if($resData['return_code']=='SUCCESS' && $resData['result_code']=='SUCCESS') return true;
write_log('分账失败,msg:'$resData['return_msg'],'profitshare');
return false;
}
// 添加可分帐帐号
public function profitSharingAddreceiver()
{
$url = 'https://api.mch.weixin.qq.com/pay/profitsharingaddreceiver';
$params = array();
$params['mch_id'] = '1406xx6102'; // 服务商 mch_id
$params['sub_mch_id'] = '1553xx6371'; // 特约商户 mch_id
$params['appid'] = 'wx18dbxxx55773c05'; // 服务商对就的 appid
$params['sub_appid'] = 'wx7814xxaddbeb8'; // 对应的子 appid
$params['nonce_str'] = $this->createNoncestr();
$params['sign_type'] = 'HMAC-SHA256';
$receiver = [
'type' => 'PERSONAL_SUB_OPENID',
'account' => 'owf0349GNSmFBkvJpxlG-92N62ZM',
'relation_type' => 'DISTRIBUTOR'
];
$params['receiver'] = json_encode($receiver);
$params['sign'] = $this->createSign($params);
// 把数组转化成 xml 格式
$xmlData = $this->arrayToXml($params);
$resXml = $this->postXmlCurl($url,$xmlData,true);
$resData = json_decode(json_encode(simplexml_load_string($resXml, 'SimpleXMLElement', LIBXML_NOCDATA)), 1);
if($resData['return_code']=='SUCCESS' && $resData['result_code']=='SUCCESS') return true;
write_log('分账用户添加失败,msg:'$resData['return_msg'],'profitshare');
return false;
}
/*
* 查询分账结果
*/
public function profitSharingQuery()
{
$url = 'https://api.mch.weixin.qq.com/pay/profitsharingquery';
$params = array();
$params['mch_id'] = '1406xx6102';
$params['sub_mch_id'] = '1553xx6371';
$params['nonce_str'] = $this->createNoncestr();
$params['sign_type'] = 'HMAC-SHA256';
$params['transaction_id'] = '4200000450201910195680876190';
$params['out_order_no'] = '157146517126_580624809017106007';
$params['sign'] = $this->createSign($params);
// 把数组转化成 xml 格式
$xmlData = $this->arrayToXml($params);
$resXml = $this->postXmlCurl($url,$xmlData,true);
$resXml = $this->xmlSafeStr(html_entity_decode($resXml));
$resData = json_decode(json_encode(simplexml_load_string($resXml, 'SimpleXMLElement', LIBXML_NOCDATA)), 1);
if($resData['return_code']=='SUCCESS' && $resData['result_code']=='SUCCESS') return true;
write_log('分红查询 到账失败,msg:'$resData['return_msg'],'profitshare');
return false;
}
// 生成签名
private function createSign($params)
{
// 签名步骤一:按字典序排序参数
ksort($params);
$String = $this->formatBizQueryParaMap($params, false);
// 签名步骤二:在 string 后加入 KEY
$String = $String."&key=".$this->key;
// 签名步骤三:加密方式 HMAC-SHA256
// $String = md5($String);
$String = hash_hmac("sha256", $String,$this->key);
// 签名步骤四:所有字符转为大写
$result_ = strtoupper($String);
return $result_;
}
// 按字典序排序参数
private function formatBizQueryParaMap($params,$urlencode=false)
{ksort($params);
$buff = '';
foreach($params as $key=>$val)
{$buff .= $key . "=" . $val . "&";}
$reqPar = substr($buff, 0, strlen($buff)-1);
return $reqPar;
}
// 随机字符串
private function createNoncestr($length=32)
{
$chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
$str = '';
for($i=0;$i<$length;$i++){$str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
}
return $str;
}
// 将数组转换为 xml 格式
private function arrayToXml($arr)
{
$xml = "<xml>";
foreach($arr as $key=>$val)
{if(is_numeric($val))
$xml .= '<' . $key .'>' . $val . '</' . $key . '>';
else
$xml .= "<".$key."><![CDATA[".$val."]]></".$key.">";
}
$xml .="</xml>";
return $xml;
}
private function postXmlCurl($url,$xml,$useCert=false, $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); // 严格校验
// 设置 header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
// 要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
if($useCert)
{
// 设置证书
// 使用证书:cert 与 key 分别属于两个.pem 文件
// 默认格式为 PEM,可以注释
curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLCERT, $this->CertPem);
// 默认格式为 PEM,可以注释
curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLKEY, $this->KeyPem);
}
//post 提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt($ch, CURLOPT_TIMEOUT, 40);
set_time_limit(0);
// 运行 curl
$data = curl_exec($ch);
// 返回结果
if ($data) {curl_close($ch);
// write_log($data,'wxpay');
return $data;
} else {// var_dump($data);
$error = curl_errno($ch);
write_log("curl 出错,错误码:$error",'wxpay');
curl_close($ch);
return false;
}
}
/**
* 过滤特殊字符
* @param string $str
* @return string
*/
function xmlSafeStr($str)
{return preg_replace("/[\\x00-\\x08\\x0b-\\x0c\\x0e-\\x1f]/", '', $str);
}
正文完