浅析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 相关文章推荐
图象函数中的中文显示
Oct 09 PHP
php的access操作类
Apr 09 PHP
PHP 工厂模式使用方法
May 18 PHP
php中mysql模块部分功能的简单封装
Sep 30 PHP
避免Smarty与CSS语法冲突的方法
Mar 02 PHP
WordPress中用于获取及自定义头像图片的PHP脚本详解
Dec 17 PHP
php外部执行命令函数用法小结
Oct 11 PHP
PHP中list方法用法示例
Dec 01 PHP
PHP单例模式与工厂模式详解
Aug 29 PHP
PHP实现的最大正向匹配算法示例
Dec 19 PHP
tp5.1 实现setInc字段自动加1
Oct 18 PHP
Laravel 在views中加载公共页面的实现代码
Oct 22 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
php 移除数组重复元素的一点说明
2008/11/27 PHP
PHP开发中常用的三个表单验证函数使用小结
2010/03/03 PHP
将php数组输出html表格的方法
2014/02/24 PHP
php实现文本数据导入SQL SERVER
2015/05/17 PHP
PHP实现的蚂蚁爬杆路径算法代码
2015/12/03 PHP
PHP获取真实IP及IP模拟方法解析
2020/11/24 PHP
深入理解JavaScript系列(2) 揭秘命名函数表达式
2012/01/15 Javascript
JavaScript之Getters和Setters 平台支持等详细介绍
2012/12/07 Javascript
javascript实现跳转菜单的具体方法
2013/07/05 Javascript
jQuery对象的selector属性用法实例
2014/12/27 Javascript
AngularJS入门教程之表格实例详解
2016/07/27 Javascript
jquery easyui validatebox remote的使用详解
2016/11/09 Javascript
开源免费天气预报接口API及全国所有地区代码(国家气象局提供)
2016/12/26 Javascript
JavaScript实现同一个页面打开多张图片
2016/12/29 Javascript
jQuery实现获取隐藏div高度的方法示例
2017/02/09 Javascript
关于meta viewport中target-densitydpi属性详解(推荐)
2017/08/18 Javascript
vue里面v-bind和Props 利用props绑定动态数据的方法
2018/08/27 Javascript
用Object.prototype.toString.call(obj)检测对象类型原因分析
2018/10/11 Javascript
JS FormData对象使用方法实例详解
2020/02/12 Javascript
[01:12:40]DOTA2-DPC中国联赛 正赛 DLG vs XG BO3 第三场 1月25日
2021/03/11 DOTA
使用Django的模版来配合字符串翻译工作
2015/07/27 Python
Python实现简单多线程任务队列
2016/02/27 Python
Python 逐行分割大txt文件的方法
2017/10/10 Python
对Python中TKinter模块中的Label组件实例详解
2019/06/14 Python
Python ini文件常用操作方法解析
2020/04/26 Python
基于 HTML5 的 WebGL 3D 版俄罗斯方块的示例代码
2018/05/28 HTML / CSS
国际领先的学术出版商:Springer
2017/01/11 全球购物
雅诗兰黛香港官网:Estee Lauder香港
2017/09/26 全球购物
JDBC操作数据库的基本流程是什么
2014/10/28 面试题
机关办公室岗位职责
2014/04/16 职场文书
乡党政领导班子群众路线教育实践活动个人对照检查材料
2014/09/20 职场文书
演讲比赛主持词
2015/06/29 职场文书
六一文艺汇演主持词
2015/06/30 职场文书
聘任书的格式及模板
2019/10/28 职场文书
总结一下关于在Java8中使用stream流踩过的一些坑
2021/06/24 Java/Android
Vue组件更新数据v-model不生效的解决
2022/04/02 Vue.js