登录  /  注册

微信支付统一下单,用PHP怎么实现?(代码全)

php是最好的语言
发布: 2018-07-26 09:29:17
原创
9050人浏览过

h5支付时出现“签名错误”怎么办?注意调用微信“统一下单”接口后返回pre_pay_id后,需要用户再次进行签名返回给html; “支付目录没有授权”,进入微信商家管理后台设置即可。

一、Model层,Wxpay.php

<?php
namespace app\common\model;
class Wxpay
{
    private $appid = &#39;wxe8*****d4&#39;;                            //微信公众号appid
    private $secret = &#39;37c4*******5f0&#39;;                        //微信公众号appsecret               
    private $mchid = &#39;13******02&#39;;                             //商家号
    private $key = &#39;5363e******49e8&#39;;                          //支付密钥
    private $sslcert_path = &#39;apiclient_cert.pem&#39;;              //证书所在绝对路径
    private $sslkey_path = &#39;apiclient_key.pem&#39;;                //证书所在绝对路径
    
    public function __construct($appid = &#39;&#39;, $secret = &#39;&#39;, $mchid = &#39;&#39;, $key = &#39;&#39;)
    {
        if(!empty($appid))     $this->appid = $appid;
        if(!empty($secret))    $this->secret = $secret;
        if(!empty($mchid))     $this->mchid  = $mchid;
        if(!empty($key))       $this->key= $key;
    }
    /*
     * 微信内H5调起支付
     * @params string $openid : 微信用户openid
     * @params string $out_trade_no : 商家生成的订单号(唯一性)
     * @params int $total_fee : 支付金额,单位分
     * return array $ret : 返回支付时所需要的数据
     * */
    public function payForWeixin($openid,$out_trade_no,$total_fee,$attach=&#39;微信支付&#39;,$body=&#39;微信支付&#39;)
    {
        //支付数据
        $data[&#39;openid&#39;] = $openid;
        $data[&#39;out_trade_no&#39;] = $out_trade_no;
        $data[&#39;total_fee&#39;] = $total_fee*100;
        $data[&#39;spbill_create_ip&#39;] = $_SERVER["REMOTE_ADDR"];
        $data[&#39;attach&#39;] = $attach;
        $data[&#39;body&#39;] = $body;
        $data[&#39;appid&#39;] = $this->appid;
        $data[&#39;mch_id&#39;] = $this->mchid;
        $data[&#39;nonce_str&#39;] = random(12);
        $data[&#39;trade_type&#39;] = "JSAPI";
        $data[&#39;notify_url&#39;] = "http://****.com/home/wxpaynofiy/notify.html";

        $sign = $this->getParam($data);
        $dataXML = "<xml>
           <appid>".$data[&#39;appid&#39;]."</appid>
           <attach>".$data[&#39;attach&#39;]."</attach>
           <body>".$data[&#39;body&#39;]."</body>
           <mch_id>".$data[&#39;mch_id&#39;]."</mch_id>
           <nonce_str>".$data[&#39;nonce_str&#39;]."</nonce_str>
           <notify_url>".$data[&#39;notify_url&#39;]."</notify_url>
           <openid>".$data[&#39;openid&#39;]."</openid>
           <out_trade_no>".$data[&#39;out_trade_no&#39;]."</out_trade_no>
           <spbill_create_ip>".$data[&#39;spbill_create_ip&#39;]."</spbill_create_ip>
           <total_fee>".$data[&#39;total_fee&#39;]."</total_fee>
           <trade_type>".$data[&#39;trade_type&#39;]."</trade_type>
           <sign>".$sign."</sign>
        </xml>";
        $url = &#39;https://api.mch.weixin.qq.com/pay/unifiedorder&#39;;
        $result =  $this->https_post($url,$dataXML);
        $ret = $this->xmlToArray($result);
        
        if($ret[&#39;return_code&#39;] == &#39;SUCCESS&#39; && $ret[&#39;return_msg&#39;] == &#39;OK&#39;) {
            return array(
                &#39;appId&#39;     => $this->appid,
                &#39;timeStamp&#39; => time(),
                &#39;nonceStr&#39;  => $data[&#39;nonce_str&#39;],
                &#39;package&#39;   => &#39;prepay_id=&#39;.$ret[&#39;prepay_id&#39;],
                &#39;signType&#39;  => &#39;MD5&#39;,
                &#39;paySign&#39;   => $sign
            );
        } else {
            $this->errorLog("微信支付失败,",$ret);
            return null;
        }
    }
     /*
     *   微信二维码支付
     *   @params string $openid : 用户的openid
     *   @params string $out_trade_no : 商户订单号
     *   @params number $total_fee : 订单金额,单位分
     *   return string $code_url : 二维码URL链接
     */
    public function payForQrcode($out_trade_no,$total_fee,$body="魔盒CMS",$attach="微信支付")
    {
        //支付数据
        $data[&#39;out_trade_no&#39;] = $out_trade_no;
        $data[&#39;total_fee&#39;] = $total_fee*100;
        $data[&#39;spbill_create_ip&#39;] = $_SERVER["REMOTE_ADDR"];
        $data[&#39;attach&#39;] = $attach;
        $data[&#39;body&#39;] = $body;
        $data[&#39;appid&#39;] = $this->appid;
        $data[&#39;mch_id&#39;] = $this->mchid;
        $data[&#39;nonce_str&#39;] = random(12);
        $data[&#39;trade_type&#39;] = "NATIVE";
        $data[&#39;notify_url&#39;] = "http://****.com/home/wxpaynofiy/notify.html";

        $sign = $this->getParam($data);
        $dataXML = "<xml>
           <appid>".$data[&#39;appid&#39;]."</appid>
           <attach>".$data[&#39;attach&#39;]."</attach>
           <body>".$data[&#39;body&#39;]."</body>
           <mch_id>".$data[&#39;mch_id&#39;]."</mch_id>
           <nonce_str>".$data[&#39;nonce_str&#39;]."</nonce_str>
           <notify_url>".$data[&#39;notify_url&#39;]."</notify_url>
           <out_trade_no>".$data[&#39;out_trade_no&#39;]."</out_trade_no>
           <spbill_create_ip>".$data[&#39;spbill_create_ip&#39;]."</spbill_create_ip>
           <total_fee>".$data[&#39;total_fee&#39;]."</total_fee>
           <trade_type>".$data[&#39;trade_type&#39;]."</trade_type>
           <sign>".$sign."</sign>
        </xml>";
        $url = &#39;https://api.mch.weixin.qq.com/pay/unifiedorder&#39;;
        $result =  $this->https_post($url,$dataXML);
        $ret = $this->xmlToArray($result);
        if($ret[&#39;return_code&#39;] == &#39;SUCCESS&#39; && $ret[&#39;return_msg&#39;] == &#39;OK&#39;) {
            return $ret[&#39;code_url&#39;];
        } else {
            $this->errorLog("获取微信支付二维码失败,",$ret);
            return null;
        }
    }

    /*
     * 订单查询
     * @params string $transaction_id : 微信订单号
     * @params string $out_trade_no : 商家订单号(与微信订单号二选一)
     * */
    public function findOrder($out_trade_no)
    {
        $data[&#39;appid&#39;] = $this->appid;
        $data[&#39;mch_id&#39;] = $this->mchid;
        $data[&#39;nonce_str&#39;] = random(12);
        $data[&#39;out_trade_no&#39;] = $out_trade_no;
        $sign = $this->getParam($data);
        $dataXML = "<xml>
            <appid>".$data[&#39;appid&#39;]."</appid>
            <mch_id>".$data[&#39;mch_id&#39;]."</mch_id>
            <nonce_str>".$data[&#39;nonce_str&#39;]."</nonce_str>
            <out_trade_no>".$data[&#39;out_trade_no&#39;]."</out_trade_no>
            <sign>".$sign."</sign>
         </xml>";
        $url = &#39;https://api.mch.weixin.qq.com/pay/orderquery&#39;;
        $result =  $this->https_post($url,$dataXML);
        $ret = $this->xmlToArray($result);
        if($ret[&#39;return_code&#39;] == &#39;SUCCESS&#39; && $ret[&#39;return_msg&#39;] == &#39;OK&#39;) {
            return $ret;
        } else {
            $this->errorLog("查询微信支付订单失败,",$ret);
            return null;
        }
    }
    /*
    * 退款订单查询
    * @params string $transaction_id : 微信订单号
    * @params string $out_trade_no : 商家订单号(与微信订单号二选一)
    * */
    public function findRefundOrder($out_trade_no)
    {
        $data[&#39;appid&#39;] = $this->appid;
        $data[&#39;mch_id&#39;] = $this->mchid;
        $data[&#39;nonce_str&#39;] = random(12);
        $data[&#39;out_trade_no&#39;] = $out_trade_no;
        $sign = $this->getParam($data);
        $dataXML = "<xml>
            <appid>".$data[&#39;appid&#39;]."</appid>
            <mch_id>".$data[&#39;mch_id&#39;]."</mch_id>
            <nonce_str>".$data[&#39;nonce_str&#39;]."</nonce_str>
            <out_trade_no>".$data[&#39;out_trade_no&#39;]."</out_trade_no>
            <sign>".$sign."</sign>
         </xml>";
        $url = &#39;https://api.mch.weixin.qq.com/pay/refundquery&#39;;
        $result =  $this->https_post($url,$dataXML);
        $ret = $this->xmlToArray($result);
        if($ret[&#39;return_code&#39;] == &#39;SUCCESS&#39; && $ret[&#39;return_msg&#39;] == &#39;OK&#39;) {
            return $ret;
        } else {
            $this->errorLog("查询微信支付退款订单失败,",$ret);
            return $ret[&#39;err_code_des&#39;];
        }
    }
    /*
     * 申请退款
     * @params string $out_trade_no : 商户订单号
     * @params string $out_refund_no : 商户退款单号
     * @params int $total_fee : 订单金额
     * @params int $refund_fee : 退款金额
     * @params string $refund_desc : 退款原因
     * */
    public function refund($out_trade_no,$out_refund_no,$total_fee,$refund_fee,$refund_desc=&#39;退款&#39;)
    {
        $data[&#39;appid&#39;]  = $this->appid;
        $data[&#39;mch_id&#39;] = $this->mchid;
        $data[&#39;nonce_str&#39;] = random(12);
        $data[&#39;out_trade_no&#39;] = $out_trade_no;
        $data[&#39;out_refund_no&#39;] = $out_refund_no;
        $data[&#39;total_fee&#39;] = $total_fee*100;
        $data[&#39;refund_fee&#39;] = $refund_fee*100;
        $data[&#39;refund_desc&#39;] = $refund_desc;
        $data[&#39;notify_url&#39;] = "http://*****.com/home/wxpaynofiy/refund.html";
        $sign = $this->getParam($data);
        $dataXML = "<xml>
           <appid>".$data[&#39;appid&#39;]."</appid>
           <mch_id>".$data[&#39;mch_id&#39;]."</mch_id>
           <nonce_str>".$data[&#39;nonce_str&#39;]."</nonce_str>
           <out_trade_no>".$data[&#39;out_trade_no&#39;]."</out_trade_no>
           <out_refund_no>".$data[&#39;out_refund_no&#39;]."</out_refund_no>
           <total_fee>".$data[&#39;total_fee&#39;]."</total_fee>
           <refund_fee>".$data[&#39;refund_fee&#39;]."</refund_fee>
           <refund_desc>".$data[&#39;refund_desc&#39;]."</refund_desc>
           <notify_url>".$data[&#39;notify_url&#39;]."</notify_url>
           <sign>".$sign."</sign>
        </xml>";
        $url = &#39;https://api.mch.weixin.qq.com/secapi/pay/refund&#39;;
        $result =  $this->https_post($url,$dataXML,true);
        $ret = $this->xmlToArray($result);
        if($ret[&#39;return_code&#39;] == &#39;SUCCESS&#39; && $ret[&#39;return_msg&#39;] == &#39;OK&#39;) {
            return $ret;
        } else {
            $this->errorLog("微信退款失败,",$ret);
            return null;
        }
    }
    /*
     * 企业付款至用户零钱
     * @params string $openid : 用户openid
     * @params int $total_fee : 付款金额,单位分
     * @params string $out_trade_no : 商家订单号
     * @params string $username : 微信用户名称(注意微信昵称若为空时支付会出错)
     * @params string $desc : 付款描述
     * @params string $check_name : 是否检测用户名
     * */
    public function payForUser($openid,$total_fee,$out_trade_no,$username=&#39;魔盒CMS&#39;,$desc=&#39;魔盒CMS付款给用户&#39;,$check_name=&#39;NO_CHECK&#39;)
    {
        $data[&#39;amount&#39;] = $total_fee*100;
        $data[&#39;check_name&#39;] = $check_name;
        $data[&#39;desc&#39;] = $desc;
        $data[&#39;mch_appid&#39;] = $this->appid;
        $data[&#39;mchid&#39;] = $this->mchid;
        $data[&#39;nonce_str&#39;] = random(12);
        $data[&#39;openid&#39;] = $openid;
        $data[&#39;partner_trade_no&#39;] = $out_trade_no;
        $data[&#39;re_user_name&#39;] = $username;
        $data[&#39;spbill_create_ip&#39;] = $_SERVER["REMOTE_ADDR"];
        $sign = $this->getParam($data);

        $dataXML="<xml>
        <mch_appid>".$data[&#39;mch_appid&#39;]."</mch_appid>
        <mchid>".$data[&#39;mchid&#39;]."</mchid>
        <nonce_str>".$data[&#39;nonce_str&#39;]."</nonce_str>
        <partner_trade_no>".$data[&#39;partner_trade_no&#39;]."</partner_trade_no>
        <openid>".$data[&#39;openid&#39;]."</openid>
        <check_name>".$data[&#39;check_name&#39;]."</check_name>
        <re_user_name>".$data[&#39;re_user_name&#39;]."</re_user_name>
        <amount>".$data[&#39;amount&#39;]."</amount>
        <desc>".$data[&#39;desc&#39;]."</desc>
        <spbill_create_ip>".$data[&#39;spbill_create_ip&#39;]."</spbill_create_ip>
        <sign>".$sign."</sign>
        </xml>";

        $url = &#39;https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers&#39;;
        $result =  $this->https_post($url,$dataXML,true);
        $ret = $this->xmlToArray($result);
        if($ret[&#39;return_code&#39;]==&#39;SUCCESS&#39; && $ret[&#39;result_code&#39;] == &#39;SUCCESS&#39;)
        {
            //支付成功返回商户订单号、微信订单号、微信支付成功时间
            $result[&#39;partner_trade_no&#39;] = $ret[&#39;partner_trade_no&#39;];
            $result[&#39;payment_no&#39;] = $ret[&#39;payment_no&#39;];
            $result[&#39;payment_time&#39;] = $ret[&#39;payment_time&#39;];
            return $ret;
        } else {
           $this->errorLog(&#39;付款给用户失败&#39;,$ret);
           return null;
        }
    }
     /*
     * 普通红包
     * @params string $out_trade_no : 商家订单号
     * @params string $openid : 接收红包用户的openid
     * @params int $total_fee : 红包金额,单位分
     * @params int $total_num : 红包发放总人数
     * @params string $wishing : 红包祝福语
     * @params string $act_name : 活动名称
     * @params string $remark : 备注
     * @params string $scene_id :场景值ID。发放红包使用场景,红包金额大于200或者小于1元时必传。PRODUCT_1:商品促销、PRODUCT_2:抽奖、PRODUCT_3:虚拟物品兑奖 、PRODUCT_4:企业内部福利、PRODUCT_5:渠道分润、PRODUCT_6:保险回馈、PRODUCT_7:彩票派奖、PRODUCT_8:税务刮奖
     * */
    public function redPack($openid,$total_fee,$out_trade_no,$total_num = 1,$wishing = &#39;感谢您光临***平台进行购物&#39;,$act_name=&#39;***购物发红包&#39;,$remark = &#39;购物领红包&#39;)
    {
        $data[&#39;mch_billno&#39;]     = $out_trade_no;
        $data[&#39;mch_id&#39;]         = $this->mchid;
        $data[&#39;wxappid&#39;]        = $this->appid;
        $data[&#39;send_name&#39;]      = &#39;发送红包者的名称&#39;;
        $data[&#39;re_openid&#39;]      = $openid;
        $data[&#39;total_amount&#39;]   = $total_fee;
        $data[&#39;total_num&#39;]      = $total_num;
        $data[&#39;wishing&#39;]        = $wishing;
        $data[&#39;client_ip&#39;]      = $_SERVER["REMOTE_ADDR"];
        $data[&#39;act_name&#39;]       = $act_name;
        $data[&#39;remark&#39;]         = $remark;
        $data[&#39;nonce_str&#39;]      = random(12);
        $sign = $this->getParam($data);

        $dataXML="<xml>
        <sign>".$sign."</sign>
        <mch_billno>".$data[&#39;mch_billno&#39;]."</mch_billno>
        <mch_id>".$data[&#39;mch_id&#39;]."</mch_id>
        <wxappid>".$data[&#39;wxappid&#39;]."</wxappid>
        <send_name>".$data[&#39;send_name&#39;]."</send_name>
        <re_openid>".$data[&#39;re_openid&#39;]."</re_openid>
        <total_amount>".$data[&#39;total_amount&#39;]."</total_amount>
        <total_num>".$data[&#39;total_num&#39;]."</total_num>
        <wishing>".$data[&#39;wishing&#39;]."</wishing>
        <client_ip>".$data[&#39;client_ip&#39;]."</client_ip>
        <act_name>".$data[&#39;act_name&#39;]."</act_name>
        <remark>".$data[&#39;remark&#39;]."</remark>
        <nonce_str>".$data[&#39;nonce_str&#39;]."</nonce_str>
        </xml>";

        $url = &#39;https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack&#39;;
        $result =  $this->https_post($url,$dataXML,true);
        $ret = $this->xmlToArray($result);
        if($ret[&#39;return_code&#39;]==&#39;SUCCESS&#39; && $ret[&#39;result_code&#39;] == &#39;SUCCESS&#39;)
        {
            return $ret;
        } else {
            $this->errorLog(&#39;发放普通红包失败&#39;,$ret);
            return $ret[&#39;err_code_des&#39;];
        }

    }

    /*
    * 裂变红包:一次可以发放一组红包。首先领取的用户为种子用户,种子用户领取一组红包当中的一个,并可以通过社交分享将剩下的红包给其他用户。
     * 裂变红包充分利用了人际传播的优势。
    * @params string $out_trade_no : 商家订单号
    * @params string $openid : 接收红包用户的openid
    * @params int $total_fee : 红包金额,单位分
    * @params int $total_num : 红包发放总人数
    * @params string $wishing : 红包祝福语
    * @params string $act_name : 活动名称
    * @params string $remark : 备注
    * @params string $scene_id :场景值ID。发放红包使用场景,红包金额大于200或者小于1元时必传。PRODUCT_1:商品促销、PRODUCT_2:抽奖、PRODUCT_3:虚拟物品兑奖 、PRODUCT_4:企业内部福利、PRODUCT_5:渠道分润、PRODUCT_6:保险回馈、PRODUCT_7:彩票派奖、PRODUCT_8:税务刮奖
    * */
    public function redPackGroup($openid,$total_fee,$out_trade_no,$total_num,$wishing = &#39;感谢您光临***进行购物&#39;,$act_name=&#39;**购物发红包&#39;,$remark = &#39;购物领红包&#39;)
    {
        $data[&#39;mch_billno&#39;]     = $out_trade_no;
        $data[&#39;mch_id&#39;]         = $this->mchid;
        $data[&#39;wxappid&#39;]        = $this->appid;
        $data[&#39;send_name&#39;]      = &#39;发送红包者的名称&#39;;
        $data[&#39;re_openid&#39;]      = $openid;
        $data[&#39;total_amount&#39;]   = $total_fee;
        $data[&#39;amt_type&#39;]       = &#39;ALL_RAND&#39;;   //ALL_RAND—全部随机,商户指定总金额和红包发放总人数,由微信支付随机计算出各红包金额
        $data[&#39;total_num&#39;]      = $total_num;
        $data[&#39;wishing&#39;]        = $wishing;
        $data[&#39;client_ip&#39;]      = $_SERVER["REMOTE_ADDR"];
        $data[&#39;act_name&#39;]       = $act_name;
        $data[&#39;remark&#39;]         = $remark;
        $data[&#39;nonce_str&#39;]      = random(12);
        $sign = $this->getParam($data);

        $dataXML="<xml>
        <sign>".$sign."</sign>
        <mch_billno>".$data[&#39;mch_billno&#39;]."</mch_billno>
        <mch_id>".$data[&#39;mch_id&#39;]."</mch_id>
        <wxappid>".$data[&#39;wxappid&#39;]."</wxappid>
        <send_name>".$data[&#39;send_name&#39;]."</send_name>
        <re_openid>".$data[&#39;re_openid&#39;]."</re_openid>
        <total_amount>".$data[&#39;total_amount&#39;]."</total_amount>
        <amt_type>".$data[&#39;amt_type&#39;]."</amt_type> 
        <total_num>".$data[&#39;total_num&#39;]."</total_num>
        <wishing>".$data[&#39;wishing&#39;]."</wishing>
        <client_ip>".$data[&#39;client_ip&#39;]."</client_ip>
        <act_name>".$data[&#39;act_name&#39;]."</act_name>
        <remark>".$data[&#39;remark&#39;]."</remark>
        <nonce_str>".$data[&#39;nonce_str&#39;]."</nonce_str>
        </xml>";

        $url = &#39;https://api.mch.weixin.qq.com/mmpaymkttransfers/sendgroupredpack&#39;;
        $result =  $this->https_post($url,$dataXML,true);
        $ret = $this->xmlToArray($result);
        if($ret[&#39;return_code&#39;]==&#39;SUCCESS&#39; && $ret[&#39;result_code&#39;] == &#39;SUCCESS&#39;)
        {
            return $ret;
        } else {
            $this->errorLog(&#39;发放裂变红包失败&#39;,$ret);
            return $ret[&#39;err_code_des&#39;];
        }

    }
    /*
     * 查询红包记录
     * @params string $out_trade_no : 商家订单号
     * */
    public function findRedPack($out_trade_no)
    {
        $data[&#39;mch_billno&#39;]     = $out_trade_no;
        $data[&#39;mch_id&#39;]         = $this->mchid;
        $data[&#39;appid&#39;]          = $this->appid;
        $data[&#39;bill_type&#39;]      = &#39;MCHT&#39;;           //MCHT:通过商户订单号获取红包信息。
        $data[&#39;nonce_str&#39;]      = random(12);
        $sign = $this->getParam($data);

        $dataXML="<xml>
        <sign>".$sign."</sign>
        <mch_billno>".$data[&#39;mch_billno&#39;]."</mch_billno>
        <mch_id>".$data[&#39;mch_id&#39;]."</mch_id>
        <appid>".$data[&#39;appid&#39;]."</appid>
        <bill_type>".$data[&#39;bill_type&#39;]."</bill_type> 
        <nonce_str>".$data[&#39;nonce_str&#39;]."</nonce_str>
        </xml>";

        $url = &#39;https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo&#39;;
        $result =  $this->https_post($url,$dataXML,true);
        $ret = $this->xmlToArray($result);
        if($ret[&#39;return_code&#39;]==&#39;SUCCESS&#39; && $ret[&#39;result_code&#39;] == &#39;SUCCESS&#39;)
        {
            return $ret;
        } else {
            $this->errorLog(&#39;查询红包记录失败&#39;,$ret);
            return $ret[&#39;err_code_des&#39;];
        }
    }
    /*
     * 获取用户微信的OPENID
     * */
    public function openid($c=false)
    {
        if($_GET[&#39;state&#39;]!="zgm"){
            $t = $c ? "snsapi_userinfo" : "snsapi_base";
            $url=urlencode(get_url());
            $url="https://open.weixin.qq.com/connect/oauth2/authorize?appid=".$this->appid."&redirect_uri=".$url."&response_type=code&scope=".$t."&state=zgm#wechat_redirect";
            echo "<html><script>window.location.href=&#39;$url&#39;;</script></html>";
            exit;
        }
        if($_GET[&#39;code&#39;]){
            $url="https://api.weixin.qq.com/sns/oauth2/access_token?appid=".$this->appid."&secret=".$this->secret."&code=".$_GET[&#39;code&#39;]."&grant_type=authorization_code";
            $wx_db=json_decode($this->https_get($url));
            if($c){
                $url_2="https://api.weixin.qq.com/sns/userinfo?access_token=".$wx_db->access_token."&openid=".$wx_db->openid."&lang=zh_CN";
                $db=json_decode($this->https_get($url_2));
                return $db;
            }else{
                return $wx_db->openid;
            }
        }
    }
    /*
    * 发起网络GET请求
    * @params string $url : URL链接
    */
    private function https_get($url)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); 
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); 
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); 
        curl_setopt($curl, CURLOPT_HEADER, FALSE) ; 
        curl_setopt($curl, CURLOPT_TIMEOUT,60);   
        if (curl_errno($curl)) {
            return &#39;Errno&#39;.curl_error($curl);
        }
        else{$result=curl_exec($curl);}
        curl_close($curl);
        return $result;
    }
    //对参数排序,生成MD5加密签名
    private function getParam($paramArray, $isencode=false)
    {
        $paramStr = &#39;&#39;;
        ksort($paramArray);
        $i = 0;
        foreach ($paramArray as $key => $value)
        {
            if ($key == &#39;Signature&#39;){
                continue;
            }
            if ($i == 0){
                $paramStr .= &#39;&#39;;
            }else{
                $paramStr .= &#39;&&#39;;
            }
            $paramStr .= $key . &#39;=&#39; . ($isencode?urlencode($value):$value);
            ++$i;
        }
        $stringSignTemp=$paramStr."&key=".$this->key;
        $sign=strtoupper(md5($stringSignTemp));
        return $sign;
    }
    //POST提交数据
    private function https_post($url,$data,$ssl = false)
    {
        $ch = curl_init ();
        curl_setopt ( $ch, CURLOPT_URL, $url );
        curl_setopt ( $ch, CURLOPT_CUSTOMREQUEST, "POST" );
        curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, FALSE );
        curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, FALSE );
        if($ssl) {
            curl_setopt ( $ch,CURLOPT_SSLCERT,$this->sslcert_path);
            curl_setopt ( $ch,CURLOPT_SSLKEY,$this->sslkey_path);
        }
        curl_setopt ( $ch, CURLOPT_FOLLOWLOCATION, 1 );
        curl_setopt ( $ch, CURLOPT_AUTOREFERER, 1 );
        curl_setopt ( $ch, CURLOPT_POSTFIELDS, $data );
        curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
        $result = curl_exec($ch);
        if (curl_errno($ch)) {
            return &#39;Errno: &#39;.curl_error($ch);
        }
        curl_close($ch);
        return $result;
    }
    /*
    * XML转array
    * @params xml $xml : xml 数据
    * return array $data : 转义后的array数组
    */
    private function xmlToArray($xml)
    {
        libxml_disable_entity_loader(true);
        $xmlstring = simplexml_load_string($xml, &#39;SimpleXMLElement&#39;, LIBXML_NOCDATA);
        $val = json_decode(json_encode($xmlstring),true);
        return $val;
    }
    /*
    * 记录日志
    * @params string $msg : 提示语句
    * @params array $ret : 错误结果
    */
    private function errorLog($msg,$ret)
    {
        file_put_contents(ROOT_PATH . &#39;runtime/error/wxpay.log&#39;, "[" . date(&#39;Y-m-d H:i:s&#39;) . "] ".$msg."," .json_encode($ret).PHP_EOL, FILE_APPEND);
    }
}
登录后复制

二、Controller层,Test.php

<?php
namespace app\goods\controller;
use app\common\model\Wxpay;
class Test
{
    /*
    * 调用微信支付
    * 一、获取微信用户的openid; 
    * 二、调用微信支付接口
    * 三、生成H5中使用的签名内容
    */
    public function wx()
    {
        $wxpay = new Wxpay();
        $openid = $wxpay->openid();
        $pay = $wxpay->payForWeixin($openid,date(&#39;YmdHis&#39;).rand(1,5),&#39;0.1&#39;);
        $paySign =strtoupper(MD5(&#39;appId=&#39;.$pay[&#39;appId&#39;].&#39;&nonceStr=&#39;.$pay[&#39;nonceStr&#39;].&#39;&package=&#39;.$pay[&#39;package&#39;].&#39;&signType=MD5&timeStamp=&#39;.$pay[&#39;timeStamp&#39;].&#39;&key=536*****9e8&#39;));
         $h5 = array(
            &#39;appId&#39;     => $pay[&#39;appId&#39;],
            &#39;timeStamp&#39; => $pay[&#39;timeStamp&#39;],
            &#39;nonceStr&#39;  => $pay[&#39;nonceStr&#39;],
            &#39;package&#39;   => $pay[&#39;package&#39;],
            &#39;signType&#39;  => $pay[&#39;signType&#39;],
            &#39;paySign&#39;   => $paySign
        );
        $this->assign(&#39;wxpay&#39;,$h5);
        return view();
    }
}
登录后复制

三、HTML中调用微信支付,wx.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>订单示例</title>
</head>
<body>

<script type="text/javascript">
    function onBridgeReady(){
        WeixinJSBridge.invoke(
            &#39;getBrandWCPayRequest&#39;, {
                "appId":"{$wxpay[&#39;appId&#39;]}",
                "timeStamp":"{$wxpay[&#39;timeStamp&#39;]}",
                "nonceStr":"{$wxpay[&#39;nonceStr&#39;]}",
                "package":"{$wxpay[&#39;package&#39;]}",
                "signType":"MD5",
                "paySign":"{$wxpay[&#39;paySign&#39;]}"
            },
            function(res){
                if(res.err_msg == "get_brand_wcpay_request:ok" ){
                    // 使用以上方式判断前端返回,微信团队郑重提示:
                    //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
                }
            });
    }
    if (typeof WeixinJSBridge == "undefined"){
        if( document.addEventListener ){
            document.addEventListener(&#39;WeixinJSBridgeReady&#39;, onBridgeReady, false);
        }else if (document.attachEvent){
            document.attachEvent(&#39;WeixinJSBridgeReady&#39;, onBridgeReady);
            document.attachEvent(&#39;onWeixinJSBridgeReady&#39;, onBridgeReady);
        }
    }else{
        onBridgeReady();
    }
</script>
</body>
</html>
登录后复制

四、接收微信支付返回结果,支付时设置的notify_url值,确保此链接外网能访问。wxpaynofiy.php

<?php
namespace app\home\controller;
class Wxpaynofiy
{
     public function notify()
    {
        $xml = isset($GLOBALS["HTTP_RAW_POST_DATA"]) ? $GLOBALS[&#39;HTTP_RAW_POST_DATA&#39;] : file_get_contents("php://input");
        $data = xmlToArray($xml);
        if($data[&#39;return_code&#39;] == &#39;SUCCESS&#39; && $data[&#39;result_code&#39;] == &#39;SUCCESS&#39;){
            if($this->checkSign($data)) {
                $transaction_id = $data[&#39;transaction_id&#39;];      //微信支付订单号
                $out_trade_no   = $data[&#39;out_trade_no&#39;];        //商家订单号
                $this->errorLog(&#39;微信支付返回结果,微信支付订单号:&#39;.$transaction_id.&#39;,商家订单号:&#39;.$out_trade_no,[]);

            } else {
                $this->errorLog(&#39;微信支付返回结果签名验证失败&#39;,$data);
            }
        } else {
            $this->errorLog(&#39;微信支付返回结果&#39;,$data);
        }
        echo &#39;<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>&#39;;
    }

    /*
     * 验证签名
     * @params array $result : 微信支付成功返回的结果数组
     * return bool $ret : 成功true,失败false
     * */
    private function checkSign(array $data)
    {
        $str = &#39;&#39;;
        ksort($data);
        foreach ($data as $k => $v) {
            if($k != &#39;sign&#39;) $str .= $k.&#39;=&#39;.$v.&#39;&&#39;;
        }
        $temp = $str . &#39;key=5363******49e8&#39;;     //key:商户支付密钥
        $sign = strtoupper(md5($temp));
        return $sign == $data[&#39;sign&#39;] ? true : false;
    }

    private function errorLog($msg,$ret)
    {
        file_put_contents(ROOT_PATH . &#39;runtime/error/wxpaynofiy.log&#39;, "[" . date(&#39;Y-m-d H:i:s&#39;) . "] ".$msg."," .json_encode($ret).PHP_EOL, FILE_APPEND);
    }
}
登录后复制

视频教程 :php微信接口开发实战项目聊天机器人+微信支付

以上就是微信支付统一下单,用PHP怎么实现?(代码全)的详细内容,更多请关注php中文网其它相关文章!

智能AI问答
PHP中文网智能助手能迅速回答你的编程问题,提供实时的代码和解决方案,帮助你解决各种难题。不仅如此,它还能提供编程资源和学习指导,帮助你快速提升编程技能。无论你是初学者还是专业人士,AI智能助手都能成为你的可靠助手,助力你在编程领域取得更大的成就。
相关标签:
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2024 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号