天天看点

APP服务端微信支付(PHP服务端)

<?php

//填写必填的参数到地址 微信统一地址

$url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; //微信统一地址

$body = "APP微信支付测试";

$appid = "wx111111111111";    //微信开放平台上的应用id

$mch_id = "2222222222"; //微信申请成功之后邮件中的商户id

$attach = "APP微信支付";

$total_fee = 1; //1分

$out_trade_no = rand(100000,999999);

$api_key = "as3aaaaaaaaaaaaaaaaaaaaaaaa"; //在微信商户平台上自己设定的api密钥 32位

$notify_url = "pay_weixin.php"; //自定义的回调程序地址

$nonce_str = $this->createNoncestr();

//获取签名必要参数

$data["appid"] = $appid;

$data["attach"] = $attach;

$data["body"] = $body;  

$data["mch_id"] = $mch_id;

$data["nonce_str"] = $nonce_str;

$data["notify_url"] = $notify_url;

$data["out_trade_no"] = $out_trade_no;

$data["spbill_create_ip"] = $this->get_client_ip();

$data["total_fee"] = $total_fee;

$data["trade_type"] = "APP";

//第一次签名 通过上传拼接的字符串 创建sign

$sign = $this->getSign($data);

$data["sign"] = $sign;

$xml = $this->arrayToXml($data);

$response = $this->postXmlCurl($xml, $url);

//将微信返回的结果xml转成数组

$response = $this->xmlToArray($response);

$new_arr=array();

$new_arr['appid'] = $appid;

$new_arr['partnerid'] = $mch_id;

$new_arr['prepayid'] = $response['prepay_id'];

$new_arr['package'] = "Sign=WXPay";

$new_arr['noncestr'] = $response['nonce_str'];

$new_arr['timestamp'] = time();

//第二次签名 调起微信支付

$sign2 = $this->getSign($new_arr);

$new_arr["sign"] = $sign2;

$xml2 = $this->arrayToXml($new_arr);

//将微信返回的结果xml转成数组

$response3 = $this->xmlToArray($xml2);

//数组转成json

echo json_encode($response3);

//微信支付 - 生成签名

public function getSign($Obj){

$api_key = "as3aaaaaaaaaaaaaaaaaaaaaaaa";

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

      $Parameters[$k] = $v;

  }

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

  ksort($Parameters);

  $String = $this->formatBizQueryParaMap($Parameters, false);

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

  //签名步骤二:在string后加入KEY

  $String = $String."&key=".$api_key;

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

  //签名步骤三:MD5加密

  $String = md5($String);

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

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

  $result_ = strtoupper($String);

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

  return $result_;

}

//微信支付 - 产生随机字符串,不长于32位

public 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;

}

//微信支付 - 数组转xml

public 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;

}

//微信支付 - 将xml转为array

public function xmlToArray($xml){

  //将XML转为array

  $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);

  return $array_data;

}

//微信支付 - 以post方式提交xml到对应的接口url

public function postXmlCurl($xml,$url,$second=30){

  //初始化curl

  $ch = curl_init();

  //设置超时

  curl_setopt($ch, CURLOPT_TIMEOUT, $second);

  //这里设置代理,如果有的话

  //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');

  //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);

  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);

  //返回结果

  if($data){

    curl_close($ch);

    return $data;

  }else{

    $error = curl_errno($ch);

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

    curl_close($ch);

    return false;

  }

}

//微信支付 - 获取当前服务器的IP

public function get_client_ip(){

  if ($_SERVER['REMOTE_ADDR']) {

     $cip = $_SERVER['REMOTE_ADDR'];

  } elseif (getenv("REMOTE_ADDR")) {

     $cip = getenv("REMOTE_ADDR");

  } elseif (getenv("HTTP_CLIENT_IP")) {

     $cip = getenv("HTTP_CLIENT_IP");

  } else {

     $cip = "unknown";

  }

  return $cip;

}

//微信支付 - 格式化参数,签名过程需要使用

public function formatBizQueryParaMap($paraMap, $urlencode){

  $buff = "";

  ksort($paraMap);

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

    if($urlencode){

        $v = urlencode($v);

    }

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

  }

  $reqPar;

  if (strlen($buff) > 0){

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

  }

  return $reqPar;

}