浅析PHP微信支付通知的处理方式


Posted in PHP onMay 25, 2014

通知机制的实现,官方只有文档没有demo代码,对没搞过的人来说,需要花大量时间来做测试。

从文档上说的来看,微信每次通知过来的数据,结构比较复杂,是一个多段数据,除了要取出POST数据外,还要取其它的数据。

这里首先涉及到一个关于php://input与$_POST取值的问题,简单列几点如下:

    1,Content- Type取值为application/x-www-form-urlencoded时,php会将http请求body相应数据会填入到数组$_POST,填入到$_POST数组中的数据是进行urldecode()解析的结果。(其实,除了该Content-Type,还有 multipart/form-data表示数据是表单数据,稍后我们介绍)
    2,php://input数据,只要Content-Type不为 multipart/form-data(该条件限制稍后会介绍)。那么php://input数据与http entity body部分数据是一致的。该部分相一致的数据的长度由Content-Length指定。
    3,仅当Content-Type为application/x-www-form-urlencoded且提交方法是POST方法时,$_POST数据与php://input数据才是”一致”(打上引号,表示它们格式不一致,内容一致)的。其它情况,它们都不一致。
    4,php://input读取不到$_GET数据。是因为$_GET数据作为query_path写在http请求头部(header)的PATH字段,而不是写在http请求的body部分。
    这也帮助我们理解了,为什么xml_rpc服务端读取数据都是通过file_get_contents(‘php://input', ‘r')。而不是从$_POST中读取,正是因为xml_rpc数据规格是xml,它的Content-Type是text/xml。
    5. php://input碰到了multipart/form-data,请查阅RFC1867对它的描述。multipart/form-data也表示以POST方法提交表单数据,它还伴随了文件上传,所以会跟application/x- www-form-urlencoded数据格式不一样。它会以一更种更合理的,更高效的数据格式传递给服务端。当Content-Type为multipart/form-data的时候,即便http请求body中存在数据,php://input也为空,PHP此时,不会把数据填入php://input流。所以,可以确定: php://input不能用于读取enctype=multipart/form-data数据。
    6. 当Content-Type为application/x- www-form-urlencoded时,php://input和$_POST数据是“一致”的,为其它Content-Type的时候,php: //input和$_POST数据数据是不一致的。因为只有在Content-Type为application/x-www-form- urlencoded或者为multipart/form-data的时候,PHP才会将http请求数据包中的body相应部分数据填入$_POST全局变量中,其它情况PHP都忽略。而php://input除了在数据类型为multipart/form-data之外为空外,其它情况都可能不为空

以上转述这么多文字的意思,就是说,得用到这两种方式来读取微信传过来的数据。

先取$POST 这是常规的支付通知信息,形如:

array (
  'bank_type' => '3006',
  'discount' => '0',
  'fee_type' => '1',
  'input_charset' => 'UTF-8',
  'notify_id' => 'YaNO6cznoNZK0aGb8nJWGgVUWssjt7Ze7gWRaRS0R_5w9oXgGNkRGxReEk0r45yk3I9a2_gzo9IqgqMYbap6bxC2T3p0o-2C',
  'out_trade_no' => '1214284731',
  'partner' => '12xxxxxxxx',
  'product_fee' => '3400',
  'sign' => '545FA0E8B594BBXXXX48XX142F084TY',
  'sign_type' => 'MD5',
  'time_end' => '20130223110224',
  'total_fee' => '3400',
  'trade_mode' => '1',
  'trade_state' => '0',
  'transaction_id' => '12XXX449012014XXX33174005XXX',
  'transport_fee' => '0',
)

再用file_get_contents('php://input')读取额外的信息,形如:

<xml><OpenId><![CDATA[o0pd3jqHaN7b0tVPDFJPzJEkSCLw]]></OpenId>
<AppId><![CDATA[wxXXX06XX2cXXX88XX]]></AppId>
<IsSubscribe>1</IsSubscribe>
<TimeStamp>1400814743</TimeStamp>
<NonceStr><![CDATA[lqxwMsiY9EXRDpms]]></NonceStr>
<AppSignature><![CDATA[c2dxxxe186116b32b06axxxc1a688b671eexxx5e]]></AppSignature>
<SignMethod><![CDATA[sha1]]></SignMethod>
</xml>

最后,做相应的业务逻辑处理,就不详述了。

PHP 相关文章推荐
php生成缩略图的类代码
Oct 02 PHP
php下HTTP Response中的Chunked编码实现方法
Nov 19 PHP
php在服务器执行exec命令失败的解决方法
Mar 03 PHP
基于Zookeeper的使用详解
May 02 PHP
浅析PHP中Collection 类的设计
Jun 21 PHP
ThinkPHP模板比较标签用法详解
Jun 30 PHP
PHP实现的一致性哈希算法完整实例
Nov 14 PHP
php四种定界符详解
Feb 16 PHP
php脚本守护进程原理与实现方法详解
Jul 20 PHP
PHP中TP5 上传文件的实例详解
Jul 31 PHP
PHP利用Mysql锁解决高并发的方法
Sep 04 PHP
Laravel如何创建服务器提供者实例代码
Apr 15 PHP
PHP开发微信支付的代码分享
May 25 #PHP
php定时计划任务与fsockopen持续进程实例
May 23 #PHP
PHP+Mysql+Ajax+JS实现省市区三级联动
May 23 #PHP
PHP解析html类库simple_html_dom的转码bug
May 22 #PHP
浅谈discuz密码加密的方式
May 22 #PHP
PHP函数strip_tags的一个bug浅析
May 22 #PHP
PHP学习笔记之字符串编码的转换和判断
May 22 #PHP
You might like
音乐朗读剧《MARS RED》2021年TV动画化决定!
2020/03/06 日漫
PHP数据库操作面向对象的优点
2006/10/09 PHP
Apache2 httpd.conf 中文版
2006/11/17 PHP
thinkPHP中钩子的两种配置调用方法详解
2016/11/11 PHP
PHP中大括号'{}'用法实例总结
2017/02/08 PHP
php ZipArchive实现多文件打包下载实例
2019/10/31 PHP
疯掉了,尽然有js写的操作系统
2007/04/23 Javascript
JavaScript高级程序设计 阅读笔记(四) ECMAScript中的类型转换
2012/02/27 Javascript
JS获取select的value和text值的简单实例
2014/02/26 Javascript
jQuery.prop() 使用详解
2015/07/19 Javascript
Angular.js回顾ng-app和ng-model使用技巧
2016/04/26 Javascript
浅谈jQuery添加的HTML,JS失效的问题
2016/10/05 Javascript
整理关于Bootstrap列表组的慕课笔记
2017/03/29 Javascript
详解基于 axios 的 Vue 项目 http 请求优化
2017/09/04 Javascript
jQuery中复合选择器简单用法示例
2018/03/31 jQuery
Vue Router的懒加载路径的解决方法
2018/06/21 Javascript
layui 监听表格复选框选中值的方法
2018/08/15 Javascript
一次Webpack配置文件的分离实战记录
2018/11/30 Javascript
Angular(5.2-&gt;6.1)升级小结
2018/12/27 Javascript
vue-cli2与vue-cli3在一台电脑共存的实现方法
2019/09/25 Javascript
Java Varargs 可变参数用法详解
2020/01/28 Javascript
js实现随机点名
2021/01/19 Javascript
[02:52]2017DOTA2国际邀请赛中国区预选赛晋级之路
2017/07/03 DOTA
批处理与python代码混合编程的方法
2016/05/19 Python
Python+selenium实现截图图片并保存截取的图片
2018/01/05 Python
Apache,wsgi,django 程序部署配置方法详解
2019/07/01 Python
OpenCV+face++实现实时人脸识别解锁功能
2019/08/28 Python
html5 跨文档消息传输示例探讨
2013/04/01 HTML / CSS
kfc实习自我鉴定
2013/12/14 职场文书
农贸市场管理制度
2014/01/31 职场文书
八项规定自查自纠报告及整改措施
2014/10/26 职场文书
工伤劳动仲裁代理词
2015/05/25 职场文书
CSS 实现多彩、智能的阴影效果
2021/05/12 HTML / CSS
Python 居然可以在 Excel 中画画你知道吗
2022/02/15 Python
Python实战之大鱼吃小鱼游戏的实现
2022/04/01 Python
详解SQL的窗口函数
2022/04/21 Oracle