## 微信支付
### 说明
在开发网页、微信公众号H5页面的过程中,微信支付是常用的使用场景。使用wxpay微信支付插件,可以快速的对项目集成微信支付功能。
当然可以在不使用插件的情况下,自己开发微信支付功能。微信支付基于EasyWechat,参考开发地址:https://www.easywechat.com/docs/master/zh-CN/payment/index
>[info] 微信支付插件地址:http://www.eacoophp.com/appstore_plugin/wxpay
### 插件使用要求
~~~
1. 依赖于composer安装easywechat,命令行composer require overtrue/wechat:~4.0 -vvv
2. EacooPHP系统版本1.1.0+
3. 微信商户号配置信息
~~~
### 应用场景
1.微信公众号H5支付
2.微信扫码支付,常用于PC端
3.APP接口调起微信支付
### 实现过程
**1.后台配置支付信息**
![微信支付后台配置](https://box.kancloud.cn/7797d8110857b7f28db63ac74afdc7f3_2740x1578.jpg)
**2.在微信商户平台配置支付授权目录**
![](https://box.kancloud.cn/fef61c432b30684ddb2908680e505dff_2752x1520.jpg)
**3.在控制器中需要处理微信支付的地方添加代码,例如**
~~~
$total_fee=0.01;
$out_trade_no=订单号;
$body='测试支付';
$notify_url = 支付异步通知地址;
$openid = 微信OPENID;
$params = [
'money' => $total_fee,
'order_number' => $out_trade_no,
'body' => $body,
'notify_url' => $notify_url,
'openid' => $openid,
'trade_type' => 'JSAPI'
];
$result = hook('wxpay',$params,true);
return $result;
~~~
返回结果根据trade_type的参数而定,目前支持JSAPI,NATIVE,APP...
比如:trade_type参数为JSAPI,默认返回json字符串。用于WeixinJSBridge发起的支付方式。
**4.要确认主题或模版中启用了页面尾部钩子PageFooter。**
~~~
html代码:
{:hook('PageFooter')}
~~~
因为微信支付插件封装的js代码会在这个钩子中加载。
**5.在自己开发的js代码中调用封装的支付方法。**
~~~[js]
$.post(请求URL, data, function(result) {
jsWxpay(result);
})
~~~
**6.完成上面的工作就能调起微信支付框了。**
微信支付成功后,支付结果会异步发送到通知地址,就是第3步中设置的notify_url。通知接收方法接收到结果数据后就进行处理。
**7.异步通知处理**
直接上代码例子:
~~~
public function Notify()
{
$wxpay_class = get_plugin_class('wxpay');
if (!class_exists($wxpay_class)) {
//wxpay插件类不存在
echo 'fail';
exit;
}
$wxpay = new $wxpay_class;
$wxpay_app = $wxpay->initPayment();
$response = $wxpay_app->handlePaidNotify(function($message, $fail){
// 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单
$order = 查询订单($message['out_trade_no']);
if (!$order) { // 如果订单不存在
$fail('Order not exist.'); // 告诉微信,我已经处理完了,订单没找到,别再通知我了
}
// 如果订单存在
// 检查订单是否已经更新过支付状态
if ($order->paid_at) { // 假设订单字段“支付时间”不为空代表已经支付
return true; // 已经支付成功了就不再更新了
}
// 用户是否支付成功
if ($message['result_code'] === 'SUCCESS') {
// 不是已经支付状态则修改为已经支付状态
$order->paid_at = time(); // 更新支付时间为当前时间
$order->status = 'paid';
} else { // 用户支付失败
$order->status = 'paid_fail';
}
$order->save(); // 保存订单
return true; // 返回处理完成
});
return $response->send(); // return $response;
}
~~~
## 最后
插件中包含Demo,不过要自己改写,主要提供思路
- 前言
- 基础
- 安装
- 规范
- 数据库设计
- 命名规范
- 建议参考
- 架构
- 架构总览
- 目录结构
- 生命周期
- 入口文件
- 模块设计
- 插件设计
- 主题设计
- API设计
- 容器和依赖注入
- 验证器设计
- 钩子和行为设计
- 介绍
- 后台介绍
- 仪表盘
- 系统设置
- 系统设置
- 网站设置
- 前台导航菜单
- 后台导航菜单
- 配置管理
- 用户管理
- 权限管理
- 角色组
- 节点管理
- 附件管理
- 工具
- 扩展中心
- 模块
- 插件
- 主题
- 前台介绍
- API接口
- 模型层
- 定义
- 逻辑层
- 定义
- 逻辑初始化
- 服务层
- 定义
- 二次开发
- 模块开发
- 介绍
- 1.结构目录
- 2.install安装目录文件
- info.json
- options.php
- menus.php
- unstall.sql
- install.sql
- 3.安装模块
- 模块函数与全局函数
- 其他
- 插件开发
- 介绍
- 定义入口文件
- 1.结构目录
- 2.install安装目录文件
- info.json
- options.php
- menus.php
- install.sql
- unstall.sql
- 3.实现钩子方法
- 4.安装插件
- 开发使用
- 插件控制器Controller
- 插件模型Model
- 插件逻辑层Logic
- 开发总结
- 主题开发
- 介绍
- 结构目录
- install安装目录
- info.json
- 主题变量
- 模块主题化
- 插件主题化
- CSS、JS静态资源引入
- 创建模版文件
- API开发
- 通用组件
- wangeditor编辑器
- 上传
- 实战开发
- 控制器
- 验证器
- 接口
- 创建自定义模版
- 数据库操作
- 通过接口上传文件
- 构建器Builder(重要)
- 表单Form
- 设置页面标题
- 表单项(调用方式)
- 文本框text
- 隐藏域hidden
- 文本区textarea
- 时间选择器datetime
- 图片选择器picture
- 多图片选择器pictures
- 图片上传image
- 文件上传file
- wang编辑器wangeditor
- 百度富文本编辑器ueditor
- 选择项
- 添加标签栏Tab
- 自定义头部工具栏
- 表单提交处理
- 列表List
- 设置页面标题
- 添加标签栏Tab
- 高级查询
- 查询构造器
- 添加列表搜索功能
- 添加批量操作
- 自定义头部工具
- 顶部新增按钮
- 顶部批量启用
- 顶部批量禁用
- 排序Sort
- 表单验证
- 插件-Builder构建器
- 命令行
- 配置
- 扩展专题
- 轻松识别客户端信息User Agent
- 字符串
- 数组
- 钩子、插件、模块相关方法
- 时间
- 请求(request)
- 附件
- 用户信息
- 前台用户
- 后台用户
- 微信(wechat模块)
- 专题
- 插件专题
- 微信支付
- 支付宝(即时到账)
- 微信小程序专题
- 微信模块
- 日志
- 后台行为日志
- 框架日志
- 自定义日志
- 常见问题集
- 附录
- 配置参考
- 常量参考
- 变量参考
- 更新日志
- 升级指导
- 关于
- 进阶
- 分布式数据库
- 分布式缓存
- 负载均衡
- Redis
- 分库分表