浅谈使用PHP开发微信支付的流程


Posted in PHP onOctober 04, 2015

下面以PHP语言为例,对微信支付的开发流程进行一下说明。

1.获取订单信息

2.根据订单信息和支付相关的账号生成sign,并且生成支付参数

3.将支付参数信息POST到微信服务器,获取返回信息

4.根据返回信息生成相应的支付代码(微信内部)或是支付二维码(非微信内),完成支付。

下面分步骤的讲一下:

1.微信支付中相关的必须的订单参数有三个,分别是:body(商品名或订单描述),out_trade_no(一般为订单号)和total_fee(订单金额,单位“分”,要注意单位问题),在不同的应用中,首先要做的就是获取订单中的相关信息,为支付参数生成做准备。

2.其他必须的支付参数有 appid(微信appid),mch_id(申请成功后告知),device_info(web端和微信端该参数都是统一的,为大写的”WEB“),trade_type(根据使用场景不同,该值也是不同的,微信外部为”NATIVE“,微信内部为”JSAPI“),nonce_str(32位随机字符串),spbill_create_ip(发起支付的终端IP,即服务器IP),notify_url(支付回调地址,微信服务器通知网站支付完成与否,修改订单状态),sign(签名),还有一个需要说明的地方,如果trade_type为JSAPI的话,openid为必填的参数。

签名算法是比较容易出错的地方,在于签名步骤繁琐,其实很关键的是,sign不参与签名

A:将1、2中提到的除sign外的参数赋值,放到一个数组array里面,按照字典顺序排序,其实就是键值按照A—Z的顺序进行排序。

B:将数组转换成字符串string,格式为 k1=v1&k2=v2&...kN=vN

C:在此string后加上KEY值(在微信支付商户后台用户自己设定的)现在string = k1=v1&k2=v2&...kN=vN&key=KEY。

D:string = md5(string)

E: sign = strtoupper(string)

至此,sign生成完毕。

将sign添加到array数组里面生成新的数组。将该数组转换为XML。至此,微信支付的参数准备工作完成。

3.将2中生成的XML,使用POST的方式发送请求到微信(https://api.mch.weixin.qq.com/pay/unifiedorder),获取返回的XML信息,将该信息转换成数组格式方便操作。返回的XML信息如下:

<xml>
 <return_code><![CDATA[SUCCESS]]></return_code>
 <return_msg><![CDATA[OK]]></return_msg>
 <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
 <mch_id><![CDATA[10000100]]></mch_id>
 <nonce_str><![CDATA[IITRi8Iabbblz1Jc]]></nonce_str>
 <sign><![CDATA[7921E432F65EB8ED0CE9755F0E86D72F]]></sign>
 <result_code><![CDATA[SUCCESS]]></result_code>
 <prepay_id><![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id>
 <trade_type><![CDATA[JSAPI]]></trade_type>
</xml>

如果是trade_type==native支付的话,还会多一个参数code_url,该URL为微信扫码支付的地址。

4.下面就是支付的过程了。

如果trade_type==native,那么使用一些方式将code_url转换成二维码,使用微信扫码就可以了,如果是微信内部点击支付的话,需要调用微信js-sdk中的相关东西,这一步中最关键是生成一个json格式的字符串。

首先要生成转换json字符串的数组array_jsapi。

A:该数组的参数包括:appId,timeStamp,nonceStr,package,signType(默认为”MD5“),要注意大小写和上面的数组里面是不一样的。

B:使用该数组生成paySign参数,签名方式同上。

C:将paySign参数追加到array_jsapi数组中。

D:将该数组使用json_encode格式化为字符串js_string。

完成上面的工作,就可以在微信内部进行支付了。

下面为相关支付的示例代码:

<script type='text/javascript'>
         function jsApiCall()
     {
      WeixinJSBridge.invoke(
       'getBrandWCPayRequest',
       $js_string,
       function(res){
        WeixinJSBridge.log(res.err_msg);
         if(res.err_msg=='get_brand_wcpay_request:ok')
         {
          alert('支付成功');
         }
         else
         {
          alert('支付失败');
         }
       }
      );
     }
     function callpay()
     {
      if (typeof WeixinJSBridge == 'undefined'){
       if( document.addEventListener ){
        document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
       }else if (document.attachEvent){
        document.attachEvent('WeixinJSBridgeReady', jsApiCall); 
        document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
       }
      }else{
       jsApiCall();
      }
     }
    </script>

代码中js_string即为我们生成的字符串。

HTML代码中调用callpay()函数发起支付。

这样微信支付的支付工作就完成了。

下面是回调工作,该功能确保订单支付成功后,有正确的状态显示给用户。

支付完成后,微信使用POST请求,将支付结果反馈给网站服务器,网站服务器获取POST信息,根据支付成功与否,来确定是否修改订单信息。

A:将POST参数中的sign去除,并且记录下来该值。

B:对剩余的参数进行签名

C:将签名结果和POST中的sign进行比对,相同说明签名正确,根据支付结果修改订单状态。

E:返回XML信息给微信,确保微信知道网站已经收到该通知,避免微信再次推送POST,示例如下:

<xml>
 <return_code><![CDATA[SUCCESS]]></return_code>
 <return_msg><![CDATA[OK]]></return_msg>
</xml>

如果失败,则返回

<xml>
 <return_code><![CDATA[FAIL]]></return_code>
 <return_msg><![CDATA[失败原因]]></return_msg>
</xml>

至此,微信支付的整个开发介绍完毕。

PHP 相关文章推荐
centos 5.6 升级php到5.3的方法
May 14 PHP
PHP性能优化准备篇图解PEAR安装
Dec 05 PHP
PHP面向对象的进阶学习(抽像类、接口、final、类常量)
May 07 PHP
php利用单例模式实现日志处理类库
Feb 10 PHP
PHP利用func_get_args和func_num_args函数实现函数重载实例
Nov 12 PHP
php修改文件上传限制方法汇总
Apr 07 PHP
php正则替换处理HTML页面的方法
Jun 17 PHP
laravel学习教程之存取器
Jul 30 PHP
PHP实现针对日期,月数,天数,周数,小时,分,秒等的加减运算示例【基于strtotime】
Apr 19 PHP
PHP通过GD库实现验证码功能示例
Feb 23 PHP
PHP将整数数字转换为罗马数字实例分享
Mar 17 PHP
php使用lua+redis实现限流,计数器模式,令牌桶模式
Apr 04 PHP
8个必备的PHP功能开发
Oct 02 #PHP
PHP人民币金额转大写实例代码
Oct 02 #PHP
基于OpenCart 开发支付宝,财付通,微信支付参数错误问题
Oct 01 #PHP
php中preg_match的isU代表什么意思
Oct 01 #PHP
php 利用array_slice函数获取随机数组或前几条数据
Sep 30 #PHP
PHP去掉json字符串中的反斜杠\及去掉双引号前的反斜杠
Sep 30 #PHP
PHP表单提交后引号前自动加反斜杠的原因及三种办法关闭php魔术引号
Sep 30 #PHP
You might like
在任意字符集下正常显示网页的方法二(续)
2007/04/01 PHP
Js的MessageBox
2006/12/03 Javascript
利用Dojo和JSON建立无限级AJAX动态加载的功能模块树
2007/03/24 Javascript
一个用js实现的页内搜索代码
2007/05/23 Javascript
Mootools 1.2教程 输入过滤第一部分(数字)
2009/09/15 Javascript
jquery 多行滚动代码(附详细解释)
2010/06/17 Javascript
jQuery JSON实现无刷新三级联动实例探讨
2013/05/28 Javascript
jQuery select表单提交省市区城市三级联动核心代码
2014/06/09 Javascript
JavaScript基础篇(3)之Object、Function等引用类型
2015/11/30 Javascript
浅谈js内置对象Math的属性和方法(推荐)
2016/09/19 Javascript
解析如何利用iframe标签以及js制作时钟
2016/12/08 Javascript
Vue-resource实现ajax请求和跨域请求示例
2017/02/23 Javascript
Extjs 中的 Treepanel 实现菜单级联选中效果及实例代码
2017/08/22 Javascript
vue如何将v-for中的表格导出来
2018/05/07 Javascript
IE9 elementUI文件上传的问题解决
2018/10/17 Javascript
JS集合set类的实现与使用方法示例
2019/02/01 Javascript
arctext.js实现文字平滑弯曲弧形效果的插件
2019/05/13 Javascript
微信小程序之侧边栏滑动实现过程解析(附完整源码)
2019/08/23 Javascript
vue 中的动态传参和query传参操作
2020/11/09 Javascript
[15:58]DOTA2国际邀请赛采访专栏:Tongfu.Sansheng&KingJ,DK.rOtk
2013/08/08 DOTA
Python 抓取动态网页内容方案详解
2014/12/25 Python
Python中shapefile转换geojson的示例
2019/01/03 Python
Python类成员继承重写的实现
2020/09/16 Python
用CSS3实现无限循环的无缝滚动的实例代码
2017/07/04 HTML / CSS
使用 CSS3 中@media 实现网页自适应的示例代码
2020/03/24 HTML / CSS
英国空调、除湿机和通风设备排名第一:Air Con Centre
2019/02/25 全球购物
请说出以下代码输出什么
2013/08/30 面试题
部队领导证婚词
2014/01/12 职场文书
光信息科学与技术专业职业生涯规划
2014/03/13 职场文书
小学安全工作汇报材料
2014/08/19 职场文书
python中pandas.read_csv()函数的深入讲解
2021/03/29 Python
MySQL Router实现MySQL的读写分离的方法
2021/05/27 MySQL
使用Djongo模块在Django中使用MongoDB数据库
2021/06/20 Python
分析设计模式之模板方法Java实现
2021/06/23 Java/Android
python中filter,map,reduce的作用
2022/06/10 Python
python计算列表元素与乘积详情
2022/08/05 Python