• 喜欢前端以及PHP的朋友们可以加PHP同好会QQ群 点击加入qq群
  • 最近在写一个项目---"小A微信托管平台",大家可以去帮忙测试一下!功能在不断完善中,敬请关注!点击进入
  • 本站使用了PHP8.1与HTTP2.0协议,速度简直超级快有木有?

微信企业支付API 类库(php)

微信 Mr.Adam 8年前 (2017-02-28) 2997次浏览 已收录 0个评论

微信企业支付 API 类库(php)

微信企业支付 API 类库(php)

做到微信支付与提现这一块,因为用了 easywechat 踩了很多坑,故在这里分享一个绝对能用的微信企业支付 demo

<?php


namespace App\wxpayv3;

class WxPayPostal{
    private $appId = null;
    private $mchId = null;
    private $certPath = null;
    private $keyPath = null;
    private $key = null;
    private $url = null;
    /*
    * 以下各个参数需要根据自己的坏境与参数进行配置,2 个证书的路径必须为绝对地址
    */
    public function __construct(){
        $this->appId = env("WXPAY_APPID");
        $this->mchId = env("WXPAY_MCHID");
        $this->key = env("WXPAY_KEY");
        $this->certPath = env("WXPAY_CERTPATH");
        $this->keyPath = env("WXPAY_KEYPATH");
        $this->url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
    }

    /**
     * 转换为 post 数据
     *
     */
    private function formatBizQueryParaMap($paraMap,$urlencode){
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v)
        {
            if($urlencode)
            {
                $v = urlencode($v);
            }
            $buff .= $k . "=" . $v . "&";
        }
        $reqPar = null;
        if (strlen($buff) > 0)
        {
            $reqPar = substr($buff, 0, strlen($buff)-1);
        }
        return $reqPar;
    }

    private function getSign($Obj){
        foreach ($Obj as $k => $v)
        {
            $Parameters[$k] = $v;
        }
        //签名步骤一:按字典序排序参数
        ksort($Parameters);
        $String = $this->formatBizQueryParaMap($Parameters, false);
        //echo '【string1】'.$String.'</br>';
        //签名步骤二:在 string 后加入 KEY
        $String = $String."&key={$this->key}";
        //echo "【string2】".$String."</br>";
        //签名步骤三:MD5 加密
        $String = md5($String);
        //echo "【string3】 ".$String."</br>";
        //签名步骤四:所有字符转为大写
        $result_ = strtoupper($String);
        //echo "【result】 ".$result_."</br>";
        return $result_;
    }

    protected function curl_post_ssl($url, $vars, $second=30,$aHeader=array()){
        $ch = curl_init();
        //超时时间
        curl_setopt($ch,CURLOPT_TIMEOUT,$second);
        curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
        //这里设置代理,如果有的话
        //curl_setopt($ch,CURLOPT_PROXY, '10.206.30.98');
        //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
        curl_setopt($ch,CURLOPT_URL,$url);
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);

        //以下两种方式需选择一种

        //第一种方法,cert 与 key 分别属于两个.pem 文件
        //默认格式为 PEM,可以注释
        curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
        curl_setopt($ch,CURLOPT_SSLCERT,$this->certPath);
        //默认格式为 PEM,可以注释
        //curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
        curl_setopt($ch,CURLOPT_SSLKEY,$this->keyPath);

        //第二种方式,两个文件合成一个.pem 文件
        //curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'/all.pem');

        if( count($aHeader) >= 1 ){
            curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);
        }

        curl_setopt($ch,CURLOPT_POST, 1);
        curl_setopt($ch,CURLOPT_POSTFIELDS,$vars);
        $data = curl_exec($ch);
        if($data){
            curl_close($ch);
            return $data;
        }
        else {
            $error = curl_errno($ch);
            echo "call faild, errorCode:$error\n";
            curl_close($ch);
            return false;
        }
    }

    //生成随机字符串
    protected function getShuffle($length = 16){
        $str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
        return substr(str_shuffle($str),0,$length);
    }

    //获取 server 端 ip
    protected function getServerIp(){
        return $_SERVER["SERVER_ADDR"];
    }

    //发起支付
    /**
     * $data=[
     *     "money"=>100,
     *     "name"=>"张三",
     *     "check"=>1 or 2 or 3,
     *     "desc"=>"支付",
     *     "openid"=>"asdkfjalkdjfa",
     *     "order_sn"=>"121313131"
     *     ]
     */
    public function postal($arr){
        $data["amount"] = $arr["money"];
        $data["openid"] = $arr["openid"];
        $data["re_user_name"] = $arr["name"];
        $data["desc"] = $arr["desc"];
        $data["spbill_create_ip"] = $this->getServerIp();
        $data["mch_appid"] = $this->appId;
        $data["mchid"] = $this->mchId;
        $data["nonce_str"] = $this->getShuffle(16);
        $data["openid"] = $arr["openid"];
        switch ($arr["check"]){
            case 1:
                $data["check_name"] = "NO_CHECK";
                break;
            case 2:
                $data["check_name"] = "FORCE_CHECK";
                break;
            default:
                $data["check_name"] = "OPTION_CHECK";
                break;
        }
        $data["partner_trade_no"] = $arr["order_sn"];
        $sign = $this->getSign($data);
        $data["sign"] = $sign;
        //拼接 xml
        $xml = "<xml>
                <mch_appid>%s</mch_appid>
                <mchid>%s</mchid>
                <nonce_str>%s</nonce_str>
                <partner_trade_no>%s</partner_trade_no>
                <openid>%s</openid>
                <check_name>%s</check_name>
                <re_user_name>%s</re_user_name>
                <amount>%s</amount>
                <desc>%s</desc>
                <spbill_create_ip>%s</spbill_create_ip>
                <sign>%s</sign>
                </xml>";
        $post = sprintf($xml,$data["mch_appid"],
            $data["mchid"],
            $data["nonce_str"],
            $data["partner_trade_no"],
            $data["openid"],
            $data["check_name"],
            $data["re_user_name"],
            $data["amount"],
            $data["desc"],
            $data["spbill_create_ip"],
            $data["sign"]
        );
        $result = $this->curl_post_ssl($this->url,$post);
        $result = $this->readXml($result);
        $res = ["error"=>1,"msg"=>""];
        if($result->return_code == "SUCCESS"){
            if($result->result_code == "SUCCESS"){
                $res = ["error"=>0,"msg"=>"返现成功!"];
            }else if($result->result_code == "FAIL"){
                $res = ["error"=>2,"msg"=>$result->err_code_des];
            }
        }else if($result->return_code == "FAIL"){
            $res = ["error"=>1,"msg"=>""];
            switch ($result->err_code){
                case "NOAUTH":
                    $res["msg"] = "没有权限";
                    break;
                case "AMOUNT_LIMIT":
                    $res["msg"] = "付款金额不能小于最低限额";
                    break;
                case "PARAM_ERROR":
                    $res["msg"] = "参数错误";
                    break;
                case "OPENID_ERROR":
                    $res["msg"] = "Openid 错误";
                    break;
                case "NOTENOUGH":
                    $res["msg"] = "余额不足";
                    break;
                case "SYSTEMERROR":
                    $res["msg"] = "系统繁忙,请稍后再试。";
                    break;
                case "NAME_MISMATCH":
                    $res["msg"] = "姓名校验出错";
                    break;
                case "SIGN_ERROR":
                    $res["msg"] = "签名错误";
                    break;
                case "XML_ERROR":
                    $res["msg"] = "Post 内容出错";
                    break;
                case "FATAL_ERROR":
                    $res["msg"] = "两次请求参数不一致";
                    break;
                case "CA_ERROR":
                    $res["msg"] = "证书出错";
                    break;
            }
        }
        return $res;
    }

    protected function readXml($xmlData){
        libxml_disable_entity_loader(true);
        $req = simplexml_load_string($xmlData, 'SimpleXMLElement', LIBXML_NOCDATA);
        return $req;
    }
}

小 A 空间 , 版权所有丨如未注明转载 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明微信企业支付 API 类库(php)
喜欢 (2)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址