PHP开发APP端微信支付功能

时间:2022-08-26 21:29:21

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

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

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

app支付流程

PHP开发APP端微信支付功能

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

中有详细的说明,这里不再赘述。

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//入口函数
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.两次签名,用的是不同的随机字符串。

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