查看: 1675|回复: 0

[PHP实例] PHP开发APP端微信支付功能

发表于 2017-12-12 08:00:01

php开发APP端微信支付的一点个人心得

最近因为公司需求,要开发APP端上的微信支付,看了微信文档,感觉还不错,没有遇到太大的坑,需要注意的点不算太多。

写一个记事文档,作为备忘录。

APP支付流程

从上面的图片中,可以看出来,需要注意的流程是一共是3部分;
第一部分:调用下单API,返回预支付订单,签名之后再返回信息(4、5、6、7)
第二部分:异步通知(15、16)
第三部分:最后的判断支付结果
最需要注意的就是第一部分:调用下单API,返回预支付订单,签名之后再返回信息

微信文档中有详细的说明,这里不再赘述。

附录一下我的代码,伸手党,稍微改点代码就可以用了。

  1. //入口函数
  2. function weChatPay(){
  3. $json = array();
  4. //生成预支付交易单的必选参数:
  5. $newPara = array();
  6. //应用ID
  7. $newPara["appid"] = "wx2421b1c4370ec43b";
  8. //商户号
  9. $newPara["mch_id"] = "10000100";
  10. //设备号
  11. $newPara["device_info"] = "WEB";
  12. //随机字符串,这里推荐使用函数生成
  13. $newPara["nonce_str"] = "1add1a30ac87aa2db72f57a2375d8fec";
  14. //商品描述
  15. $newPara["body"] = "APP支付测试";
  16. //商户订单号,这里是商户自己的内部的订单号
  17. $newPara["out_trade_no"] = "1415659990";
  18. //总金额
  19. $newPara["total_fee"] = 1;
  20. //终端IP
  21. $newPara["spbill_create_ip"] = $_SERVER["REMOTE_ADDR"];
  22. //通知地址,注意,这里的url里面不要加参数
  23. $newPara["notify_url"] = "http://wxpay.wxutil.com/pub_v2/pay/notify.v2.php";
  24. //交易类型
  25. $newPara["trade_type"] = "APP";
  26. //第一次签名
  27. $newPara["sign"] = produceWeChatSign($newPara);
  28. //把数组转化成xml格式
  29. $xmlData = getWeChatXML($newPara);
  30. //利用PHP的CURL包,将数据传给微信统一下单接口,返回正常的prepay_id
  31. $get_data = sendPrePayCurl($xmlData);
  32. //返回的结果进行判断。
  33. if($get_data['return_code'] == "SUCCESS" && $get_data['result_code'] == "SUCCESS"){
  34. //根据微信支付返回的结果进行二次签名
  35. //二次签名所需的随机字符串
  36. $newPara["nonce_str"] = "5K8264ILTKCH16CQ2502SI8ZNMTM67VS";
  37. //二次签名所需的时间戳
  38. $newPara['timeStamp'] = time()."";
  39. //二次签名剩余参数的补充
  40. $secondSignArray = array(
  41. "appid"=>$newPara['appid'],
  42. "noncestr"=>$newPara['nonce_str'],
  43. "package"=>"Sign=WXPay",
  44. "prepayid"=>$get_data['prepay_id'],
  45. "partnerid"=>$newPara['mch_id'],
  46. "timestamp"=>$newPara['timeStamp'],
  47. );
  48. $json['datas'] = $secondSignArray;
  49. $json['ordersn'] = $newPara["out_trade_no"];
  50. $json['datas']['sign'] = weChatSecondSign($newPara,$get_data['prepay_id']);
  51. $json['message'] = "预支付完成";
  52. //预支付完成,在下方进行自己内部的业务逻辑
  53. /*****************************/
  54. return json_encode($json);
  55. }
  56. else{
  57. $json['message'] = $get_data['return_msg'];
  58. }
  59. }
  60. return json_encode($json);
  61. }
  62. //第一次签名的函数produceWeChatSign
  63. function produceWeChatSign($newPara){
  64. $stringA = self::getSignContent($newPara);
  65. $stringSignTemp=$stringA."&key=192006250b4c09247ec02edce69f6a2d";
  66. return strtoupper(MD5($stringSignTemp));
  67. }
  68. //生成xml格式的函数
  69. public static function getWeChatXML($newPara){
  70. $xmlData = "<xml>";
  71. foreach ($newPara as $key => $value) {
  72. $xmlData = $xmlData."<".$key.">".$value."</".$key.">";
  73. }
  74. $xmlData = $xmlData."</xml>";
  75. return $xmlData;
  76. }
  77. //通过curl发送数据给微信接口的函数
  78. function sendPrePayCurl($xmlData) {
  79. $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
  80. $header[] = "Content-type: text/xml";
  81. $curl = curl_init();
  82. curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
  83. curl_setopt($curl, CURLOPT_URL, $url);
  84. curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  85. curl_setopt($curl, CURLOPT_POST, 1);
  86. curl_setopt($curl, CURLOPT_POSTFIELDS, $xmlData);
  87. $data = curl_exec($curl);
  88. if (curl_errno($curl)) {
  89. print curl_error($curl);
  90. }
  91. curl_close($curl);
  92. return self::XMLDataParse($data);
  93. }
  94. //xml格式数据解析函数
  95. public static function XMLDataParse($data){
  96. $msg = array();
  97. $msg = (array)simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA);
  98. return $msg;
  99. }
  100. //二次签名的函数
  101. function weChatSecondSign($newPara,$prepay_id){
  102. $secondSignArray = array(
  103. "appid"=>$newPara['appid'],
  104. "noncestr"=>$newPara['nonce_str'],
  105. "package"=>"Sign=WXPay",
  106. "prepayid"=>$prepay_id,
  107. "partnerid"=>$newPara['mch_id'],
  108. "timestamp"=>$newPara['timeStamp'],
  109. );
  110. $stringA = self::getSignContent($secondSignArray);
  111. $stringSignTemp=$stringA."&key=192006250b4c09247ec02edce69f6a2d";
  112. return strtoupper(MD5($stringSignTemp));
  113. }
复制代码

两个注意点:

1.二次签名需要在后台完成,并且完成之后,连带着二次签名所用的所有信息一起传给前端,让前段唤起微信支付。这样不容易出现没法吊起微信支付的情况。
2.两次签名,用的是不同的随机字符串。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持程序员之家。



回复

使用道具 举报