微信APP支付服务端PHP完整代码

<?php

//微信APP支付 一定要先仔细阅读微信的官方文档,统一下单接口
// 调取微信APP支付必须先开通商户后台的微信APP支付
// 注意:开通微信APP支付会发邮件到你们邮箱,下面的商户号和appid还有key密钥,都必须是开通后的。说这些主要是提醒,有些商户是多个商户后台的,所以就有多个商户id和商户appid和商户key,必须匹配,不然获取不到预支付id,也就是prepay_id的。
// header("Content-type: text/xml");   // 支付出问题时,方便查看xml格式数据,放开可以查看传送的xml字符串    xml要用 echo输出 不要var_dump()

echo weChatPay('订单号','价格');  //直接输出json给前台APP

//入口函数
function weChatPay($order_num,$price){
   $json = array();
   //生成预支付交易单的必选参数:
   $newPara = array();
   //应用ID
   $newPara["appid"] = "商户appid";
   //商户号
   $newPara["mch_id"] = "商户id";
   //设备号
   $newPara["device_info"] = "WEB";
   //随机字符串,这里推荐使用函数生成
   $newPara["nonce_str"] = createNoncestr();
   //商品描述
   $newPara["body"] = "APP支付";
   //商户订单号,这里是商户自己的内部的订单号
   $newPara["out_trade_no"] = $order_num;
   //总金额
   $newPara["total_fee"] = $price*100;
   //终端IP
   $newPara["spbill_create_ip"] = $_SERVER["REMOTE_ADDR"];
   //通知地址,注意,这里的url里面不要加参数
   $newPara["notify_url"] = "支付成功后的回调地址";
   //交易类型
   $newPara["trade_type"] = "APP";

   $key = "密钥:在商户后台个人安全中心设置";
   //第一次签名
   $newPara["sign"] = appgetSign($newPara,$key);

   //把数组转化成xml格式
   $xmlData = arrayToXml($newPara);

   $get_data = sendPrePayCurl($xmlData);

   //返回的结果进行判断。
   if($get_data['return_code'] == "SUCCESS" && $get_data['result_code'] == "SUCCESS"){
    //根据微信支付返回的结果进行二次签名
    //二次签名所需的随机字符串
    $newPara["nonce_str"] = createNoncestr();
    //二次签名所需的时间戳
    $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['success'] = 1;
    $json['ordersn'] = $newPara["out_trade_no"]; //订单号
    $json['order_arr'] = $secondSignArray;  //返给前台APP的预支付订单信息
    $json['order_arr']['sign'] = appgetSign($secondSignArray,$key);  //预支付订单签名
    $json['data'] = "预支付完成";
    //预支付完成,在下方进行自己内部的业务逻辑
    /*****************************/
    return json_encode($json);
   }
   else{

    $json['success'] = 0;
    $json['error'] = $get_data['return_msg']; 
    return json_encode($json); 
   }
  }

//将数组转换为xml格式 
function arrayToXml($arr)

    {
    
        $xml = "<xml>";

        foreach ($arr as $key=>$val)

        {

           if (is_numeric($val))

           {

            $xml.="<".$key.">".$val."</".$key.">"; 

           }

           else

            $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";  

        }

        $xml.="</xml>";

        return $xml; 

    }


  //发送请求
  function sendPrePayCurl($xml,$second=30)

  { 

    $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

    $ch = curl_init();

    curl_setopt($ch,CURLOPT_URL, $url);

    curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);

    curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);

    //设置header

    curl_setopt($ch, CURLOPT_HEADER, FALSE);

    //要求结果为字符串且输出到屏幕上

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

    //post提交方式

    curl_setopt($ch, CURLOPT_POST, TRUE);

    curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);

    //运行curl

        $data = curl_exec($ch);

    curl_close($ch);

    $data_xml_arr =XMLDataParse($data);

    if($data_xml_arr)

    {

      return $data_xml_arr;
    }

    else 

    { 

      $error = curl_errno($ch);

      echo "curl出错,错误码:$error"."<br>"; 

      echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>";

      curl_close($ch);

      return false;

    }

  }
 
//xml格式数据解析函数
 function XMLDataParse($data){
  $xml = simplexml_load_string($data,NULL,LIBXML_NOCDATA);
  $array=json_decode(json_encode($xml),true);
  return $array;
 }
 
//随机字符串
function createNoncestr( $length = 32 ) 

  {

    $chars = "abcdefghijklmnopqrstuvwxyz0123456789";  

    $str ="";

    for ( $i = 0; $i < $length; $i++ )  {  

      $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);  

    }  

    return $str;

  }

/*
 * 格式化参数格式化成url参数  生成签名sign
*/
 function appgetSign($Obj,$appwxpay_key)

  {

    foreach ($Obj as $k => $v)

    {

      $Parameters[$k] = $v;

    }

    //签名步骤一:按字典序排序参数

    ksort($Parameters);

    $String = formatBizQueryParaMap($Parameters, false);

    //echo '【string1】'.$String.'</br>';

    //签名步骤二:在string后加入KEY
        if($appwxpay_key){
            $String = $String."&key=".$appwxpay_key;
        }
        
    //echo "【string2】".$String."</br>";

    //签名步骤三:MD5加密

    $String = md5($String);

    //echo "【string3】 ".$String."</br>";

    //签名步骤四:所有字符转为大写

    $result_ = strtoupper($String);

    //echo "【result】 ".$result_."</br>";

    return $result_;

  }

  //按字典序排序参数
  function formatBizQueryParaMap($paraMap, $urlencode)

  {

    $buff = "";

    ksort($paraMap);

    foreach ($paraMap as $k => $v)

    {

        if($urlencode)

        {

         $v = urlencode($v);

      }

      //$buff .= strtolower($k) . "=" . $v . "&";

      $buff .= $k . "=" . $v . "&";

    }

    $reqPar;

    if (strlen($buff) > 0) 

    {

      $reqPar = substr($buff, 0, strlen($buff)-1);

    }

    return $reqPar;

  }

猜你喜欢

转载自blog.csdn.net/weixin_40896800/article/details/81121631