ThinkPHP5微信扫码支付

1.把微信官网下载的demo放在根目录/vendor/目录下,这里我的是/vendor/wxpay_pc目录

2.把cert里面的文件替换成自己项目的证书(登陆微信商户平台,账户中心,API安全下载)

3.把/wxpay_pc/lib目录下的WxPay.Config.php文件里的信息改成自己的信息,只需改以下四个就行:

3.把example/目录下的notify.php改名为PayNotifyCallBack.php  不改也没事,我是为了和该文件里的类名保持一致

4.把里面require_once包含的文件都写成框架包含的形式,只要是用到的类里面的包含都改成框架包含的形式,如:

改成:注意,“ . ”用“ # ”表示,至于为什么,这里不是重点,你可以看看底层代码。

5.把native.php  里面的模式二的php代码拿出来,封装起来放到控制器里,把里面的信息补充上去

WX_LOG(‘wxpay‘,‘60‘,‘二维码加载完成‘); 这里的WX_LOG()方法是我自己写的打印日志的函数,放在common.php文件下,怎么写的可以看上一篇ThinkPHP5自己写日志 ,使用日志排错还是在下面回调异步通知的方法里还是很有用的,当初在这里我踩了不少坑,毕竟是后台异步,用日志记录比较直观

public function pay_pc()
    {

        error_reporting(E_ERROR);

        ini_set(‘date.timezone‘,‘Asia/Shanghai‘);
        vendor(‘wxpay_pc.lib.WxPay#Api‘);
        vendor(‘wxpay_pc.example.WxPay#NativePay‘);

        $notify = new \NativePay();

        $input = new \WxPayUnifiedOrder();
        // 必填项
        $out_trade_no = date(‘Ymd‘) . str_pad(mt_rand(1, 99999), 6, ‘0‘, STR_PAD_LEFT);;    //订单号

        $input->SetBody("蜜蜂云");    //商品名称
        $input->SetOut_trade_no($out_trade_no);    //订单号
        $input->SetTotal_fee("1");    //价格0.01 以分为单位1分
        $input->SetNotify_url(‘https://www.hulianweidu.com/index/wxpay/notify.html‘);  //异步回调通知地址
        $input->SetTrade_type("NATIVE");    //NATIVE 扫码支付
        $input->SetProduct_id("123456789");    //商品ID

        // 可填项
        $input->SetAttach("互联维度");    //附加数据
        $input->SetTime_start(date("YmdHis"));  //订单生成时间
        $input->SetTime_expire(date("YmdHis", time() + 600));  //订单失效时间
        $input->SetGoods_tag("PC网页支付");    //订单优惠标记

        $result = $notify->GetPayUrl($input);

        WX_LOG(‘wxpay‘,‘60‘,‘二维码加载完成‘);

        $url2 = urlencode($result["code_url"]);    //对url中文字字符编码
        $this->assign(‘url2‘,$url2);
        $this->assign(‘out_trade_no‘,$out_trade_no);
        return $this->fetch()
    }

需要注意的是$input->SetTotal_fee("1"); //价格0.01 以分为单位1分,我这里是为了方便测试,上线的时候别忘了乘以100,变成以元为单位

6.前端二维码:二维码$url2别忘了对中文字符编码,因为我在对应的方法里已经编码过了,所以在前端就没有再次编码操作。

<img alt="微信扫码支付" id="img" src="http://www.wxpay.com/example/qrcode.php?data={$url2}" style="width:150px;height:150px;"/>

7.现在二维码生成了,现在不出意外应该能支付成功了,一种方法是可以在商户平台查看交易信息,一种是自己写个方法,查看交易结果,因为这个方法下面会用到,还是推荐用这种。因为当用户进入二维码页面之后,我们需要用户支付成功之后给出相应的提示,并跳转下一页面,所以我们需要ajax轮询请求刚刚说的这个方法,3秒查询一次,去判断用户有没有支付,如果支付则进入下一步操作,如果没有支付则继续轮询,直到支付结果改变。

首先是前端代码:

<body>
    <input type="hidden" id="out_trade_no" value="{$out_trade_no}" >
    <img alt="微信扫码支付" id="img" src="http://www.wxpay.com/example/qrcode.php?data={$url2}" style="width:150px;height:150px;"/>

</body>
<script src="/public/index/index/vendor/bootstrap/jquery-3.2.1.min.js"></script>
<script type="text/javascript">

    var time = setInterval("check()",3000);    //3秒查询一次是否支付成功

    function check() {
        var url = "{:url(‘/index/Wxpay/orderstate‘)}";
        var out_trade_no = $("#out_trade_no").val();
        var param = {‘out_trade_no‘:out_trade_no};
        $.post(url,param,function(data){
            data = JSON.parse(data);
            if (data[‘trade_state‘] == ‘SUCCESS‘) {

                time = window.clearInterval(time);
                // 支付成功把二维码替换成支付成功图标
                $("#img").attr(‘src‘,‘/public/index/pay/images/success.png‘);
                console.log(data);
                // window.location.href="{:url(‘/index/wxpay/notify‘)}";
            }else{
                console.log(data);
            }
        });
    }
</script>

注意:别忘了在传二维码$url2的时候顺便把订单号也传过来,可以看上面的代码,并把订单号放在隐藏域,使用该订单号去查询该订单的支付结果

后端代码:

//订单查询结果
    public function orderstate()
    {
        error_reporting(E_ERROR);
        ini_set(‘date.timezone‘,‘Asia/Shanghai‘);
        vendor(‘wxpay_pc.lib.WxPay#Api‘);

        if(isset($_REQUEST["transaction_id"]) && $_REQUEST["transaction_id"] != ""){
            $transaction_id = $_REQUEST["transaction_id"];
            $input = new \WxPayOrderQuery();
            $input->SetTransaction_id($transaction_id);
            echo json_encode(\WxPayApi::orderQuery($input));
            exit();
        }

        if(isset($_REQUEST["out_trade_no"]) && $_REQUEST["out_trade_no"] != ""){
            $out_trade_no = $_REQUEST["out_trade_no"];
            $input = new \WxPayOrderQuery();
            $input->SetOut_trade_no($out_trade_no);
            echo json_encode(\WxPayApi::orderQuery($input));
            exit();
        }
    }

为扫码支付的时候显示

扫码支付成功后,trade_state会改为SECCESS,成功的时候就可以进行后面的操作了(更改通知信息,跳转页面)

8.支付成功后,微信服务器会异步返回你信息(xml格式数据),判断是否正确(包括签名),就是在最上面那段代码要填的异步通知地址,这个地址必须保证外网能访问,就是必须放在线上。关于异步回调当初可是坑了我不少啊!

关于异步通知的代码,其他不用改,就是把/example/PayNotifyCallBack.php(官网里notify.php)里的代码最后几行注释掉了,其他的没改:

<?php
ini_set(‘date.timezone‘,‘Asia/Shanghai‘);
error_reporting(E_ERROR);

vendor(‘wxpay_pc.lib.WxPay#Api‘);
vendor(‘wxpay_pc.lib.WxPay#Notify‘);
vendor(‘wxpay_pc.example.log‘);

//初始化日志
// $logHandler= new CLogFileHandler("../logs/".date(‘Y-m-d‘).‘.log‘);
// $log = Log::Init($logHandler, 15);

class PayNotifyCallBack extends WxPayNotify
{
    //查询订单
    public function Queryorder($transaction_id)
    {
        $input = new \WxPayOrderQuery();
        $input->SetTransaction_id($transaction_id);
        $result = \WxPayApi::orderQuery($input);
        // Log::DEBUG("query:" . json_encode($result));
        if(array_key_exists("return_code", $result)
            && array_key_exists("result_code", $result)
            && $result["return_code"] == "SUCCESS"
            && $result["result_code"] == "SUCCESS")
        {

            return true;
        }
        return false;
    }

    //重写回调处理函数  通知地址
    public function NotifyProcess($data, &$msg)
    {
        // Log::DEBUG("call back:" . json_encode($data));
        $notfiyOutput = array();

        if(!array_key_exists("transaction_id", $data)){
            $msg = "输入参数不正确";
            return false;
        }
        //查询订单,判断订单真实性
        if(!$this->Queryorder($data["transaction_id"])){
            $msg = "订单查询失败";
            return false;
        }

        return true;
    }
}

// Log::DEBUG("begin notify");
// $notify = new PayNotifyCallBack();
// $notify->Handle(false);

这是异步返回的数据:

只需判断 return_code 是否等于SUCCESS

然后就是异步回调通知这个方法了:

    // 回调页面
    public function notify() {

      // 是否接收到了返回的xml数据
      // $data = file_get_contents(‘php://input‘);
      // WX_LOG(‘wxpay‘,‘95‘,$data);

     error_reporting(E_ERROR);
        ini_set(‘date.timezone‘, ‘Asia/Shanghai‘);
        vendor(‘wxpay_pc.example.PayNotifyCallBack‘);

        $notify = new \PayNotifyCallBack();
        $notify->Handle(false);    

        $result = $notify->GetValues();    //数组
// ///////////////////更新支付状态//////////////
        if ($result[‘return_code‘] == ‘SUCCESS‘) {
            //订单支付完成,修改订单状态,发货。
            $res = Db::table(‘test‘)->insert([‘state‘=>1]);
            if ($res) {
                WX_LOG(‘wxpay‘,‘114‘,‘支付成功‘);
            }else{
                WX_LOG(‘wxpay‘,‘116‘,‘支付失败‘);
            }
        }
    }

操作数据库等逻辑,只需要在这个方法写就行了!

对于这个方法,因为是后台异步操作的,前端看不到,所以建议打印日志,看看微信服务器有没有给这个方法传数据,方便排错!

支付页面pay_pc,查询订单结果orderstate,异步回调notify,我都写在wxpay这个控制器里面了。

9.到现在整个微信扫码支付整个流程就完成了!

原文地址:https://www.cnblogs.com/zxf100/p/8794630.html

时间: 2024-10-29 10:46:38

ThinkPHP5微信扫码支付的相关文章

Thinkphp5整合微信扫码支付开发实例

ThinkPHP框架是比较多人用的,曾经做过的一个Thinkphp5整合微信扫码支付开发实例,分享出来大家一起学习 打开首页生成订单,并显示支付二维码 public function index() { $wechat = new Wechat(); $data['order'] = date('Ymd') . substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8); //订单号 $

C#微信扫码支付,回调页面

[C#]C# 微信扫码支付 回调页面 C# 微信扫码支付 回调页面 .NET版 微信扫码支付,官方推荐使用[模式二]一.微信扫码支付模式一:1.回调页面:官方demo中example文件下的NativeNotifyPage.aspx2.微信回调地址:http://域名/目录/NativeNotifyPage.aspx是在公众账号平台里面设置的,如下图 二.微信扫码支付模式二:1.回调页面:官方demo中example文件下的ResultNotifyPage.aspx2.微信回调地址:http:/

JAVA微信扫码支付模式二功能实现以及回调

一.准备工作 首先吐槽一下微信关于支付这块,本身支持的支付模式就好几种,但是官方文档特别零散,连像样的JAVA相关的demo也没几个.本人之前没有搞过微信支付,一开始真是被它搞晕,折腾两天终于调通了,特此写下来,以享后人吧! 关于准备工作,就"微信扫码支付模式二"官方文档地址在这 https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1 可以先看看,实际上需要准备的东西有以下几个: 其中APP_ID和APP_SECRET

ThinkPHP微信扫码支付接口

最近折腾微信扫码支付,看了微信官方文档,找了很多网页,发现和文档/demo不匹配,现在自己算是弄出来了(文件名称有所更改),贴出来分享一下 一.将有用的官方lib文件和使用的相关文件放置到vendor当中 二.调用同一支付接口 WechatController //调用同一支付接口public function native($v_oid='',$v_amount=''){ ini_set('date.timezone','Asia/Shanghai'); error_reporting(E_E

微信扫码支付官方配置

微信扫码支付官方API: https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1 .net C# SDK: https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1 介绍扫码支付模式一: 首先要配置:微信公众平台>微信支付>开发配置 支付授权目录:就是项目中存放官方SDK的运行路径.例如:http://www.xxxx.com/Wx/或者http://www.

C# 微信扫码支付API (微信扫码支付模式二)

一.SDK下载地址:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1,下载.NET C#版本: 二.微信相关设置:(微信扫码支付模式二) 1. 公众账号ID,公众账号secert ,地址:https://mp.weixin.qq.com/ 2. 商户号,商户支付密钥KEY,商户平台地址:https://pay.weixin.qq.com/ 5. 部署的服务器终端ip及回调页面 (1)部署的服务器终端ip:即程序部署所在的

C# 微信扫码支付 回调页面

.NET版 微信扫码支付,官方推荐使用[模式二] 一.微信扫码支付模式一: 1.回调页面:官方demo中example文件下的NativeNotifyPage.aspx 2.微信回调地址:http://域名/目录/NativeNotifyPage.aspx 是在公众账号平台里面设置的,如下图 二.微信扫码支付模式二: 1.回调页面:官方demo中example文件下的ResultNotifyPage.aspx 2.微信回调地址:http://域名/目录/NativeNotifyPage.aspx

Net MVC微信扫码支付

微信扫码支付+Asp.Net MVC 这里的扫码支付指的是PC网站上面使用微信支付,也就是官方的模式二,网站是Asp.net MVC,整理如下. 一.准备工作 使用的微信API中的统一下单方法,关键的参数是‘公众账号ID(appid)’,‘商户号(mch_id)’和’商户支付密钥(KEY)‘,所以首先要有一个审核过的公众号,并开通支付功能,然后申请商户,通过审核后得到商户号,也就是商户平台的登录名.商户支付密钥是用来签名的,确保url不被篡改.进入商户平台后在API安全中设置,是一个32位的字符

微信开发笔记:微信扫码支付详解

作为一个PC端的在线购物类网站,具备微信支付的功能自然是必须要有的,那么我们就来详细的看一下微信支付平台提供的微信扫码支付的使用流程: 首先你必须要有一个完成认证的服务号,申请开通微信支付功能,我们可以获得appid 和mch_id (也称为partnerid),之后就会是一个向微信支付平台提交一个支付请求来换取一个支付链接的过程: class wxpay{ function __construct(){ $this->wxpay(); } function wxpay(){ } /** * 生