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(3)
Oct 09 PHP
PHPwind整合最土系统用户同步登录实现方法
Dec 08 PHP
PHP统计目录下的文件总数及代码行数(去除注释及空行)
Jan 17 PHP
解析linux下安装memcacheq(mcq)全过程笔记
Jun 27 PHP
浅析PHP Socket技术
Aug 02 PHP
php实现从上传文件创建缩略图的方法
Apr 02 PHP
CodeIgniter与PHP5.6的兼容问题
Jul 16 PHP
php如何获取文件的扩展名
Oct 28 PHP
浅谈PHP正则中的捕获组与非捕获组
Jul 18 PHP
PHP中set_include_path()函数相关用法分析
Jul 18 PHP
php readfile()修改文件上传大小设置
Aug 11 PHP
PHP后门隐藏的一些技巧总结
Nov 04 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简单防盗链实现方法
2015/07/29 PHP
给PHP开发者的编程指南 第一部分降低复杂程度
2016/01/18 PHP
PHP集成环境XAMPP的安装与配置
2018/11/13 PHP
用一段js程序来实现动画功能
2007/03/06 Javascript
jquery利用event.which方法获取键盘输入值的代码
2011/10/09 Javascript
深入理解Javascript中的循环优化
2013/11/09 Javascript
JS二维数组的定义说明
2014/03/03 Javascript
js创建表单元素并使用submit进行提交
2014/08/14 Javascript
JS仿淘宝实现的简单滑动门效果代码
2015/10/14 Javascript
JS实现unicode和UTF-8之间的互相转换互转
2017/07/05 Javascript
Vue.js结合Ueditor富文本编辑器的实例代码
2017/07/11 Javascript
浅谈React + Webpack 构建打包优化
2018/01/23 Javascript
利用js实现前后台传送Json的示例代码
2018/03/29 Javascript
Vue开发环境中修改端口号的实现方法
2019/08/15 Javascript
vue.js this.$router.push获取不到params参数问题
2020/03/03 Javascript
[53:13]DOTA2-DPC中国联赛 正赛 DLG vs PHOENIX BO3 第三场 1月18日
2021/03/11 DOTA
python字符串,数值计算
2016/10/05 Python
Django验证码的生成与使用示例
2017/05/20 Python
基于pandas将类别属性转化为数值属性的方法
2018/07/25 Python
python pygame实现五子棋小游戏
2020/10/26 Python
django中瀑布流写法实例代码
2019/10/14 Python
python os.path.isfile 的使用误区详解
2019/11/29 Python
python模拟哔哩哔哩滑块登入验证的实现
2020/04/24 Python
css3实现超立体3D图片侧翻倾斜效果
2014/04/16 HTML / CSS
贝玲妃美国官方网站:Benefit美国
2016/08/28 全球购物
iRobot官网:改变生活的家用机器人品牌
2016/09/20 全球购物
会计毕业生自荐信
2013/11/21 职场文书
工作自荐信
2013/12/11 职场文书
学校采购员岗位职责
2014/01/02 职场文书
初二生物教学反思
2014/02/03 职场文书
安全生产管理合理化建议书
2014/03/12 职场文书
幼儿园大班家长评语
2014/04/17 职场文书
雷锋精神演讲稿
2014/05/13 职场文书
员工激励培训演讲稿
2014/09/16 职场文书
闪闪的红星观后感
2015/06/08 职场文书
动画《平凡职业成就世界最强》宣布制作OVA
2022/04/01 日漫