微信jsapi支付(微信支付)

微信h5支付首先商户平台要开通jsapi支付,商户平台要关联公众号,php

这里要注意的是h5支付不须要openid,而微信jsapi支付须要openid。jsapi对客户端ip没有要求,而微信h5支付对客户端ip有要求
而后拿到:
$appid = ""; //应用 
APPID $mch_id = ""; //微信支付商户号 
$key = ""; //微信商户 API 密钥
注意配置相关域名和受权目录
商户平台html

公众平台sql

public function pay()
    {
        // 获取openid
        $pr = req::$forms;
        ///查询到的价格
        $sql="select price,id,no from `sm_order` where no='".$pr['oid']."'";
        //echo $sql;die;
        $order = db::queryone($sql);
        //echo '<pre>';print_r($order);die;
        $appAttr = [];
        $appAttr['appid'] = $this->appid;
        $key = $this->key;
        $appAttr['attach'] = '命理学院';
        $appAttr['body'] = '星座运势';
        $appAttr['detail'] = '{"info":"微信支付"}';
        $appAttr['mch_id'] = $this->mch_id;
        $appAttr['nonce_str'] = md5(time().rand(1000,9999));
        $appAttr['notify_url'] = 'https://你的域名/v1.0.0/XcxPay/FaceAiPay/notify.php';
        $appAttr['openid'] = $pr['open_id'];//$_POST['openid'];
        $appAttr['out_trade_no'] = $order['no'];//平台内部订单号
        $appAttr['spbill_create_ip'] = '127.0.0.1';
        $appAttr['total_fee'] = $order['price'] * 100;//单位分
        $appAttr['trade_type'] = 'JSAPI';
//推荐上面有数据按官方的“ASCII字典”排序的设键放置数据

        $appAttr['sign'] = self::getParam($appAttr,false,$key);
        $post_data = "<xml>
                    <appid>".$appAttr['appid']."</appid>
                    <attach>".$appAttr['attach']."</attach>
                    <body>".$appAttr['body']."</body>
                    <mch_id>".$appAttr['mch_id']."</mch_id>
                    <detail>".$appAttr['detail']."</detail>
                    <notify_url>".$appAttr['notify_url']."</notify_url>
                    <nonce_str>".$appAttr['nonce_str']."</nonce_str>
                    <openid>".$appAttr['openid']."</openid>
                    <out_trade_no>".$appAttr['out_trade_no']."</out_trade_no>
                    <spbill_create_ip>".$appAttr['spbill_create_ip']."</spbill_create_ip>
                    <total_fee>".$appAttr['total_fee']."</total_fee>
                    <trade_type>".$appAttr['trade_type']."</trade_type>
                    <sign>".$appAttr['sign']."</sign>
            </xml>";//拼接成 XML 格式
        //echo $post_data;die;
        $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";//微信传参地址
        $dataxml = self::__postXmlCurl($post_data,$url); //后台 POST 微信传参地址  同时取得微信返回的参数
        $objectxml = (array)simplexml_load_string($dataxml, 'SimpleXMLElement', LIBXML_NOCDATA); //将微信返回的 XML 转换成数组
        //echo '<pre>';print_r($objectxml);die;
        $resultData=[];
        $resultData['appId']=$appAttr['appid'];
        $resultData['nonceStr']=$objectxml['nonce_str'];
        $resultData['package']='prepay_id='.$objectxml['prepay_id'];
        $resultData['signType']='MD5';
        $resultData['timeStamp']=(string)time();
        $resultData['paySign']=self::getParam($resultData,false,$key);
        echo json_encode($resultData);
        die;
    }
    public function scanquery(){
        $pr = req::$forms;
        //查询订单状态
        $sql="select status from `sm_order` where no='".$pr['oid']."' and product_id='".$pr['star_id']."'";
        //echo $sql;die;
        $order = db::queryone($sql);
        //echo json_decode($order);die;
        //echo '<pre>';print_r($order);die;
        if($order && $order['status'] == 'PAYED'){
            $url = '/xingzuo/?ct=index&ac=xingzuo_info&oid='.$pr['oid'].'&star_id='.$pr['star_id'];
            echo '{"status":1,"orderId":"'.$pr['oid'].'","url":"'.$url.'"}';
        }else{
            echo '{"code":1,"orderId":"'.$pr['oid'].'"}';
        }
    }

    private 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;
    }
    private function __postXmlCurl($xml,$url,$second = 30){
        $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        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);
            curl_close($ch);
            echo "curl 出错,错误码:$error"."<br>";
        }
    }
    private function __get_client_ip() {
        if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
            $ip = getenv('HTTP_CLIENT_IP');
        } elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
            $ip = getenv('HTTP_X_FORWARDED_FOR');
        } elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
            $ip = getenv('REMOTE_ADDR');
        } elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        return preg_match ( '/[\d\.]{7,15}/', $ip, $matches ) ? $matches [0] : '';
    }
    //对参数排序,生成MD5加密签名

    private function getParam($paramArray, $isencode=false,$k)
    {
        $paramStr = '';
        ksort($paramArray);
        $i = 0;
        foreach ($paramArray as $key => $value)
        {
            if ($key == 'Signature'){
                continue;
            }
            if ($i == 0){
                $paramStr .= '';
            }else{
                $paramStr .= '&';
            }
            $paramStr .= $key . '=' . ($isencode?urlencode($value):$value);
            ++$i;
        }
        $stringSignTemp=$paramStr."&key=".$k;
        $sign=strtoupper(md5($stringSignTemp));
        return $sign;
    }