浅析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 应用程序的安全 -- 不能违反的四条安全规则
Nov 26 PHP
采集邮箱的php代码(抓取网页中的邮箱地址)
Jul 17 PHP
PHP之生成GIF动画的实现方法
Jun 07 PHP
php.ini 配置文件的深入解析
Jun 17 PHP
php制作unicode解码工具(unicode编码转换器)代码分享
Dec 24 PHP
php基于socket实现SMTP发送邮件的方法
Mar 05 PHP
Symfony2联合查询实现方法
Mar 18 PHP
php数组分页实现方法
Apr 30 PHP
php 实现301重定向跳转实例代码
Jul 18 PHP
PHP未登录自动跳转到登录页面
Dec 21 PHP
PHP实现的防止跨站和xss攻击代码【来自阿里云】
Jan 29 PHP
PHP date()格式MySQL中插入datetime方法
Jan 29 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列出MySQL中所有数据库的方法
2015/03/12 PHP
PHP使用Redis长连接的方法详解
2018/02/12 PHP
Laravel如何实现自动加载类
2019/10/14 PHP
Apache+PHP+MySQL搭建PHP开发环境图文教程
2020/08/06 PHP
JavaScript 字符串处理函数使用小结
2010/12/02 Javascript
JavaScript对象之间的转换 jQuery对象和原声DOM
2011/03/07 Javascript
JS动态修改图片的URL(src)的方法
2015/04/01 Javascript
jQuery实现强制cookie过期方法汇总
2015/05/22 Javascript
jQuery+css实现的换页标签栏效果
2016/01/27 Javascript
jQuery制作网页版选项卡
2016/07/28 Javascript
微信小程序实战之自定义抽屉菜单(7)
2017/04/18 Javascript
Vue中正确使用jQuery的方法
2017/10/30 jQuery
vue组件开发之用户无限添加自定义填写表单的方法
2018/08/28 Javascript
vue中利用simplemde实现markdown编辑器(增加图片上传功能)
2019/04/29 Javascript
基于redis的小程序登录实现方法流程分析
2020/05/25 Javascript
[01:33:14]LGD vs VP Supermajor 败者组决赛 BO3 第二场 6.10
2018/07/04 DOTA
python获取豆瓣电影简介代码分享
2014/01/16 Python
Python实现合并字典的方法
2015/07/07 Python
rabbitmq(中间消息代理)在python中的使用详解
2017/12/14 Python
pandas数据预处理之dataframe的groupby操作方法
2018/04/13 Python
详解python的sorted函数对字典按key排序和按value排序
2018/08/10 Python
django连接mysql配置方法总结(推荐)
2018/08/18 Python
详解Ubuntu16.04安装Python3.7及其pip3并切换为默认版本
2019/02/25 Python
基于python实现高速视频传输程序
2019/05/05 Python
anaconda中更改python版本的方法步骤
2019/07/14 Python
python批量处理文件或文件夹
2020/07/28 Python
Python reshape的用法及多个二维数组合并为三维数组的实例
2020/02/07 Python
Mac PyCharm中的.gitignore 安装设置教程
2020/04/16 Python
Python调用.net动态库实现过程解析
2020/06/05 Python
利用HTML5+CSS3实现3D转换效果实例详解
2017/05/02 HTML / CSS
请用用Java代码写一个堆栈
2012/01/26 面试题
尊师重教演讲稿
2014/09/04 职场文书
预备党员考察意见范文
2015/06/01 职场文书
浅谈Python实现opencv之图片色素的数值运算和逻辑运算
2021/06/23 Python
Python中的嵌套循环详情
2022/03/23 Python
Python实现简单得递归下降Parser
2022/05/02 Python