php微信分账功能 —— app支付
时间:2021-03-03 19:17:23
收藏:0
阅读:355
分账官方文档:https://pay.weixin.qq.com/wiki/doc/api/allocation.php?chapter=26_2
准备一:开通微信分账功能
(1)进入微信商户平台;
(2)点击产品中心;
(3)点击我的产品;
(4)支付扩展工具里面的分账功能;
准备二:公众号
(1)官方文档里面的写法是要用公众号和公众号的openid,没有说只能用公众号,但是我测试过,这里是只能使用公众号。
(2)网上说是只要是相应的平台和获取的openid就行,但是我测试的结果是,使用公众号以外的appid和openid,会报一个openid和appid不匹配的错误。
(3)我使用的app进行的支付,所以我原以为使用公众平台的appid个openid就可以,结果显示,不行,所以我又去公众上面添加了一个绑定页面,这里不做描述,后续有时间我会写一个公众号的获取openid的例子。
分账功能实现:
(1)基础方法
/**
*
* 产生随机字符串,不长于32位
* @param int $length
* @return 产生的随机字符串
*/
public static 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;
}
/**
* 将xml转为array
* @param string $xml
*/
private function fromXml($xml)
{
if(!$xml){
return "";
}
//将XML转为array
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$this->values = json_decode(json_encode(simplexml_load_string($xml, ‘SimpleXMLElement‘, LIBXML_NOCDATA)), true);
return $this->values;
}
/**
* 输出xml字符
**/
public function toXml($data)
{
if(!is_array($data)
|| count($data) <= 0)
{
return "";
}
$xml = "<xml>";
foreach ($data as $key=>$val)
{
if (is_numeric($val)){
$xml.="<".$key.">".$val."</".$key.">";
}else{
$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
}
}
$xml.="</xml>";
return $xml;
}
/**
* 以post方式提交xml到对应的接口url
*
* @param string $xml 需要post的xml数据
* @param string $url url
* @param bool $useCert 是否需要证书,默认不需要
* @param int $second url执行超时时间,默认30s
*/
public function postXmlCurl($xml, $url, $useCert = false, $second = 30)
{
$ch = curl_init();
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
//如果有配置代理这里就设置代理
// if(WxPayConfig::CURL_PROXY_HOST != "0.0.0.0"
// && WxPayConfig::CURL_PROXY_PORT != 0){
// curl_setopt($ch,CURLOPT_PROXY, WxPayConfig::CURL_PROXY_HOST);
// curl_setopt($ch,CURLOPT_PROXYPORT, WxPayConfig::CURL_PROXY_PORT);
// }
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验
//设置header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
if (defined(‘CURLOPT_IPRESOLVE‘) && defined(‘CURL_IPRESOLVE_V4‘)) {
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
}
if($useCert == true){
$cert_dir = ROOT_PATH.DS."config".DS."payment_cert".DS."wechatpay".DS;
if(
!file_exists($cert_dir."apiclient_cert.pem") ||
!file_exists($cert_dir."apiclient_key.pem")
){
return "";
}
//设置证书 证书自己参考支付设置
//使用证书:cert 与 key 分别属于两个.pem文件
curl_setopt($ch,CURLOPT_SSLCERTTYPE,‘PEM‘);
curl_setopt($ch,CURLOPT_SSLCERT, $cert_dir."apiclient_cert.pem");
curl_setopt($ch,CURLOPT_SSLKEYTYPE,‘PEM‘);
curl_setopt($ch,CURLOPT_SSLKEY, $cert_dir."apiclient_key.pem");
}
//post提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
//运行curl
$data = curl_exec($ch);
//返回结果
if($data){
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
curl_close($ch);
return "";
}
}
(2)分账方法
ps:分账需要先提交 添加分账方 然后才能提起分账
/**
* 微信分账功能
* $out_order_no 系统自定义的单号
* $transaction_id 微信支付单号
* $profitSharingAccounts array 分账接收方
*
*/
public function ProfitShare($out_order_no, $transaction_id, $profitSharingAccounts)
{
$result = array();
$result[‘status‘] = false;
$result[‘message‘] = ‘未知错误!‘;
if ($out_order_no == ‘‘) {
$result[‘message‘] = ‘系统单号为空!‘;
}
if ($transaction_id == ‘‘) {
$result[‘message‘] = ‘支付单号为空!‘;
}
$url = ‘https://api.mch.weixin.qq.com/secapi/pay/profitsharing‘;
//添加请求xml
$xmlArr = array();
$xmlArr[‘appid‘] = config(‘jshop.service_wechatgzh_appid‘);
$xmlArr[‘mch_id‘] = config(‘jshop.service_wechatpay_mch_id‘);
$xmlArr[‘out_order_no‘] = $out_order_no;
$xmlArr[‘transaction_id‘] = $transaction_id;
$xmlArr[‘nonce_str‘] = $this->getNonceStr();
$xmlArr[‘sign_type‘] = ‘HMAC-SHA256‘;
$xmlArr[‘receivers‘] = json_encode($profitSharingAccounts);
$sign = $this->makeSignBySHA($xmlArr);
$xmlArr[‘sign‘] = $sign;
$XmlStr = $this->toXml($xmlArr);
$res = $this->postXmlCurl($XmlStr, $url, true);
$res = $this->fromXml($res);
if ($res[‘return_code‘] == ‘SUCCESS‘) {
$result[‘status‘] = true;
$result[‘message‘] = ‘查询成功!‘;
}
return $result;
}
/**
* 查询分账结果
* $out_order_no 系统自定义的单号
* $transaction_id 微信支付单号
*/
public function ProfitsharingQuery($out_order_no, $transaction_id)
{
$result = array();
$result[‘status‘] = false;
$result[‘message‘] = ‘未知错误!‘;
if ($out_order_no == ‘‘) {
$result[‘message‘] = ‘系统单号为空!‘;
}
if ($transaction_id == ‘‘) {
$result[‘message‘] = ‘支付单号为空!‘;
}
$url = ‘https://api.mch.weixin.qq.com/pay/profitsharingquery‘;
$xmlArr = array();
$xmlArr[‘mch_id‘] = config(‘jshop.service_wechatpay_mch_id‘);
$xmlArr[‘out_order_no‘] = $out_order_no;
$xmlArr[‘transaction_id‘] = $transaction_id;
$xmlArr[‘nonce_str‘] = $this->getNonceStr();
$xmlArr[‘sign_type‘] = ‘HMAC-SHA256‘;
$sign = $this->makeSignBySHA($xmlArr);
$xmlArr[‘sign‘] = $sign;
$XmlStr = $this->toXml($xmlArr);
$res = $this->postXmlCurl($XmlStr, $url);
$res = $this->fromXml($res);
$result[‘data‘] = $res;
if ($res[‘return_code‘] == ‘SUCCESS‘ && $res[‘result_code‘] == ‘SUCCESS‘) {
$result[‘status‘] = true;
$result[‘message‘] = ‘查询成功!‘;
}
return $result;
}
/**
* 添加分账方
*/
public function ProfitSharingAddReceiver($profitSharingAccounts)
{
$result = array();
$result[‘status‘] = false;
$result[‘message‘] = ‘未知错误!‘;
if (count($profitSharingAccounts) == 0) {
$result[‘message‘] = ‘分账接收为空!‘;
return $result;
}
$url = ‘https://api.mch.weixin.qq.com/pay/profitsharingaddreceiver‘;
//添加请求xml
$xmlArr = array();
$xmlArr[‘appid‘] = config(‘jshop.service_wechatgzh_appid‘);
$xmlArr[‘mch_id‘] = config(‘jshop.service_wechatpay_mch_id‘);
$xmlArr[‘nonce_str‘] = $this->getNonceStr();
$xmlArr[‘sign_type‘] = ‘HMAC-SHA256‘;
$xmlArr[‘receiver‘] = json_encode($profitSharingAccounts);
$sign = $this->makeSignBySHA($xmlArr);
$xmlArr[‘sign‘] = $sign;
$XmlStr = $this->toXml($xmlArr);
$res = $this->postXmlCurl($XmlStr, $url);
var_dump($res);
}
/**
* 删除分账方
* profitSharingAccounts 分账方数组
*/
public function ProfitSharingRemoverEceiver($profitSharingAccounts)
{
$result = array();
$result[‘status‘] = false;
$result[‘message‘] = ‘未知错误!‘;
if (count($profitSharingAccounts) == 0) {
$result[‘message‘] = ‘分账接收为空!‘;
return $result;
}
$url = ‘https://api.mch.weixin.qq.com/pay/profitsharingremovereceiver
‘;
//添加请求xml
$xmlArr = array();
$xmlArr[‘appid‘] = config(‘jshop.service_wechatgzh_appid‘);
$xmlArr[‘mch_id‘] = config(‘jshop.service_wechatpay_mch_id‘);
$xmlArr[‘nonce_str‘] = $this->getNonceStr();
$xmlArr[‘sign_type‘] = ‘HMAC-SHA256‘;
$xmlArr[‘receiver‘] = json_encode($profitSharingAccounts);
$sign = $this->makeSignBySHA($xmlArr);
$xmlArr[‘sign‘] = $sign;
$XmlStr = $this->toXml($xmlArr);
$res = $this->postXmlCurl($XmlStr, $url);
var_dump($res);
}
/**
* 完结分账
* * $out_order_no 系统自定义的单号
* $transaction_id 微信支付单号
*/
public function ProfitSharingFinish($out_order_no, $transaction_id)
{
$result = array();
$result[‘status‘] = false;
$result[‘message‘] = ‘未知错误!‘;
if ($out_order_no == ‘‘) {
$result[‘message‘] = ‘系统单号为空!‘;
}
if ($transaction_id == ‘‘) {
$result[‘message‘] = ‘支付单号为空!‘;
}
$url = ‘https://api.mch.weixin.qq.com/secapi/pay/profitsharingfinish‘;
$xmlArr = array();
$xmlArr[‘mch_id‘] = config(‘jshop.service_wechatpay_mch_id‘);
$xmlArr[‘appid‘] = config(‘jshop.service_wechatgzh_appid‘);
$xmlArr[‘out_order_no‘] = $out_order_no.‘1‘;
$xmlArr[‘transaction_id‘] = $transaction_id;
$xmlArr[‘nonce_str‘] = $this->getNonceStr();
$xmlArr[‘sign_type‘] = ‘HMAC-SHA256‘;
$xmlArr[‘description‘] = ‘完结分账‘;
$sign = $this->makeSignBySHA($xmlArr);
$xmlArr[‘sign‘] = $sign;
$XmlStr = $this->toXml($xmlArr);
$res = $this->postXmlCurl($XmlStr, $url, true);
$res = $this->fromXml($res);
$result[‘data‘] = $res;
if ($res[‘return_code‘] == ‘SUCCESS‘) {
$result[‘status‘] = true;
$result[‘message‘] = ‘查询成功!‘;
}
return $result;
}
写的不好,大家将就看,有啥不懂的,记得留言大家讨论,我只是记录一下我遇到的坑,随便提供一下简单的方法,希望后面的人不要重复踩坑
原文:https://www.cnblogs.com/wangbaishi/p/14475975.html
评论(0)