天天看點

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;

}