微信分账详情

获取商户号和开发者ID,并开启分账
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

<?php

$fileurl = 'payment/wxpay_jsapi.php';
include_once($fileurl);
require_once( 'payment/wxpay/WxPay.JsApiPay.php');
require_once( 'acount.php');
$tools = new JsApiPay();
$result_openid = $tools->GetOpenid();
$open_id = $result_openid['openid'];//获取openid,必须是可以直接访问的页面,没有post的数据

$new = new profits();
$da=$new->addProfit($open_id );//成为分账方
if($da){
    $receivers = [
        [
            "type" => "PERSONAL_OPENID",    // 分账接收方类型
            "account" => $open_id,        // 分账接收方账号,一次可添加50个
            "amount" => $teacherMoney * 100,        // 分账金额 分
            "description" => "分钱了"            // 分账描述
        ]
    ];
    $transaction_id='4200002295202407187404008583';
    sleep(5);//如果是支付后立即分账的建议 延迟几秒再分账,否则可能会返回“订单处理中,暂时无法分账,请稍后再试”
    $new->profitsharing($receivers,$transaction_id);//分账
}






<?php

/**
 * 微信分账类
 */

class profits{
    /**
     * 分账(必须先成为分账方以后才可以分账),分账金额不可超过总金额的百分之三十
     * @param $receivers
     * @param $transaction_id
     * @return int
     * @throws WxPayException
     */
    public function profitsharing($receivers,$transaction_id)
    {
        $aData = [
            "mch_id" => "166643434", //商户号
            "appid" => "wx1b36900831943434f", //微信appid
            "nonce_str" => $this->getNonceStr(),       // 随机字符串
            "transaction_id" => $transaction_id,            // 微信订单号:根据你的业务场景来获取
            "out_order_no" => $this->get_order_sn(),                    // 商户分账单号
            "receivers" => json_encode($receivers)// 分账接收方列表 json格式 中文不转码
        ];
        // 签名
        ksort($aData);
        $aData['sign'] = $this->MakeSign($aData);
        // 请求单次分账
        //$url = 'https://api.mch.weixin.qq.com/secapi/pay/profitsharing';//单次分账
        $url="https://api.mch.weixin.qq.com/secapi/pay/multiprofitsharing"; //多次分账
        // 参数转ml
        $postXML = $this->ToXml($aData);
        // 结果
        $timeOut = 6;
        $response = self::postXmlCurl($postXML, $url, true, $timeOut);
        //var_dump($response);
        // 结果转数组
        $ret = $this->FromXml($response);
        //var_dump($ret);
        file_put_contents('receivers.txt', json_encode($receivers), FILE_APPEND | LOCK_EX);
        file_put_contents('fenzhang.txt', $response, FILE_APPEND | LOCK_EX);
        // 保存分账订单状态或者别的操作
        if ($ret["return_code"] == "SUCCESS" && $ret["result_code"] == "SUCCESS") {
            return 1;
        } else {
            return 2;
        }
    }
    
    /**
     * 添加分账方(一次只能加一个,很鸡肋)
     * @param $open_id
     * @return int
     * @throws WxPayException
     */ 
    public function addProfit($open_id)
    {
        // 添加分账接收方
        $url = 'https://api.mch.weixin.qq.com/pay/profitsharingaddreceiver';
        // 接收方信息
        $receiver = [
            // 分账接收方类型
            "type" => "PERSONAL_OPENID",
            // 分账接收方账号 (个人:openid)
            "account" => $open_id,
            // 关系
            "relation_type" => 'PARTNER',
        ];
        // 公共参数
        $oValues = [
            "mch_id" => "166643434",
            "appid" => "wx1b36900831943434f",
            "nonce_str" => $this->getNonceStr(),  // 随机字符串
            "receiver" => json_encode($receiver),// 接收方信息
        ];
        // 产生签名
        ksort($oValues);
        $oValues["sign"] = $this->MakeSign($oValues);
        // 参数转ml
        $postXML = $this->ToXml($oValues);

        // 请求
        $timeOut = 6;
        $response = self::postXmlCurl($postXML, $url, true, $timeOut);

        // 结果转数组
        $ret = $this->FromXml($response);
        if ($ret["return_code"] == "SUCCESS" && $ret["result_code"] == "SUCCESS") {
            // 添加分账接收方成功
            return 1;
        } else {
            return 2;
        }
    }
    
    /**
     *
     * 产生随机字符串,不长于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字符
     **/
    public function ToXml($values)
    {

        if (!is_array($values) || count($values) <= 0) {
            return "数组数据异常!";
        }

        $xml = "<xml>";

        foreach ($values as $key => $val) {
            if (is_numeric($val)) {
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            } else {
                $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
            }
        }
        $xml .= "</xml>";

        return $xml;
    }

    /**
     * 将xml转为array
     * @param string $xml
     * @throws WxPayException
     */
    public function FromXml($xml)
    {
        if (!$xml) {
            return "xml数据异常!";
        }
        //将XML转为array
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $res = json_decode(json_encode(simplexml_load_string($xml,             'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $res;
    }

    /**
     * 生成签名
     * @param bool $needSignType  是否需要补signtype
     * @return 签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
     */
    public function MakeSign($values, $needSignType = true)
    {
        if ($needSignType) {
            // $this->SetSignType($config->GetSignType());
            $sSignType = "HMAC-SHA256";
        }

        $sKey = "gUAcBjXMHoEzLG9duUffU0s7nUhWwO17";

        // 签名步骤一:按字典序排序参数
        ksort($values);
        $string = $this->ToUrlParams($values);

        // 签名步骤二:在string后加入KEY
        $string = $string . "&key=" . $sKey;

        // 签名步骤三:MD5加密或者HMAC-SHA256
        if ($sSignType == "MD5") {
            $string = md5($string);
        } else if ($sSignType == "HMAC-SHA256") {
            $string = hash_hmac("sha256", $string, $sKey);
        } else {
            return "签名类型不支持!";
        }

        // 签名步骤四:所有字符转为大写
        $result = strtoupper($string);

        return $result;
    }

    /**
     * 拼接参数
     * @param $values
     * @return string
     */
    public function ToUrlParams($values)
    {
        $buff = "";
        foreach ($values as $k => $v)
        {
            if($k != "sign" && $v != "" && !is_array($v)){
                $buff .= $k . "=" . $v . "&";
            }
        }

        $buff = trim($buff, "&");
        return $buff;
    }

    /**
     * 以post方式提交xml到对应的接口url
     *
     * @param WxPayConfigInterface $config  配置对象
     * @param string 	$xml  		需要post的xml数据
     * @param string 	$url  		url
     * @param bool 		$useCert 	是否需要证书,默认不需要
     * @param int 		$second   	url执行超时时间,默认30s
     */
    private function postXmlCurl($xml, $url, $useCert = false, $second = 30)
    {

        $ch 			= curl_init();
        $curlVersion 	= curl_version();
        //$ua 			= "WXPaySDK/" . self::VERSION . " (" . PHP_OS . ") PHP/" . PHP_VERSION . " CURL/" . $curlVersion['version'] . " " . $aWxpayParam['mchid'];

        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);

        $proxyHost = "0.0.0.0";
        $proxyPort = 0;

        // 如果有配置代理这里就设置代理
        if ($proxyHost != "0.0.0.0" && $proxyPort != 0) {
            curl_setopt($ch, CURLOPT_PROXY, $proxyHost);
            curl_setopt($ch, CURLOPT_PROXYPORT, $proxyPort);
        }

        curl_setopt($ch, CURLOPT_URL, $url);
        // curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);
        // curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //严格校验
        //curl_setopt($ch, CURLOPT_USERAGENT, $ua);
        // 设置header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        // 要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

        if ($useCert == true) {
            // 设置证书
            // 使用证书:cert 与 key 分别属于两个.pem文件
            // 证书文件请放入服务器的非web目录下
            $sslCertPath 	= './payment/cert/apiclient_cert.pem';        // 证书路径
            $sslKeyPath 	= './payment/cert/apiclient_key.pem';         // 证书路径
            curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
            curl_setopt($ch, CURLOPT_SSLCERT, $sslCertPath);
            curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
            curl_setopt($ch, CURLOPT_SSLKEY, $sslKeyPath);
        }

        // 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);
            throw new WxPayException("curl出错,错误码:$error");
        }
    }
    
	function get_order_sn()
	{
	    mt_srand((double) microtime() * 1000000);
	    return date('Ymd') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
	}
}


分账完成后会收取万分之五四的手续费

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值