| 
				
				
					
				
				
				 | 
			
			 | 
			@@ -338,18 +338,18 @@ public class WxMpServiceImpl implements WxMpService { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    return WxMpQrCodeTicket.fromJson(responseContent); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    public WxMpQrCodeTicket qrCodeCreateLastTicket(String scene_str) throws WxErrorException { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        String url = "https://api.weixin.qq.com/cgi-bin/qrcode/create"; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        JsonObject json = new JsonObject(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        json.addProperty("action_name", "QR_LIMIT_STR_SCENE"); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        JsonObject actionInfo = new JsonObject(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        JsonObject scene = new JsonObject(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        scene.addProperty("scene_str", scene_str); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        actionInfo.add("scene", scene); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        json.add("action_info", actionInfo); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        String responseContent = execute(new SimplePostRequestExecutor(), url, json.toString()); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        return WxMpQrCodeTicket.fromJson(responseContent); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  public WxMpQrCodeTicket qrCodeCreateLastTicket(String scene_str) throws WxErrorException { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    String url = "https://api.weixin.qq.com/cgi-bin/qrcode/create"; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    JsonObject json = new JsonObject(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    json.addProperty("action_name", "QR_LIMIT_STR_SCENE"); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    JsonObject actionInfo = new JsonObject(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    JsonObject scene = new JsonObject(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    scene.addProperty("scene_str", scene_str); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    actionInfo.add("scene", scene); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    json.add("action_info", actionInfo); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    String responseContent = execute(new SimplePostRequestExecutor(), url, json.toString()); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    return WxMpQrCodeTicket.fromJson(responseContent); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  public File qrCodePicture(WxMpQrCodeTicket ticket) throws WxErrorException { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    String url = "https://mp.weixin.qq.com/cgi-bin/showqrcode"; | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -631,77 +631,77 @@ public class WxMpServiceImpl implements WxMpService { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    this.maxRetryTimes = maxRetryTimes; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    @Override | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    public WxMpPrepayIdResult getPrepayId(String openId, String outTradeNo, double amt, String body, String tradeType, String ip, String callbackUrl) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        String nonce_str = System.currentTimeMillis() + ""; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        SortedMap<String, String> packageParams = new TreeMap<String, String>(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        packageParams.put("appid", wxMpConfigStorage.getAppId()); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        packageParams.put("mch_id", wxMpConfigStorage.getPartnerId()); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        packageParams.put("nonce_str", nonce_str); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        packageParams.put("body", body); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        packageParams.put("out_trade_no", outTradeNo); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        packageParams.put("total_fee", (int)(amt*100) + ""); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        packageParams.put("spbill_create_ip", ip); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        packageParams.put("notify_url", callbackUrl); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        packageParams.put("trade_type", tradeType); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        packageParams.put("openid", openId); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        String sign = WxCryptUtil.createSign(packageParams, wxMpConfigStorage.getPartnerKey()); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        String xml = "<xml>" + | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                "<appid>" + wxMpConfigStorage.getAppId() + "</appid>" + | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                "<mch_id>" + wxMpConfigStorage.getPartnerId() + "</mch_id>" + | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                "<nonce_str>" + nonce_str + "</nonce_str>" + | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                "<sign>" + sign + "</sign>" + | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                "<body><![CDATA[" + body + "]]></body>" + | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                "<out_trade_no>" + outTradeNo + "</out_trade_no>" + | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                "<total_fee>" + packageParams.get("total_fee") + "</total_fee>" + | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                "<spbill_create_ip>" + ip + "</spbill_create_ip>" + | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                "<notify_url>" + callbackUrl + "</notify_url>" + | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                "<trade_type>" + tradeType + "</trade_type>" + | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                "<openid>" + openId + "</openid>" + | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                "</xml>"; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/pay/unifiedorder"); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if (httpProxy != null) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            httpPost.setConfig(config); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        StringEntity entity = new StringEntity(xml, Consts.UTF_8); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        httpPost.setEntity(entity); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        try { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            CloseableHttpResponse response = httpClient.execute(httpPost); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            XStream xstream = XStreamInitializer.getInstance(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            xstream.alias("xml", WxMpPrepayIdResult.class); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            WxMpPrepayIdResult wxMpPrepayIdResult = (WxMpPrepayIdResult) xstream.fromXML(responseContent); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            return wxMpPrepayIdResult; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } catch (IOException e) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            e.printStackTrace(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        return new WxMpPrepayIdResult(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  @Override | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  public WxMpPrepayIdResult getPrepayId(String openId, String outTradeNo, double amt, String body, String tradeType, String ip, String callbackUrl) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    String nonce_str = System.currentTimeMillis() + ""; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    SortedMap<String, String> packageParams = new TreeMap<String, String>(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    packageParams.put("appid", wxMpConfigStorage.getAppId()); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    packageParams.put("mch_id", wxMpConfigStorage.getPartnerId()); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    packageParams.put("nonce_str", nonce_str); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    packageParams.put("body", body); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    packageParams.put("out_trade_no", outTradeNo); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    packageParams.put("total_fee", (int)(amt*100) + ""); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    packageParams.put("spbill_create_ip", ip); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    packageParams.put("notify_url", callbackUrl); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    packageParams.put("trade_type", tradeType); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    packageParams.put("openid", openId); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    String sign = WxCryptUtil.createSign(packageParams, wxMpConfigStorage.getPartnerKey()); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    String xml = "<xml>" + | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            "<appid>" + wxMpConfigStorage.getAppId() + "</appid>" + | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            "<mch_id>" + wxMpConfigStorage.getPartnerId() + "</mch_id>" + | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            "<nonce_str>" + nonce_str + "</nonce_str>" + | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            "<sign>" + sign + "</sign>" + | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            "<body><![CDATA[" + body + "]]></body>" + | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            "<out_trade_no>" + outTradeNo + "</out_trade_no>" + | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            "<total_fee>" + packageParams.get("total_fee") + "</total_fee>" + | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            "<spbill_create_ip>" + ip + "</spbill_create_ip>" + | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            "<notify_url>" + callbackUrl + "</notify_url>" + | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            "<trade_type>" + tradeType + "</trade_type>" + | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            "<openid>" + openId + "</openid>" + | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            "</xml>"; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/pay/unifiedorder"); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (httpProxy != null) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      httpPost.setConfig(config); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    @Override | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    public Map<String, String> getJSSDKPayInfo(String openId, String outTradeNo, double amt, String body, String tradeType, String ip, String callbackUrl) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        WxMpPrepayIdResult wxMpPrepayIdResult = getPrepayId(openId, outTradeNo, amt, body, tradeType, ip, callbackUrl); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        String prepayId = wxMpPrepayIdResult.getPrepay_id(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if (prepayId == null || prepayId.equals("")) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            throw new RuntimeException("get prepayid error"); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    StringEntity entity = new StringEntity(xml, Consts.UTF_8); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    httpPost.setEntity(entity); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    try { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      CloseableHttpResponse response = httpClient.execute(httpPost); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      XStream xstream = XStreamInitializer.getInstance(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      xstream.alias("xml", WxMpPrepayIdResult.class); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      WxMpPrepayIdResult wxMpPrepayIdResult = (WxMpPrepayIdResult) xstream.fromXML(responseContent); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      return wxMpPrepayIdResult; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } catch (IOException e) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      e.printStackTrace(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    return new WxMpPrepayIdResult(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        Map<String, String> payInfo = new HashMap<String, String>(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        payInfo.put("appId", wxMpConfigStorage.getAppId()); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        payInfo.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000)); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        payInfo.put("nonceStr", System.currentTimeMillis() + ""); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        payInfo.put("package", "prepay_id=" + prepayId); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        payInfo.put("signType", "MD5"); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        String finalSign = WxCryptUtil.createSign(payInfo, wxMpConfigStorage.getPartnerKey()); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        payInfo.put("sign", finalSign); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        return payInfo; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  @Override | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  public Map<String, String> getJSSDKPayInfo(String openId, String outTradeNo, double amt, String body, String tradeType, String ip, String callbackUrl) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    WxMpPrepayIdResult wxMpPrepayIdResult = getPrepayId(openId, outTradeNo, amt, body, tradeType, ip, callbackUrl); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    String prepayId = wxMpPrepayIdResult.getPrepay_id(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (prepayId == null || prepayId.equals("")) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        throw new RuntimeException("get prepayid error"); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    Map<String, String> payInfo = new HashMap<String, String>(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    payInfo.put("appId", wxMpConfigStorage.getAppId()); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    payInfo.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000)); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    payInfo.put("nonceStr", System.currentTimeMillis() + ""); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    payInfo.put("package", "prepay_id=" + prepayId); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    payInfo.put("signType", "MD5"); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    String finalSign = WxCryptUtil.createSign(payInfo, wxMpConfigStorage.getPartnerKey()); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    payInfo.put("sign", finalSign); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    return payInfo; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} |