浅谈使用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 相关文章推荐
在PHP3中实现SESSION的功能(一)
Oct 09 PHP
PHP登陆后跳转到登陆前页面实现思路及代码
Jan 17 PHP
PHP获取浏览器信息类和客户端地理位置的2个方法
Apr 24 PHP
使用CodeIgniter的类库做图片上传
Jun 12 PHP
PHP实现绘制3D扇形统计图及图片缩放实例
Oct 01 PHP
php5.3提示Function ereg() is deprecated Error问题解决方法
Nov 12 PHP
使用PHP接受文件并获得其后缀名的方法
Aug 05 PHP
PHP使用fopen与file_get_contents读取文件实例分享
Mar 04 PHP
Yii CDBCriteria常用方法实例小结
Jan 19 PHP
php使用ftp实现文件上传与下载功能
Jul 21 PHP
PHP的mysqli_set_charset()函数讲解
Jan 23 PHP
PHP 多进程与信号中断实现多任务常驻内存管理实例方法
Oct 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
Extended CHM PHP 语法手册之 DIY
2006/10/09 PHP
Ajax+PHP 边学边练之四 表单
2009/11/27 PHP
解析使用substr截取UTF-8中文字符串出现乱码的问题
2013/06/20 PHP
PHP提交表单失败后如何保留已经填写的信息
2014/06/20 PHP
php与flash as3 socket通信传送文件实现代码
2014/08/16 PHP
phpnow php探针环境检测代码
2014/11/04 PHP
PHP集成百度Ueditor 1.4.3
2014/11/23 PHP
详解PHP防止直接访问.php 文件的实现方法
2017/07/28 PHP
js 深拷贝函数
2008/12/04 Javascript
Jquery选择器中使用变量实现动态选择例子
2014/07/25 Javascript
引用其它js时如何同时处理多个window.onload事件
2014/09/02 Javascript
js与jQuery实现checkbox复选框全选/全不选的方法
2016/01/05 Javascript
jQuery组件easyui基本布局实现代码
2016/08/25 Javascript
纯js实现悬浮按钮组件
2016/12/17 Javascript
JS出现失效的情况总结
2017/01/20 Javascript
nodejs使用express创建一个简单web应用
2017/03/31 NodeJs
Vue组件之全局组件与局部组件的使用详解
2017/10/09 Javascript
vue+webpack实现异步加载三种用法示例详解
2018/04/24 Javascript
vue监听键盘事件的快捷方法【推荐】
2018/07/11 Javascript
vue 项目中使用Loading组件的示例代码
2018/08/31 Javascript
基于Vue2实现简易的省市区县三级联动组件效果
2018/11/05 Javascript
对layui中table组件工具栏的使用详解
2019/09/19 Javascript
Node.js Domain 模块实例详解
2020/03/18 Javascript
如何基于layui的laytpl实现数据绑定的示例代码
2020/04/10 Javascript
原生js 实现表单验证功能
2021/02/08 Javascript
[53:15]2018DOTA2亚洲邀请赛3月29日 小组赛A组 LGD VS TNC
2018/03/30 DOTA
浅谈python中np.array的shape( ,)与( ,1)的区别
2018/06/04 Python
Python实现html转换为pdf报告(生成pdf报告)功能示例
2019/05/04 Python
python调用并链接MATLAB脚本详解
2019/07/05 Python
如何让PyQt5中QWebEngineView与JavaScript交互
2020/10/21 Python
中国一家专注拼团的社交购物网站:拼多多
2018/06/13 全球购物
银行开户授权委托书格式
2014/10/10 职场文书
成本会计实训报告
2014/11/05 职场文书
社区党务工作总结2015
2015/05/19 职场文书
嵌入式Redis服务器在Spring Boot测试中的使用教程
2021/07/21 Redis
python热力图实现的完整实例
2022/06/25 Python