当前位置:首页 > PHP教程 > php高级应用 > 列表

PHP实现APP微信支付的实例讲解

发布:smiling 来源: PHP粉丝网  添加日期:2021-09-03 11:20:08 浏览: 评论:0 

下面小编就为大家分享一篇PHP实现APP微信支付的实例讲解,具有很好的参考价值,希望对大家有所帮助,一起跟随小编过来看看吧。

一、PHP后台后台生成预支付交易单,返回正确的预支付交易回话标识后再在APP里面调起支付!

官方文档:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1

根据文档拼接微信需要的参数,这里需要几个方法,直接上代码!

传输给微信的参数要组装成xml格式发送,传如参数数组!

  1. public function ToXml($data=array()) 
  2.  { 
  3.  if(!is_array($data) || count($data) <= 0) 
  4.  { 
  5.   return '数组异常'
  6.  } 
  7.  $xml = "<xml>"
  8.  foreach ($data as $key=>$val
  9.  { 
  10.   if (is_numeric($val)){ 
  11.   $xml.="<".$key.">".$val."</".$key.">"
  12.   }else
  13.   $xml.="<".$key."><![CDATA[".$val."]]></".$key.">"
  14.   } 
  15.  } 
  16.  $xml.="</xml>"
  17.  return $xml
  18.  } 

2.生成随机字符串,微信所需参数! 这里方法很多,看自己爱好都行!

  1. function rand_code(){ 
  2.  $str = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';//62个字符 
  3.  $str = str_shuffle($str); 
  4.  $str = substr($str,0,32); 
  5.  return $str

3.这里是微信比较重要的一步了,这个方法会多次用到!生成签名

  1. private function getSign($params) { 
  2.  ksort($params); //将参数数组按照参数名ASCII码从小到大排序 
  3.  foreach ($params as $key => $item) { 
  4.   if (!emptyempty($item)) {  //剔除参数值为空的参数 
  5.   $newArr[] = $key.'='.$item// 整合新的参数数组 
  6.   } 
  7.  } 
  8.  $stringA = implode("&"$newArr);  //使用 & 符号连接参数 
  9.  $stringSignTemp = $stringA."&key="."************************"//拼接key 
  10.  // key是在商户平台API安全里自己设置的 
  11.  $stringSignTemp = MD5($stringSignTemp); //将字符串进行MD5加密 
  12.  $sign = strtoupper($stringSignTemp); //将所有字符转换为大写 
  13.  return $sign
  14.  } 

4.传递参数给微信,生成预支付订单! 接收微信返回的数据,在反给APP端,APP端调用支付接口,完成支付 ! APP端所需参数见微信文档:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12&index=2

  1. public function wx_pay() { 
  2.  $nonce_str = $this->rand_code(); //调用随机字符串生成方法获取随机字符串 
  3.  $data['appid'] ='wxdbc5dc*******'//appid 
  4.  $data['mch_id'] = '1493*****' ; //商户号 
  5.  $data['body'] = "APP支付测试"
  6.  $data['spbill_create_ip'] = $_SERVER['HTTP_HOST']; //ip地址 
  7.  $data['total_fee'] = 1;    //金额 
  8.  $data['out_trade_no'] = time().mt_rand(10000,99999); //商户订单号,不能重复 
  9.  $data['nonce_str'] = $nonce_str;   //随机字符串 
  10.  $data['notify_url'] = 'http://xxx.xxx.com/wx_notify'; //回调地址,用户接收支付后的通知,必须为能直接访问的网址,不能跟参数 
  11.  $data['trade_type'] = 'APP'//支付方式 
  12.  //将参与签名的数据保存到数组 注意:以上几个参数是追加到$data中的,$data中应该同时包含开发文档中要求必填的剔除sign以外的所有数据 
  13.  $data['sign'] = $this->getSign($data); //获取签名 
  14.  $xml = $this->ToXml($data);  //数组转xml 
  15.  //curl 传递给微信方 
  16.  $url = "https://api.mch.weixin.qq.com/pay/unifiedorder"
  17.  //header("Content-type:text/xml"); 
  18.  $ch = curl_init(); 
  19.  curl_setopt($ch,CURLOPT_URL, $url); 
  20.  if(stripos($url,"https://")!==FALSE){ 
  21.   curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); 
  22.   curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
  23.   curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); 
  24.  } else { 
  25.   curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE); 
  26.   curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验 
  27.  } 
  28.  //设置header 
  29.  curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); 
  30.  curl_setopt($ch, CURLOPT_HEADER, FALSE); 
  31.  //要求结果为字符串且输出到屏幕上 
  32.  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 
  33.  //设置超时 
  34.  curl_setopt($ch, CURLOPT_TIMEOUT, 30); 
  35.  curl_setopt($ch, CURLOPT_POST, TRUE); 
  36.  //传输文件 
  37.  curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); 
  38.  //运行curl 
  39.  $data = curl_exec($ch); 
  40.  //返回结果 
  41.  if($data){ 
  42.   curl_close($ch); 
  43.   //返回成功,将xml数据转换为数组. 
  44.   $re = $this->FromXml($data); 
  45.   if($re['return_code'] != 'SUCCESS'){ 
  46.   json("201",'签名失败'); 
  47.   } 
  48.   else
  49.   //接收微信返回的数据,传给APP! 
  50.   $arr =array
  51.    'prepayid' =>$re['prepay_id'], 
  52.    'appid' => 'wxdbc5dc*****'
  53.    'partnerid' => '14937****'
  54.    'package' => 'Sign=WXPay'
  55.    'noncestr' => $nonce_str
  56.    'timestamp' =>time(), 
  57.   ); 
  58.   //第二次生成签名 
  59.   $sign = $this->getSign($arr); 
  60.   $arr['sign'] = $sign
  61.   json('200','签名成功',$arr); 
  62.   } 
  63.  } else { 
  64.   $error = curl_errno($ch); 
  65.   curl_close($ch); 
  66.   json('201',"curl出错,错误码:$error"); 
  67.  } 
  68.  } 

5.将xml数据转换为数组,接收微信返回数据时用到.

  1. public function FromXml($xml
  2.  { 
  3.  if(!$xml){ 
  4.   echo "xml数据异常!"
  5.  } 
  6.  //将XML转为array 
  7.  //禁止引用外部xml实体 
  8.  libxml_disable_entity_loader(true); 
  9.  $data = json_decode(json_encode(simplexml_load_string($xml'SimpleXMLElement', LIBXML_NOCDATA)), true); 
  10.  return $data
  11.  } 

二、APP支付成功后,会调用你填写的回调地址.

返回参数详见微信文档:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_7&index=3

  1. // 微信支付回调 
  2.  function wx_notify(){ 
  3.   //接收微信返回的数据数据,返回的xml格式 
  4.   $xmlData = file_get_contents('php://input'); 
  5.   //将xml格式转换为数组 
  6.   $data = $this->FromXml($xmlData); 
  7.   //用日志记录检查数据是否接受成功,验证成功一次之后,可删除。 
  8.   $file = fopen('./log.txt''a+'); 
  9.   fwrite($file,var_export($data,true)); 
  10.   //为了防止假数据,验证签名是否和返回的一样。 
  11.   //记录一下,返回回来的签名,生成签名的时候,必须剔除sign字段。 
  12.   $sign = $data['sign']; 
  13.   unset($data['sign']); 
  14.   if($sign == $this->getSign($data)){ 
  15.   //签名验证成功后,判断返回微信返回的 
  16.   if ($data['result_code'] == 'SUCCESS') { 
  17.   //根据返回的订单号做业务逻辑 
  18.   $arr = array
  19.    'pay_status' => 1, 
  20.    ); 
  21.   $re = M('order')->where(['order_sn'=>$data['out_trade_no']])->save($arr); 
  22.   //处理完成之后,告诉微信成功结果! 
  23.   if($re){ 
  24.    echo '<xml> 
  25.   <return_code><![CDATA[SUCCESS]]></return_code> 
  26.   <return_msg><![CDATA[OK]]></return_msg> 
  27.   </xml>';exit(); 
  28.   } 
  29.   } 
  30.   //支付失败,输出错误信息 
  31.   else
  32.   $file = fopen('./log.txt''a+'); 
  33.   fwrite($file,"错误信息:".$data['return_msg'].date("Y-m-d H:i:s"),time()."\r\n");  
  34.   } 
  35.  } 
  36.  else
  37.   $file = fopen('./log.txt''a+'); 
  38.   fwrite($file,"错误信息:签名验证失败".date("Y-m-d H:i:s"),time()."\r\n");  
  39.   } 

在这里,微信APP支付流程就成功走完了!谢谢支持!

Tags: APP微信支付 PHP微信支付

分享到: