浅析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 相关文章推荐
珊瑚虫IP库浅析
Feb 15 PHP
详解php的魔术方法__get()和__set()使用介绍
Sep 19 PHP
php中判断数组是一维,二维,还是多维的解决方法
May 04 PHP
使用php伪造referer的方法 利用referer防止图片盗链
Jan 20 PHP
php的webservice的wsdl的XML无法显示问题的解决方法
Mar 11 PHP
PHP获取文件夹内文件数的方法
Mar 12 PHP
php无法连接mysql数据库的正确解决方法
Jul 01 PHP
PHP 验证身份证是否合法的函数
Feb 09 PHP
浅谈php(codeigniter)安全性注意事项
Apr 06 PHP
PHP性能分析工具xhprof的安装使用与注意事项
Dec 19 PHP
php桥接模式应用案例分析
Oct 23 PHP
Laravel 框架控制器 Controller原理与用法实例分析
Apr 14 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模块memcached使用指南
2014/12/08 PHP
PHP自定义函数获取汉字首字母的方法
2016/12/01 PHP
PHP中大括号'{}'用法实例总结
2017/02/08 PHP
js获取url中的参数且参数为中文时通过js解码
2014/03/19 Javascript
node.js中的fs.fchmod方法使用说明
2014/12/16 Javascript
jQuery学习笔记之回调函数
2016/08/15 Javascript
Bootstrap Table 在指定列中添加下拉框控件并获取所选值
2017/07/31 Javascript
Vue.js实现实例搜索应用功能详细代码
2017/08/24 Javascript
nodejs读取并去重excel文件
2018/04/22 NodeJs
说说如何在Vue.js中实现数字输入组件的方法
2019/01/08 Javascript
记一次vue-webpack项目优化实践详解
2019/02/17 Javascript
jQuery高级编程之js对象、json与ajax用法实例分析
2019/11/01 jQuery
python调用新浪微博API项目实践
2014/07/28 Python
Python比较两个图片相似度的方法
2015/03/13 Python
python爬虫入门教程--快速理解HTTP协议(一)
2017/05/25 Python
python中is与双等于号“==”的区别示例详解
2017/11/21 Python
Python cookbook(数据结构与算法)实现对不原生支持比较操作的对象排序算法示例
2018/03/15 Python
Python cv2 图像自适应灰度直方图均衡化处理方法
2018/12/07 Python
Django框架封装外部函数示例
2019/05/28 Python
python创建与遍历List二维列表的方法
2019/08/16 Python
TensorFlow Saver:保存和读取模型参数.ckpt实例
2020/02/10 Python
把Anaconda中的环境导入到Pycharm里面的方法步骤
2020/10/30 Python
爱尔兰领先的在线体育用品零售商:theGAAstore
2018/04/16 全球购物
英国简约舒适女装品牌:Great Plains
2018/07/27 全球购物
定义一结构体变量,用其表示点坐标,并输入两点坐标,求两点之间的距离
2015/08/17 面试题
营销主管自我评价怎么写
2013/09/19 职场文书
小学数学国培感言
2014/03/10 职场文书
初中毕业典礼演讲稿
2014/09/09 职场文书
南京市纪委监察局整改方案
2014/09/16 职场文书
自主招生自荐信范文
2015/03/04 职场文书
少先队入队仪式主持词
2015/07/04 职场文书
音乐研修感悟
2015/11/18 职场文书
2019年消防宣传标语集锦
2019/11/21 职场文书
css3 实现文字闪烁效果的三种方式示例代码
2021/04/25 HTML / CSS
Java实战之用Swing实现通讯录管理系统
2021/06/13 Java/Android
Java使用Unsafe类的示例详解
2021/09/25 Java/Android