浅析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调用三种数据库的方法(1)
Oct 09 PHP
如何在PHP中使用Oracle数据库(4)
Oct 09 PHP
利用 window_onload 实现select默认选择
Oct 09 PHP
php 将excel导入mysql
Nov 09 PHP
Warning: session_destroy() : Trying to destroy uninitialized sessionq错误
Jun 16 PHP
如何使用PHP计算上一个月的今天
May 23 PHP
php获取参数的几种方法总结
Feb 18 PHP
讲解WordPress中用于获取评论模板和搜索表单的PHP函数
Dec 28 PHP
php解决和避免form表单重复提交的几种方法
Aug 31 PHP
SAE实时日志接口SDK用法示例
Oct 09 PHP
php PDO判断连接是否可用的实现方法
Apr 03 PHP
Laravel框架模型的创建及模型对数据操作示例
May 07 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
Ext grid 添加右击菜单
2009/11/26 Javascript
把jQuery的类、插件封装成seajs的模块的方法
2014/03/12 Javascript
JavaScript中匿名、命名函数的性能测试
2014/09/04 Javascript
JavaScript中的getDay()方法使用详解
2015/06/09 Javascript
jquery如何获取元素的滚动条高度等实现代码
2015/10/19 Javascript
jQuery多个版本和其他js库冲突的解决方法
2016/08/11 Javascript
浅谈javascript控制HTML5的全屏操控,浏览器兼容的问题
2016/10/10 Javascript
boostrapTable的refresh和refreshOptions区别浅析
2017/01/22 Javascript
vue如何引用其他组件(css和js)
2017/04/13 Javascript
nodejs入门教程一:概念与用法简介
2017/04/24 NodeJs
解决ztree搜索中多级菜单展示不全问题
2017/07/05 Javascript
什么是Vue.js框架 为什么选择它?
2017/10/17 Javascript
ReactNative之FlatList的具体使用方法
2017/11/29 Javascript
Vue工程模板文件 webpack打包配置方法
2017/12/26 Javascript
Javascript将图片的绝对路径转换为base64编码的方法
2018/01/11 Javascript
Layui数据表格之获取表格中所有的数据方法
2018/08/20 Javascript
[03:17]2014DOTA2 国际邀请赛中国区预选赛 四强专访
2014/05/23 DOTA
跟老齐学Python之Python文档
2014/10/10 Python
Saltstack快速入门简单汇总
2016/03/01 Python
python中(str,list,tuple)基础知识汇总
2018/02/20 Python
Python+Pandas 获取数据库并加入DataFrame的实例
2018/07/25 Python
浅谈Python3中strip()、lstrip()、rstrip()用法详解
2019/04/29 Python
浅谈pandas.cut与pandas.qcut的使用方法及区别
2020/03/03 Python
Python实现多线程下载脚本的示例代码
2020/04/03 Python
CSS3 3D位移translate效果实例介绍
2016/05/03 HTML / CSS
CSS3旋转——彩色扇子兼容firefox浏览器
2013/06/04 HTML / CSS
html5定位获取当前位置并在百度地图上显示
2014/08/22 HTML / CSS
周仰杰(JIMMY CHOO)法国官方网站:闻名世界的鞋子品牌
2019/09/27 全球购物
laravel使用redis队列实例讲解
2021/03/23 PHP
团工委书记自荐书范文
2013/12/17 职场文书
违纪检讨书2000字
2014/02/08 职场文书
优秀高中生事迹材料
2014/02/11 职场文书
预备党员期盼十八届四中全会召开思想汇报
2014/10/17 职场文书
五好家庭申报材料
2014/12/20 职场文书
2015年大学生村官工作总结
2015/04/21 职场文书
Java反应式框架Reactor中的Mono和Flux
2021/07/25 Java/Android