原生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;
    }
    
    
}
相关文章
相关标签/搜索