• PHP实现微信商户支付企业付款到零钱功能代码实例


    本文为大家分享了PHP实现微信商户支付企业付款到零钱的具体代码,供大家参考,具体内容如下

    微信支付开发文档

    一、开通条件

    企业付款为企业提供付款至用户零钱的能力,支持通过API接口付款,或通过微信支付商户平台(pay.weixin.qq.com)网页操作付款。

    使用条件

    • 商户号(或同主体其他非服务商商户号)已入驻90日
    • 商户号(或同主体其他非服务商商户号)有30天连续正常交易
    • 登录微信支付商户平台-产品中心,开通企业付款。

    具体的可以看微信支付开发文档

    二、代码展示

    //企业付款到微信零钱,PHP接口调用方法
    define("APPID", "wxe062425f740c30d8"); // 商户账号appid
    define("MCHID", "10000098");  // 商户号
    define("SECRECT_KEY", "453436425252"); //支付密钥签名
    define("IP", "xxx.xxx.xx.xx"); //IP
     
     
     /**
     * [xmltoarray xml格式转换为数组]
     * @param [type] $xml [xml]
     * @return [type]  [xml 转化为array]
     */
     function xmltoarray($xml) { 
      //禁止引用外部xml实体 
      libxml_disable_entity_loader(true); 
      $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA); 
      $val = json_decode(json_encode($xmlstring),true); 
      return $val;
     }
     
     /**
     * [arraytoxml 将数组转换成xml格式(简单方法):]
     * @param [type] $data [数组]
     * @return [type]  [array 转 xml]
     */
     function arraytoxml($data){
      $str='<xml>';
      foreach($data as $k=>$v) {
       $str.='<'.$k.'>'.$v.'</'.$k.'>';
      }
      $str.='</xml>';
      return $str;
     }
     
     /**
     * [createNoncestr 生成随机字符串]
     * @param integer $length [长度]
     * @return [type]   [字母大小写加数字]
     */
     function createNoncestr($length =32){
      $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYabcdefghijklmnopqrstuvwxyz0123456789"; 
      $str ="";
     
      for($i=0;$i<$length;$i++){ 
       $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1); 
      } 
      return $str;
     }
     
     /**
     * [curl_post_ssl 发送curl_post数据]
     * @param [type] $url  [发送地址]
     * @param [type] $xmldata [发送文件格式]
     * @param [type] $second [设置执行最长秒数]
     * @param [type] $aHeader [设置头部]
     * @return [type]   [description]
     */
     function curl_post_ssl($url, $xmldata, $second = 30, $aHeader = array()){
      $isdir = $_SERVER['DOCUMENT_ROOT']."/cert/";//证书位置;绝对路径
     
      $ch = curl_init();//初始化curl
     
      curl_setopt($ch, CURLOPT_TIMEOUT, $second);//设置执行最长秒数
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//要求结果为字符串且输出到屏幕上
      curl_setopt($ch, CURLOPT_URL, $url);//抓取指定网页
      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);// 终止从服务端进行验证
      curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);//
      curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');//证书类型
      curl_setopt($ch, CURLOPT_SSLCERT, $isdir . 'apiclient_cert.pem');//证书位置
      curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');//CURLOPT_SSLKEY中规定的私钥的加密类型
      curl_setopt($ch, CURLOPT_SSLKEY, $isdir . 'apiclient_key.pem');//证书位置
      curl_setopt($ch, CURLOPT_CAINFO, 'PEM');
      curl_setopt($ch, CURLOPT_CAINFO, $isdir . 'rootca.pem');
      if (count($aHeader) >= 1) {
       curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);//设置头部
      }
      curl_setopt($ch, CURLOPT_POST, 1);//post提交方式
      curl_setopt($ch, CURLOPT_POSTFIELDS, $xmldata);//全部数据使用HTTP协议中的"POST"操作来发送
     
      $data = curl_exec($ch);//执行回话
      if ($data) {
       curl_close($ch);
       return $data;
      } else {
       $error = curl_errno($ch);
       echo "call faild, errorCode:$error
    ";
       curl_close($ch);
       return false;
      }
     }
     
     
     /**
     * [sendMoney 企业付款到零钱]
     * @param [type] $amount  [发送的金额(分)目前发送金额不能少于1元]
     * @param [type] $re_openid [发送人的 openid]
     * @param string $desc  [企业付款描述信息 (必填)]
     * @param string $check_name [收款用户姓名 (选填)]
     * @return [type]    [description]
     */
     function sendMoney($amount,$re_openid,$desc='测试',$check_name=''){
       
      $total_amount = (100) * $amount;
       
      $data=array(
       'mch_appid'=>APPID,//商户账号appid
       'mchid'=> MCHID,//商户号
       'nonce_str'=>createNoncestr(),//随机字符串
       'partner_trade_no'=> date('YmdHis').rand(1000, 9999),//商户订单号
       'openid'=> $re_openid,//用户openid
       'check_name'=>'NO_CHECK',//校验用户姓名选项,
       're_user_name'=> $check_name,//收款用户姓名
       'amount'=>$total_amount,//金额
       'desc'=> $desc,//企业付款描述信息
       'spbill_create_ip'=> IP,//Ip地址
      );
     
      //生成签名算法
      $secrect_key=SECRECT_KEY;///这个就是个API密码。MD5 32位。
      $data=array_filter($data);
      ksort($data);
      $str='';
      foreach($data as $k=>$v) {
       $str.=$k.'='.$v.'&';
      }
      $str.='key='.$secrect_key;
      $data['sign']=md5($str);
      //生成签名算法
     
     
      $xml=arraytoxml($data);
      
      $url='https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers'; //调用接口
      $res=curl_post_ssl($url,$xml);
      $return=xmltoarray($res);
       
      
      print_r($return);
      //返回来的结果是xml,最后转换成数组
     /*
     array(9) {
      ["return_code"]=>
      string(7) "SUCCESS"
      ["return_msg"]=>
      array(0) {
      }
      ["mch_appid"]=>
      string(18) "wx57676786465544b2a5"
      ["mchid"]=>
      string(10) "143345612"
      ["nonce_str"]=>
      string(32) "iw6TtHdOySMAfS81qcnqXojwUMn8l8mY"
      ["result_code"]=>
      string(7) "SUCCESS"
      ["partner_trade_no"]=>
      string(18) "201807011410504098"
      ["payment_no"]=>
      string(28) "1000018301201807019357038738"
      ["payment_time"]=>
      string(19) "2018-07-01 14:56:35"
     }
     */
     
       
      $responseObj = simplexml_load_string($res, 'SimpleXMLElement', LIBXML_NOCDATA);
      echo $res= $responseObj->return_code; //SUCCESS 如果返回来SUCCESS,则发生成功,处理自己的逻辑
       
      return $res;
     }

    三、调用方法

    sendMoney(1,'gdgfdg56456223423','xxxx测试','xxx');

    调用的话,稍微在修改下,加上自己的业务逻辑就行了。

    四、调用效果

     

    本功能也可以参看如下类文件:wechat_paymentchange.class.php

    <?php
    
    //企业付款到微信零钱,PHP接口调用方法
    define("APPID", "wxe062425f740c30d8"); // 商户账号appid
    define("MCHID", "10000098");      // 商户号
    define("SECRECT_KEY", "453436425252");  //支付密钥签名
    define("IP", "xxx.xxx.xx.xx");   //IP
    
    
    
    class wechat_paymentchange {
    
        /**
         * [xmltoarray xml格式转换为数组]
         * @param  [type] $xml [xml]
         * @return [type]      [xml 转化为array]
         */
        public function xmltoarray($xml) { 
             //禁止引用外部xml实体 
            libxml_disable_entity_loader(true); 
            $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA); 
            $val = json_decode(json_encode($xmlstring),true); 
            return $val;
        }
    
    
        /**
         * [arraytoxml 将数组转换成xml格式(简单方法):]
         * @param  [type] $data [数组]
         * @return [type]       [array 转 xml]
         */
        public function arraytoxml($data){
            $str='<xml>';
            foreach($data as $k=>$v) {
                $str.='<'.$k.'>'.$v.'</'.$k.'>';
            }
            $str.='</xml>';
            return $str;
        }
    
        /**
         * [createNoncestr 生成随机字符串]
         * @param  integer $length [长度]
         * @return [type]          [字母大小写加数字]
         */
        public function createNoncestr($length =32){
            $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYabcdefghijklmnopqrstuvwxyz0123456789";  
            $str ="";
    
            for($i=0;$i<$length;$i++){  
                $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);   
            }  
            return $str;
        }
    
        /**
         * [curl_post_ssl 发送curl_post数据]
         * @param  [type]  $url     [发送地址]
         * @param  [type]  $xmldata [发送文件格式]
         * @param  [type]  $second [设置执行最长秒数]
         * @param  [type]  $aHeader [设置头部]
         * @return [type]           [description]
         */
        function curl_post_ssl($url, $vars, $second = 30, $aHeader = array()){
            $isdir = $_SERVER['DOCUMENT_ROOT']."/cert/";//证书位置
    
            $ch = curl_init();//初始化curl
    
            curl_setopt($ch, CURLOPT_TIMEOUT, $second);//设置执行最长秒数
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//要求结果为字符串且输出到屏幕上
            curl_setopt($ch, CURLOPT_URL, $url);//抓取指定网页
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);// 终止从服务端进行验证
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);//
            curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');//证书类型
            curl_setopt($ch, CURLOPT_SSLCERT, $isdir . 'apiclient_cert.pem');//证书位置
            curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');//CURLOPT_SSLKEY中规定的私钥的加密类型
            curl_setopt($ch, CURLOPT_SSLKEY, $isdir . 'apiclient_key.pem');//证书位置
            curl_setopt($ch, CURLOPT_CAINFO, 'PEM');
            curl_setopt($ch, CURLOPT_CAINFO, $isdir . 'rootca.pem');
            if (count($aHeader) >= 1) {
                curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);//设置头部
            }
            curl_setopt($ch, CURLOPT_POST, 1);//post提交方式
            curl_setopt($ch, CURLOPT_POSTFIELDS, $vars);//全部数据使用HTTP协议中的"POST"操作来发送
    
            $data = curl_exec($ch);//执行回话
            if ($data) {
                curl_close($ch);
                return $data;
            } else {
                $error = curl_errno($ch);
                echo "call faild, errorCode:$error
    ";
                curl_close($ch);
                return false;
            }
        }
    
    
    
    
        /**
         * [sendMoney 企业付款到零钱]
         * @param  [type] $amount     [发送的金额(分)目前发送金额不能少于1元]
         * @param  [type] $re_openid  [发送人的 openid]
         * @param  string $desc       [企业付款描述信息 (必填)]
         * @param  string $check_name [收款用户姓名 (选填)]
         * @return [type]             [description]
         */
        public function sendMoney($amount,$re_openid,$desc='测试',$check_name=''){
    
            $total_amount = (100) * $amount;
            
            $data=array(
                'mch_appid'=>APPID,//商户账号appid
                'mchid'=> MCHID,//商户号
                'nonce_str'=>$this->createNoncestr(),//随机字符串
                'partner_trade_no'=> date('YmdHis').rand(1000, 9999),//商户订单号
                'openid'=> $re_openid,//用户openid
                'check_name'=>'NO_CHECK',//校验用户姓名选项,
                're_user_name'=> $check_name,//收款用户姓名
                'amount'=>$total_amount,//金额
                'desc'=> $desc,//企业付款描述信息
                'spbill_create_ip'=> IP,//Ip地址
            );
    
            //生成签名算法
            $secrect_key=SECRECT_KEY;///这个就是个API密码。MD5 32位。
            $data=array_filter($data);
            ksort($data);
            $str='';
            foreach($data as $k=>$v) {
               $str.=$k.'='.$v.'&';
            }
            $str.='key='.$secrect_key;
            $data['sign']=md5($str);
            //生成签名算法
    
    
            $xml=$this->arraytoxml($data);
          
            $url='https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers'; //调用接口
            $res=$this->curl_post_ssl($url,$xml);
            $return=$this->xmltoarray($res);
            
             return $return;
         
            print_r($return);
            //返回来的结果
            // [return_code] => SUCCESS [return_msg] => Array ( ) [mch_appid] => wxd44be6876gg73 [mchid] => 76775512 [nonce_str] => 616615516 [result_code] => SUCCESS [partner_trade_no] => 20186505080216815 
            // [payment_no] => 1000018361251805057502564679 [payment_time] => 2018-05-15 15:29:50
            
            $responseObj = simplexml_load_string($res, 'SimpleXMLElement', LIBXML_NOCDATA);
            echo $res= $responseObj->return_code;  //SUCCESS  如果返回来SUCCESS,则发生成功,处理自己的逻辑
            
            return $res;
        }
    
    
    }
    
    ?>

    PHP实现微信开发中提现功能(企业付款到用户零钱)

    一.实现该功能目的

        这几天在小程序里要实现用户从系统中提现到零钱的功能,查了一下文档可以使用 企业付款到用户零钱 来实现;

     官方文档:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_1;

     注意事项:商户打款时是从商户可用余额中减钱,所以确保商户可用余额充足,同时注意官方文档中的付款规则;

    二.PHP实现

    复制代码
     //封装提现方法
      function tixian($money){
            $appid = "################";//商户账号appid
            $secret = "##########";//api密码
            $mch_id = "#######";//商户号
            $mch_no = "#######";
            $openid="123456789";//授权用户openid
                 
            $arr = array();
            $arr['mch_appid'] = $appid;
            $arr['mchid'] = $mch_id;
            $arr['nonce_str'] = ugv::randomid(20);//随机字符串,不长于32位
            $arr['partner_trade_no'] = '1298016501' . date("Ymd") . rand(10000, 90000) . rand(10000, 90000);//商户订单号
            $arr['openid'] = $openid;
            $arr['check_name'] = 'NO_CHECK';//是否验证用户真实姓名,这里不验证
            $arr['amount'] = $money;//付款金额,单位为分
            $desc = "###提现";
            $arr['desc'] = $desc;//描述信息
            $arr['spbill_create_ip'] = '192.168.0.1';//获取服务器的ip
            //封装的关于签名的算法
            $notify = new Notify_pub();
            $notify->weixin_app_config = array();
            $notify->weixin_app_config['KEY'] = $mch_no;
    
            $arr['sign'] = $notify->getSign($arr);//签名
    
            $var = $notify->arrayToXml($arr);
            $xml = $this->curl_post_ssl('https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers', $var, 30, array(), 1);
            $rdata = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
            $return_code = (string)$rdata->return_code;
            $result_code = (string)$rdata->result_code;
            $return_code = trim(strtoupper($return_code));
            $result_code = trim(strtoupper($result_code));
    
            if ($return_code == 'SUCCESS' && $result_code == 'SUCCESS') {
                $isrr = array(
                    'con'=>'ok',
                    'error' => 0,
                );
            } else {
                $returnmsg = (string)$rdata->return_msg;
                $isrr = array(
                    'error' => 1,
                    'errmsg' => $returnmsg,
                );
    
            }
            return json_encode($isrr);
        }    
    复制代码
    复制代码
    //上个方法中用到的curl_post_ssl()
    function curl_post_ssl($url, $vars, $second = 30, $aHeader = array())
        {
            $isdir = "/cert/";//证书位置
    
            $ch = curl_init();//初始化curl
    
            curl_setopt($ch, CURLOPT_TIMEOUT, $second);//设置执行最长秒数
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//要求结果为字符串且输出到屏幕上
            curl_setopt($ch, CURLOPT_URL, $url);//抓取指定网页
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);// 终止从服务端进行验证
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);//
            curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');//证书类型
            curl_setopt($ch, CURLOPT_SSLCERT, $isdir . 'apiclient_cert.pem');//证书位置
            curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');//CURLOPT_SSLKEY中规定的私钥的加密类型
            curl_setopt($ch, CURLOPT_SSLKEY, $isdir . 'apiclient_key.pem');//证书位置
            curl_setopt($ch, CURLOPT_CAINFO, 'PEM');
            curl_setopt($ch, CURLOPT_CAINFO, $isdir . 'rootca.pem');
            if (count($aHeader) >= 1) {
                curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);//设置头部
            }
            curl_setopt($ch, CURLOPT_POST, 1);//post提交方式
            curl_setopt($ch, CURLOPT_POSTFIELDS, $vars);//全部数据使用HTTP协议中的"POST"操作来发送
    
            $data = curl_exec($ch);//执行回话
            if ($data) {
                curl_close($ch);
                return $data;
            } else {
                $error = curl_errno($ch);
                echo "call faild, errorCode:$error
    ";
                curl_close($ch);
                return false;
            }
        }
    复制代码

    三.补充

    关于具体签名算法,可参考微信官方文档;

    简单示范签名算法:

    复制代码
    //将要发送的数据整理为$data
    
    ksort($data);//排序
    //使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串
    $str='';
    foreach($data as $k=>$v) {
        $str.=$k.'='.$v.'&';
    }
    //拼接API密钥
    $str.='key='.$secrect;
    $data['sign']=md5($str);//加密
    复制代码

    将数组转换成xml格式(简单方法):

    复制代码
    //遍历数组方法
    function arraytoxml($data){
        $str='<xml>';
        foreach($data as $k=>$v) {
            $str.='<'.$k.'>'.$v.'</'.$k.'>';
        }
        $str.='</xml>';
        return $str;
    }
    复制代码

    将xml格式转换为数组:

    复制代码
    function xmltoarray($xml) { 
         //禁止引用外部xml实体 
        libxml_disable_entity_loader(true); 
        $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA); 
        $val = json_decode(json_encode($xmlstring),true); 
        return $val;
    }
    复制代码
  • 相关阅读:
    JAVA基础 (三)反射 深入解析反射机制
    JAVA基础 (二)反射 深入解析反射机制
    JAVA注解引发的思考
    深入理解jsonp解决跨域访问
    设计模式之简单工厂模式
    设计模式之接口隔离原则
    设计模式之迪米特法则
    设计模式之依赖倒置原则
    设计模式之里氏替换原则
    设计模式之开放封闭原则
  • 原文地址:https://www.cnblogs.com/kenshinobiy/p/10344086.html
Copyright © 2020-2023  润新知