微信服务商分账功能 PHP

项目说明

  1. 微信服务商分账接口说明:https://pay.weixin.qq.com/wiki/doc/api/allocation_sl.php?chapter=24_1&index=1

项目大概逻辑

  1. 开通分账功能(https://pay.weixin.qq.com/wiki/doc/api/allocation_sl.php?chapter=24_2&index=2)
  2. 服务商代子商户发起添加分账接收方请求
  3. 在统一下单API、付款码支付API、委托扣款API中上传新增参数profit_sharing,请求支付
  4. 支付完成后,调用请求分账接口,完成分账

其他注意事项

  1. 分账接口分为单次分账和多次分账
  2. 当用户需要退款时,单次分账调用接口的步骤是:分账回退->申请退款
  3. 当用户需要退款时,多次分账调用接口的步骤是:分账完结->分账回退->申请退款
  4. 这里画重点,商户系统内部的分账单号,在商户系统内部唯一(***单次分账、多次分账、完结分账应使用不同的商户分账单号),同一分账单号多次请求等同一次。**只能是数字、大小写字母_-|@
  5. Ilog是一个日志类,这里就不提供了,大家都有自己的
  6. ProfitSharingSign.class.php是用来生成签名的,跟微信支付、微信退款生成签名类是一样的,会贴在最后
  7. ProfitSharingCurl.class.php是一个发送http请求的类,会贴在最后
  8. pdo_*的方法是微擎框架自带的数据库操作(这框架估计没谁会喜欢…)
  9. 使用例子就不写了,单身狗都知道,new一个对象嘛,大家给我介绍一个也行的,然后照着参数传就行
  10. 最后,欢迎指错~~

代码

分账接口类 ProfitSharing.class.php

wxConfig = $this->wxConfig();
        $this->sign = new ProfitSharingSign();
        $this->curl = new ProfitSharingCurl();
    }


    /**
     * @function 发起请求所必须的配置参数
     * @return mixed
     */
    private function wxConfig()
    {
        $wxConfig['app_id'] = '';//服务商公众号AppID
        $wxConfig['mch_id'] = ''; //服务商商户号
        $wxConfig['sub_app_id'] = '';//todo 子服务商公众号AppID
        $wxConfig['sub_mch_id'] = ''; //todo 子服务商商户号
        $wxConfig['md5_key'] = ''; //md5 秘钥
        $wxConfig['app_cert_pem'] = '';//证书路径
        $wxConfig['app_key_pem'] = '';//证书路径
        return $wxConfig;
    }


    /**
     * @function 请求多次分账接口
     * @param $orders array 待分账订单
     * @param $accounts array 分账接收方
     * @return array
     * @throws Exception
     */
    public function multiProfitSharing($orders,$accounts)
    {
        if(empty($orders)){
            throw new Exception('没有待分帐订单');
        }
        if(empty($accounts)){
            throw new Exception('接收分账账户为空');
        }

        //1.设置分账账号
        $receivers = array();
        foreach ($accounts as $account)
        {
            $tmp = array(
                'type'=>$account['type'],
                'account'=>$account['account'],
                'amount'=>intval($account['amount']),
                'description'=>$account['desc'],
            );
            $receivers[] = $tmp;
        }
        $receivers = json_encode($receivers,JSON_UNESCAPED_UNICODE);

        $totalCount = count($orders);
        $successCount = 0;
        $failCount = 0;
        $now = time();
        foreach ($orders as $order)
        {
            //2.生成签名
            $postArr = array(
                'appid'=>$this->wxConfig['app_id'],
                'mch_id'=>$this->wxConfig['mch_id'],
                'sub_mch_id'=>$this->wxConfig['sub_mch_id'],
                'sub_appid'=>$this->wxConfig['sub_app_id'],
                'nonce_str'=>md5(time() . rand(1000, 9999)),
                'transaction_id'=>$order['trans_id'],
                'out_order_no'=>$order['order_no'].$order['ticket_no'],
                'receivers'=>$receivers,
            );

            $sign = $this->sign->getSign($postArr, 'HMAC-SHA256',$this->wxConfig['md5_key']);
            $postArr['sign'] = $sign;


            //3.发送请求
            $url = 'https://api.mch.weixin.qq.com/secapi/pay/multiprofitsharing';
            $postXML = $this->toXml($postArr);
            Ilog::DEBUG("multiProfitSharing.postXML: " . $postXML);

            $opts = array(
                CURLOPT_HEADER    => 0,
                CURLOPT_SSL_VERIFYHOST    => false,
                CURLOPT_SSLCERTTYPE   => 'PEM', //默认支持的证书的类型,可以注释
                CURLOPT_SSLCERT   => $this->wxConfig['app_cert_pem'],
                CURLOPT_SSLKEY    => $this->wxConfig['app_key_pem'],
            );
            Ilog::DEBUG("multiProfitSharing.opts: " . json_encode($opts));

            $curl_res = $this->curl->setOption($opts)->post($url,$postXML);
            Ilog::DEBUG("multiProfitSharing.curl_res: " . $curl_res);

            $ret = $this->toArray($curl_res);
            if($ret['return_code']=='SUCCESS' and $ret['result_code']=='SUCCESS')
            {
                //更新分账订单状态
                $params = array();
                $params['order_no'] =  $order['order_no'];
                $params['trans_id'] =  $order['trans_id'];
                $params['ticket_no'] =  $order['ticket_no'];

                $data = array();
                $data['profitsharing'] = $receivers;
                $data['state'] = 2;
                pdo_update('ticket_orders_profitsharing',$data,$params);
                $successCount++;

            }else{
                $failCount++;
            }
            usleep(500000);//微信会报频率过高,所以停一下
        }

        return array('processTime'=>date('Y-m-d H:i:s',$now),'totalCount'=>$totalCount,'successCount'=>$successCount,'failCount'=>$failCount);

    }


    /**
     * @function 请求单次分账接口
     * @param $profitSharingOrders array 待分账订单
     * @param $profitSharingAccounts array 分账接收方
     * @return array
     * @throws Exception
     */
    public function profitSharing($profitSharingOrders,$profitSharingAccounts)
    {
        if(empty($profitSharingOrders)){
            throw new Exception('没有待分帐订单');
        }
        if(empty($profitSharingAccounts)){
            throw new Exception('接收分账账户为空');
        }

        //1.设置分账账号
        $receivers = array();
        foreach ($profitSharingAccounts as $profitSharingAccount)
        {
            $tmp = array(
                'type'=>$profitSharingAccount['type'],
                'account'=>$profitSharingAccount['account'],
                'amount'=>intval($profitSharingAccount['amount']),
                'description'=>$profitSharingAccount['desc'],
            );
            $receivers[] = $tmp;
        }
        $receivers = json_encode($receivers,JSON_UNESCAPED_UNICODE);

        $totalCount = count($profitSharingOrders);
        $successCount = 0;
        $failCount = 0;
        $now = time();

        foreach ($profitSharingOrders as $profitSharingOrder)
        {
            //2.生成签名
            $postArr = array(
                'appid'=>$this->wxConfig['app_id'],
                'mch_id'=>$this->wxConfig['mch_id'],
                'sub_mch_id'=>$this->wxConfig['sub_mch_id'],
                'sub_appid'=>$this->wxConfig['sub_app_id'],
                'nonce_str'=>md5(time() . rand(1000, 9999)),
                'transaction_id'=>$profitSharingOrder['trans_id'],
                'out_order_no'=>$profitSharingOrder['order_no'].$profitSharingOrder['ticket_no'],
                'receivers'=>$receivers,
            );

            $sign = $this->sign->getSign($postArr, 'HMAC-SHA256',$this->wxConfig['md5_key']);
            $postArr['sign'] = $sign;

            //3.发送请求
            $url = 'https://api.mch.weixin.qq.com/secapi/pay/profitsharing';
            $postXML = $this->toXml($postArr);
            Ilog::DEBUG("profitSharing.postXML: " . $postXML);

            $opts = array(
                CURLOPT_HEADER    => 0,
                CURLOPT_SSL_VERIFYHOST    => false,
                CURLOPT_SSLCERTTYPE   => 'PEM', //默认支持的证书的类型,可以注释
                CURLOPT_SSLCERT   => $this->wxConfig['app_cert_pem'],
                CURLOPT_SSLKEY    => $this->wxConfig['app_key_pem'],
            );
            Ilog::DEBUG("profitSharing.opts: " . json_encode($opts));

            $curl_res = $this->curl->setOption($opts)->post($url,$postXML);
            Ilog::DEBUG("profitSharing.curl_res: " . $curl_res);

            $ret = $this->toArray($curl_res);
            if($ret['return_code']=='SUCCESS' and $ret['result_code']=='SUCCESS')
            {
                //更新分账订单状态
                $params = array();
                $params['order_no'] =  $profitSharingOrder['order_no'];
                $params['trans_id'] =  $profitSharingOrder['trans_id'];
                $params['ticket_no'] =  $profitSharingOrder['ticket_no'];

                $data = array();
                $data['profitsharing'] = $receivers;
                $data['state'] = 2;
                pdo_update('ticket_orders_profitsharing',$data,$params);
                $successCount++;

            }else{
                $failCount++;
            }

        }

        return array('processTime'=>date('Y-m-d H:i:s',$now),'totalCount'=>$totalCount,'successCount'=>$successCount,'failCount'=>$failCount);

    }


    /**
     * @function 查询分账结果
     * @param $trans_id string 微信支付单号
     * @param $out_order_no string 分账单号
     * @return array|false
     * @throws Exception
     */
    public function query($trans_id,$out_order_no)
    {
        //1.生成签名
        $postArr = array(
            'mch_id'=>$this->wxConfig['mch_id'],
            'sub_mch_id'=>$this->wxConfig['sub_mch_id'],
            'transaction_id'=>$trans_id,
            'out_order_no'=>$out_order_no,
            'nonce_str'=>md5(time() . rand(1000, 9999)),
        );

        $sign = $this->sign->getSign($postArr, 'HMAC-SHA256',$this->wxConfig['md5_key']);
        $postArr['sign'] = $sign;


        //2.发送请求
        $url = 'https://api.mch.weixin.qq.com/pay/profitsharingquery';
        $postXML = $this->toXml($postArr);
        Ilog::DEBUG("query.postXML: " . $postXML);

        $curl_res = $this->curl->post($url,$postXML);
        Ilog::DEBUG("query.curl_res: " . $curl_res);

        $ret = $this->toArray($curl_res);
        return $ret;
    }


    /**
     * @function 添加分账接收方
     * @param $profitSharingAccount array 分账接收方
     * @return array|false
     * @throws Exception
     */
    public function addReceiver($profitSharingAccount)
    {
        //1.接收分账账户
        $receiver = array(
            'type'=>$profitSharingAccount['type'],
            'account'=>$profitSharingAccount['account'],
            'name'=>$profitSharingAccount['name'],
            'relation_type'=>$profitSharingAccount['relation_type'],
        );
        $receiver = json_encode($receiver,JSON_UNESCAPED_UNICODE);

        //2.生成签名
        $postArr = array(
            'appid'=>$this->wxConfig['app_id'],
            'mch_id'=>$this->wxConfig['mch_id'],
            'sub_mch_id'=>$this->wxConfig['sub_mch_id'],
            'sub_appid'=>$this->wxConfig['sub_app_id'],
            'nonce_str'=>md5(time() . rand(1000, 9999)),
            'receiver'=>$receiver
        );

        $sign = $this->sign->getSign($postArr, 'HMAC-SHA256',$this->wxConfig['md5_key']);
        $postArr['sign'] = $sign;


        //3.发送请求
        $url = 'https://api.mch.weixin.qq.com/pay/profitsharingaddreceiver';
        $postXML = $this->toXml($postArr);
        Ilog::DEBUG("addReceiver.postXML: " . $postXML);

        $curl_res = $this->curl->post($url,$postXML);
        Ilog::DEBUG("addReceiver.curl_res: " . $curl_res);

        $ret = $this->toArray($curl_res);
        return $ret;
    }


    /**
     * @function 删除分账接收方
     * @param $profitSharingAccount array 分账接收方
     * @return array|false
     * @throws Exception
     */
    public function removeReceiver($profitSharingAccount)
    {
        //1.接收分账账户
        $receiver = array(
            'type'=>$profitSharingAccount['type'],
            'account'=>$profitSharingAccount['account'],
            'name'=>$profitSharingAccount['name'],
        );
        $receiver = json_encode($receiver,JSON_UNESCAPED_UNICODE);

        //2.生成签名
        $postArr = array(
            'appid'=>$this->wxConfig['app_id'],
            'mch_id'=>$this->wxConfig['mch_id'],
            'sub_mch_id'=>$this->wxConfig['sub_mch_id'],
            'sub_appid'=>$this->wxConfig['sub_app_id'],
            'nonce_str'=>md5(time() . rand(1000, 9999)),
            'receiver'=>$receiver
        );

        $sign = $this->sign->getSign($postArr, 'HMAC-SHA256',$this->wxConfig['md5_key']);
        $postArr['sign'] = $sign;


        //3.发送请求
        $url = 'https://api.mch.weixin.qq.com/pay/profitsharingremovereceiver';
        $postXML = $this->toXml($postArr);
        Ilog::DEBUG("removeReceiver.postXML: " . $postXML);

        $curl_res = $this->curl->post($url,$postXML);
        Ilog::DEBUG("removeReceiver.curl_res: " . $curl_res);

        $ret = $this->toArray($curl_res);
        return $ret;
    }


    /**
     * @function 完结分账
     * @param $profitOrder array 分账订单
     * @param $description string 完结分账描述
     * @return array|false
     * @throws Exception
     */
    public function finish($profitOrder,$description='分账完结')
    {
        $ret = array();
        if(!empty($profitOrder))
        {
            //1.签名
            $postArr = array(
                'mch_id'=>$this->wxConfig['mch_id'],
                'sub_mch_id'=>$this->wxConfig['sub_mch_id'],
                'appid'=>$this->wxConfig['app_id'],
                'nonce_str'=>md5(time() . rand(1000, 9999)),
                'transaction_id'=>$profitOrder['trans_id'],
                'out_order_no'=>'finish'.'_'.$profitOrder['order_no'],
                'description'=>$description,
            );

            $sign = $this->sign->getSign($postArr, 'HMAC-SHA256',$this->wxConfig['md5_key']);
            $postArr['sign'] = $sign;


            //2.请求
            $url = 'https://api.mch.weixin.qq.com/secapi/pay/profitsharingfinish';
            $postXML = $this->toXml($postArr);
            Ilog::DEBUG("finish.postXML: " . $postXML);

            $opts = array(
                CURLOPT_HEADER    => 0,
                CURLOPT_SSL_VERIFYHOST    => false,
                CURLOPT_SSLCERTTYPE   => 'PEM', //默认支持的证书的类型,可以注释
                CURLOPT_SSLCERT   => $this->wxConfig['app_cert_pem'],
                CURLOPT_SSLKEY    => $this->wxConfig['app_key_pem'],
            );
            Ilog::DEBUG("finish.opts: " . json_encode($opts));

            $curl_res = $this->curl->setOption($opts)->post($url,$postXML);
            Ilog::DEBUG("finish.curl_res: " . $curl_res);

            $ret = $this->toArray($curl_res);
        }

        return $ret;
    }


    /**
     * @function 分账回退
     * @param $profitOrder array 分账订单
     * @return array
     * @throws Exception
     */
    public function profitSharingReturn($profitOrder)
    {
        $ret = array();
        if(!empty($profitOrder) and $profitOrder['channel']==1)
        {
            $accounts = json_decode($profitOrder['profitsharing'],true);
            foreach ($accounts as $account)
            {
                //1.签名
                $postArr = array(
                    'appid'=>$this->wxConfig['app_id'],
                    'mch_id'=>$this->wxConfig['mch_id'],
                    'sub_mch_id'=>$this->wxConfig['sub_mch_id'],
                    'sub_appid'=>$this->wxConfig['sub_app_id'],
                    'nonce_str'=>md5(time() . rand(1000, 9999)),
                    'out_order_no'=>$profitOrder['order_no'].$profitOrder['ticket_no'],
                    'out_return_no'=>'return_'.$profitOrder['order_no'].$profitOrder['ticket_no'].'_'.$account['account'],
                    'return_account_type'=>'MERCHANT_ID',
                    'return_account'=>$account['account'],
                    'return_amount'=>$account['amount'],
                    'description'=>'用户退款',
                    'sign_type'=>'HMAC-SHA256',
                );

                $sign = $this->sign->getSign($postArr, 'HMAC-SHA256',$this->wxConfig['md5_key']);
                $postArr['sign'] = $sign;


                //2.请求
                $url = 'https://api.mch.weixin.qq.com/secapi/pay/profitsharingreturn';
                $postXML = $this->toXml($postArr);
                Ilog::DEBUG("profitSharingReturn.postXML: " . $postXML);

                $opts = array(
                    CURLOPT_HEADER    => 0,
                    CURLOPT_SSL_VERIFYHOST    => false,
                    CURLOPT_SSLCERTTYPE   => 'PEM', //默认支持的证书的类型,可以注释
                    CURLOPT_SSLCERT   => $this->wxConfig['app_cert_pem'],
                    CURLOPT_SSLKEY    => $this->wxConfig['app_key_pem'],
                );
                Ilog::DEBUG("profitSharingReturn.opts: " . json_encode($opts));

                $curl_res = $this->curl->setOption($opts)->post($url,$postXML);
                Ilog::DEBUG("profitSharingReturn.curl_res: " . $curl_res);

                $ret[] = $this->toArray($curl_res);
            }

        }
        return $ret;
    }


    /**
     * @function 回退结果查询
     * @param $order_no string 本地订单号
     * @param $ticket_no string 本地票号
     * @return array|false
     * @throws \Exception
     */
    public function returnQuery($order_no,$ticket_no)
    {
        $ret = array();
        $profitOrder = pdo_fetch("SELECT * FROM zc_ticket_orders_profitsharing WHERE order_no='{$order_no}' AND ticket_no='{$ticket_no}'");
        if($profitOrder['channel']==1 and $profitOrder['state']==2)
        {
            $accounts = json_decode($profitOrder['profitsharing'],true);
            foreach ($accounts as $account)
            {
                //1.签名
                $postArr = array(
                    'appid'=>$this->wxConfig['app_id'],
                    'mch_id'=>$this->wxConfig['mch_id'],
                    'sub_mch_id'=>$this->wxConfig['sub_mch_id'],
                    'nonce_str'=>md5(time() . rand(1000, 9999)),
                    'out_order_no'=>$profitOrder['order_no'].$profitOrder['ticket_no'],
                    'out_return_no'=>'return_'.$profitOrder['order_no'].$profitOrder['ticket_no'].'_'.$account['account'],
                    'sign_type'=>'HMAC-SHA256',
                );

                $sign = $this->sign->getSign($postArr, 'HMAC-SHA256',$this->wxConfig['md5_key']);
                $postArr['sign'] = $sign;

                //2.请求
                $url = 'https://api.mch.weixin.qq.com/pay/profitsharingreturnquery';
                $postXML = $this->toXml($postArr);
                Ilog::DEBUG("returnQuery.postXML: " . $postXML);

                $curl_res = $this->curl->post($url,$postXML);
                Ilog::DEBUG("returnQuery.curl_res: " . $curl_res);

                $ret[] = $this->toArray($curl_res);
            }

        }
        return $ret;
    }


    /**
     * @function 将array转为xml
     * @param array $values
     * @return string|bool
     * @author xiewg
     **/
    public function toXml($values)
    {
        if (!is_array($values) || count($values) <= 0) {
            return false;
        }

        $xml = "";
        foreach ($values as $key => $val) {
            if (is_numeric($val)) {
                $xml.="<".$key.">".$val."";
            } else {
                $xml.="<".$key.">";
            }
        }
        $xml.="";
        return $xml;
    }

    /**
     * @function 将xml转为array
     * @param string $xml
     * @return array|false
     * @author xiewg
     */
    public function toArray($xml)
    {
        if (!$xml) {
            return false;
        }

        // 检查xml是否合法
        $xml_parser = xml_parser_create();
        if (!xml_parse($xml_parser, $xml, true)) {
            xml_parser_free($xml_parser);
            return false;
        }

        //将XML转为array
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);

        $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);

        return $data;
    }


}

发送请求类: ProfitSharingCurl.class.php

示例:
* * // 失败时再重试2次 * $curl = new CUrl(2); * * // GET * $rs = $curl->get('http://phalapi.oschina.mopaas.com/Public/demo/?service=Default.Index'); * * // POST * $data = array('username' => 'dogstar'); * $rs = $curl->post('http://phalapi.oschina.mopaas.com/Public/demo/?service=Default.Index', $data); * * @package PhalApi\CUrl * @license http://www.phalapi.net/license GPL 协议 * @link http://www.phalapi.net/ * @author dogstar 2015-01-02 */ class ProfitSharingCurl { /** * 最大重试次数 */ const MAX_RETRY_TIMES = 10; /** * @var int $retryTimes 超时重试次数;注意,此为失败重试的次数,即:总次数 = 1 + 重试次数 */ protected $retryTimes; protected $header = array(); protected $option = array(); protected $hascookie = FALSE; protected $cookie = array(); /** * @param int $retryTimes 超时重试次数,默认为1 */ public function __construct($retryTimes = 1) { $this->retryTimes = $retryTimes < static::MAX_RETRY_TIMES ? $retryTimes : static::MAX_RETRY_TIMES; } /** ------------------ 核心使用方法 ------------------ **/ /** * GET方式的请求 * @param string $url 请求的链接 * @param int $timeoutMs 超时设置,单位:毫秒 * @return string 接口返回的内容,超时返回false */ public function get($url, $timeoutMs = 3000) { return $this->request($url, array(), $timeoutMs); } /** * POST方式的请求 * @param string $url 请求的链接 * @param array $data POST的数据 * @param int $timeoutMs 超时设置,单位:毫秒 * @return string 接口返回的内容,超时返回false */ public function post($url, $data, $timeoutMs = 3000) { return $this->request($url, $data, $timeoutMs); } /** ------------------ 前置方法 ------------------ **/ /** * 设置请求头,后设置的会覆盖之前的设置 * * @param array $header 传入键值对如: ``` * array( * 'Accept' => 'text/html', * 'Connection' => 'keep-alive', * ) ``` * * @return $this */ public function setHeader($header) { $this->header = array_merge($this->header, $header); return $this; } /** * 设置curl配置项 * * - 1、后设置的会覆盖之前的设置 * - 2、开发者设置的会覆盖框架的设置 * * @param array $option 格式同上 * * @return $this */ public function setOption($option) { $this->option = $option + $this->option; return $this; } /** * @param array $cookie */ public function setCookie($cookie) { $this->cookie = $cookie; return $this; } /** * @return array */ public function getCookie() { return $this->cookie; } public function withCookies() { $this->hascookie = TRUE; if (!empty($this->cookie)) { $this->setHeader(array('Cookie' => $this->getCookieString())); } $this->setOption(array(CURLOPT_COOKIEFILE => '')); return $this; } /** ------------------ 辅助方法 ------------------ **/ /** * 统一接口请求 * @param string $url 请求的链接 * @param array $data POST的数据 * @param int $timeoutMs 超时设置,单位:毫秒 * @return string 接口返回的内容,超时返回false * @throws Exception */ protected function request($url, $data, $timeoutMs = 3000) { $options = array( CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => TRUE, CURLOPT_HEADER => 0, CURLOPT_CONNECTTIMEOUT_MS => $timeoutMs, CURLOPT_HTTPHEADER => $this->getHeaders(), ); if (!empty($data)) { $options[CURLOPT_POST] = 1; $options[CURLOPT_POSTFIELDS] = $data; } $options = $this->option + $options; //$this->>option优先 $ch = curl_init(); curl_setopt_array($ch, $options); $curRetryTimes = $this->retryTimes; do { $rs = curl_exec($ch); $curRetryTimes--; } while ($rs === FALSE && $curRetryTimes >= 0); $errno = curl_errno($ch); if ($errno) { throw new InternalServerErrorException(sprintf("%s::%s(%d)\n", $url, curl_error($ch), $errno)); } //update cookie if ($this->hascookie) { $cookie = $this->getRetCookie(curl_getinfo($ch, CURLINFO_COOKIELIST)); !empty($cookie) && $this->cookie = $cookie + $this->cookie; $this->hascookie = FALSE; unset($this->header['Cookie']); unset($this->option[CURLOPT_COOKIEFILE]); } curl_close($ch); return $rs; } /** * * @return array */ protected function getHeaders() { $arrHeaders = array(); foreach ($this->header as $key => $val) { $arrHeaders[] = $key . ': ' . $val; } return $arrHeaders; } protected function getRetCookie(array $cookies) { $ret = array(); foreach ($cookies as $cookie) { $arr = explode("\t", $cookie); if (!isset($arr[6])) { continue; } $ret[$arr[5]] = $arr[6]; } return $ret; } protected function getCookieString() { $ret = ''; foreach ($this->getCookie() as $key => $val) { $ret .= $key . '=' . $val . ';'; } return trim($ret, ';'); } }

签名类 ProfitSharing.class.php

paraFilter($param);
        $values = $this->arraySort($values);
        $signStr = $this->createLinkstring($values);

        $signStr .= '&key=' . $md5Key;
        switch ($signType)
        {
            case 'MD5':
                $sign = md5($signStr);
                break;
            case 'HMAC-SHA256':
                $sign = hash_hmac('sha256', $signStr, $md5Key);
                break;
            default:
                $sign = '';
        }
        return strtoupper($sign);
    }


    /**
     * 移除空值的key
     * @param $para
     * @return array
     */
    public function paraFilter($para)
    {
        $paraFilter = array();
        while (list($key, $val) = each($para))
        {
            if ($val == "") {
                continue;

            } else {
                if (! is_array($para[$key])) {
                    $para[$key] = is_bool($para[$key]) ? $para[$key] : trim($para[$key]);
                }

                $paraFilter[$key] = $para[$key];
            }
        }
        return $paraFilter;
    }


    /**
     * @function 对输入的数组进行字典排序
     * @param array $param 需要排序的数组
     * @return array
     * @author helei
     */
    public function arraySort(array $param)
    {
        ksort($param);
        reset($param);
        return $param;
    }


    /**
     * @function 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
     * @param array $para 需要拼接的数组
     * @return string
     * @throws \Exception
     */
    public function createLinkString($para)
    {
        if (! is_array($para)) {
            throw new \Exception('必须传入数组参数');
        }

        reset($para);
        $arg  = "";
        while (list($key, $val) = each($para)) {
            if (is_array($val)) {
                continue;
            }

            $arg.=$key."=".urldecode($val)."&";
        }
        //去掉最后一个&字符
        $arg = substr($arg, 0, count($arg) - 2);

        //如果存在转义字符,那么去掉转义
        if (get_magic_quotes_gpc()) {
            $arg = stripslashes($arg);
        }

        return $arg;
    }
}

你可能感兴趣的:(PHP,微信服务商)