PHP开发APP端微信支付功能


Posted in PHP onFebruary 17, 2017

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

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

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

APP支付流程

PHP开发APP端微信支付功能

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

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

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

//入口函数
function weChatPay(){
   $json = array();
   //生成预支付交易单的必选参数:
   $newPara = array();
   //应用ID
   $newPara["appid"] = "wx2421b1c4370ec43b";
   //商户号
   $newPara["mch_id"] = "10000100";
   //设备号
   $newPara["device_info"] = "WEB";
   //随机字符串,这里推荐使用函数生成
   $newPara["nonce_str"] = "1add1a30ac87aa2db72f57a2375d8fec";
   //商品描述
   $newPara["body"] = "APP支付测试";
   //商户订单号,这里是商户自己的内部的订单号
   $newPara["out_trade_no"] = "1415659990";
   //总金额
   $newPara["total_fee"] = 1;
   //终端IP
   $newPara["spbill_create_ip"] = $_SERVER["REMOTE_ADDR"];
   //通知地址,注意,这里的url里面不要加参数
   $newPara["notify_url"] = "http://wxpay.wxutil.com/pub_v2/pay/notify.v2.php";
   //交易类型
   $newPara["trade_type"] = "APP";
   //第一次签名
   $newPara["sign"] = produceWeChatSign($newPara);
   //把数组转化成xml格式
   $xmlData = getWeChatXML($newPara);
   //利用PHP的CURL包,将数据传给微信统一下单接口,返回正常的prepay_id
   $get_data = sendPrePayCurl($xmlData);
   //返回的结果进行判断。
   if($get_data['return_code'] == "SUCCESS" && $get_data['result_code'] == "SUCCESS"){
    //根据微信支付返回的结果进行二次签名
    //二次签名所需的随机字符串
    $newPara["nonce_str"] = "5K8264ILTKCH16CQ2502SI8ZNMTM67VS";
    //二次签名所需的时间戳
    $newPara['timeStamp'] = time()."";
    //二次签名剩余参数的补充
    $secondSignArray = array(
     "appid"=>$newPara['appid'],
     "noncestr"=>$newPara['nonce_str'],
     "package"=>"Sign=WXPay",
     "prepayid"=>$get_data['prepay_id'],
     "partnerid"=>$newPara['mch_id'],
     "timestamp"=>$newPara['timeStamp'],
    );
    $json['datas'] = $secondSignArray;
    $json['ordersn'] = $newPara["out_trade_no"];
    $json['datas']['sign'] = weChatSecondSign($newPara,$get_data['prepay_id']);
    $json['message'] = "预支付完成";
    //预支付完成,在下方进行自己内部的业务逻辑
    /*****************************/
    return json_encode($json);
   }
   else{
    $json['message'] = $get_data['return_msg'];
   }
  }
  return json_encode($json);
 }

//第一次签名的函数produceWeChatSign
function produceWeChatSign($newPara){
  $stringA = self::getSignContent($newPara);
  $stringSignTemp=$stringA."&key=192006250b4c09247ec02edce69f6a2d";
  return strtoupper(MD5($stringSignTemp));
 }

//生成xml格式的函数
 public static function getWeChatXML($newPara){
  $xmlData = "<xml>";
  foreach ($newPara as $key => $value) {
   $xmlData = $xmlData."<".$key.">".$value."</".$key.">";
  }
  $xmlData = $xmlData."</xml>";
  return $xmlData;
 }

//通过curl发送数据给微信接口的函数
function sendPrePayCurl($xmlData) {
  $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
  $header[] = "Content-type: text/xml";
  $curl = curl_init();
  curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
  curl_setopt($curl, CURLOPT_URL, $url);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($curl, CURLOPT_POST, 1);
  curl_setopt($curl, CURLOPT_POSTFIELDS, $xmlData);
  $data = curl_exec($curl);
  if (curl_errno($curl)) {
   print curl_error($curl);
  }
  curl_close($curl);
  return self::XMLDataParse($data);

 }

//xml格式数据解析函数
 public static function XMLDataParse($data){
  $msg = array();
  $msg = (array)simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA);
  return $msg;
 }

//二次签名的函数
function weChatSecondSign($newPara,$prepay_id){
  $secondSignArray = array(
   "appid"=>$newPara['appid'],
   "noncestr"=>$newPara['nonce_str'],
   "package"=>"Sign=WXPay",
   "prepayid"=>$prepay_id,
   "partnerid"=>$newPara['mch_id'],
   "timestamp"=>$newPara['timeStamp'],
  );
  $stringA = self::getSignContent($secondSignArray);
  $stringSignTemp=$stringA."&key=192006250b4c09247ec02edce69f6a2d";
  return strtoupper(MD5($stringSignTemp));
 }

两个注意点:

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
PHP生成带有雪花背景的验证码
Oct 09 PHP
php 大数据量及海量数据处理算法总结
May 07 PHP
php判断上传的Excel文件中是否有图片及PHPExcel库认识
Jan 11 PHP
PHP捕获Fatal error错误的方法
Jun 11 PHP
PHP中error_log()函数的使用方法
Jan 20 PHP
PHP获取文件相对路径的方法
Feb 26 PHP
学习php设计模式 php实现适配器模式
Dec 07 PHP
学习php设计模式 php实现备忘录模式(Memento)
Dec 09 PHP
PHP Imagick完美实现图片裁切、生成缩略图、添加水印
Feb 22 PHP
Yii2增删改查之查询 where参数详细介绍
Aug 08 PHP
PHP explode()函数用法讲解
Feb 15 PHP
Linux下安装Memcached服务器和客户端与PHP使用示例
Apr 15 PHP
php+webSoket实现聊天室示例代码(附源码)
Feb 17 #PHP
PHP中检索字符串的方法分析【strstr与substr_count方法】
Feb 17 #PHP
PHP常用的三种设计模式
Feb 17 #PHP
轻松实现php文件上传功能
Feb 17 #PHP
php自定义函数br2nl实现将html中br换行符转换为文本输入中换行符的方法【与函数nl2br功能相反】
Feb 17 #PHP
php过滤输入操作之htmlentities与htmlspecialchars用法分析
Feb 17 #PHP
php使用parse_str实现查询字符串解析到变量中的方法
Feb 17 #PHP
You might like
用php和MySql来与ODBC数据连接
2006/10/09 PHP
PHP 文件上传进度条的两种实现方法的代码
2007/11/25 PHP
php中Smarty模板初体验
2011/08/08 PHP
PHP中spl_autoload_register函数的用法总结
2013/11/07 PHP
浅谈php优化需要注意的地方
2014/11/27 PHP
PHP实现网站访问量计数器
2017/10/27 PHP
PHP实现十进制数字与二十六进制字母串相互转换操作示例
2018/08/10 PHP
看了就知道什么是JSON
2007/12/09 Javascript
jQuery LigerUI 使用教程表格篇(1)
2012/01/18 Javascript
浅析Cookie中的Path与domain
2013/12/18 Javascript
再谈Jquery Ajax方法传递到action(补充)
2014/05/12 Javascript
函数式 JavaScript(一)简介
2014/07/07 Javascript
jquery中实现时间戳与日期相互转换
2016/04/12 Javascript
AngularJS 实现弹性盒子布局的方法
2016/08/30 Javascript
vue的一个分页组件的示例代码
2017/12/25 Javascript
Vue项目数据动态过滤实践及实现思路
2018/09/11 Javascript
js指定日期增加指定月份的实现方法
2018/12/19 Javascript
Vue项目前后端联调(使用proxyTable实现跨域方式)
2020/07/18 Javascript
Python中的并发编程实例
2014/07/07 Python
跟老齐学Python之用while来循环
2014/10/02 Python
使用Python压缩和解压缩zip文件的教程
2015/05/06 Python
python爬取w3shcool的JQuery课程并且保存到本地
2017/04/06 Python
Python最火、R极具潜力 2017机器学习调查报告
2017/12/11 Python
Python input函数使用实例解析
2019/11/22 Python
关于python中plt.hist参数的使用详解
2019/11/28 Python
深入浅析Python 函数注解与匿名函数
2020/02/24 Python
Django admin 实现search_fields精确查询实例
2020/03/30 Python
Python3爬虫中Ajax的用法
2020/07/10 Python
怎么解决pycharm license Acti的方法
2020/10/28 Python
python 实现全球IP归属地查询工具
2020/12/18 Python
Cotton On南非:澳洲时尚平价品牌
2018/06/28 全球购物
阿姆斯特丹杜莎夫人蜡像馆官方网站:Madame Tussauds Amsterdam
2019/03/12 全球购物
医院标语大全
2014/06/23 职场文书
办公室班子四风问题对照检查材料
2014/10/04 职场文书
浅析Django接口版本控制
2021/06/26 Python
Redis Lua脚本实现ip限流示例
2022/07/15 Redis