原生app微信支付-服務器端PHP代碼

注意點:html

一、簽名是倆次簽名,第一次,是獲取prepay_id時候,第二次簽名是最後返回結果的時候,所謂簽名就是對所傳遞參數的一個加密操做;json

二、加簽方式默認md5就能夠,若是要改爲HMAC-SHA256,須要在第一次簽名時候,傳遞參數:$newPara["sign_type"] = "HMAC-SHA256";  而後在簽名加密的時候,使用:$String = hash_hmac("sha256",參數拼接字符串,密鑰);api

三、使用的密鑰,不是AppSecret,而是在微信商戶平臺上本身設定的api密鑰 32位;數組

四、重點:body參數格式:應用市場上的APP名字-實際商品名稱,好比:每天愛消除-遊戲充值。安全

代碼:服務器

$wx = new TegWXPay();
$res = $wx->weChatPay(訂單號,金額,商品名稱);
echo $res;
exit;

//weixinpay class
class TegWXPay{
    
    private $config = array(
        'appid' => "",    /*微信開放平臺上的應用id*/
        'mch_id' => "",   /*微信申請成功以後郵件中的商戶id*/
        'api_key' => "",    /*在微信商戶平臺上本身設定的api密鑰 32位*/          
        'notify_url' => '', /*自定義的回調程序地址*/
        'appname' => '' //app名稱
    );

    //入口函數
    public function weChatPay($order_num,$price,$subject)
    {
       $json = array();
       //生成預支付交易單的必選參數:
       $newPara = array();
       //應用ID
       $newPara["appid"] = $this->config['appid']; //商戶appid;

       //商品描述
       $newPara["body"] = $this->config['appname']."-".$subject;

       //設備號
       $newPara["device_info"] = "WEB";

       //商戶號
       $newPara["mch_id"] = $this->config['mch_id']; //商戶id

       //隨機字符串,這裏推薦使用函數生成
       $newPara["nonce_str"] = $this->createNoncestr();

       //通知地址,注意,這裏的url裏面不要加參數
       $newPara["notify_url"] = $this->config['notify_url'];//支付成功後的回調地址;

       //商戶訂單號,這裏是商戶本身的內部的訂單號
       $newPara["out_trade_no"] = $order_num;

       //簽名類型 HMAC-SHA256 MD5
       $newPara["sign_type"] = "MD5";

       //終端IP
       $newPara["spbill_create_ip"] = $this->get_client_ip();

       //總金額
       $newPara["total_fee"] = $price;


       //交易類型
       $newPara["trade_type"] = "APP";
       $key = $this->config['api_key']; //密鑰:在商戶後臺我的安全中心設置

       //第一次簽名
       $newPara["sign"] = $this->appgetSign($newPara,$key);
//echo json_encode($newPara);
//exit;
       //把數組轉化成xml格式
       $xmlData = $this->arrayToXml($newPara);

       $get_data = $this->sendPrePayCurl($xmlData);

       //返回的結果進行判斷。
       if($get_data['return_code'] == "SUCCESS" && $get_data['result_code'] == "SUCCESS")
       {
            //根據微信支付返回的結果進行二次簽名
            //二次簽名所需的隨機字符串
            $newPara["nonce_str"] = $this->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'] = $this->appgetSign($secondSignArray,$key);  //預支付訂單簽名
            $json['data'] = "預支付完成";
            //預支付完成,在下方進行本身內部的業務邏輯
            /*****************************/
            //return json_encode($json);

            $json['order_arr']['nonce_str'] = $secondSignArray['noncestr'];
            $json['order_arr']['prepay_id'] = $secondSignArray['prepayid'];
            $json['order_arr']['return_code'] = 'SUCCESS';
            $json['order_arr']['return_msg'] = 'OK';
            $test['pay_code'] = $json['order_arr'];

            return json_encode($test);
       }else{
            $json['success'] = 0;
            $json['error'] = $get_data['return_msg']; 
            return json_encode($json); 
       }
      }
      
    //將數組轉換爲xml格式 
    public function arrayToXml($arr)
    {
        $xml = "<xml>";
        foreach ($arr as $key=>$val)
        {
           //if (is_numeric($val))
            if(false)
           {
            $xml.="<".$key.">".$val."</".$key.">"; 
           }
           else
            $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";  
        }
        $xml.="</xml>";
        return $xml; 
    }

      //發送請求
    public 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 =$this->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格式數據解析函數
    public function XMLDataParse($data)
    {
        $xml = simplexml_load_string($data,NULL,LIBXML_NOCDATA);
        $array = json_decode(json_encode($xml),true);
        return $array;
    }
     
    //隨機字符串
    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;
    }
      
    /*
     * 格式化參數格式化成url參數  生成簽名sign
    */
    public function appgetSign($Obj,$appwxpay_key)
    {
        foreach ($Obj as $k => $v)
        {
          $Parameters[$k] = $v;
        }
        //簽名步驟一:按字典序排序參數
        ksort($Parameters);
        $String = $this->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);

        //HMAC-SHA256簽名方式
        //$String = hash_hmac("sha256",$String,$appwxpay_key);

        //echo "【string3】 ".$String."</br>";
        //簽名步驟四:全部字符轉爲大寫
        $result_ = strtoupper($String);
        //echo "【result】 ".$result_."</br>";
        return $result_;
    }
     
     //按字典序排序參數
    public 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;
    }

    
    //獲取當前服務器的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;
    }
    
    
}
相關文章
相關標籤/搜索