getConfig(); // var_dump('
', $config);

	// 接口URL(测试)
	$api_url = $config['pay_url'];

	// 加个body字段传中文试试

	// 组装交易报文
	$reqsn_prefix = date('Ymd');
	// var_dump("uniq_id(reqsn)");
	// echo "\r\n";
	// var_dump(uniqid($reqsn_prefix));
	$trade_data = array(
        'orgid' => $config['org_num'],
        'cusid' => $config['cusid'],
        'branchno' => $config['branchno'],
        'termcode' => $config['termcode'],
        'version' => $config['version'],
        'trxamt' => '1',
        'reqsn' => uniqid($reqsn_prefix),
        'producp' => 'JX0002',
        'transtype' => 'JSP511',
        'paytype' => 'W01',
        'randomstr' => md5( uniqid() ),
        'body' => 'pages',
        "acct" => $this->parameters["openid"] # 不知道好不好用...
    );

    	// 生成签名
	$sign = $Base->Crypt->makeSign($trade_data);
	if($sign === false)
	{
		// echo $Base->Crypt->err_msg;
		die();
	}
	// echo "\r\n";
	// echo "[sign]: {$sign}";
	// die();

	// 加密交易报文
	$crypted_trade_data = $Base->Crypt->encryptTradeData($trade_data);
	if($crypted_trade_data === false)
	{
		// echo $Base->Crypt->err_msg;
		die();
	}
	// echo "\r\n";
	// echo "[crypted message]: {$crypted_trade_data}";
	// die();

	// 发送报文
	// echo "\r\n";
	// var_dump($api_url);
	$response = $Base->Request->send($api_url, $crypted_trade_data, $sign);
	if($response === false)
	{
		// echo $Base->Request->err_msg;
		die();
	}

	// echo "\r\n";
	// echo "[response message]: {$response}";

	// 解析响应报文
	$response = json_decode($response, true);
	$response_data_crypted = $response['data'];
	$response_sign = $response['sign'];
	// echo "\r\n";
	// echo "[response sign]: {$response_sign}";
	// echo "\r\n";
	// echo "[response data (ciphertext)]: {$response_data_crypted}";

	// 解密响应密文
	$response_data = $Base->Crypt->decryptTradeData($response_data_crypted);
	if($response_data === false)
	{
		// echo $Base->Crypt->err_msg;
		die();
	}
	// echo "\r\n";
	// echo "[response data(clear text)]: {$response_data}";
	echo $response_data;
	// die();
    }

    /**
     * 生成支付代码
     * @param   array $order 订单信息
     * @param   array $payment 支付方式信息
     */
    public function get_code($order, $payment)
    {
        include_once(BASE_PATH.'helpers/payment_helper.php');        
        // 配置参数
        $this->payment = $payment;
        // 网页授权获取用户openid
        if (! isset($_SESSION['openid']) || empty($_SESSION['openid'])) {

            // $button = '微信支付';
            // return $button;
            // 应该重新发起授权登录 
            // require_once("../connect/wechat.php");
            // return wxchat::redirect("shop/mobile");
            // $_SESSION['openid'] = 'sdf4asgdf2ag1';
            return false; 
        }

        // 设置必填参数
        // 根目录url
        $order_amount = $order['order_amount'] * 100;
        $this->setParameter("openid", "$_SESSION[openid]"); // 商品描述
        $this->setParameter("body", $order['order_sn']); // 商品描述
        $this->setParameter("out_trade_no", $order['order_sn'] . $order_amount . 'O' . $order['log_id']); // 商户订单号
        $this->setParameter("total_fee", $order_amount); // 总金额
        $this->setParameter("notify_url", __URL__ . 'wxpay.php'); // 通知地址
        $this->setParameter("trade_type", "JSAPI"); // 交易类型

        $prepay_id = $this->getPrepayId();
        $jsApiParameters = $this->getParameters($prepay_id);
        // wxjsbridge
        $js = '
        ';

        $button = '微信支付(测试)' . $js;
        // $button = '微信支付';

        return $button;
        
    }

    /**
     * 同步通知
     * @param $data
     * @return mixed
     */
    public function callback($data)
    {
        return true;
    }

    /**
     * 异步通知
     * @param $data
     * @return mixed
     */
    public function notify($data)
    {
        include_once(BASE_PATH.'helpers/payment_helper.php');
        if (! empty($data['postStr'])) {
            $payment = get_payment($data['code']);
            $postdata = json_decode(json_encode(simplexml_load_string($data['postStr'], 'SimpleXMLElement', LIBXML_NOCDATA)), true);
            /* 检查插件文件是否存在,如果存在则验证支付是否成功,否则则返回失败信息 */
            // 微信端签名
            $wxsign = $postdata['sign'];
            unset($postdata['sign']);

            foreach ($postdata as $k => $v) {
                $Parameters[$k] = $v;
            }
            // 签名步骤一:按字典序排序参数
            ksort($Parameters);

            $buff = "";
            foreach ($Parameters as $k => $v) {
                $buff .= $k . "=" . $v . "&";
            }
            $String;
            if (strlen($buff) > 0) {
                $String = substr($buff, 0, strlen($buff) - 1);
            }
            // 签名步骤二:在string后加入KEY
            $String = $String . "&key=" . $payment['wxpay_key'];
            // 签名步骤三:MD5加密
            $String = md5($String);
            // 签名步骤四:所有字符转为大写
            $sign = strtoupper($String);
            // 验证成功
            if ($wxsign == $sign) {
                // 交易成功
                if ($postdata['result_code'] == 'SUCCESS') {
                    // 获取log_id
                    $out_trade_no = explode('O', $postdata['out_trade_no']);
                    $order_sn = $out_trade_no[1]; // 订单号log_id
                                                  // 改变订单状态
                    order_paid($order_sn, 2);

                    // 修改订单信息(openid,tranid)
                    model()->table('pay_log')
                        ->data(array('openid'=>$postdata['openid'], 'transid'=>$postdata['transaction_id']))
                        ->where(array('log_id'=>$order_sn))
                        ->update();
                    /*if(method_exists('WechatController', 'do_oauth')){
                        // 如果需要,微信通知 wanglu
                        $order_id = model('Base')->model->table('order_info')
                            ->field('order_id')
                            ->where('order_sn = "' . $out_trade_no[0] . '"')
                            ->getOne();
                        $order_url = __HOST__ . url('user/order_detail', array(
                            'order_id' => $order_id
                        ));
                        $order_url = urlencode(base64_encode($order_url));
                        send_wechat_message('pay_remind', '', $out_trade_no[0] . ' 订单已支付', $order_url, $out_trade_no[0]);
                    }*/
                }
                $returndata['return_code'] = 'SUCCESS';
            } else {
                $returndata['return_code'] = 'FAIL';
                $returndata['return_msg'] = '签名失败';
            }
        } else {
            $returndata['return_code'] = 'FAIL';
            $returndata['return_msg'] = '无数据返回';
        }
        // 数组转化为xml
        $xml = "";
        foreach ($returndata as $key => $val) {
            if (is_numeric($val)) {
                $xml .= "<" . $key . ">" . $val . "";
            } else
                $xml .= "<" . $key . ">";
        }
        $xml .= "";

        echo $xml;
        exit();
    }

    function trimString($value)
    {
        $ret = null;
        if (null != $value) {
            $ret = $value;
            if (strlen($ret) == 0) {
                $ret = null;
            }
        }
        return $ret;
    }

    /**
     * 作用:产生随机字符串,不长于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;
    }

    /**
     * 作用:设置请求参数
     */
    function setParameter($parameter, $parameterValue)
    {
        $this->parameters[$this->trimString($parameter)] = $this->trimString($parameterValue);
    }

    /**
     * 作用:生成签名
     */
    public function getSign($Obj)
    {
        foreach ($Obj as $k => $v) {
            $Parameters[$k] = $v;
        }
        // 签名步骤一:按字典序排序参数
        ksort($Parameters);

        $buff = "";
        foreach ($Parameters as $k => $v) {
            $buff .= $k . "=" . $v . "&";
        }
        $String = "";
        if (strlen($buff) > 0) {
            $String = substr($buff, 0, strlen($buff) - 1);
        }
        // echo '【string1】'.$String.'
'; // 签名步骤二:在string后加入KEY $String = $String . "&key=" . $this->payment['wxpay_key']; // echo "【string2】".$String."
"; // 签名步骤三:MD5加密 $String = md5($String); // echo "【string3】 ".$String."
"; // 签名步骤四:所有字符转为大写 $result_ = strtoupper($String); // echo "【result】 ".$result_."
"; return $result_; } /** * 作用:以post方式提交xml到对应的接口url */ public function postXmlCurl($xml, $url, $second = 30) { // 初始化curl $ch = curl_init(); // 设置超时 curl_setopt($ch, CURLOP_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); curl_close($ch); // 返回结果 if ($data) { curl_close($ch); return $data; } else { $error = curl_errno($ch); echo "curl出错,错误码:$error" . "
"; echo "错误原因查询
"; curl_close($ch); return false; } } /** * 获取prepay_id */ function getPrepayId() { // 设置接口链接 $url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; try { // 检测必填参数 if ($this->parameters["out_trade_no"] == null) { throw new Exception("缺少统一支付接口必填参数out_trade_no!" . "
"); } elseif ($this->parameters["body"] == null) { throw new Exception("缺少统一支付接口必填参数body!" . "
"); } elseif ($this->parameters["total_fee"] == null) { throw new Exception("缺少统一支付接口必填参数total_fee!" . "
"); } elseif ($this->parameters["notify_url"] == null) { throw new Exception("缺少统一支付接口必填参数notify_url!" . "
"); } elseif ($this->parameters["trade_type"] == null) { throw new Exception("缺少统一支付接口必填参数trade_type!" . "
"); } elseif ($this->parameters["trade_type"] == "JSAPI" && $this->parameters["openid"] == NULL) { throw new Exception("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!" . "
"); } $this->parameters["appid"] = $this->payment['wxpay_appid']; // 公众账号ID $this->parameters["mch_id"] = $this->payment['wxpay_mchid']; // 商户号 $this->parameters["spbill_create_ip"] = $_SERVER['REMOTE_ADDR']; // 终端ip $this->parameters["nonce_str"] = $this->createNoncestr(); // 随机字符串 $this->parameters["sign"] = $this->getSign($this->parameters); // 签名 $xml = ""; foreach ($this->parameters as $key => $val) { if (is_numeric($val)) { $xml .= "<" . $key . ">" . $val . ""; } else { $xml .= "<" . $key . ">"; } } $xml .= ""; } catch (Exception $e) { die($e->getMessage()); } // $response = $this->postXmlCurl($xml, $url, 30); $response = \libraries\Http::curlPost($url, $xml, 30); $result = json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA)), true); $prepay_id = $result["prepay_id"]; return $prepay_id; } /** * 作用:设置jsapi的参数 */ public function getParameters($prepay_id) { $jsApiObj["appId"] = $this->payment['wxpay_appid']; $timeStamp = time(); $jsApiObj["timeStamp"] = "$timeStamp"; $jsApiObj["nonceStr"] = $this->createNoncestr(); $jsApiObj["package"] = "prepay_id=$prepay_id"; $jsApiObj["signType"] = "MD5"; $jsApiObj["paySign"] = $this->getSign($jsApiObj); $this->parameters = json_encode($jsApiObj); return $this->parameters; } /** * 订单查询 * @return mixed */ public function query($order, $payment) { } }