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 相关文章推荐
PHP4实际应用经验篇(9)
Oct 09 PHP
PHP中使用localhost连接Mysql不成功的解决方法
Aug 20 PHP
浅析iis7.5安装配置php环境
May 10 PHP
php实现表单多按钮提交action的处理方法
Oct 24 PHP
PHP异常处理Exception类
Dec 11 PHP
PHP中的print_r 与 var_dump 输出数组
Jun 13 PHP
PHP巧妙利用位运算实现网站权限管理的方法
Mar 12 PHP
php表单习惯用的正则表达式
Oct 11 PHP
多个Laravel项目如何共用migrations详解
Sep 25 PHP
PHP Laravel中的Trait使用方法
Jan 20 PHP
php分享朋友圈的实现代码
Feb 18 PHP
Laravel jwt 多表(多用户端)验证隔离的实现
Dec 18 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服务器页面间跳转实现方法
2012/08/02 PHP
WordPress中用于获取及自定义头像图片的PHP脚本详解
2015/12/17 PHP
Prototype 学习 工具函数学习($A方法)
2009/07/12 Javascript
javascript 操作Word和Excel的实现代码
2009/10/26 Javascript
js模拟滚动条(横向竖向)
2013/02/22 Javascript
JavaScript动态加载样式表的方法
2015/03/21 Javascript
javascript跨域方法、原理以及出现问题解决方法(详解)
2015/08/06 Javascript
jQuery继承extend用法详解
2016/10/10 Javascript
浅谈Webpack打包优化技巧
2018/06/12 Javascript
Vue.js组件高级特性实例详解
2018/12/24 Javascript
Vue和React组件之间的传值方式详解
2019/01/31 Javascript
9102年webpack4搭建vue项目的方法步骤
2019/02/20 Javascript
详解一个小实例理解js原型和继承
2019/04/24 Javascript
RxJS的入门指引和初步应用
2019/06/15 Javascript
vue封装可复用组件confirm,并绑定在vue原型上的示例
2019/10/31 Javascript
怎么理解wx.navigateTo的events参数使用详情
2020/05/18 Javascript
Python中的包和模块实例
2014/11/22 Python
Python获取CPU、内存使用率以及网络使用状态代码
2018/02/08 Python
Python正则表达式和元字符详解
2018/11/29 Python
学习和使用python的13个理由
2019/07/30 Python
python批量处理文件或文件夹
2020/07/28 Python
python实现输出一个序列的所有子序列示例
2019/11/18 Python
Python numpy.zero() 初始化矩阵实例
2019/11/27 Python
Python中Subprocess的不同函数解析
2019/12/10 Python
django框架F&amp;Q 聚合与分组操作示例
2019/12/12 Python
如何使用python切换hosts文件
2020/04/29 Python
美国新娘礼品店:The Paisley Box
2020/09/08 全球购物
学校募捐倡议书
2014/05/14 职场文书
计算机网络及管理学专业求职信
2014/06/05 职场文书
松材线虫病防治方案
2014/06/15 职场文书
单位工作证明格式模板
2014/10/04 职场文书
校长师德表现自我评价
2015/03/04 职场文书
廉洁自律证明
2015/06/24 职场文书
CSS3 制作精美的定价表
2021/04/06 HTML / CSS
漫画「日和酱的要求是绝对的」第3卷封面公开
2022/03/21 日漫
CSS的calc函数用法小结
2022/06/25 HTML / CSS