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.到现在整个微信扫码支付整个流程就完成了!

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

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

    ThinkPHP框架是比较多人用的,曾经做过的一个Thinkphp5整合微信扫码支付开发实例,分享出来大家一起学习 打开首页生成订单,并显示支付二维码 public function index() ...

  2. thinkphp.2 thinkphp5微信支付 微信公众号支付 thinkphp 微信扫码支付 thinkphp 微信企业付款5

    前面已经跑通了微信支付的流程,接下来吧微信支付和微信企业付款接入到thinkphp中,版本是3.2 把微信支付类.企业付款类整合到一起放到第三方类库,这里我把微信支付帮助类和企业付款类放到同一个文件了 ...

  3. MVC 微信扫码支付

    微信扫码支付有两种模式, 模式一和模式二, 两者具体的区别可参考官网文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4 微 ...

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

    .NET版 微信扫码支付,官方推荐使用[模式二] 一.微信扫码支付模式一: 1.回调页面:官方demo中example文件下的NativeNotifyPage.aspx 2.微信回调地址:http:/ ...

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

    一.SDK下载地址:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1,下载.NET C#版本: 二.微信相关设置:(微信扫码 ...

  6. Net MVC微信扫码支付

    微信扫码支付+Asp.Net MVC 这里的扫码支付指的是PC网站上面使用微信支付,也就是官方的模式二,网站是Asp.net MVC,整理如下. 一.准备工作 使用的微信API中的统一下单方法,关键的 ...

  7. 微信公众号支付|微信H5支付|微信扫码支付|小程序支付|APP微信支付解决方案总结

    最近负责的一些项目开发,都用到了微信支付(微信公众号支付.微信H5支付.微信扫码支付.APP微信支付).在开发的过程中,在调试支付的过程中,或多或少都遇到了一些问题,今天总结下,分享,留存. 先说注意 ...

  8. php微信扫码支付

    一 概述 扫码支付是商户系统按微信支付协议生成支付二维码,用户再用微信"扫一扫"完成支付的模式.该模式适用于PC网站支付.实体店单品或订单支付.媒体广告支付等场景.前几天公司需要做 ...

  9. ASP.NET Core Web 支付功能接入 微信-扫码支付篇

    这篇文章将介绍ASP.NET Core中使用 开源项目 Payment,实现接入微信-扫码支付及异步通知功能. 开发环境:Win 10 x64.VS2017 15.6.4..NET Core SDK ...

随机推荐

  1. 纯css实现打字效果

    概述 很早以前就在别人的博客上面看到打字动画了,觉得非常炫酷,以为是用js做的,找了半天也没找到js在哪里.今天看<css揭秘>,碰巧看到书上打字动画的实现了,而且是纯css实现的!我参考 ...

  2. win10+Theano+GPU

    1. cuda + cudnn 首先还是要先安装GPU库,具体和caffe安装中一样. 2. Theano 为防止下载速度慢,配置清华镜像 conda config --add channels ht ...

  3. Math、Random、System、BigInteger、Date、DateFormat、Calendar类,正则表达式_DAY14

    1:Math&大数据类四则运算 X abs(X x) double random()         产生随机数 double ceil(double a)   向上取整 double flo ...

  4. 测试驱动开发 - Test-Driven Development

    TDD 开发模式流程: 编写测试用例 -> 运行测试用例 –> 编写项目代码 -> 运行测试用例 -> 重构代码 优点: 1.TDD 开发中加入了回归测试,这样就确保了之前的功 ...

  5. unsigned/signed int/char类型表示的数值范围

    一个32位的signed int类型整数表示的范围:-2^31~2^31-1 一个32位的unsigned int类型整数表示的范围: 0~2^32-1 一个8位的signed char类型整数表示的 ...

  6. Linux安装codis

    codis用go语言开发的,安装前记得先安装go开发环境,Linux安装go语言开发包 前提条件:记得安装git,否则无法下载go语言开发包 1.建立一个go语言的工作目录创建目录:sudo mkdi ...

  7. OopMap介绍

    摘自:http://blog.csdn.net/woaigaolaoshi/article/details/51439227 在HotSpot中,对象的类型信息里有记录自己的OopMap,记录了在该类 ...

  8. 人人,金山西山居,腾讯互娱,微信,网易游戏offer及面经

    转自:http://www.itmian4.com/forum.php?mod=viewthread&tid=3985 首先感谢师兄在两年前发的贴([天道酬勤] 腾讯.百度.网易游戏.华为Of ...

  9. Tomcat学习总结(7)——Tomcat与Jetty比较

    Jetty 基本架构 Jetty目前的是一个比较被看好的 Servlet 引擎,它的架构比较简单,也是一个可扩展性和非常灵活的应用服务器. 它有一个基本数据模型,这个数据模型就是 Handler(处理 ...

  10. 【IT笔试面试题整理】删除无序链表中重复的节点

    [试题描述]定义一个函数,输入一个链表,删除无序链表中重复的节点 [参考代码] 方法一: Without a buffer, we can iterate with two pointers: &qu ...