package com.cirle.scientific.service.impl;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.cirle.scientific.constants.WeixinConsts;
import com.cirle.scientific.dto.weixin.WxUerInfoDTO;
import com.cirle.scientific.service.WeixinService;
import com.cirle.scientific.utils.HttpClientUtil;
import com.cirle.scientific.utils.OkHttpUtil;
import com.cirle.scientific.utils.redis.RedisUtil;
import com.cirle.scientific.utils.weixin.PayConfig;
import com.cirle.scientific.utils.weixin.SignUtil;
import com.cirle.scientific.utils.weixin.WeiXinPay;
import com.cirle.scientific.utils.weixin.WeixinpayConfig;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayUtil;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * 微信相关service
 */
@Component
@Transactional
@Slf4j
public class WeixinServiceImpl implements WeixinService {

	@Resource
	private RedisUtil redisUtil;
	@Autowired
	StringRedisTemplate stringRedisTemplate;
	@Override
	public Map<String, String> wxapay(WeiXinPay weiXinPay) {

		// 微信接口统一下单
		Map<String, String> resp = unifiedorder(weiXinPay);

		//组装发起支付数据
		String timeStamp = String.valueOf(Math.round(System.currentTimeMillis() / 1000f));
		//随机字符串
		String nonceStr = UUID.randomUUID().toString().replace("-", "");
		String prepayId = resp.get("prepay_id");

		//微信支付实体类
		weiXinPay.setAppId(weiXinPay.getAppId());
		weiXinPay.setNonceStr(nonceStr);
		weiXinPay.setPackages("prepay_id=" + prepayId);
		weiXinPay.setSignType("MD5");
		weiXinPay.setTimeStamp(timeStamp);

		//生成签名信息
		String sign = SignUtil.getJsSignString(weiXinPay);

		Map<String, String> wxInfo = new HashMap<String, String>();
		wxInfo.put("appId", weiXinPay.getAppId());
		wxInfo.put("timeStamp", timeStamp);
		wxInfo.put("nonceStr", nonceStr);
		wxInfo.put("packages", "prepay_id=" + prepayId);
		wxInfo.put("signType", "MD5");
		wxInfo.put("paySign", sign);

		log.info("发起支付数据:" + wxInfo);

		return wxInfo;
	}

	@Override
	public String mwebpay(WeiXinPay weiXinPay) {

		// 微信接口统一下单
		Map<String, String> resp = unifiedorder(weiXinPay);

		String mweb_url = resp.get("mweb_url");

		log.info("mweb_url为拉起微信支付收银台的中间页面:" + mweb_url);

		return mweb_url;
	}

	@Override
	public Map<String, String> jsapipay(WeiXinPay weiXinPay) {

		//通过code获取openid
		Map<String, String> tokenMap = getTokenByCode(weiXinPay.getAppId(), weiXinPay.getAppSecret(), weiXinPay.getCode(), "authorization_code");
		log.info("微信授权openid:" + tokenMap.get("openid"));

		weiXinPay.setOpenId(tokenMap.get("openid"));

		// 微信接口统一下单
		Map<String, String> resp = unifiedorder(weiXinPay);

		//组装发起支付数据
		String timeStamp = String.valueOf(Math.round(System.currentTimeMillis() / 1000f));
		//随机字符串
		String nonceStr = UUID.randomUUID().toString().replace("-", "");
		String prepayId = resp.get("prepay_id");

		//微信支付实体类
		weiXinPay.setAppId(weiXinPay.getAppId());
		weiXinPay.setNonceStr(nonceStr);
		weiXinPay.setPackages("prepay_id=" + prepayId);
		weiXinPay.setSignType("MD5");
		weiXinPay.setTimeStamp(timeStamp);

		//生成签名信息
		String sign = SignUtil.getJsSignString(weiXinPay);

		Map<String, String> wxInfo = new HashMap<String, String>();
		wxInfo.put("appId", weiXinPay.getAppId());
		wxInfo.put("timeStamp", timeStamp);
		wxInfo.put("nonceStr", nonceStr);
		wxInfo.put("packages", "prepay_id=" + prepayId);
		wxInfo.put("signType", "MD5");
		wxInfo.put("paySign", sign);

		log.info("发起支付数据:" + wxInfo);

		return wxInfo;
	}

	@Override
	public Map<String, String> jsapicollagepay(WeiXinPay weiXinPay) {

		//通过code获取openid
		Map<String, String> tokenMap = getTokenByCode(weiXinPay.getAppId(), weiXinPay.getAppSecret(), weiXinPay.getCode(), "authorization_code");
		log.info("微信授权openid:" + tokenMap.get("openid"));

		weiXinPay.setOpenId(tokenMap.get("openid"));

		// 微信接口统一下单
		Map<String, String> resp = unifiedorder(weiXinPay);

		//组装发起支付数据
		String timeStamp = String.valueOf(Math.round(System.currentTimeMillis() / 1000f));
		//随机字符串
		String nonceStr = UUID.randomUUID().toString().replace("-", "");
		String prepayId = resp.get("prepay_id");

		//微信支付实体类
		weiXinPay.setAppId(weiXinPay.getAppId());
		weiXinPay.setNonceStr(nonceStr);
		weiXinPay.setPackages("prepay_id=" + prepayId);
		weiXinPay.setSignType("MD5");
		weiXinPay.setTimeStamp(timeStamp);

		//生成签名信息
		String sign = SignUtil.getJsSignString(weiXinPay);

		Map<String, String> wxInfo = new HashMap<String, String>();
		wxInfo.put("appId", weiXinPay.getAppId());
		wxInfo.put("timeStamp", timeStamp);
		wxInfo.put("nonceStr", nonceStr);
		wxInfo.put("packages", "prepay_id=" + prepayId);
		wxInfo.put("signType", "MD5");
		wxInfo.put("paySign", sign);
		wxInfo.put("orderId", weiXinPay.getOutTradeNo());

		log.info("发起支付数据:" + wxInfo);

		return wxInfo;
	}


	@Override
	public Map<String, String> apppay(WeiXinPay weiXinPay) {

		//微信接口统一下单
		Map<String, String> resp = unifiedorder(weiXinPay);
		log.info("微信接口统一下单返回数据：" + resp);

		//组装发起支付数据
		//时间戳
		String timeStamp = String.valueOf(Math.round(System.currentTimeMillis() / 1000f));
		//随机字符串
		String nonceStr = UUID.randomUUID().toString().replace("-", "");
		//微信下单返回的支付交易会话ID
		String prepayId = resp.get("prepay_id");
		//微信支付实体类
		weiXinPay.setPrepayid(prepayId);
		weiXinPay.setPackages("Sign=WXPay");
		weiXinPay.setNonceStr(nonceStr);
		weiXinPay.setTimeStamp(timeStamp);

		//生成签名信息
		String sign = SignUtil.getAppSignString(weiXinPay);

		Map<String, String> wxInfo = new HashMap<String, String>();
		wxInfo.put("appid", weiXinPay.getAppId());
		wxInfo.put("partnerid", weiXinPay.getMchId());
		wxInfo.put("prepayid", prepayId);
		wxInfo.put("package", "Sign=WXPay");
		wxInfo.put("noncestr", nonceStr);
		wxInfo.put("timestamp", timeStamp);
		wxInfo.put("sign", sign);
		wxInfo.put("orderId", weiXinPay.getOutTradeNo());

		return wxInfo;
	}

	@Override
	public Map<String, String> wxshare(String url) {

		String access_token = generateWxAccessToken(WeixinpayConfig.appId, WeixinpayConfig.appSecret);

		//获取公众号用于调用微信JS接口的临时票据jsapi_ticket
		String ticket = (String) redisUtil.get(WeixinpayConfig.appId + "_ticket");
		if (ticket == null || "".equals(ticket)) {
			//获取公众号用于调用微信JS接口的临时票据jsapi_ticke
			ticket = getTicket(access_token);
			//保存ticket
			redisUtil.set(WeixinpayConfig.appId + "_ticket", ticket, 5300);
		}

		// 随机字符串
		String noncestr = UUID.randomUUID().toString().replace("-", "");

		//时间戳
		String timeStamp = Long.toString(System.currentTimeMillis() / 1000);

		String str_sign = "jsapi_ticket=" + ticket
				+ "&noncestr=" + noncestr
				+ "&timestamp=" + timeStamp
				+ "&url=" + url;
		log.info("签名字符串：" + str_sign);

		// 生成签名信息
		String signature = SignUtil.getSha1(str_sign);

		log.info("签名为：" + signature);

		Map<String, String> wxInfo = new HashMap<String, String>();
		wxInfo.put("appId", WeixinpayConfig.appId);
		wxInfo.put("timestamp", timeStamp);
		wxInfo.put("nonceStr", noncestr);
		wxInfo.put("signature", signature);

		return wxInfo;
	}

	@Override
	public String getTicket() {

		String access_token = generateWxAccessToken(WeixinpayConfig.appId, WeixinpayConfig.appSecret);

		//获取公众号用于调用微信JS接口的临时票据jsapi_ticket
		String ticket = (String) redisUtil.get(WeixinpayConfig.appId + "_ticket");
		if (ticket == null || "".equals(ticket)) {
			//获取公众号用于调用微信JS接口的临时票据jsapi_ticke
			ticket = getTicket(access_token);
			redisUtil.set(WeixinpayConfig.appId + "_ticket", ticket, 7000);
		}

		return ticket;
	}

	/**
	 * 通过code获取access_token openid(服务号)
	 *
	 * @param code
	 * @return
	 */
	@Override
	public Map<String, String> getTokenByCode(String appid, String secret, String code, String grant_type) {

		Map<String, String> result = new HashMap<String, String>();

		String urlstr = WeixinpayConfig.accessTokenUrlBycode + "?appid="
				+ appid
				+ "&secret="
				+ secret
				+ "&code="
				+ code
				+ "&grant_type=" + grant_type;
		// 获取要发送的网页代码
		StringBuffer document = new StringBuffer();
		URL url;
		try {
			url = new URL(urlstr);
			URLConnection conn = url.openConnection();
			BufferedReader reader = new BufferedReader(new InputStreamReader(conn
					.getInputStream(), "UTF-8"));
			String line = null;
			while ((line = reader.readLine()) != null)
				document.append(line);
			reader.close();

			System.out.println("=======通过code获取access_token openid(服务号)=======");
			System.out.println(document);
			System.out.println("=======通过code获取access_token openid(服务号)====");

			try {
				JSONObject jo = JSONObject.parseObject(document.toString());
				result.put("openid", jo.getString("openid"));
				result.put("access_token", jo.getString("access_token"));
			} catch (JSONException e) {
				e.getMessage();
			}
		} catch (MalformedURLException e1) {
			e1.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return result;
	}

	@Override
	public String getPhone(String code) {
		log.info("getPhone code:{}", code);
		try {

			String token = getToken();
			log.info("getPhone token:{}", token);

			String urlstr = WeixinpayConfig.getPhone + "?access_token=" + token;

			Map<String, String> map = Maps.newHashMap();
			map.put("code", code);
			String s = OkHttpUtil.postA(urlstr, map);


			log.info("getPhone wewixin result:{}", s);
			JSONObject jo = JSONObject.parseObject(s);
			String phoneInfo = jo.getString("phone_info");
			if (StringUtils.isNotBlank(phoneInfo)) {
				JSONObject phoneInfoJson = JSONObject.parseObject(phoneInfo);

				String phoneNumber = phoneInfoJson.getString("phoneNumber");
				return phoneNumber;
			}

		} catch (Exception e) {
			log.error("getPhone e:{}", e);
		}
		return "";
	}

	private String getToken(){
		String key = WeixinpayConfig.mini_appId + "access_token";
		String token = (String) redisUtil.get(key);
		if(StringUtils.isNotBlank(token)){
			return token;
		}
		String urlstr = WeixinpayConfig.accessTokenUrlBykey + "?appid="
				+ WeixinpayConfig.mini_appId
				+ "&secret="
				+ WeixinpayConfig.mini_appSecret
				+ "&grant_type=client_credential";
		// 获取要发送的网页代码
		StringBuffer document = new StringBuffer();
		URL url;
		try {
			url = new URL(urlstr);
			URLConnection conn = url.openConnection();
			BufferedReader reader = new BufferedReader(new InputStreamReader(conn
					.getInputStream(), "UTF-8"));
			String line = null;
			while ((line = reader.readLine()) != null)
				document.append(line);
			reader.close();

			try {
				JSONObject jo = JSONObject.parseObject(document.toString());
				String access_token = jo.getString("access_token");
				if(StringUtils.isNotBlank(access_token)){

					redisUtil.set(key, access_token, 1, TimeUnit.HOURS);
				}
				return access_token;
			} catch (JSONException e) {
				log.info("getToken e:{}",e);
			}
		} catch (MalformedURLException e1) {
			log.info("getToken e1:{}",e1);
		} catch (IOException e) {
			log.info("getToken e:{}",e);
		}
		return null;
	}

	/**
	 * 获取微信用户信息(服务号)
	 *
	 * @return
	 */
	@Override
	public WxUerInfoDTO getUserInfo(String access_token, String openid) {

		String urlstr = "https://api.weixin.qq.com/sns/userinfo?access_token="
				+ access_token + "&openid=" + openid + "&lang=zh_CN";
		// 获取要发送的网页代码
		WxUerInfoDTO wxUerInfoDTO = null;
		StringBuffer document = new StringBuffer();
		URL url;
		try {
			url = new URL(urlstr);
			URLConnection conn = url.openConnection();
			BufferedReader reader = new BufferedReader(new InputStreamReader(conn
					.getInputStream(), "UTF-8"));
			String line = null;
			while ((line = reader.readLine()) != null)
				document.append(line);
			reader.close();

			log.info("====获取微信用户信息======");
			log.info(document.toString());
			log.info("====获取微信用户信息=======");

			try {
				ObjectMapper mapper = new ObjectMapper();
				wxUerInfoDTO = mapper.readValue(document.toString(), WxUerInfoDTO.class);
			} catch (Exception e) {
				log.debug("转WxUerInfoDTO对象失败：" + e.getMessage());
			}
		} catch (MalformedURLException e1) {
			log.debug("获取微信用户信息(服务号)异常：" + e1.getMessage());
		} catch (IOException e) {
			log.debug("获取微信用户信息(服务号)异常：" + e.getMessage());
		}
		return wxUerInfoDTO;
	}

	/**
	 * 申请退款
	 *
	 * @param appid
	 * @param mch_id
	 * @param apiKey
	 * @param out_trade_no 订单号
	 * @param total_fee
	 * @param refund_fee
	 * @param refund_desc
	 * @return
	 */
	@Override
	public Map<String, String> refund(String appid, String mch_id, String apiKey, String out_trade_no,
									  Double total_fee, Double refund_fee, String refund_desc) {

		log.info("进行微信申请退款");
		// 获取结果信息
		Map<String, String> result = null;

		PayConfig config = null;
		try {
			config = new PayConfig(appid, mch_id, apiKey);
		} catch (Exception e1) {
			e1.printStackTrace();
		}

		WXPay wxpay = new WXPay(config);
		Double total_fee_str = total_fee * 100;
		Double refund_fee_str = refund_fee * 100;
		String total_fee_data = total_fee_str.toString().substring(0, total_fee_str.toString().indexOf("."));
		String refund_fee_data = refund_fee_str.toString().substring(0, refund_fee_str.toString().indexOf("."));
		Map<String, String> data = new HashMap<String, String>();
		data.put("transaction_id", out_trade_no);
		data.put("out_refund_no", UUID.randomUUID().toString().replace("-", ""));
		data.put("total_fee", total_fee_data);
		data.put("refund_fee", refund_fee_data);
		data.put("notify_url", WeixinpayConfig.refundNotifyUrl);

		try {
			result = wxpay.refund(data);
			log.info("发起微信申请退款，返回参数：" + result);
        	/*if("SUCCESS".equals(result.get("return_code"))){
        		log.info("发起微信申请退款-调用微信退款接口成功");
        		return true;
        	}else{
        		log.info("发起微信申请退款-调用微信退款接口失败。return_msg："+result.get("return_msg"));
        		return false;
        	}*/
		} catch (Exception e) {
			e.printStackTrace();
			log.info("调用微信退款接口异常");
		}

		return result;
	}

	/**
	 * 微信支付统一下单
	 */
	private Map<String, String> unifiedorder(WeiXinPay weiXinPay) {
		log.info("进行微信预支付下单");
		// 获取结果信息
		Map<String, String> result = null;
		// 通知地址
		String notifyUrl = WeixinpayConfig.notifyUrl;

		PayConfig config = null;
		try {
			config = new PayConfig(weiXinPay.getAppId(), weiXinPay.getMchId(), weiXinPay.getApiKey());
		} catch (Exception e1) {
			e1.printStackTrace();
		}

		WXPay wxpay = new WXPay(config);

		Map<String, String> data = new HashMap<String, String>();
		data.put("body", weiXinPay.getBody());
		data.put("out_trade_no", weiXinPay.getOutTradeNo());
		data.put("device_info", "");
		data.put("fee_type", "CNY");
		data.put("total_fee", weiXinPay.getTotalFee() + "");
		data.put("spbill_create_ip", weiXinPay.getIp());
		data.put("notify_url", notifyUrl);
		data.put("trade_type", weiXinPay.getTradeType());
		data.put("product_id", weiXinPay.getProductId());
		if ("JSAPI".equals(weiXinPay.getTradeType())) {
			data.put("openid", weiXinPay.getOpenId());
		}
		if (weiXinPay.getSceneInfo() != null && !"".equals(weiXinPay.getSceneInfo())) {
			data.put("scene_info", weiXinPay.getSceneInfo());
		}

		try {
			result = wxpay.unifiedOrder(data);
		} catch (Exception e) {
			e.printStackTrace();
		}
		log.info("微信预支付下单返回数据：" + result.toString());

		return result;
	}


	@Override
	public Map<String, String> queryPayStatus(String orderNo) {

			WeiXinPay weiXinPay = new WeiXinPay();
			weiXinPay.setAppId(WeixinpayConfig.appId);
			weiXinPay.setAppSecret(WeixinpayConfig.appSecret);
			weiXinPay.setMchId(WeixinpayConfig.mchId);
			weiXinPay.setApiKey(WeixinpayConfig.apiKey);
			weiXinPay.setOutTradeNo(orderNo);

			//进行微信订单状态查询
			Map<String, String> resp = orderQuery(weiXinPay);
			return resp;

	}

	@Override
	public WxUerInfoDTO oauth2getAccessToken(String code,String memCard) {

		String wx_fwh_access_token = (String)stringRedisTemplate.opsForValue().get("wx_fwh_access_token" + code);
		String wx_fwh_openid = (String)stringRedisTemplate.opsForValue().get("wx_fwh_openid" + code);
		if (wx_fwh_access_token == null || wx_fwh_openid == null) {
			Map<String, String> tokenMap = getTokenByCode(WeixinpayConfig.appId, WeixinpayConfig.appSecret,code, "authorization_code");
			log.info("微信授权tokenMap为：" + tokenMap);
			wx_fwh_access_token = tokenMap.get("access_token");
			log.info("微信授权wx_fwh_access_token为：" + wx_fwh_access_token);
			wx_fwh_openid = tokenMap.get("openid");
			log.info("微信授权wx_fwh_openid为：" + wx_fwh_openid);
			stringRedisTemplate.opsForValue().set("wx_fwh_access_token" + code,wx_fwh_access_token, 7100, TimeUnit.SECONDS );
			stringRedisTemplate.opsForValue().set("wx_fwh_openid" + code,wx_fwh_openid, 7100,TimeUnit.SECONDS );
		} else {
			stringRedisTemplate.opsForValue().get("wx_fwh_access_token" + code);
			stringRedisTemplate.opsForValue().get("wx_fwh_openid" + code);
		}

		// 获取微信用户信息
		WxUerInfoDTO wxUerInfoDTO = getUserInfo(wx_fwh_access_token, wx_fwh_openid);
		log.info(wxUerInfoDTO.getNickname());
		if (wxUerInfoDTO == null) {
			log.info("获取微信用户信息异常，返回手机号登录页面");
			return null;
		}

		JSONObject userInfo = generateWxUserInfo(WeixinpayConfig.appId, WeixinpayConfig.appSecret, wxUerInfoDTO.getOpenid());
		log.info("获取用户基本信息：" + userInfo.toString() + "*******************");
		if (userInfo != null) {
			if (userInfo.get("subscribe") != null) {
				wxUerInfoDTO.setSubscribe((Integer) userInfo.get("subscribe"));
			}
		}
//		QkjMember member = memberDao.findByMemCard(memCard);
//		if (member != null){
//			//判断用户是否绑定
//			if (StringUtils.isEmpty(member.getWxId())){
//				//绑定
//				member.setWxId(wxUerInfoDTO.getUnionid());
//				memberDao.save(member);
//			}
//		}

		return wxUerInfoDTO;
	}

	@Override
	public Map<String, String> getTokenByCodeNew(String appid, String secret, String code, String grant_type) {
		log.info("getTokenByCodeNew join appid:{} secret:{} code:{} grant_type:{}", appid, secret, code, grant_type);
		Map<String, String> tokenMap = null;
		String wx_fwh_access_token = (String) stringRedisTemplate.opsForValue().get("wx_fwh_access_token" + code);
		String wx_fwh_openid = (String) stringRedisTemplate.opsForValue().get("wx_fwh_openid" + code);
		if (wx_fwh_access_token == null || wx_fwh_openid == null) {
			// 通过code获取openid
			tokenMap = getTokenByCode(WeixinConsts.appId, WeixinConsts.appSecret, code,
					"authorization_code");
			log.info("getTokenByCodeNew 返回tokenMap为：" + tokenMap);
			wx_fwh_access_token = tokenMap.get("access_token");
			log.info("微信授权登陆，返回wx_fwh_access_token为：" + wx_fwh_access_token);
			wx_fwh_openid = tokenMap.get("openid");
			log.info("微信授权登陆，返回wx_fwh_openid为：" + wx_fwh_openid);

			stringRedisTemplate.opsForValue().set("wx_fwh_access_token" + code, wx_fwh_access_token, 7100, TimeUnit.SECONDS);
			stringRedisTemplate.opsForValue().set("wx_fwh_openid" + code, wx_fwh_openid, 7100, TimeUnit.SECONDS);

		} else {
			stringRedisTemplate.opsForValue().get("wx_fwh_access_token" + code);
			stringRedisTemplate.opsForValue().get("wx_fwh_openid" + code);
			tokenMap.put("access_token", wx_fwh_access_token);
			tokenMap.put("openid", wx_fwh_openid);
		}
		log.info("getTokenByCodeNew tokenMap:{}", tokenMap);
		return tokenMap;
	}

	/**
	 * 微信支付支付查询订单状态
	 */
	private Map<String, String> orderQuery(WeiXinPay weiXinPay) {
		log.info("进行微信订单状态查询");
		// 获取结果信息
		Map<String, String> result = null;
		// 通知地址
		String notifyUrl = WeixinpayConfig.notifyUrl;

		PayConfig config = null;
		try {
			config = new PayConfig(weiXinPay.getAppId(), weiXinPay.getMchId(), weiXinPay.getApiKey());
		} catch (Exception e1) {
			e1.printStackTrace();
		}

		WXPay wxpay = new WXPay(config);

		Map<String, String> data = new HashMap<String, String>();
		data.put("nonce_str", WXPayUtil.generateNonceStr());
		data.put("out_trade_no", weiXinPay.getOutTradeNo());
		data.put("notify_url", notifyUrl);
		data.put("appid",WeixinpayConfig.appId);
		data.put("mch_id",WeixinpayConfig.mchId);


		try {
			result = wxpay.orderQuery(data);
		} catch (Exception e) {
			e.printStackTrace();
		}
		log.info("微信订单状态查询："+result.toString());

		return result;
	}
	/**
	 * 获取公众号用于调用微信JS接口的临时票据jsapi_ticket
	 * @return
	 */
	private String getTicket(String access_token){

		Map<String, Object> result = new HashMap<String, Object>();

		String urlstr = WeixinpayConfig.getTicketUrl
				+"?access_token="+access_token+"&type=jsapi";
		// 获取要发送的网页代码
		StringBuffer document = new StringBuffer();
		String ticket = "";
		URL url;
		try {
			url = new URL(urlstr);
			URLConnection conn = url.openConnection();
			BufferedReader reader = new BufferedReader(new InputStreamReader(conn
					.getInputStream(), "UTF-8"));
			String line = null;
			while ((line = reader.readLine()) != null)
				document.append(line);
			reader.close();

			System.out.println("======================");
			System.out.println("======================");
			System.out.println(document);
			System.out.println("======================");
			System.out.println("======================");

			try {
				System.out.println("===" + document + "===");
				JSONObject jo = JSONObject.parseObject(document.toString());
				System.out.println(jo);
				ticket = jo.getString("ticket");

				result.put("access_token", access_token);
			} catch (JSONException e) {
				e.getMessage();
			}
		} catch (MalformedURLException e1) {
			e1.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return ticket;
	}

	/**
	 * 根据微信公众号appId和token,openId获取用户信息
	 *
	 * @param appId
	 *            信公众号appId
	 * @param secret
	 *            信公众号secret
	 * @return access_token
	 */
	@Override
	public JSONObject generateWxUserInfo(String appId, String secret, String openId) {
		String access_token = generateWxAccessToken(appId, secret);
		String requesturl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + access_token + "&openid="
				+ openId + "&lang=zh_CN";
		log.info("根据微信公众号appId和secret获取access_token");
		log.info("根据微信公众号appId和secret获取access_token请求URL：" + requesturl);

		String result = com.cirle.scientific.utils.HttpClientUtil.sendGetSSL(requesturl);

		log.info("根根据微信公众号appId和secret获取access_token的请求结果" + result);

		JSONObject obj = null;
		try {
			obj = JSONObject.parseObject(result);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return obj;
	}

	/**
	 * 根据微信公众号appId和secret获取access_token
	 *
	 * @param appId
	 *            信公众号appId
	 * @param secret
	 *            信公众号secret
	 * @return access_token
	 */
	private String generateWxAccessToken(String appId, String secret) {

		log.info("根据微信公众号appId和secret获取access_token");
		String result = "";
		if (redisUtil.get(appId + "_final_access_token") != null) {
			result = (String) redisUtil.get(appId + "_final_access_token");
			return result;
		}

		String requesturl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId
				+ "&secret=" + secret;

		log.info("根据微信公众号appId和secret获取access_token请求URL：" + requesturl);

		String s = com.cirle.scientific.utils.HttpClientUtil.sendGetSSL(requesturl);

		log.info("根根据微信公众号appId和secret获取access_token的请求结果" + s);
		ObjectMapper mapper = new ObjectMapper();
		Map<String, Object> resultJson = null;
		try {
			resultJson = mapper.readValue(s, Map.class);
		} catch (Exception e) {
			e.printStackTrace();
		}

		log.info("根据微信公众号appId和secret获取access_token的URL请求返回结果：" + resultJson);

		if (resultJson.containsKey("errcode")) {
			int errcode = (int) resultJson.get("errcode");
			String errmsg = (String) resultJson.get("errmsg");
			log.warn("根据微信公众号appId和secret获取access_token返回错误，错误代码：" + errcode + ",错误信息：" + errmsg);
			return "-1";
		}

		String access_token = (String) resultJson.get("access_token");
		Integer expires_in = (Integer) resultJson.get("expires_in");

		log.info("根据微信公众号appId和secret获取access_token的返回值,access_token=" + access_token + "，expires_in=" + expires_in);

		redisUtil.set(appId + "_final_access_token", access_token, 5400);

		return access_token;
	}
}
