浅析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的ASP防火墙
Oct 09 PHP
html中select语句读取mysql表中内容
Oct 09 PHP
MYSQL环境变量设置方法
Jan 15 PHP
php读取数据库信息的几种方法
May 24 PHP
php discuz 主题表和回帖表的设计
Mar 13 PHP
php共享内存段示例分享
Jan 20 PHP
php获取指定日期之间的各个周和月的起止时间
Nov 24 PHP
ecshop后台编辑器替换成ueditor编辑器
Mar 03 PHP
启用Csrf后POST数据时出现的400错误
Jul 05 PHP
如何使用Gitblog和Markdown建自己的博客
Jul 31 PHP
php版微信公众号接口实现发红包的方法
Oct 14 PHP
php屏蔽错误及提示的方法
May 10 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修改时间格式的代码
2011/05/29 PHP
php通过sort()函数给数组排序的方法
2015/03/18 PHP
PHP实现的多文件上传类及用法示例
2016/05/06 PHP
mysql查找删除重复数据并只保留一条实例详解
2016/09/24 PHP
php四种定界符详解
2017/02/16 PHP
javascript之学会吝啬 精简代码
2010/04/25 Javascript
js拼接html注意问题示例探讨
2014/07/14 Javascript
JS或jQuery获取ASP.NET服务器控件ID的方法
2015/06/08 Javascript
jQuery实现简单弹窗遮罩效果
2017/02/27 Javascript
vue2.X组件学习心得(新手必看篇)
2017/07/05 Javascript
Kindeditor单独调用多图上传实例
2017/07/31 Javascript
实例详解Node.js 函数
2018/06/10 Javascript
微信小程序实现上传图片裁剪图片过程解析
2019/08/22 Javascript
ES6中Promise的使用方法实例总结
2020/02/18 Javascript
JS实现前端动态分页码代码实例
2020/06/02 Javascript
JavaScript实现网页动态生成表格
2020/11/25 Javascript
微信小程序学习之自定义滚动弹窗
2020/12/20 Javascript
tensorflow 用矩阵运算替换for循环 用tf.tile而不写for的方法
2018/07/27 Python
python 同时运行多个程序的实例
2019/01/07 Python
python使用requests模块实现爬取电影天堂最新电影信息
2019/04/03 Python
python实现弹跳小球
2019/05/13 Python
pytorch实现用Resnet提取特征并保存为txt文件的方法
2019/08/20 Python
Python 脚本拉取 Docker 镜像问题
2019/11/10 Python
编译 pycaffe时报错:fatal error: numpy/arrayobject.h没有那个文件或目录
2020/11/29 Python
Free People中国官网:波西米亚风格女装服饰
2016/08/30 全球购物
英国领先的鞋类零售商:Shoe Zone
2018/12/13 全球购物
大学生职业规划前言模板
2013/12/27 职场文书
拾金不昧的表扬信
2014/01/16 职场文书
财务出纳岗位职责
2014/02/03 职场文书
土建专业大学生自荐信范文
2014/04/09 职场文书
党员承诺书怎么写
2014/05/20 职场文书
授权委托书(公民个人适用)
2014/09/19 职场文书
2014年车间工作总结
2014/11/21 职场文书
大学军训口号大全
2015/12/24 职场文书
导游词之五台山
2019/10/11 职场文书
图片批量处理 - 尺寸、格式、水印等
2022/03/07 杂记