From ffc0fc442d2bee5cd42353167b85594df8348e62 Mon Sep 17 00:00:00 2001 From: Daniel Qian Date: Thu, 16 Apr 2015 14:19:47 +0800 Subject: [PATCH 1/7] upgrade to 1.1.5-SNAPSHOT --- README.md | 4 ++-- pom.xml | 2 +- weixin-java-common/pom.xml | 2 +- weixin-java-cp/pom.xml | 2 +- weixin-java-mp/pom.xml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 2e673e84cb..f4ea8ca65c 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ weixin-java-tools me.chanjar weixin-java-mp - 1.1.4 + 1.1.5 ``` @@ -27,7 +27,7 @@ weixin-java-tools me.chanjar weixin-java-cp - 1.1.4 + 1.1.5 ``` diff --git a/pom.xml b/pom.xml index de9f2ed98e..8c0e062748 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 me.chanjar weixin-java-parent - 1.1.4 + 1.1.5-SNAPSHOT pom WeiXin Java Tools - Parent 微信公众号、企业号上级POM diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index a4654ac395..6d4b581b24 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -6,7 +6,7 @@ me.chanjar weixin-java-parent - 1.1.4 + 1.1.5-SNAPSHOT weixin-java-common diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index d89ae4436b..b7cc03fdca 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -6,7 +6,7 @@ me.chanjar weixin-java-parent - 1.1.4 + 1.1.5-SNAPSHOT weixin-java-cp diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index bfb653ece4..16fafd08a5 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -6,7 +6,7 @@ me.chanjar weixin-java-parent - 1.1.4 + 1.1.5-SNAPSHOT weixin-java-mp WeiXin Java Tools - MP From fcd3a9d76b0f2f898130de93c111a9591abb28c8 Mon Sep 17 00:00:00 2001 From: dxw Date: Fri, 24 Apr 2015 15:31:44 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E7=B1=BB=E5=9E=8Barm=E4=B8=BAamr?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/me/chanjar/weixin/common/api/WxConsts.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java index addbd93522..a6bb1b669c 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java @@ -105,7 +105,7 @@ public class WxConsts { /////////////////////// public static final String FILE_JPG = "jpeg"; public static final String FILE_MP3 = "mp3"; - public static final String FILE_ARM = "arm"; + public static final String FILE_AMR = "amr"; public static final String FILE_MP4 = "mp4"; From 5aba724633b97b34397b4f6d097efd11d4165c83 Mon Sep 17 00:00:00 2001 From: oohusl Date: Wed, 29 Apr 2015 20:34:26 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E5=85=AC=E4=BC=97=E5=8F=B7=E6=94=AF?= =?UTF-8?q?=E4=BB=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + .../weixin/common/util/crypto/SHA1.java | 27 +---- .../common/util/crypto/WxCryptUtil.java | 34 ++++++- .../weixin/mp/api/WxMpConfigStorage.java | 4 + .../mp/api/WxMpInMemoryConfigStorage.java | 22 +++++ .../me/chanjar/weixin/mp/api/WxMpService.java | 42 ++++++++ .../weixin/mp/api/WxMpServiceImpl.java | 97 +++++++++++++++++- .../mp/bean/result/WxMpPrepayIdResult.java | 98 +++++++++++++++++++ 8 files changed, 298 insertions(+), 27 deletions(-) create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpPrepayIdResult.java diff --git a/.gitignore b/.gitignore index 740251bad4..336065509d 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ target sw-pom.xml *.iml test-config.xml +.idea diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/SHA1.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/SHA1.java index c97facd304..a711c590d2 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/SHA1.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/SHA1.java @@ -1,5 +1,7 @@ package me.chanjar.weixin.common.util.crypto; +import org.apache.commons.codec.digest.DigestUtils; + import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; @@ -21,7 +23,7 @@ public static String gen(String... arr) throws NoSuchAlgorithmException { for (String a : arr) { sb.append(a); } - return genStr(sb.toString()); + return DigestUtils.sha1Hex(sb.toString()); } /** @@ -40,25 +42,6 @@ public static String genWithAmple(String... arr) throws NoSuchAlgorithmException sb.append('&'); } } - return genStr(sb.toString()); - } - - public static String genStr(String str) throws NoSuchAlgorithmException { - MessageDigest sha1 = MessageDigest.getInstance("SHA1"); - sha1.update(str.getBytes()); - byte[] output = sha1.digest(); - return bytesToHex(output); + return DigestUtils.sha1Hex(sb.toString()); } - - protected static String bytesToHex(byte[] b) { - char hexDigit[] = { '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; - StringBuffer buf = new StringBuffer(); - for (int j = 0; j < b.length; j++) { - buf.append(hexDigit[(b[j] >> 4) & 0x0f]); - buf.append(hexDigit[b[j] & 0x0f]); - } - return buf.toString(); - } - -} + } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/WxCryptUtil.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/WxCryptUtil.java index 363f0be01c..9be54b55a6 100755 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/WxCryptUtil.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/WxCryptUtil.java @@ -14,6 +14,7 @@ package me.chanjar.weixin.common.util.crypto; import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.digest.DigestUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.InputSource; @@ -27,8 +28,7 @@ import java.io.StringReader; import java.nio.charset.Charset; import java.security.NoSuchAlgorithmException; -import java.util.Arrays; -import java.util.Random; +import java.util.*; public class WxCryptUtil { @@ -224,6 +224,36 @@ public String decrypt(String cipherText) { } + /** + * 微信公众号支付签名算法(详见:http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=4_3) + * @param packageParams 原始参数 + * @param signKey 加密Key(即 商户Key) + * @param charset 编码 + * @return 签名字符串 + */ + public static String createSign(Map packageParams, String signKey) { + SortedMap sortedMap = new TreeMap(); + sortedMap.putAll(packageParams); + + List keys = new ArrayList(packageParams.keySet()); + Collections.sort(keys); + + + StringBuffer toSign = new StringBuffer(); + for (String key : keys) { + String value = packageParams.get(key); + if (null != value && !"".equals(value) && !"sign".equals(key) + && !"key".equals(key)) { + toSign.append(key + "=" + value + "&"); + } + } + toSign.append("key=" + signKey); + System.out.println(toSign.toString()); + String sign = DigestUtils.md5Hex(toSign.toString()) + .toUpperCase(); + return sign; + } + /** * 将一个数字转换成生成4个字节的网络字节序bytes数组 * diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java index c54a119dba..46d58bc379 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java @@ -50,6 +50,10 @@ public interface WxMpConfigStorage { public String getSecret(); + public String getPartnerId(); + + public String getPartnerKey(); + public String getToken(); public String getAesKey(); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java index 3033d1789b..c14241f418 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java @@ -11,6 +11,8 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { protected volatile String appId; protected volatile String secret; + protected volatile String partnerId; + protected volatile String partnerKey; protected volatile String token; protected volatile String accessToken; protected volatile String aesKey; @@ -168,6 +170,8 @@ public String toString() { "appId='" + appId + '\'' + ", secret='" + secret + '\'' + ", token='" + token + '\'' + + ", partnerId='" + partnerId + '\'' + + ", partnerKey='" + partnerKey + '\'' + ", accessToken='" + accessToken + '\'' + ", aesKey='" + aesKey + '\'' + ", expiresTime=" + expiresTime + @@ -179,4 +183,22 @@ public String toString() { ", jsapiTicketExpiresTime='" + jsapiTicketExpiresTime + '\'' + '}'; } + + @Override + public String getPartnerId() { + return partnerId; + } + + public void setPartnerId(String partnerId) { + this.partnerId = partnerId; + } + + @Override + public String getPartnerKey() { + return partnerKey; + } + + public void setPartnerKey(String partnerKey) { + this.partnerKey = partnerKey; + } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java index 3205adbe43..b03ce09079 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java @@ -11,9 +11,11 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; +import java.util.Map; /** * 微信API的Service @@ -332,6 +334,18 @@ public interface WxMpService { */ public WxMpQrCodeTicket qrCodeCreateLastTicket(int scene_id) throws WxErrorException; + /** + *
+     * 换取永久字符串二维码ticket
+     * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=生成带参数的二维码
+     * 
+ * + * @param scene_str 参数。字符串类型长度现在为1到64 + * @return + * @throws WxErrorException + */ + public WxMpQrCodeTicket qrCodeCreateLastTicket(String scene_str) throws WxErrorException; + /** *
    * 换取二维码图片文件,jpg格式
@@ -528,4 +542,32 @@ public interface WxMpService {
    */
   void setMaxRetryTimes(int maxRetryTimes);
 
+    /**
+     * 统一下单(详见http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=9_1)
+     * 在发起微信支付前,需要调用统一下单接口,获取"预支付交易会话标识"
+     * @param openId 支付人openId
+     * @param outTradeNo 商户端对应订单号
+     * @param amt 金额(单位元)
+     * @param body 商品描述
+     * @param tradeType 交易类型 JSAPI,NATIVE,APP,WAP
+     * @param ip 发起支付的客户端IP
+     * @param notifyUrl 通知地址
+     * @return
+     */
+    WxMpPrepayIdResult getPrepayId(String openId, String outTradeNo, double amt, String body, String tradeType, String ip, String notifyUrl);
+
+    /**
+     * 该接口调用“统一下单”接口,并拼装JSSDK发起支付请求需要的参数
+     * 详见http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E5.8F.91.E8.B5.B7.E4.B8.80.E4.B8.AA.E5.BE.AE.E4.BF.A1.E6.94.AF.E4.BB.98.E8.AF.B7.E6.B1.82
+     * @param openId 支付人openId
+     * @param outTradeNo 商户端对应订单号
+     * @param amt 金额(单位元)
+     * @param body 商品描述
+     * @param tradeType 交易类型 JSAPI,NATIVE,APP,WAP
+     * @param ip 发起支付的客户端IP
+     * @param notifyUrl 通知地址
+     * @return
+     */
+    Map getJSSDKPayInfo(String openId, String outTradeNo, double amt, String body, String tradeType, String ip, String notifyUrl);
+
 }
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java
index e41a26e534..b2ee18529f 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java
@@ -6,6 +6,7 @@
 import com.google.gson.internal.Streams;
 import com.google.gson.reflect.TypeToken;
 import com.google.gson.stream.JsonReader;
+import com.thoughtworks.xstream.XStream;
 import me.chanjar.weixin.common.bean.WxAccessToken;
 import me.chanjar.weixin.common.bean.WxMenu;
 import me.chanjar.weixin.common.bean.WxJsapiSignature;
@@ -17,13 +18,16 @@
 import me.chanjar.weixin.common.util.RandomUtils;
 import me.chanjar.weixin.common.util.StringUtils;
 import me.chanjar.weixin.common.util.crypto.SHA1;
+import me.chanjar.weixin.common.util.crypto.WxCryptUtil;
 import me.chanjar.weixin.common.util.fs.FileUtils;
 import me.chanjar.weixin.common.util.http.*;
 import me.chanjar.weixin.common.util.json.GsonHelper;
+import me.chanjar.weixin.common.util.xml.XStreamInitializer;
 import me.chanjar.weixin.mp.bean.*;
 import me.chanjar.weixin.mp.bean.result.*;
 import me.chanjar.weixin.mp.util.http.QrCodeRequestExecutor;
 import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+import org.apache.http.Consts;
 import org.apache.http.HttpHost;
 import org.apache.http.auth.AuthScope;
 import org.apache.http.auth.UsernamePasswordCredentials;
@@ -32,6 +36,8 @@
 import org.apache.http.client.config.RequestConfig;
 import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
 import org.apache.http.impl.client.BasicCredentialsProvider;
 import org.apache.http.impl.client.BasicResponseHandler;
 import org.apache.http.impl.client.CloseableHttpClient;
@@ -43,10 +49,9 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.StringReader;
+import java.math.BigDecimal;
 import java.security.NoSuchAlgorithmException;
-import java.util.Date;
-import java.util.List;
-import java.util.UUID;
+import java.util.*;
 
 public class WxMpServiceImpl implements WxMpService {
 
@@ -332,6 +337,19 @@ public WxMpQrCodeTicket qrCodeCreateLastTicket(int scene_id) throws WxErrorExcep
     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";
@@ -613,4 +631,77 @@ public void setMaxRetryTimes(int maxRetryTimes) {
     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 packageParams = new TreeMap();
+        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 = "" +
+                "" + wxMpConfigStorage.getAppId() + "" +
+                "" + wxMpConfigStorage.getPartnerId() + "" +
+                "" + nonce_str + "" +
+                "" + sign + "" +
+                "" +
+                "" + outTradeNo + "" +
+                "" + packageParams.get("total_fee") + "" +
+                "" + ip + "" +
+                "" + callbackUrl + "" +
+                "" + tradeType + "" +
+                "" + openId + "" +
+                "";
+
+        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 Map 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 payInfo = new HashMap();
+        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;
+    }
 }
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpPrepayIdResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpPrepayIdResult.java
new file mode 100644
index 0000000000..252861682b
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpPrepayIdResult.java
@@ -0,0 +1,98 @@
+package me.chanjar.weixin.mp.bean.result;
+
+import java.io.Serializable;
+
+/**
+ * 
+ * 群发消息一发送就返回的结果
+ *
+ * 真正的群发消息是否发送成功要看
+ * http://mp.weixin.qq.com/wiki/index.php?title=高级群发接口#.E4.BA.8B.E4.BB.B6.E6.8E.A8.E9.80.81.E7.BE.A4.E5.8F.91.E7.BB.93.E6.9E.9C
+ *
+ * 
+ * + * @author chanjarster + */ +public class WxMpPrepayIdResult implements Serializable { + private String return_code; + private String return_msg; + private String appid; + private String mch_id; + private String nonce_str; + private String sign; + private String result_code; + private String prepay_id; + private String trade_type; + + public String getReturn_code() { + return return_code; + } + + public void setReturn_code(String return_code) { + this.return_code = return_code; + } + + public String getReturn_msg() { + return return_msg; + } + + public void setReturn_msg(String return_msg) { + this.return_msg = return_msg; + } + + public String getAppid() { + return appid; + } + + public void setAppid(String appid) { + this.appid = appid; + } + + public String getMch_id() { + return mch_id; + } + + public void setMch_id(String mch_id) { + this.mch_id = mch_id; + } + + public String getNonce_str() { + return nonce_str; + } + + public void setNonce_str(String nonce_str) { + this.nonce_str = nonce_str; + } + + public String getSign() { + return sign; + } + + public void setSign(String sign) { + this.sign = sign; + } + + public String getResult_code() { + return result_code; + } + + public void setResult_code(String result_code) { + this.result_code = result_code; + } + + public String getPrepay_id() { + return prepay_id; + } + + public void setPrepay_id(String prepay_id) { + this.prepay_id = prepay_id; + } + + public String getTrade_type() { + return trade_type; + } + + public void setTrade_type(String trade_type) { + this.trade_type = trade_type; + } +} From 29cc3f6558ff214ad77a7b9403386594c2db9826 Mon Sep 17 00:00:00 2001 From: Daniel Qian Date: Thu, 30 Apr 2015 15:39:35 +0800 Subject: [PATCH 4/7] format --- .../me/chanjar/weixin/mp/api/WxMpService.java | 22 +-- .../weixin/mp/api/WxMpServiceImpl.java | 162 +++++++++--------- 2 files changed, 92 insertions(+), 92 deletions(-) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java index b03ce09079..45de6f8cd9 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java @@ -334,17 +334,17 @@ public interface WxMpService { */ public WxMpQrCodeTicket qrCodeCreateLastTicket(int scene_id) throws WxErrorException; - /** - *
-     * 换取永久字符串二维码ticket
-     * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=生成带参数的二维码
-     * 
- * - * @param scene_str 参数。字符串类型长度现在为1到64 - * @return - * @throws WxErrorException - */ - public WxMpQrCodeTicket qrCodeCreateLastTicket(String scene_str) throws WxErrorException; + /** + *
+   * 换取永久字符串二维码ticket
+   * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=生成带参数的二维码
+   * 
+ * + * @param scene_str 参数。字符串类型长度现在为1到64 + * @return + * @throws WxErrorException + */ + public WxMpQrCodeTicket qrCodeCreateLastTicket(String scene_str) throws WxErrorException; /** *
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java
index b2ee18529f..1e08a69f75 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java
@@ -338,18 +338,18 @@ public WxMpQrCodeTicket qrCodeCreateLastTicket(int scene_id) throws WxErrorExcep
     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 void setMaxRetryTimes(int maxRetryTimes) {
     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 packageParams = new TreeMap();
-        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 = "" +
-                "" + wxMpConfigStorage.getAppId() + "" +
-                "" + wxMpConfigStorage.getPartnerId() + "" +
-                "" + nonce_str + "" +
-                "" + sign + "" +
-                "" +
-                "" + outTradeNo + "" +
-                "" + packageParams.get("total_fee") + "" +
-                "" + ip + "" +
-                "" + callbackUrl + "" +
-                "" + tradeType + "" +
-                "" + openId + "" +
-                "";
-
-        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 packageParams = new TreeMap();
+    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 = "" +
+            "" + wxMpConfigStorage.getAppId() + "" +
+            "" + wxMpConfigStorage.getPartnerId() + "" +
+            "" + nonce_str + "" +
+            "" + sign + "" +
+            "" +
+            "" + outTradeNo + "" +
+            "" + packageParams.get("total_fee") + "" +
+            "" + ip + "" +
+            "" + callbackUrl + "" +
+            "" + tradeType + "" +
+            "" + openId + "" +
+            "";
+
+    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 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 payInfo = new HashMap();
-        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 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 payInfo = new HashMap();
+    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;
+  }
 }

From ab916ddd710aa8efe7b41471390341a2e47fdbf8 Mon Sep 17 00:00:00 2001
From: Daniel Qian 
Date: Wed, 13 May 2015 19:47:50 +0800
Subject: [PATCH 5/7] =?UTF-8?q?issue=20#138=20tagAddUsers=20=E6=8E=A5?=
 =?UTF-8?q?=E5=8F=A3=E5=B0=91=E4=BA=86=E4=B8=80=E4=B8=AA=E5=8F=82=E6=95=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../me/chanjar/weixin/cp/api/WxCpService.java |  2 +-
 .../weixin/cp/api/WxCpServiceImpl.java        | 25 +++++++++++++------
 2 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java
index 70d59046dc..ac07ea6b6c 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java
@@ -399,7 +399,7 @@ WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream i
    * @param tagId
    * @param userIds
    */
-  void tagAddUsers(String tagId, List userIds) throws WxErrorException;
+  void tagAddUsers(String tagId, List userIds, List partyIds) throws WxErrorException;
 
   /**
    * 
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java
index c04d753345..0ef29b55f1 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java
@@ -271,7 +271,8 @@ public List departGet() throws WxErrorException {
     return WxCpGsonBuilder.INSTANCE.create()
         .fromJson(
             tmpJsonElement.getAsJsonObject().get("department"),
-            new TypeToken>() { }.getType()
+            new TypeToken>() {
+            }.getType()
         );
   }
 
@@ -389,7 +390,8 @@ public List tagGet() throws WxErrorException {
     return WxCpGsonBuilder.INSTANCE.create()
         .fromJson(
             tmpJsonElement.getAsJsonObject().get("taglist"),
-            new TypeToken>() { }.getType()
+            new TypeToken>() {
+            }.getType()
         );
   }
 
@@ -406,15 +408,24 @@ public List tagGetUsers(String tagId) throws WxErrorException {
   }
 
   @Override
-  public void tagAddUsers(String tagId, List userIds) throws WxErrorException {
+  public void tagAddUsers(String tagId, List userIds, List partyIds) throws WxErrorException {
     String url = "https://qyapi.weixin.qq.com/cgi-bin/tag/addtagusers";
     JsonObject jsonObject = new JsonObject();
     jsonObject.addProperty("tagid", tagId);
-    JsonArray jsonArray = new JsonArray();
-    for (String userId : userIds) {
-      jsonArray.add(new JsonPrimitive(userId));
+    if (userIds != null) {
+      JsonArray jsonArray = new JsonArray();
+      for (String userId : userIds) {
+        jsonArray.add(new JsonPrimitive(userId));
+      }
+      jsonObject.add("userlist", jsonArray);
+    }
+    if (partyIds != null) {
+      JsonArray jsonArray = new JsonArray();
+      for (String userId : partyIds) {
+        jsonArray.add(new JsonPrimitive(userId));
+      }
+      jsonObject.add("partylist", jsonArray);
     }
-    jsonObject.add("userlist", jsonArray);
     post(url, jsonObject.toString());
   }
 

From f7b5b528085884e709443aafc1a0df601a6e61e1 Mon Sep 17 00:00:00 2001
From: Daniel Qian 
Date: Thu, 14 May 2015 08:51:50 +0800
Subject: [PATCH 6/7] fix: compile error

---
 .../src/test/java/me/chanjar/weixin/cp/api/WxCpTagAPITest.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpTagAPITest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpTagAPITest.java
index 0bb7dba92e..b101eeb660 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpTagAPITest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpTagAPITest.java
@@ -42,7 +42,7 @@ public void testTagGet() throws Exception {
   public void testTagAddUsers() throws Exception {
     List userIds = new ArrayList();
     userIds.add(((ApiTestModule.WxXmlCpInMemoryConfigStorage)configStorage).getUserId());
-    wxService.tagAddUsers(tagId, userIds);
+    wxService.tagAddUsers(tagId, userIds, null);
   }
 
   @Test(dependsOnMethods = "testTagAddUsers")

From 72db0a2a76b14e2f9d02db4ef0bac4d7793dfb9b Mon Sep 17 00:00:00 2001
From: Daniel Qian 
Date: Wed, 27 May 2015 09:15:57 +0800
Subject: [PATCH 7/7] update to 1.1.5

---
 pom.xml                    | 2 +-
 weixin-java-common/pom.xml | 2 +-
 weixin-java-cp/pom.xml     | 2 +-
 weixin-java-mp/pom.xml     | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/pom.xml b/pom.xml
index 8c0e062748..090e4760ff 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
   4.0.0
   me.chanjar
   weixin-java-parent
-  1.1.5-SNAPSHOT
+  1.1.5
   pom
   WeiXin Java Tools - Parent
   微信公众号、企业号上级POM
diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml
index 6d4b581b24..b34d29be46 100644
--- a/weixin-java-common/pom.xml
+++ b/weixin-java-common/pom.xml
@@ -6,7 +6,7 @@
   
     me.chanjar
     weixin-java-parent
-    1.1.5-SNAPSHOT
+    1.1.5
   
 
   weixin-java-common
diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml
index b7cc03fdca..e7b7501694 100644
--- a/weixin-java-cp/pom.xml
+++ b/weixin-java-cp/pom.xml
@@ -6,7 +6,7 @@
     
         me.chanjar
         weixin-java-parent
-        1.1.5-SNAPSHOT
+        1.1.5
     
 
     weixin-java-cp
diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml
index 16fafd08a5..3893b1cc0e 100644
--- a/weixin-java-mp/pom.xml
+++ b/weixin-java-mp/pom.xml
@@ -6,7 +6,7 @@
     
         me.chanjar
         weixin-java-parent
-        1.1.5-SNAPSHOT
+        1.1.5
     
     weixin-java-mp
     WeiXin Java Tools - MP