最近公司项目需要接入微信支付购买道具,本人负责h5和微信公众号支付这一块。app支付由另一同事负责,在这里就不说了。

关于公众号支付,腾讯官方有提供demo。下载地址:官方Demo

吐嘈一下,官方Demo的好像有点问题,在WxPay.Api.php line 537 538这两个代码会导致错误码60

1
2
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验

修改为

1
2
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);

就好了

使用公众号支付时,需要先获取用户的openId(需要设置微信js接口安全域名/网页授权域名(在公众号设置-功能设置))。这个授权在官方给出的demo中使用的是静默授权

关于网页授权的两种scope的区别说明
1、以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)
2、以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。
3、用户管理类接口中的“获取用户基本信息接口”,是在用户和公众号产生消息交互或关注后事件推送后,才能根据用户OpenID来获取用户基本信息。这个接口,包括其他微信接口,都是需要该用户(即openid)关注了公众号后,才能调用成功的。

经过测试,静默授权跳转回到页面需要花费2秒左右。所以我使用ajax去请求授权

首先在业务页面获取code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
    error_reporting(E_ERROR);
    ini_set('date.timezone','Asia/Shanghai');
    header("Content-Type: text/html; charset=UTF-8");
    require_once "JsApiPay.php";   
     
    //是否是微信打开 h5和微信内是同一个网页,所以加上这个判断
    function is_weixin(){
        if ( strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false ) {
                return true;
        }   
        return false;
    }
    if(is_weixin()){
        $tools = new JsApiPay();
        //触发微信返回code码
        if (!isset($_GET['code'])){
            $baseUrl = urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].$_SERVER['QUERY_STRING']);
            $url = $tools->__CreateOauthUrlForCode($baseUrl);
            Header("Location: $url");
            exit();
        }                                
        //获取共享收货地址js函数参数
        $editAddress = $tools->GetEditAddressParameters();
    }
?>

前端ajax请求用户信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//显示loading 建议内容不超出六个汉字
function showLoading(msg){
    var $loadingToast = $('#loadingToast');
    if ($loadingToast.css('display') != 'none') return;
    $('.weui-toast__content').html(msg)
    $loadingToast.fadeIn(100);
}
function closeLoading()
{
    var $loadingToast = $('#loadingToast');
    $loadingToast.fadeOut(100);
}
//是否是微信打开
function is_weixin(){
    var ua = navigator.userAgent.toLowerCase();
    if(ua.match(/MicroMessenger/i)=="micromessenger") {
        return true;
     } else {
        return false;
    }
}
$(function(){
        var userInfo;
        if(is_weixin()){
            showLoading("获取授权中");//请求过程中显示一个loading
            var userInfo
            $.get('get_user_info.php?<?php echo $_SERVER['QUERY_STRING'] ?>', function(data, st){
                closeLoading();
                userInfo = JSON.parse(data);
                $('.page__title').html(userInfo.nick);
                $('.page__desc').html("UID:"+userInfo.uid);
                if(userInfo.uid == -1){           
                    $('.page__desc').html("UID:null");               
                    showMessage("您还未使用过当前微信号登陆过游戏,请确认");
                }
            });
        }else
        {
           userInfo = {"unionid":"0","nick":"未登录用户","uid":"-1","openId":"0"};
           $('.page__title').html(userInfo.nick);
           $('.page__desc').html("UID:"+userInfo.uid);
        }

get_user_info.php代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
    ini_set('date.timezone','Asia/Shanghai');
    header("Content-Type: text/html; charset=UTF-8");
    require_once "JsApiPay.php";
    //①、获取用户openid
    $tools = new JsApiPay();
    $openId = $tools->GetOpenid(); 
    $usInfo = $tools->GetUserInfo();
    $unionid = $usInfo["unionid"];  
    $ret_data = function()//跟后台确认用户信息<span>,建议后台用户标识使用开放平台的unionid,可以在平台绑定该公众号。
    //这样获取的用户信息就带有unionid字段了。而且公众平台和开放平台下其它应用是一致的unionid
    $nick = "尚未登录游戏";
    $uid = -1;
    if($ret_data->ret == 1){
       $nick = $ret_data->data->nick;
       $uid = $ret_data->data->uid;
    }
    //'{"ret":1,"data":'.$jsApiParameters.'}';
    echo '{"unionid":"'.$unionid.'","nick":"'.$nick.'","uid":"'.$uid.'","openId":"'.$openId.'"}';
?></span>

JsApiPay(Demo中的WxPay.JsApiPay.php)增加两个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/**
*
*   获取access_token
*
*/
private function GetAccessToken()
{
    $urlObj["grant_type"] = "client_credential";
    $urlObj["appid"] = WxPayConfig::APPID;
    $urlObj["secret"] = WxPayConfig::APPSECRET;
    $bizString = $this->ToUrlParams($urlObj);
    $url "https://api.weixin.qq.com/cgi-bin/token?".$bizString;
    //初始化curl
    $ch = curl_init();
    //设置超时
    curl_setopt($ch, CURLOPT_TIMEOUT, $this->curl_timeout);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,FALSE);
    curl_setopt($ch, CURLOPT_HEADER, FALSE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    if(WxPayConfig::CURL_PROXY_HOST != "0.0.0.0"
        && WxPayConfig::CURL_PROXY_PORT != 0){
        curl_setopt($ch,CURLOPT_PROXY, WxPayConfig::CURL_PROXY_HOST);
        curl_setopt($ch,CURLOPT_PROXYPORT, WxPayConfig::CURL_PROXY_PORT);
    }
    //运行curl,结果以jason形式返回
    $res = curl_exec($ch);
    curl_close($ch);
    //取出accessToken
    $data = json_decode($res,true);
    $accessToken = $data['access_token'];
    $this->accessToken = $accessToken;
    return $accessToken;
}
/**
*
*   获取用户信息
*
*/
public function GetUserInfo()
{
    $access_token = $this->GetAccessToken();
    $getData = $this->data;
    $urlObj["access_token"] = $access_token;//$getData["access_token"];//this->GetAccessToken();
    $urlObj["openid"] = $getData["openid"];
    $urlObj["lang"] = "zh_CN";
    $bizString = $this->ToUrlParams($urlObj);
    $url "https://api.weixin.qq.com/cgi-bin/user/info?".$bizString;
    //初始化curl
    $ch = curl_init();
    //设置超时
    curl_setopt($ch, CURLOPT_TIMEOUT, $this->curl_timeout);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,FALSE);
    curl_setopt($ch, CURLOPT_HEADER, FALSE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    if(WxPayConfig::CURL_PROXY_HOST != "0.0.0.0"
        && WxPayConfig::CURL_PROXY_PORT != 0){
        curl_setopt($ch,CURLOPT_PROXY, WxPayConfig::CURL_PROXY_HOST);
        curl_setopt($ch,CURLOPT_PROXYPORT, WxPayConfig::CURL_PROXY_PORT);
    }
    //运行curl,结果以jason形式返回
    $res = curl_exec($ch);
    curl_close($ch);
    //取出openid
    $userInfo = json_decode($res,true);
    $this->userInfo = $userInfo;
    return $userInfo;
}

效果如下:

下单付款:

这个官方给出的Demo有,就不多说了。

以下为微信内和h5页面的对比:

再来说说h5的微信支付,其它和微信内的支付差不了多少。对比图如下:

点击立即付款按钮时动作分别是

微信内

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
var PayApiArgs;
//调用微信JS api 支付
function jsApiCall()
{
    WeixinJSBridge.invoke(
        'getBrandWCPayRequest',
        PayApiArgs,
        function(res){
            WeixinJSBridge.log(res.err_msg);
            if(res.err_msg == "get_brand_wcpay_request:cancel")
            {
                showMessage("用户取消支付");
            }else if(res.err_msg == "get_brand_wcpay_request:ok")
            {
                showMessage("支付成功", function()
                {
                    WeixinJSBridge.call('closeWindow');
                });
            }else if(res.err_msg == "get_brand_wcpay_request:fail")
            {
                showMessage("支付失败", function(){
                    writeLog("err_code:"+res.err_code+",err_desc:"+res.err_desc+", err_msg:"+res.err_msg, 1);
                });
            }
        }
    );
}
                    $.get('CreatOrder.php', function(data, status){
                        var dtatObj = JSON.parse(data);
                        if(dtatObj.ret == 1){
                            PayApiArgs = dtatObj.data;
                            callpay();
                        }else{
                            showMessage(dtatObj.msg)
                        }
                    });

h5页面

1
2
3
4
5
6
7
8
9
10
showLoading("创建订单中");
$.get('CreatOrder.php', function(data){
    closeLoading();
    var dtatObj = JSON.parse(data);
    if(dtatObj.ret == 1){        
        window.location.href=dtatObj.mweb_url;//跳转到中间页面自动拉起微信客户端
    }else{
        showMessage(dtatObj.msg)
    }
})

上面页面中使用的样式均为weui

原文地址

PHP 微信公众号和html5接入微信支付相关推荐

  1. 微信公众号一、接入微信并实现机器人自动回复功能

    一.说明 微信公众平台 https://mp.weixin.qq.com/cgi-bin/loginpage?t=wxm2-login&lang=zh_CN 测试平台 https://mp.w ...

  2. 微信公众号 - H5 网页接入微信支付(JSAPI)

    前言 假设您已经申请成为微信商户(认证)且各项配置弄好了,并且开通 JSAPI 支付等,只差代码(前端)编写. 如果你之前不了解,强烈建议 先看一遍如下标注的文档: [官方文档]网页客户端(H5),需 ...

  3. Java开发微信公众号(四)---微信服务器post消息体的接收及消息的处理

    在前几节文章中我们讲述了微信公众号环境的搭建.如何接入微信公众平台.以及微信服务器请求消息,响应消息,事件消息以及工具处理类的封装:接下来我们重点说一下-微信服务器post消息体的接收及消息的处理,这 ...

  4. 小程序 php wecahtpay,PHP 微信公众号,小程序获取支付参数。微信支付

    PHP 微信公众号,小程序获取支付参数.微信支付 发布时间:2018-09-26 11:19, 浏览次数:278 , 标签: PHP 首先下载微信官方demo放入项目中 地址:https://gith ...

  5. 微信公众号数据2019_历史微信公众号排名,微信公众号新榜排名

    历史微信公众号排名,微信公众号新榜排名 公众号排名优化的注意事项及细节今天给大家分享一下,作为微信公众号的排名优化对于大多数人来说都已经知道了有这个渠道的事情,其实很多的新产品及渠道出来以后有不少的人 ...

  6. php公众号提现功能,微信公众号打赏的钱怎么提现_微信公众号打赏功能_微信公众号打赏从哪里取出来...

    微信公众号打赏的钱怎么提现,微信公众号打赏功能.微信公众号之前打赏功能可以立即取现,但是最近出现了一些变动,会有人问微信公众号打赏为什么不能立刻取现?小编为大家带来了微信公众号打赏取现时间调整. 微信 ...

  7. 微信公众号H5页面开发--微信JS-SDK引用

    微信公众号H5页面开发–微信JS-SDK引用 微信提供了微信公众号开发者手册,官方地址:https://mp.weixin.qq.com/ 公众号内许多复杂的业务场景,都是通过网页形式来提供服务,这时 ...

  8. 如何开发微信公众号以及如何运营微信公众号

    微信公众号已经成为了企业.个人和组织进行品牌推广.宣传和营销的重要平台.但是,如何开发和运营微信公众号并不是一件容易的事情.本文将从以下几个方面来介绍如何开发和运营微信公众号. 一.微信公众号的开发 ...

  9. 微信公众号开发者自动回复php,微信公众平台开发者模式的启用并自动回复

    这篇文章介绍的内容是关于微信公众平台开发者模式的启用并自动回复,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 首先,什么是开发者模式? 开发者模式,就是先验证你的服务器地址,验证完成之 ...

  10. 微信公众号配置后台接入

    微信公众号服务器配置启用,如果接入controller未配置requestmappint则可不填最末尾的"/",若配置requestmapping则填方法名 配置微信公众号回调地址 ...

最新文章

  1. 腾讯斥资3.17亿美元增持B站 持股增至12%
  2. 成都网络推广告诉大家网站抓取量要如何解决?
  3. hdu 1404/zoj 2725 Digital Deletions 博弈论
  4. 数学之美 系列十六 (下)- 不要把所有的鸡蛋放在一个篮子里 最大熵模型...
  5. [转]你所不知的 CSS ::before 和 ::after 伪元素用法
  6. windows之tracert与linux之traceroute用法详解
  7. 打印菱形(Java)
  8. mysql base64 图片php_php实现图片以base64显示的方法
  9. .NET团队送给.NET开发人员的云原生学习资源
  10. hive kerberos java_Kerberos身份验证错误 - Sqoop通过Hive从SQL导入HDFS
  11. elasticsearch 学习须知
  12. 开发时浏览器缓存问题
  13. 安全基础教育第二季第1集:屡战屡败的找回密码
  14. git切换到旧版本_git如何更新到指定版本,然后再更新到最新版本
  15. PDF文档的页面方向旋转后如何保存?
  16. window.print() 实现A4纸张打图片分页,解决预览首页空白页、打印多出一张空白页问题
  17. 如何使用JMX_Expoter+Prometheus+Grafana监控Hadoop集群
  18. 介绍几个ipad的使用技巧
  19. Onvif OSD相关操作
  20. 运筹学 知识点总结 (七)

热门文章

  1. python计算机器人运动学分析_orocos_kdl学习(二):KDL Tree与机器人运动学
  2. 大学计算机课程学习路线(左飞老师)
  3. WPF快速学习--一布局
  4. ubuntu编辑只读文件_Ubuntu linux vim 修改只读文件 修改Apache2端口号 ports.conf
  5. RDLC报表中使用自定义函数
  6. XMU毕业生总结写paper常用网站
  7. HTML 表单 (form) 的作用解释
  8. zznu 2054 : 油田
  9. 联想台式电脑修复计算机,处理联想一键恢复电脑系统教程
  10. 【VUE2开发20221004】-day1.1