TP5 JSAPI微信支付

使用jsapi微信支付需要两次加密过程,首先通过自己的业务参数来进行加密,去生成签名请求微信服务器、微信服务器会返回给你一个结果、根据返回的结果判断是否需要二次加密、代码如下。

			$WecatPay = new \app\lib\WecatPay();
			$request = \think\Request::instance();
			$openId = input("post.openid");  // openId 前端小程序发送给你的
            $nowTime = date("Y-m-d H:i:s");  
            $appId  = \think\Config::get('wecat.appid');  
            $secert = \think\Config::get('wecat.secert'); 
            $mch_id = \think\Config::get('wecat.mch_id');
            $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
            $nonceStr = getRandomStr(32);
            $time = time();
			settype($time,'string'); 
			$orderNum = $WecatPay->getOrderNumber('HXFIB');// orderNum 为随机生成的订单号,根据个人业务场景来生成

由于微信服务端需要一个字符串时间戳,而php的time()函数获取到的为整数类型、所以在这里使用settype方法转为strting类型参数。
将业务参数存入数组中,并调用生成签名方法(此处WecatPay类为个人封装的工具类)

			$data = array(
                'appid'             => $appId,
                'body'              => '微信(在线支付)',
                'mch_id'            => $mch_id,
                'nonce_str'         => $nonceStr,
                'notify_url'        => '这里填写你的回调地址',
                'out_trade_no'      => $orderNum,
                'openid'            => $openId,
                'spbill_create_ip'  => $request->ip(),
                'total_fee'         => $BusinessOnePayNumber * 100,
                'trade_type'        => 'JSAPI'
            );
            $data['sign'] = $WecatPay->MakeSign($data);

生成签名方法如下

	/**
     * 生成sign签名
     * @param array $data
     * @return string
     */
    public function MakeSign($data) {
        $key = \think\Config::get('wecat.pay_key');
        ksort($data);
        $buff = '';
        foreach ($data as $k => $v) {
            if ($k != 'sign' && $v != '' && !is_array($v)) {
                $buff .= $k . '=' . $v . '&';
            }
        }
        $buff = trim($buff, '&');
        $str = $buff . '&key=' . $key;
        $str = md5($str);
        return strtoupper($str);
    }

方法返回生成的签名,在上步代码逻辑中已将签名存到$data数组中。
将业务数组转换为xml格式

$xmldata = $WecatPay->xml($data); //调用工具类转换方法
	/**
     * array 转 xml
     * @param string $param
     */
    public function xml($param) {
        ksort($param);
        $data_xml = "<xml>";
        foreach ($param as $key => $val) {
            if (is_numeric($val)) {
                $data_xml .= '<' . $key . '>' . $val . '</' . $key . '>';
            } else {
                $data_xml .= '<' . $key . '><![CDATA[' . $val . ']]></' . $key . '>';
            }
        }
        $data_xml .= '</xml>';
        return $data_xml;
    }

发送请求,并根据结果判断是否需要二次加密

			$res = \app\lib\HttpServer::sendHttp($url,$xmldata,1);
            $result = $WecatPay->xmlToArray($res);
            if ($result['return_code'] == 'SUCCESS'){
                $info = array(
                    'appId' => $appId,
                    'timeStamp' => $time,
                    'nonceStr'  => $nonceStr,
                    'package'   => 'prepay_id='.$result['prepay_id'],
                    'signType'  => 'MD5'
                );
                $sign = $WecatPay->MakeSign($info); // 二次签名加密
                returnCode(1,[
                    'nonceStr'  => $info['nonceStr'],
                    'openid'    => $openId,
                    'orderNum'  => $orderNum,
                    'package'   => $result['prepay_id'],
                    'paySign'   => $sign,
                    'fibPriceInfoId' => null,
                    'timeStamp' => $time,
                    'tradenum'  => $orderNum
                ]);
            }else{
                returnCode(-1,[],'发起支付请求失败!');
            }
/**
     *  发送请求
     * @param string $url
     * @param boolean $params
     * @param number $ispost
     * @param array $header
     * @param boolean $verify
     * @return boolean|mixed
     */
    public static function sendHttp($url, $params = false, $ispost = 0, $header = [], $verify = false) {
        
        $httpInfo = array();
        $ch = curl_init();
        if (!empty($header)) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        }
        curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
        curl_setopt($ch, CURLOPT_TIMEOUT, 60);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        if ($verify === true) {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
        } else {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        }
        if ($ispost) {
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
            curl_setopt($ch, CURLOPT_URL, $url);
        } else {
            if (is_array($params)) {
                $params = http_build_query($params);
            }
            if ($params) {
                curl_setopt($ch, CURLOPT_URL, $url . '?' . $params);
            } else {
                curl_setopt($ch, CURLOPT_URL, $url);
            }
        }
        $response = curl_exec($ch);
        if ($response === FALSE) {
            trace("cURL Error: " . curl_errno($ch) . ',' . curl_error($ch), 'error');
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            $httpInfo = array_merge($httpInfo, curl_getinfo($ch));
            trace($httpInfo, 'error');
            return false;
        }
        curl_close($ch);
        return $response;
    }
	//将XML转为array
    public function xmlToArray($xml) {
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $values;
    }

猜你喜欢

转载自blog.csdn.net/Quiet_tomcat/article/details/89134472