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
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!