zoukankan      html  css  js  c++  java
  • 一个PHP文件搞定微信H5支付

    过年期间也坚持要撸码啊接着给博客除草,在这个小除夕是情人节的一天,祝大家新年快乐,情人节能够顺利脱单~~~ 回归正题,这篇文章介绍一下微信H5支付,以及单PHP文件完成微信H5支付。

    什么是微信H5支付

    H5支付是指商户在微信客户端外的移动端网页展示商品或服务,用户在前述页面确认使用微信支付时,商户发起本服务呼起微信客户端进行支付

    主要用于触屏版的手机浏览器请求微信支付的场景。可以方便的从外部浏览器唤起微信支付

    微信官方也提供了一个体验链接,请在微信外浏览器打开

    开发流程

    1、用户在商户侧完成下单,使用微信支付进行支付

    2、由商户后台向微信支付发起下单请求(调用统一下单接口)注:交易类型trade_type=MWEB

    3、统一下单接口返回支付相关参数给商户后台,如支付跳转url(参数名“mweb_url”),商户通过mweb_url调起微信支付中间页

    4、中间页进行H5权限的校验,安全性检查(此处常见错误请见下文)

    5、如支付成功,商户后台会接收到微信侧的异步通知

    6、用户在微信支付收银台完成支付或取消支付,返回商户页面(默认为返回支付发起页面)

    7、商户在展示页面,引导用户主动发起支付结果的查询

    8,9、商户后台判断是否接到收微信侧的支付结果通知,如没有,后台调用我们的订单查询接口确认订单状态

    10、展示最终的订单支付结果给用户

    网上的对于微信H5支付的资源感觉少之又少,可能是因为微信H5支付出来时间不久吧,很多PHP微信支付接入教程都比较复杂,且需要配置和引入较多的文件,本人通过整理后给出一个单文件版的,希望可以给各位想接入微信H5支付的带来些许帮助和借鉴意义。以下为本篇文章的重点:

    PHP代码

    <?php
    /**
     * 微信H5支付PHP版本demo 部分代码来自网络
     * 作者:沈唁 
     * 博客:https://qq52o.me
     */
    $money= 1;                     //充值金额 微信支付单位为分
    $userip = get_client_ip();     //获得用户设备IP
    $appid  = "";                  //应用APPID
    $mch_id = "";                  //微信支付商户号
    $key    = "";                 //微信商户API密钥
    $out_trade_no = date('YmdHis').rand(1000,9999);//平台内部订单号
    $nonce_str = createNoncestr();//随机字符串
    $body = "H5充值";//内容
    $total_fee = $money; //金额
    $spbill_create_ip = $userip; //IP
    $notify_url = "http://qq52o.me/wxpay/notify.php"; //回调地址
    $trade_type = 'MWEB';//交易类型 具体看API 里面有详细介绍
    $scene_info ='{"h5_info":{"type":"Wap","wap_url":"http://qq52o.me","wap_name":"支付"}}';//场景信息 必要参数
    $signA ="appid=$appid&attach=$out_trade_no&body=$body&mch_id=$mch_id&nonce_str=$nonce_str&notify_url=$notify_url&out_trade_no=$out_trade_no&scene_info=$scene_info&spbill_create_ip=$spbill_create_ip&total_fee=$total_fee&trade_type=$trade_type";
    $strSignTmp = $signA."&key=$key"; //拼接字符串  注意顺序微信有个测试网址 顺序按照他的来 直接点下面的校正测试 包括下面XML  是否正确
    $sign = strtoupper(MD5($strSignTmp)); // MD5 后转换成大写
    $post_data = "<xml>
                        <appid>$appid</appid>
                        <mch_id>$mch_id</mch_id>
                        <body>$body</body>
                        <out_trade_no>$out_trade_no</out_trade_no>
                        <total_fee>$total_fee</total_fee>
                        <spbill_create_ip>$spbill_create_ip</spbill_create_ip>
                        <notify_url>$notify_url</notify_url>
                        <trade_type>$trade_type</trade_type>
                        <scene_info>$scene_info</scene_info>
                        <attach>$out_trade_no</attach>
                        <nonce_str>$nonce_str</nonce_str>
                        <sign>$sign</sign>
                </xml>";//拼接成XML 格式
    $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";//微信传参地址
    $dataxml = postXmlCurl($post_data,$url); //后台POST微信传参地址  同时取得微信返回的参数 
    $objectxml = (array)simplexml_load_string($dataxml, 'SimpleXMLElement', LIBXML_NOCDATA); //将微信返回的XML 转换成数组
    function createNoncestr( $length = 32 ){
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
        $str ="";
        for ( $i = 0; $i < $length; $i++ )  {
            $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
        }
        return $str;
    }
    function postXmlCurl($xml,$url,$second = 30){
        $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        curl_setopt($ch,CURLOPT_URL, $url);
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
        //设置header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        //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);
            echo "curl出错,错误码:$error"."<br>";
        }
    }
    function get_client_ip($type = 0) {
        $type       =  $type ? 1 : 0;
        $ip         =   'unknown';
        if ($ip !== 'unknown') return $ip[$type];
        if($_SERVER['HTTP_X_REAL_IP']){//nginx 代理模式下,获取客户端真实IP
            $ip=$_SERVER['HTTP_X_REAL_IP'];
        }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {//客户端的ip
            $ip     =   $_SERVER['HTTP_CLIENT_IP'];
        }elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {//浏览当前页面的用户计算机的网关
            $arr    =   explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
            $pos    =   array_search('unknown',$arr);
            if(false !== $pos) unset($arr[$pos]);
            $ip     =   trim($arr[0]);
        }elseif (isset($_SERVER['REMOTE_ADDR'])) {
            $ip     =   $_SERVER['REMOTE_ADDR'];//浏览当前页面的用户计算机的ip地址
        }else{
            $ip=$_SERVER['REMOTE_ADDR'];
        }
        // IP地址合法验证
        $long = sprintf("%u",ip2long($ip));
        $ip   = $long ? array($ip, $long) : array('0.0.0.0', 0);
        return $ip[$type];
    }
    ?>

    HTML代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
     <meta charset="UTF-8">
     <title>微信支付</title>
     <style type="text/css">
     body{
     font-family: "Microsoft YaHei";
     }
     .pay-box{
     position: absolute;
     top: 50%;
     margin-top: -516px;
     left: 50%;
     margin-left: -320px;
     }
     .ico{
     width: 240px;
     height: 240px;
     border-radius: 120px;
     background: #3FB837;
     color: #fff;
     display: inline-block;
     font-size: 160px;
     line-height: 240px;
     }
     .txt{
     font-size: 42px;
     padding-top: 30px;
     color: #333;
     }
     .val{
     font-size: 80px;
     font-weight: bold;
     }
     .pay{
     width: 640px;
     height: 100px;
     margin-top: 100px;
     padding: 20px;
     border-radius: 10px;
     font-size:42px;
     color: #fff;
     background: #07BF05;
     border: 0px;
     text-align: center;
     }
     a{
     color: #fff;
     background: transparent !important;
     }
     </style>
    </head>
    <body>
     <div class="pay-box" style="text-align: center;">
     <div class="ico">
     ¥
     </div>
     <div class="txt">
     支付金额
     </div>
     <div class="val">
     ¥<span><?php echo $total_fee/100 ?></span> 
    <!-- 这里使用原生PHP echo输出需要支付的价格 -->
     </div>
     <a class="pay" href="<?php echo $objectxml['mweb_url'] ?>"><button class="pay">确认支付</button></a> 
    <!-- 这里点击调起微信支付页面 mweb_url  -->
     </div>
    </body>
    </html>

    以上为微信H5支付demo的全部代码,其中HTML部分中的mweb_url是为拉起微信支付收银台的中间页面,可通过访问该url来拉起微信客户端,完成支付,mweb_url的有效期为5分钟。

    回调部分

    因为微信支付相关回调代码基本一样,可参考PHP完成微信小程序在线支付功能一文中的回调代码,有什么问题可以联系我QQ或者评论留言。下文补充了同步回调

    如何使用

    标题说的就是单PHP文件完成微信支付,你可以把HTML代码写在PHP文件的后面,或者在HTML文件里面引入PHP文件,就可以使用了。


    2018年3月21日补充:

    根据公司需求,需要一个同步回调页面,微信的支付是没有同步回调的,去查微信支付文档

    正常流程用户支付完成后会返回至发起支付的页面,如需返回至指定页面,则可以在MWEB_URL后拼接上redirect_url参数,来指定回调页面。

    我昨天想着是在生成mweb_url参数之前去拼接,结果证明是我想太多了!只能怪老板让加班到8点,我到6点就走了 , 直接在生成之后加上回调页面,文档读来读去也是这个意思,看来以后读文档真的要认真了。

    PHP部分:

    需对redirect_url进行urlencode处理,将此部分代码加入到上面代码$post_dat之前就行。

    $returnUrl = "https://www.wechatpay.com.cn";
    $return_Url = urlencode($returnUrl);

    HTML部分:

    <a class="pay" href="<?php echo $objectxml['mweb_url'] ?>&redirect_url=<?php echo $returns_Url; ?>"><button class="pay">确认支付</button></a>

    通过统一下单接口获到的MWEB_URL= https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx20161110163838f231619da20804912345&package=1037687096

    则拼接后的地址为MWEB_URL= https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx20161110163838f231619da20804912345&package=1037687096&redirect_url=https%3A%2F%2Fwww.wechatpay.com.cn

    相关文档:

  • 相关阅读:
    普通的一个python脚本,hadoop进军的准备
    Python之数据类型讲解
    开始博客的理由
    【微机原理及应用】程序的分类
    【jvm】jvm学习第二篇。jvm运行机制
    【jvm】jvm学习第一篇。初识jvm
    【it公司】it公司简介-项目流程-研发小技巧
    【感悟】20岁的人生不应该停止奋斗。----------------努力努力再努力
    【书籍学习】史上最全的Java进阶书籍推荐
    【职业规划】3年工作经验的程序员应该具备的技能
  • 原文地址:https://www.cnblogs.com/whowhere/p/9264594.html
Copyright © 2011-2022 走看看