diff --git a/README.md b/README.md index 01f9cddc..876eefc4 100644 --- a/README.md +++ b/README.md @@ -48,10 +48,14 @@ weixin4j + 优化了代码 +* 2014-11-06 + + + **weixin-base**: 删除`WeixinConfig`类只保留`WeixinAccount`类 + + + **weixin-mp**: 新增`退款接口` + 接下来 ------ -* 公众号退款接口 - * 公众号智能接口 * 微信消息加密 diff --git a/weixin4j-base/README.md b/weixin4j-base/README.md index 2db9dced..ce482a10 100644 --- a/weixin4j-base/README.md +++ b/weixin4j-base/README.md @@ -17,4 +17,8 @@ weixin4j-base + `TokenApi`重命名为`TokenHolder` - + 新增`WeixinConfig`等类 \ No newline at end of file + + 新增`WeixinConfig`等类 + +* 2014-11-06 + + + 删除`WeixinConfig`类只保留`WeixinAccount`类 \ No newline at end of file diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/HttpRequest.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/HttpRequest.java index dd861c35..d5eca567 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/HttpRequest.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/HttpRequest.java @@ -47,7 +47,7 @@ import com.foxinmy.weixin4j.exception.WeixinException; */ public class HttpRequest { private final String SUCCESS = "success"; - private AbstractHttpClient client; + protected AbstractHttpClient client; public HttpRequest() { this(150, 100, 10000, 10000); @@ -155,17 +155,17 @@ public class HttpRequest { HttpResponse httpResponse = client.execute(request); StatusLine statusLine = httpResponse.getStatusLine(); HttpEntity httpEntity = httpResponse.getEntity(); - int status = statusLine.getStatusCode(); if (status != HttpStatus.SC_OK) { - throw new WeixinException(status + "", "request fail"); + throw new WeixinException(Integer.toString(status), + "request fail"); } // 301或者302 if (status == HttpStatus.SC_MOVED_PERMANENTLY || status == HttpStatus.SC_MOVED_TEMPORARILY) { - throw new WeixinException(status + "", String.format( - "the page was redirected to %s", - httpResponse.getFirstHeader("location"))); + throw new WeixinException(Integer.toString(status), + String.format("the page was redirected to %s", + httpResponse.getFirstHeader("location"))); } byte[] data = EntityUtils.toByteArray(httpEntity); response = new Response(); @@ -186,8 +186,8 @@ public class HttpRequest { JsonResult jsonResult = response.getAsJsonResult(); response.setJsonResult(true); if (jsonResult.getCode() != 0) { - throw new WeixinException(jsonResult.getCode() + "", - jsonResult.getDesc()); + throw new WeixinException(Integer.toString(jsonResult + .getCode()), jsonResult.getDesc()); } return response; } catch (JSONException e) { @@ -205,7 +205,7 @@ public class HttpRequest { } } } catch (IOException e) { - throw new WeixinException(e.getMessage()); + throw new WeixinException("-1", e.getMessage()); } finally { request.releaseConnection(); } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/SSLHttpRequest.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/SSLHttpRequest.java new file mode 100644 index 00000000..dd5acbd7 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/SSLHttpRequest.java @@ -0,0 +1,48 @@ +package com.foxinmy.weixin4j.http; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.KeyStore; + +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.ssl.SSLSocketFactory; + +/** + * ssl请求 + * + * @className SSLHttpRequest + * @author jy + * @date 2014年11月6日 + * @since JDK 1.7 + * @see + */ +public class SSLHttpRequest extends HttpRequest { + + public SSLHttpRequest(String password, File file) throws IOException { + this(password, new FileInputStream(file)); + } + + public SSLHttpRequest(String password, InputStream inputStream) { + super(); + try { + KeyStore trustStore = KeyStore.getInstance("PKCS12"); + trustStore.load(inputStream, password.toCharArray()); + SSLSocketFactory socketFactory = new SSLSocketFactory(trustStore, + password); + client.getConnectionManager().getSchemeRegistry() + .register(new Scheme("https", 443, socketFactory)); + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + if (inputStream != null) { + inputStream.close(); + } + } catch (Exception ignore) { + ; + } + } + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Token.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Token.java index abaa2e09..ecefbe07 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Token.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Token.java @@ -24,7 +24,6 @@ public class Token implements Serializable { private String accessToken; @JSONField(name = "expires_in") private int expiresIn; - private String openid; private long time; public String getAccessToken() { @@ -43,14 +42,6 @@ public class Token implements Serializable { this.expiresIn = expiresIn; } - public String getOpenid() { - return openid; - } - - public void setOpenid(String openid) { - this.openid = openid; - } - public long getTime() { return time; } @@ -69,6 +60,7 @@ public class Token implements Serializable { @Override public String toString() { - return "Token [accessToken=" + accessToken + ", expiresIn=" + expiresIn + ", openid=" + openid + ", time=" + time + "]"; + return "Token [accessToken=" + accessToken + ", expiresIn=" + expiresIn + + ", time=" + time + "]"; } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinAccount.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinAccount.java index fbe55410..8c7ae02a 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinAccount.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinAccount.java @@ -1,5 +1,7 @@ package com.foxinmy.weixin4j.model; +import java.io.Serializable; + /** * 微信账户信息 * @@ -9,9 +11,16 @@ package com.foxinmy.weixin4j.model; * @since JDK 1.7 * @see */ -public class WeixinAccount extends WeixinConfig { +public class WeixinAccount implements Serializable { private static final long serialVersionUID = 3689999353867189585L; + private String token; + // 支付场景下为用户的openid 其余情况可能是公众号的原始ID + private String openId; + // 公众号身份的唯一标识 + private String appId; + // 公众平台接口 API 的权限获取所需密钥 Key + private String appSecret; // 公众号支付请求中用于加密的密钥 Key,可验证商户唯一身份,PaySignKey 对应于支付场景中的 appKey 值 private String paySignKey; // 财付通商户身份的标识 @@ -30,6 +39,38 @@ public class WeixinAccount extends WeixinConfig { // 是否是订阅号 private boolean isSubscribe; + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public String getOpenId() { + return openId; + } + + public void setOpenId(String openId) { + this.openId = openId; + } + + public String getAppId() { + return appId; + } + + public void setAppId(String appId) { + this.appId = appId; + } + + public String getAppSecret() { + return appSecret; + } + + public void setAppSecret(String appSecret) { + this.appSecret = appSecret; + } + public String getPaySignKey() { return paySignKey; } @@ -98,19 +139,51 @@ public class WeixinAccount extends WeixinConfig { } + public WeixinAccount(String appId, String appSecret) { + this.appId = appId; + this.appSecret = appSecret; + } + + /** + * V3版本字段 + * + * @param appId + * @param appSecret + * @param paySignKey + * @param mchId + */ public WeixinAccount(String appId, String appSecret, String paySignKey, String mchId) { - super(appId, appSecret); + this(appId, appSecret); this.paySignKey = paySignKey; this.mchId = mchId; } + /** + * V2版本字段 + * + * @param appId + * @param appSecret + * @param paySignKey + * @param partnerId + * @param partnerKey + */ public WeixinAccount(String appId, String appSecret, String paySignKey, String partnerId, String partnerKey) { - super(appId, appSecret); + this(appId, appSecret); this.paySignKey = paySignKey; this.partnerId = partnerId; this.partnerKey = partnerKey; } + @Override + public String toString() { + return "WeixinAccount [token=" + token + ", openId=" + openId + + ", appId=" + appId + ", appSecret=" + appSecret + + ", paySignKey=" + paySignKey + ", partnerId=" + partnerId + + ", partnerKey=" + partnerKey + ", mchId=" + mchId + + ", deviceInfo=" + deviceInfo + ", isAlive=" + isAlive + + ", isService=" + isService + ", isSubscribe=" + isSubscribe + + "]"; + } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinConfig.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinConfig.java deleted file mode 100644 index 748ce003..00000000 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinConfig.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.foxinmy.weixin4j.model; - -import java.io.Serializable; - -public class WeixinConfig implements Serializable { - - private static final long serialVersionUID = -3454743453282851243L; - - private String token; - // 支付场景下为用户的openid 其余情况可能是公众号的原始ID - private String openId; - // 公众号身份的唯一标识 - private String appId; - // 除了支付请求需要用到 paySignKey,公众平台接口 API 的权限获取所需密 钥 Key - private String appSecret; - - public String getToken() { - return token; - } - - public void setToken(String token) { - this.token = token; - } - - public String getOpenId() { - return openId; - } - - public void setOpenId(String openId) { - this.openId = openId; - } - - public String getAppId() { - return appId; - } - - public void setAppId(String appId) { - this.appId = appId; - } - - public String getAppSecret() { - return appSecret; - } - - public void setAppSecret(String appSecret) { - this.appSecret = appSecret; - } - - public WeixinConfig() { - - } - - public WeixinConfig(String appId, String appSecret) { - this.appId = appId; - this.appSecret = appSecret; - } - - @Override - public String toString() { - return "WeixinConfig [token=" + token + ", openId=" + openId - + ", appId=" + appId + ", appSecret=" + appSecret + "]"; - } - -} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/AbstractTokenHolder.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/AbstractTokenHolder.java index 24d9169d..ec5ca972 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/AbstractTokenHolder.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/AbstractTokenHolder.java @@ -1,7 +1,7 @@ package com.foxinmy.weixin4j.token; import com.foxinmy.weixin4j.http.HttpRequest; -import com.foxinmy.weixin4j.model.WeixinConfig; +import com.foxinmy.weixin4j.model.WeixinAccount; import com.foxinmy.weixin4j.util.ConfigUtil; /** @@ -16,17 +16,17 @@ import com.foxinmy.weixin4j.util.ConfigUtil; public abstract class AbstractTokenHolder implements TokenHolder { protected final String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"; protected final HttpRequest request = new HttpRequest(); - private final WeixinConfig weixinConfig; + private final WeixinAccount weixinAccount; public AbstractTokenHolder() { - this.weixinConfig = ConfigUtil.getWeixinConfig(); + this.weixinAccount = ConfigUtil.getWeixinAccount(); } - public AbstractTokenHolder(String appid, String appsecret) { - this.weixinConfig = new WeixinConfig(appid, appsecret); + public AbstractTokenHolder(WeixinAccount weixinAccount) { + this.weixinAccount = weixinAccount; } - public WeixinConfig getConfig() { - return this.weixinConfig; + public WeixinAccount getAccount() { + return weixinAccount; } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/FileTokenHolder.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/FileTokenHolder.java index 3d855bb8..9a8749ca 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/FileTokenHolder.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/FileTokenHolder.java @@ -12,6 +12,7 @@ import com.alibaba.fastjson.TypeReference; import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.http.Response; import com.foxinmy.weixin4j.model.Token; +import com.foxinmy.weixin4j.model.WeixinAccount; import com.foxinmy.weixin4j.util.ConfigUtil; import com.foxinmy.weixin4j.xml.XStream; @@ -32,8 +33,12 @@ public class FileTokenHolder extends AbstractTokenHolder { super(); } + public FileTokenHolder(WeixinAccount weixinAccount) { + super(weixinAccount); + } + public FileTokenHolder(String appid, String appsecret) { - super(appid, appsecret); + this(new WeixinAccount(appid, appsecret)); } /** @@ -50,8 +55,8 @@ public class FileTokenHolder extends AbstractTokenHolder { */ @Override public Token getToken() throws WeixinException { - String appid = getConfig().getAppId(); - String appsecret = getConfig().getAppSecret(); + String appid = getAccount().getAppId(); + String appsecret = getAccount().getAppSecret(); if (StringUtils.isBlank(appid) || StringUtils.isBlank(appsecret)) { throw new IllegalArgumentException( "appid or appsecret not be null!"); @@ -65,7 +70,6 @@ public class FileTokenHolder extends AbstractTokenHolder { if (token_file.exists()) { token = XStream.get(new FileInputStream(token_file), Token.class); - long expise_time = token.getTime() + (token.getExpiresIn() * 1000) - 3; if (expise_time > now_time) { @@ -79,7 +83,6 @@ public class FileTokenHolder extends AbstractTokenHolder { token = response.getAsObject(new TypeReference() { }); token.setTime(now_time); - token.setOpenid(appid); XStream.to(token, new FileOutputStream(token_file)); } catch (IOException e) { throw new WeixinException("-1", "IO ERROR"); diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/RedisTokenHolder.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/RedisTokenHolder.java index 6367bc24..1e4c1a94 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/RedisTokenHolder.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/RedisTokenHolder.java @@ -10,6 +10,7 @@ import redis.clients.jedis.exceptions.JedisException; import com.alibaba.fastjson.TypeReference; import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.model.Token; +import com.foxinmy.weixin4j.model.WeixinAccount; /** * 基于redis保存的Token获取类 @@ -26,17 +27,7 @@ public class RedisTokenHolder extends AbstractTokenHolder { private JedisPool jedisPool; - public RedisTokenHolder() { - super(); - } - - public RedisTokenHolder(String appid, String appsecret) { - this(appid, appsecret, "localhost", 6379); - } - - public RedisTokenHolder(String appid, String appsecret, String host, - int port) { - super(appid, appsecret); + private void createPool(String host, int port) { JedisPoolConfig poolConfig = new JedisPoolConfig(); poolConfig.setMaxTotal(50); poolConfig.setMaxIdle(5); @@ -46,10 +37,33 @@ public class RedisTokenHolder extends AbstractTokenHolder { this.jedisPool = new JedisPool(poolConfig, host, port); } + public RedisTokenHolder() { + this("localhost", 6379); + } + + public RedisTokenHolder(String host, int port) { + super(); + createPool(host, port); + } + + public RedisTokenHolder(WeixinAccount weixinAccount) { + this(weixinAccount, "localhost", 6379); + } + + public RedisTokenHolder(String appId, String appSecret, String host, + int port) { + this(new WeixinAccount(appId, appSecret), host, port); + } + + public RedisTokenHolder(WeixinAccount weixinAccount, String host, int port) { + super(weixinAccount); + createPool(host, port); + } + @Override public Token getToken() throws WeixinException { - String appid = getConfig().getAppId(); - String appsecret = getConfig().getAppSecret(); + String appid = getAccount().getAppId(); + String appsecret = getAccount().getAppSecret(); if (StringUtils.isBlank(appid) || StringUtils.isBlank(appsecret)) { throw new IllegalArgumentException( "appid or appsecret not be null!"); @@ -68,13 +82,12 @@ public class RedisTokenHolder extends AbstractTokenHolder { }); jedis.setex(key, token.getExpiresIn() - 3, token.getAccessToken()); + token.setTime(System.currentTimeMillis()); } else { token = new Token(); token.setAccessToken(accessToken); token.setExpiresIn(jedis.ttl(key).intValue()); } - token.setTime(System.currentTimeMillis()); - token.setOpenid(appid); } catch (JedisException e) { jedisPool.returnBrokenResource(jedis); } finally { @@ -82,4 +95,4 @@ public class RedisTokenHolder extends AbstractTokenHolder { } return token; } -} +} \ No newline at end of file diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenHolder.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenHolder.java index d3a6bb5e..f84041ff 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenHolder.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenHolder.java @@ -2,7 +2,7 @@ package com.foxinmy.weixin4j.token; import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.model.Token; -import com.foxinmy.weixin4j.model.WeixinConfig; +import com.foxinmy.weixin4j.model.WeixinAccount; /** * 获取Token接口 @@ -17,7 +17,7 @@ import com.foxinmy.weixin4j.model.WeixinConfig; * @see com.foxinmy.weixin4j.token.RedisTokenHolder */ public interface TokenHolder { - public WeixinConfig getConfig(); + public WeixinAccount getAccount(); public Token getToken() throws WeixinException; } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/ConfigUtil.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/ConfigUtil.java index 75cbca62..993ee312 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/ConfigUtil.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/ConfigUtil.java @@ -6,7 +6,6 @@ import java.util.Set; import com.alibaba.fastjson.JSON; import com.foxinmy.weixin4j.model.WeixinAccount; -import com.foxinmy.weixin4j.model.WeixinConfig; /** * 商户配置工具类 @@ -38,9 +37,4 @@ public class ConfigUtil { String text = getValue("account"); return JSON.parseObject(text, WeixinAccount.class); } - - public static WeixinConfig getWeixinConfig() { - String text = getValue("account"); - return JSON.parseObject(text, WeixinConfig.class); - } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/DateUtil.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/DateUtil.java index 6db3b10d..9b2a086c 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/DateUtil.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/DateUtil.java @@ -1,6 +1,7 @@ package com.foxinmy.weixin4j.util; import java.text.DecimalFormat; +import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; @@ -25,7 +26,16 @@ public class DateUtil { return new SimpleDateFormat(yyyyMMddHHmmss).format(date); } - public static String format2fee(double fee) { + public static Date parse2yyyyMMddHHmmss(String date) { + try { + return new SimpleDateFormat(yyyyMMddHHmmss).parse(date); + } catch (ParseException e) { + ; + } + return null; + } + + public static String formaFee2Fen(double fee) { return new DecimalFormat("#").format(fee * 100); } } diff --git a/weixin4j-mp/README.md b/weixin4j-mp/README.md index 0ee477d8..d7a261ad 100644 --- a/weixin4j-mp/README.md +++ b/weixin4j-mp/README.md @@ -28,7 +28,7 @@ weixin4j-mp * **weixin4j-mp-server** - `netty服务器 & 消息分发` + `netty服务器` & `消息分发` 更新LOG ------- @@ -48,4 +48,8 @@ weixin4j-mp + `weixin-mp`分离为`weixin-mp-api`和`weixin-mp-server`两个工程 - + **weixin-mp**: 加入`支付`模块 \ No newline at end of file + + **weixin-mp**: 新增`支付`模块 + +* 2014-11-06 + + + **weixin-mp**: 新增`退款接口` \ No newline at end of file diff --git a/weixin4j-mp/weixin4j-mp-api/README.md b/weixin4j-mp/weixin4j-mp-api/README.md index 4d3bcee2..20722763 100644 --- a/weixin4j-mp/weixin4j-mp-api/README.md +++ b/weixin4j-mp/weixin4j-mp-api/README.md @@ -41,7 +41,7 @@ weixin.properties说明 | media_path | 调用媒体接口时保存媒体文件的物理路径 | | bill_path | 调用支付(`V3`)下载对账单接口保存excel文件的物理路径 | -示例(properties中换行用右斜杆\) +示例(properties中换行用右斜杆\\) > account={"appId":"appId","appSecret":"appSecret", > "token":"开放者的token 非必须","openId":"公众号的openid 非必须", @@ -84,4 +84,8 @@ weixin.properties说明 + 分离为`weixin-mp-api`和`weixin-mp-server`两个工程 - + 加入`支付模块` \ No newline at end of file + + 新增`支付模块` + +* 2014-11-06 + + + 新增`退款申请`接口 \ No newline at end of file diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java index be6c54a5..e3b466e1 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java @@ -2,6 +2,7 @@ package com.foxinmy.weixin4j.mp; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.util.Date; import java.util.List; @@ -25,18 +26,18 @@ import com.foxinmy.weixin4j.mp.model.CustomRecord; import com.foxinmy.weixin4j.mp.model.Following; import com.foxinmy.weixin4j.mp.model.Group; import com.foxinmy.weixin4j.mp.model.MpArticle; +import com.foxinmy.weixin4j.mp.model.OauthToken; import com.foxinmy.weixin4j.mp.model.QRParameter; import com.foxinmy.weixin4j.mp.model.User; -import com.foxinmy.weixin4j.mp.model.OauthToken; import com.foxinmy.weixin4j.mp.msg.model.Article; import com.foxinmy.weixin4j.mp.msg.model.BaseMsg; import com.foxinmy.weixin4j.mp.msg.notify.BaseNotify; import com.foxinmy.weixin4j.mp.payment.v2.Order; import com.foxinmy.weixin4j.mp.payment.v3.Refund; +import com.foxinmy.weixin4j.mp.payment.v3.RefundResult; import com.foxinmy.weixin4j.mp.response.TemplateMessage; import com.foxinmy.weixin4j.mp.type.BillType; import com.foxinmy.weixin4j.mp.type.IdQuery; -import com.foxinmy.weixin4j.mp.type.IdType; import com.foxinmy.weixin4j.token.FileTokenHolder; import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.type.MediaType; @@ -396,8 +397,7 @@ public class WeixinProxy { * href="http://mp.weixin.qq.com/wiki/index.php?title=%E9%AB%98%E7%BA%A7%E7%BE%A4%E5%8F%91%E6%8E%A5%E5%8F%A3#.E5.88.A0.E9.99.A4.E7.BE.A4.E5.8F.91">删除群发 * @see com.foxinmy.weixin4j.mp.api.MassApi * @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#massByGroup(JSONObject, String)} - * @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#massByOpenIds(JSONObject, String...) - + * @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#massByOpenIds(JSONObject, String...) */ public JsonResult deleteMassNews(String msgid) throws WeixinException { return massApi.deleteMassNews(msgid); @@ -720,8 +720,6 @@ public class WeixinProxy { /** * 发货通知 * - * @param weixinAccount - * 商户信息 * @param openId * 用户ID * @param transid @@ -736,28 +734,25 @@ public class WeixinProxy { * @throws WeixinException * @see com.foxinmy.weixin4j.mp.api.PayApi */ - public JsonResult deliverNotify(WeixinAccount weixinAccount, String openId, - String transid, String orderNo, boolean status, String statusMsg) + public JsonResult deliverNotify(String openId, String transid, + String outTradeNo, boolean status, String statusMsg) throws WeixinException { - return payApi.deliverNotify(weixinAccount, openId, transid, orderNo, - status, statusMsg); + return payApi.deliverNotify(openId, transid, outTradeNo, status, + statusMsg); } /** * 订单查询 * - * @param weixinAccount - * 商户信息 - * @param orderNo + * @param outTradeNo * 订单号 * @return 订单信息 * @throws WeixinException * @see com.foxinmy.weixin4j.mp.api.PayApi */ - public Order orderQueryV2(WeixinAccount weixinAccount, String orderNo) + public Order orderQueryV2(WeixinAccount weixinAccount, String outTradeNo) throws WeixinException { - return payApi.orderQueryV2(weixinAccount, new IdQuery(orderNo, - IdType.ORDERNO)); + return payApi.orderQueryV2(outTradeNo); } /** @@ -779,18 +774,15 @@ public class WeixinProxy { /** * V3订单查询 * - * @param weixinAccount - * 商户信息 * @param idQuery * 商户系统内部的订单号, transaction_id、out_trade_no 二 选一,如果同时存在优先级: * transaction_id> out_trade_no * @see com.foxinmy.weixin4j.mp.api.PayApi * @throws WeixinException */ - public com.foxinmy.weixin4j.mp.payment.v3.Order orderQueryV3( - WeixinAccount weixinAccount, IdQuery idQuery) + public com.foxinmy.weixin4j.mp.payment.v3.Order orderQueryV3(IdQuery idQuery) throws WeixinException { - return payApi.orderQueryV3(weixinAccount, idQuery); + return payApi.orderQueryV3(idQuery); } /** @@ -800,8 +792,6 @@ public class WeixinProxy { * 2.微信在次日 9 点启动生成前一天的对账单,建议商户 9 点半后再获取;
* 3.对账单中涉及金额的字段单位为“元”。
* - * @param weixinAccount - * 商户配置 * @param billDate * 下载对账单的日期 * @param billType @@ -812,16 +802,60 @@ public class WeixinProxy { * @throws WeixinException * @throws IOException */ - public File downloadbill(WeixinAccount weixinAccount, Date billDate, - BillType billType) throws WeixinException, IOException { - return payApi.downloadbill(weixinAccount, billDate, billType); + public File downloadbill(Date billDate, BillType billType) + throws WeixinException, IOException { + return payApi.downloadbill(billDate, billType); + } + + /** + * 申请退款(请求需要双向证书)
+ *

+ * 交易时间超过 1 年的订单无法提交退款;
+ * 支持部分退款,部分退需要设置相同的订单号和不同的 out_refund_no。一笔退款失 败后重新提交,要采用原来的 + * out_refund_no。总退款金额不能超过用户实际支付金额。
+ *

+ * + * @param ca + * 证书文件 + * @param idQuery + * ) 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级: + * transaction_id> out_trade_no + * @param outRefundNo + * 商户系统内部的退款单号,商 户系统内部唯一,同一退款单号多次请求只退一笔 + * @param totalFee + * 订单总金额,单位为元 + * @param refundFee + * 退款总金额,单位为元,可以做部分退款 + * @param opUserId + * 操作员帐号, 默认为商户号 + * @see com.foxinmy.weixin4j.mp.api.PayApi + * @throws WeixinException + * @throws IOException + * @return 退款结果 + */ + public RefundResult refund(InputStream ca, IdQuery idQuery, + String outRefundNo, double totalFee, double refundFee, + String opUserId) throws WeixinException, IOException { + return payApi.refund(idQuery, outRefundNo, totalFee, refundFee, + opUserId); + } + + /** + * 使用properties中配置的ca文件 + * + * @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#refund(InputStream, IdQuery, String, double, double, String)} + */ + public RefundResult refund(IdQuery idQuery, String outRefundNo, + double totalFee, double refundFee, String opUserId) + throws WeixinException, IOException { + return payApi.refund(idQuery, outRefundNo, totalFee, refundFee, + opUserId); } /** * 退款查询
* 退款有一定延时,用零钱支付的退款20分钟内到账,银行卡支付的退款 3 个工作日后重新查询退款状态 * - * @param weixinAccount * @param idQuery * 单号 refund_id、out_refund_no、 out_trade_no 、 transaction_id * 四个参数必填一个,优先级为: @@ -830,9 +864,8 @@ public class WeixinProxy { * @return 退款记录 * @throws WeixinException */ - public Refund refundQuery(WeixinAccount weixinAccount, IdQuery idQuery) - throws WeixinException { - return payApi.refundQuery(weixinAccount, idQuery); + public Refund refundQuery(IdQuery idQuery) throws WeixinException { + return payApi.refundQuery(idQuery); } /** @@ -840,33 +873,26 @@ public class WeixinProxy { * 当订单支付失败,调用关单接口后用新订单号重新发起支付,如果关单失败,返回已完 * 成支付请按正常支付处理。如果出现银行掉单,调用关单成功后,微信后台会主动发起退款。 * - * @param weixinAccount - * 商户信息 - * @param order + * @param outTradeNo * 商户系统内部的订单号 * @return 执行结果 * @see com.foxinmy.weixin4j.mp.api.PayApi * @throws WeixinException */ - public XmlResult closeOrder(WeixinAccount weixinAccount, String orderNo) - throws WeixinException { - return payApi.orderQueryV3(weixinAccount, new IdQuery(orderNo, - IdType.ORDERNO)); + public XmlResult closeOrder(String outTradeNo) throws WeixinException { + return payApi.closeOrder(outTradeNo); } /** * native支付URL转短链接 * - * @param weixinAccount - * 商户信息 * @param url * 具有native标识的支付URL * @return 转换后的短链接 * @see com.foxinmy.weixin4j.mp.api.PayApi * @throws WeixinException */ - public String getPayShorturl(WeixinAccount weixinAccount, String url) - throws WeixinException { - return payApi.getShorturl(weixinAccount, url); + public String getPayShorturl(String url) throws WeixinException { + return payApi.getShorturl(url); } } diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/PayApi.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/PayApi.java index 2e336b7b..101a9f15 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/PayApi.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/PayApi.java @@ -2,8 +2,10 @@ package com.foxinmy.weixin4j.mp.api; import java.io.BufferedReader; import java.io.File; +import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.StringReader; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; @@ -16,6 +18,7 @@ import java.util.List; import java.util.Map; import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import com.alibaba.fastjson.JSON; @@ -25,6 +28,7 @@ import com.alibaba.fastjson.parser.Feature; import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.http.JsonResult; import com.foxinmy.weixin4j.http.Response; +import com.foxinmy.weixin4j.http.SSLHttpRequest; import com.foxinmy.weixin4j.http.XmlResult; import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.WeixinAccount; @@ -32,8 +36,10 @@ import com.foxinmy.weixin4j.mp.payment.PayUtil; import com.foxinmy.weixin4j.mp.payment.v2.Order; import com.foxinmy.weixin4j.mp.payment.v3.Refund; import com.foxinmy.weixin4j.mp.payment.v3.RefundConverter; +import com.foxinmy.weixin4j.mp.payment.v3.RefundResult; import com.foxinmy.weixin4j.mp.type.BillType; import com.foxinmy.weixin4j.mp.type.IdQuery; +import com.foxinmy.weixin4j.mp.type.IdType; import com.foxinmy.weixin4j.mp.util.ExcelUtil; import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.util.ConfigUtil; @@ -60,24 +66,23 @@ public class PayApi extends BaseApi { /** * 发货通知 * - * @param weixinAccount - * 商户信息 * @param openId * 用户ID * @param transid * 交易单号 - * @param orderNo + * @param outTradeNo * 订单号 * @param status * 成功|失败 * @param statusMsg * status为失败时携带的信息 - * @return + * @return 发货处理结果 * @throws WeixinException */ - public JsonResult deliverNotify(WeixinAccount weixinAccount, String openId, - String transid, String orderNo, boolean status, String statusMsg) + public JsonResult deliverNotify(String openId, String transid, + String outTradeNo, boolean status, String statusMsg) throws WeixinException { + WeixinAccount weixinAccount = tokenHolder.getAccount(); String delivernotify_uri = getRequestUri("delivernotify_uri"); Token token = tokenHolder.getToken(); @@ -87,7 +92,7 @@ public class PayApi extends BaseApi { // 用户购买的openId param.put("openid", openId); param.put("transid", transid); - param.put("out_trade_no", orderNo); + param.put("out_trade_no", outTradeNo); param.put("deliver_timestamp", System.currentTimeMillis() / 1000 + ""); param.put("deliver_status", status ? "1" : "0"); param.put("deliver_msg", statusMsg); @@ -105,20 +110,17 @@ public class PayApi extends BaseApi { /** * 订单查询 * - * @param weixinAccount - * 商户信息 * @param orderNo * 订单号 * @return * @throws WeixinException */ - public Order orderQueryV2(WeixinAccount weixinAccount, IdQuery idQuery) - throws WeixinException { + public Order orderQueryV2(String orderNo) throws WeixinException { + WeixinAccount weixinAccount = tokenHolder.getAccount(); String orderquery_uri = getRequestUri("orderquery_uri"); Token token = tokenHolder.getToken(); - StringBuilder sb = new StringBuilder(); - sb.append(idQuery.getType().getName()).append(idQuery.getId()); + sb.append("out_trade_no=").append(orderNo); sb.append("&partner=").append(weixinAccount.getPartnerId()); String part = sb.toString(); sb.append("&key=").append(weixinAccount.getPartnerKey()); @@ -149,6 +151,10 @@ public class PayApi extends BaseApi { String order_info = response.getAsJson().getString("order_info"); Order order = JSON.parseObject(order_info, Order.class, Feature.IgnoreNotMatch); + if (order.getRetCode() != 0) { + throw new WeixinException(Integer.toString(order.getRetCode()), + order.getRetMsg()); + } order.setMapData(JSON.parseObject(order_info, new TypeReference>() { })); @@ -177,21 +183,15 @@ public class PayApi extends BaseApi { /** * V3订单查询 * - * @param weixinAccount - * 商户信息 * @param idQuery * 商户系统内部的订单号, transaction_id、out_trade_no 二 选一,如果同时存在优先级: * transaction_id> out_trade_no * @throws WeixinException */ - public com.foxinmy.weixin4j.mp.payment.v3.Order orderQueryV3( - WeixinAccount weixinAccount, IdQuery idQuery) + public com.foxinmy.weixin4j.mp.payment.v3.Order orderQueryV3(IdQuery idQuery) throws WeixinException { - Map map = new HashMap(); - map.put("appid", weixinAccount.getAppId()); - map.put("mch_id", weixinAccount.getMchId()); - map.put("nonce_str", RandomUtil.generateString(16)); - map.put(idQuery.getType().getName(), idQuery.getId()); + WeixinAccount weixinAccount = tokenHolder.getAccount(); + Map map = baseMap2V3(idQuery); String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey()); map.put("sign", sign); String param = map2xml(map); @@ -202,6 +202,67 @@ public class PayApi extends BaseApi { }); } + /** + * 申请退款(请求需要双向证书)
+ *

+ * 交易时间超过 1 年的订单无法提交退款;
+ * 支持部分退款,部分退需要设置相同的订单号和不同的 out_refund_no。一笔退款失 败后重新提交,要采用原来的 + * out_refund_no。总退款金额不能超过用户实际支付金额。
+ *

+ * + * @param ca + * 证书文件 + * @param idQuery + * ) 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级: + * transaction_id> out_trade_no + * @param outRefundNo + * 商户系统内部的退款单号,商 户系统内部唯一,同一退款单号多次请求只退一笔 + * @param totalFee + * 订单总金额,单位为元 + * @param refundFee + * 退款总金额,单位为元,可以做部分退款 + * @param opUserId + * 操作员帐号, 默认为商户号 + * @throws WeixinException + * @throws IOException + * @return 退款结果 + */ + public RefundResult refund(InputStream ca, IdQuery idQuery, + String outRefundNo, double totalFee, double refundFee, + String opUserId) throws WeixinException, IOException { + WeixinAccount weixinAccount = tokenHolder.getAccount(); + Map map = baseMap2V3(idQuery); + map.put("out_refund_no", outRefundNo); + map.put("total_fee", DateUtil.formaFee2Fen(totalFee)); + map.put("refund_fee", DateUtil.formaFee2Fen(refundFee)); + if (StringUtils.isBlank(opUserId)) { + opUserId = weixinAccount.getMchId(); + } + map.put("op_user_id", opUserId); + String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey()); + map.put("sign", sign); + String param = map2xml(map); + String refund_uri = getRequestUri("refund_uri"); + SSLHttpRequest request = new SSLHttpRequest(weixinAccount.getMchId(), + ca); + Response response = request.post(refund_uri, param); + return response.getAsObject(new TypeReference() { + }); + } + + /** + * 使用properties中配置的ca文件 + * + * @see {@link com.foxinmy.weixin4j.mp.api.PayApi#refund(InputStream, IdQuery, String, double, double, String)} + */ + public RefundResult refund(IdQuery idQuery, String outRefundNo, + double totalFee, double refundFee, String opUserId) + throws WeixinException, IOException { + File caFile = new File(ConfigUtil.getValue("ca_file")); + return refund(new FileInputStream(caFile), idQuery, outRefundNo, + totalFee, refundFee, opUserId); + } + /** * native支付URL转短链接 * @@ -212,13 +273,10 @@ public class PayApi extends BaseApi { * @return 转换后的短链接 * @throws WeixinException */ - public String getShorturl(WeixinAccount weixinAccount, String url) - throws WeixinException { - Map map = new HashMap(); - map.put("appid", weixinAccount.getAppId()); - map.put("mch_id", weixinAccount.getMchId()); + public String getShorturl(String url) throws WeixinException { + WeixinAccount weixinAccount = tokenHolder.getAccount(); + Map map = baseMap2V3(null); map.put("long_url", url); - map.put("nonce_str", RandomUtil.generateString(16)); String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey()); map.put("sign", sign); try { @@ -238,20 +296,15 @@ public class PayApi extends BaseApi { * 当订单支付失败,调用关单接口后用新订单号重新发起支付,如果关单失败,返回已完 * 成支付请按正常支付处理。如果出现银行掉单,调用关单成功后,微信后台会主动发起退款。 * - * @param weixinAccount - * 商户信息 - * @param idQuery + * @param outTradeNo * 商户系统内部的订单号 * @return * @throws WeixinException */ - public XmlResult closeOrder(WeixinAccount weixinAccount, IdQuery idQuery) - throws WeixinException { - Map map = new HashMap(); - map.put("appid", weixinAccount.getAppId()); - map.put("mch_id", weixinAccount.getMchId()); - map.put("nonce_str", RandomUtil.generateString(16)); - map.put(idQuery.getType().getName(), idQuery.getId()); + public XmlResult closeOrder(String outTradeNo) throws WeixinException { + WeixinAccount weixinAccount = tokenHolder.getAccount(); + Map map = baseMap2V3(new IdQuery(outTradeNo, + IdType.TRADENO)); String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey()); map.put("sign", sign); String param = map2xml(map); @@ -267,8 +320,6 @@ public class PayApi extends BaseApi { * 2.微信在次日 9 点启动生成前一天的对账单,建议商户 9 点半后再获取;
* 3.对账单中涉及金额的字段单位为“元”。
* - * @param weixinAccount - * 商户配置 * @param billDate * 下载对账单的日期 * @param billType @@ -278,9 +329,9 @@ public class PayApi extends BaseApi { * @throws WeixinException * @throws IOException */ - public File downloadbill(WeixinAccount weixinAccount, Date billDate, - BillType billType) throws WeixinException, IOException { - + public File downloadbill(Date billDate, BillType billType) + throws WeixinException, IOException { + WeixinAccount weixinAccount = tokenHolder.getAccount(); if (billDate == null) { Calendar now = Calendar.getInstance(); now.add(Calendar.DAY_OF_MONTH, -10); @@ -297,11 +348,7 @@ public class PayApi extends BaseApi { if (file.exists()) { return file; } - Map map = new HashMap(); - map.put("appid", weixinAccount.getAppId()); - map.put("mch_id", weixinAccount.getMchId()); - map.put("nonce_str", RandomUtil.generateString(16)); - map.put("device_info", weixinAccount.getDeviceInfo()); + Map map = baseMap2V3(null); map.put("bill_date", _billDate); map.put("bill_type", billType.name()); String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey()); @@ -334,7 +381,6 @@ public class PayApi extends BaseApi { * 退款查询
* 退款有一定延时,用零钱支付的退款20分钟内到账,银行卡支付的退款 3 个工作日后重新查询退款状态 * - * @param weixinAccount 商户信息 * @param idQuery * 单号 refund_id、out_refund_no、 out_trade_no 、 transaction_id * 四个参数必填一个,优先级为: @@ -342,14 +388,9 @@ public class PayApi extends BaseApi { * @return 退款记录 * @throws WeixinException */ - public Refund refundQuery(WeixinAccount weixinAccount, IdQuery idQuery) - throws WeixinException { - Map map = new HashMap(); - map.put("appid", weixinAccount.getAppId()); - map.put("mch_id", weixinAccount.getMchId()); - map.put("nonce_str", RandomUtil.generateString(16)); - map.put("device_info", weixinAccount.getDeviceInfo()); - map.put(idQuery.getType().getName(), idQuery.getId()); + public Refund refundQuery(IdQuery idQuery) throws WeixinException { + WeixinAccount weixinAccount = tokenHolder.getAccount(); + Map map = baseMap2V3(idQuery); String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey()); map.put("sign", sign); String param = map2xml(map); @@ -357,4 +398,24 @@ public class PayApi extends BaseApi { Response response = request.post(refundquery_uri, param); return new RefundConverter().fromXML(response.getAsString()); } + + /** + * V3接口请求基本数据 + * + * @return + */ + private Map baseMap2V3(IdQuery idQuery) { + WeixinAccount weixinAccount = tokenHolder.getAccount(); + Map map = new HashMap(); + map.put("appid", weixinAccount.getAppId()); + map.put("mch_id", weixinAccount.getMchId()); + map.put("nonce_str", RandomUtil.generateString(16)); + if (StringUtils.isNotBlank(weixinAccount.getDeviceInfo())) { + map.put("device_info", weixinAccount.getDeviceInfo()); + } + if (idQuery != null) { + map.put(idQuery.getType().getName(), idQuery.getId()); + } + return map; + } } diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/UserApi.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/UserApi.java index 078264bd..e85fee95 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/UserApi.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/UserApi.java @@ -10,7 +10,7 @@ import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.http.JsonResult; import com.foxinmy.weixin4j.http.Response; import com.foxinmy.weixin4j.model.Token; -import com.foxinmy.weixin4j.model.WeixinConfig; +import com.foxinmy.weixin4j.model.WeixinAccount; import com.foxinmy.weixin4j.mp.model.Following; import com.foxinmy.weixin4j.mp.model.OauthToken; import com.foxinmy.weixin4j.mp.model.User; @@ -45,10 +45,10 @@ public class UserApi extends BaseApi { * @see com.foxinmy.weixin4j.mp.model.OauthToken */ public OauthToken getOauthToken(String code) throws WeixinException { + WeixinAccount weixinAccount = tokenHolder.getAccount(); String user_token_uri = getRequestUri("sns_user_token_uri"); - WeixinConfig weixinConfig = tokenHolder.getConfig(); Response response = request.get(String.format(user_token_uri, - weixinConfig.getAppId(), weixinConfig.getAppSecret(), code)); + weixinAccount.getAppId(), weixinAccount.getAppSecret(), code)); return response.getAsObject(new TypeReference() { }); diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/OauthToken.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/OauthToken.java index 49b8dd6f..f8146343 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/OauthToken.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/OauthToken.java @@ -17,11 +17,21 @@ public class OauthToken extends Token { private static final long serialVersionUID = 1L; + private String openid; + @JSONField(name = "refresh_token") private String refreshToken; private String scope; + public String getOpenid() { + return openid; + } + + public void setOpenid(String openid) { + this.openid = openid; + } + public String getRefreshToken() { return refreshToken; } @@ -40,6 +50,9 @@ public class OauthToken extends Token { @Override public String toString() { - return "UserToken [refreshToken=" + refreshToken + ", scope=" + scope + ", getAccessToken()=" + getAccessToken() + ", getExpiresIn()=" + getExpiresIn() + ", getOpenid()=" + getOpenid() + ", getTime()=" + getTime() + "]"; + return "OauthToken [openid=" + openid + ", refreshToken=" + + refreshToken + ", scope=" + scope + ", getAccessToken()=" + + getAccessToken() + ", getExpiresIn()=" + getExpiresIn() + + ", getTime()=" + getTime() + "]"; } } diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/ApiResult.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/ApiResult.java index d0f5d75b..9952d30b 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/ApiResult.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/ApiResult.java @@ -20,6 +20,8 @@ public class ApiResult extends XmlResult { private String appId;// 微信分配的公众账号 ID商户号 非空 @XStreamAlias("mch_id") private String mchId;// 微信支付分配的商户号 非空 + @XStreamAlias("sub_mch_id") + private String subMchId; // 未知 可能为空 @XStreamAlias("nonce_str") private String nonceStr;// 随机字符串 非空 private String sign;// 签名 非空 @@ -50,6 +52,14 @@ public class ApiResult extends XmlResult { this.mchId = mchId; } + public String getSubMchId() { + return subMchId; + } + + public void setSubMchId(String subMchId) { + this.subMchId = subMchId; + } + public String getNonceStr() { return nonceStr; } @@ -76,8 +86,11 @@ public class ApiResult extends XmlResult { @Override public String toString() { - return "ApiResult [appId=" + appId + ", mchId=" + mchId + ", nonceStr=" - + nonceStr + ", sign=" + sign + ", deviceInfo=" + deviceInfo - + "]"; + return "ApiResult [appId=" + appId + ", mchId=" + mchId + ", subMchId=" + + subMchId + ", nonceStr=" + nonceStr + ", sign=" + sign + + ", deviceInfo=" + deviceInfo + ", getReturnCode()=" + + getReturnCode() + ", getReturnMsg()=" + getReturnMsg() + + ", getResultCode()=" + getResultCode() + ", getErrCode()=" + + getErrCode() + ", getErrCodeDes()=" + getErrCodeDes() + "]"; } } diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/PayPackage.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/PayPackage.java index b2365f69..fb1ace61 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/PayPackage.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/PayPackage.java @@ -52,7 +52,7 @@ public class PayPackage implements Serializable { } public void setTotal_fee(double total_fee) { - this.total_fee = DateUtil.format2fee(total_fee); + this.total_fee = DateUtil.formaFee2Fen(total_fee); } public String getSpbill_create_ip() { @@ -78,7 +78,6 @@ public class PayPackage implements Serializable { public void setTime_start(Date time_start) { this.time_start = time_start != null ? DateUtil .fortmat2yyyyMMddHHmmss(time_start) : null; - ; } public String getTime_expire() { @@ -88,7 +87,6 @@ public class PayPackage implements Serializable { public void setTime_expire(Date time_expire) { this.time_expire = time_expire != null ? DateUtil .fortmat2yyyyMMddHHmmss(time_expire) : null; - ; } public String getGoods_tag() { @@ -116,7 +114,7 @@ public class PayPackage implements Serializable { this.body = body; this.attach = attach; this.out_trade_no = out_trade_no; - this.total_fee = DateUtil.format2fee(total_fee); + this.total_fee = DateUtil.formaFee2Fen(total_fee); this.spbill_create_ip = spbill_create_ip; this.time_start = time_start != null ? DateUtil .fortmat2yyyyMMddHHmmss(time_start) : null; diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/Order.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/Order.java index 3dd922db..c4f5de27 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/Order.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/Order.java @@ -1,8 +1,11 @@ package com.foxinmy.weixin4j.mp.payment.v2; +import java.util.Date; import java.util.Map; +import com.alibaba.fastjson.annotation.JSONField; import com.foxinmy.weixin4j.http.JsonResult; +import com.foxinmy.weixin4j.util.DateUtil; /** * 订单信息 @@ -18,84 +21,104 @@ public class Order extends JsonResult { private static final long serialVersionUID = 4543552984506609920L; // 是查询结果状态码,0 表明成功,其他表明错误; - private String ret_code; + @JSONField(name = "ret_code") + private int retCode; // 是查询结果出错信息; - private String ret_msg; + @JSONField(name = "ret_msg") + private String retMsg; // 是返回信息中的编码方式; - private String input_charset; + @JSONField(name = "input_charset") + private String inputCharset; // 是订单状态,0 为成功,其他为失败; - private String trade_state; + @JSONField(name = "trade_state") + private int tradeState; // 是交易模式,1 为即时到帐,其他保留; - private String trade_mode; + @JSONField(name = "trade_mode") + private int tradeMode; // 是财付通商户号,即前文的 partnerid; private String partner; // 是银行类型; - private String bank_type; + @JSONField(name = "bank_type") + private String bankType; // 是银行订单号; - private String bank_billno; + @JSONField(name = "bank_billno") + private String bankBillno; // 是总金额,单位为分; - private String total_fee; + @JSONField(name = "total_fee") + private int totalFee; // 是币种,1 为人民币; - private String fee_type; + @JSONField(name = "fee_type") + private String feeType; // 是财付通订单号; - private String transaction_id; + @JSONField(name = "transaction_id") + private String transactionId; // 是第三方订单号; - private String out_trade_no; + @JSONField(name = "out_trade_no") + private String outTradeNo; // 表明是否分账,false 为无分账,true 为有分账; - private boolean is_split; + @JSONField(name = "is_split") + private boolean isSplit; // 表明是否退款,false 为无退款,ture 为退款; - private boolean is_refund; + @JSONField(name = "is_refund") + private boolean isRefund; // attach 是商户数据包,即生成订单package 时商户填入的 attach; private String attach; // 支付完成时间; - private String time_end; + @JSONField(name = "time_end") + private String timeEnd; // 物流费用,单位为分; - private String transport_fee; + @JSONField(name = "transport_fee") + private int transportFee; // 物品费用,单位为分; - private String product_fee; + @JSONField(name = "product_fee") + private int productFee; // 折扣价格,单位为分; - private String discount; + private int discount; // 换算成人民币之后的总金额,单位为分,一般看 total_fee 即可。 - private String rmb_total_fee; + @JSONField(name = "rmb_total_fee") + private int rmbTotalFee; - public String getRet_code() { - return ret_code; + @JSONField(serialize = false) + private Map mapData; + + public int getRetCode() { + return retCode; } - public void setRet_code(String ret_code) { - this.ret_code = ret_code; + public void setRetCode(int retCode) { + this.retCode = retCode; } - public String getRet_msg() { - return ret_msg; + public String getRetMsg() { + return retMsg; } - public void setRet_msg(String ret_msg) { - this.ret_msg = ret_msg; + public void setRetMsg(String retMsg) { + this.retMsg = retMsg; } - public String getInput_charset() { - return input_charset; + public String getInputCharset() { + return inputCharset; } - public void setInput_charset(String input_charset) { - this.input_charset = input_charset; + public void setInputCharset(String inputCharset) { + this.inputCharset = inputCharset; } - public String getTrade_state() { - return trade_state; + public int getTradeState() { + return tradeState; } - public void setTrade_state(String trade_state) { - this.trade_state = trade_state; + public void setTradeState(int tradeState) { + this.tradeState = tradeState; } - public String getTrade_mode() { - return trade_mode; + public int getTradeMode() { + return tradeMode; } - public void setTrade_mode(String trade_mode) { - this.trade_mode = trade_mode; + public void setTradeMode(int tradeMode) { + this.tradeMode = tradeMode; } public String getPartner() { @@ -106,68 +129,73 @@ public class Order extends JsonResult { this.partner = partner; } - public String getBank_type() { - return bank_type; + public String getBankType() { + return bankType; } - public void setBank_type(String bank_type) { - this.bank_type = bank_type; + public void setBankType(String bankType) { + this.bankType = bankType; } - public String getBank_billno() { - return bank_billno; + public String getBankBillno() { + return bankBillno; } - public void setBank_billno(String bank_billno) { - this.bank_billno = bank_billno; + public void setBankBillno(String bankBillno) { + this.bankBillno = bankBillno; } - public String getTotal_fee() { - return total_fee; + /** + * 调用接口获取单位为分,get方法转换为元方便使用 + * + * @return 元单位 + */ + public double getTotalFee() { + return totalFee / 100d; } - public void setTotal_fee(String total_fee) { - this.total_fee = total_fee; + public void setTotalFee(int totalFee) { + this.totalFee = totalFee; } - public String getFee_type() { - return fee_type; + public String getFeeType() { + return feeType; } - public void setFee_type(String fee_type) { - this.fee_type = fee_type; + public void setFeeType(String feeType) { + this.feeType = feeType; } - public String getTransaction_id() { - return transaction_id; + public String getTransactionId() { + return transactionId; } - public void setTransaction_id(String transaction_id) { - this.transaction_id = transaction_id; + public void setTransactionId(String transactionId) { + this.transactionId = transactionId; } - public String getOut_trade_no() { - return out_trade_no; + public String getOutTradeNo() { + return outTradeNo; } - public void setOut_trade_no(String out_trade_no) { - this.out_trade_no = out_trade_no; + public void setOutTradeNo(String outTradeNo) { + this.outTradeNo = outTradeNo; } - public boolean isIs_split() { - return is_split; + public boolean isSplit() { + return isSplit; } - public void setIs_split(boolean is_split) { - this.is_split = is_split; + public void setSplit(boolean isSplit) { + this.isSplit = isSplit; } - public boolean isIs_refund() { - return is_refund; + public boolean isRefund() { + return isRefund; } - public void setIs_refund(boolean is_refund) { - this.is_refund = is_refund; + public void setRefund(boolean isRefund) { + this.isRefund = isRefund; } public String getAttach() { @@ -178,48 +206,66 @@ public class Order extends JsonResult { this.attach = attach; } - public String getTime_end() { - return time_end; + public Date getTimeEnd() { + return DateUtil.parse2yyyyMMddHHmmss(timeEnd); } - public void setTime_end(String time_end) { - this.time_end = time_end; + public void setTimeEnd(String timeEnd) { + this.timeEnd = timeEnd; } - public String getTransport_fee() { - return transport_fee; + /** + * 调用接口获取单位为分,get方法转换为元方便使用 + * + * @return 元单位 + */ + public double getTransportFee() { + return transportFee / 100d; } - public void setTransport_fee(String transport_fee) { - this.transport_fee = transport_fee; + public void setTransportFee(int transportFee) { + this.transportFee = transportFee; } - public String getProduct_fee() { - return product_fee; + /** + * 调用接口获取单位为分,get方法转换为元方便使用 + * + * @return 元单位 + */ + public double getProductFee() { + return productFee / 100d; } - public void setProduct_fee(String product_fee) { - this.product_fee = product_fee; + public void setProductFee(int productFee) { + this.productFee = productFee; } - public String getDiscount() { - return discount; + /** + * 调用接口获取单位为分,get方法转换为元方便使用 + * + * @return 元单位 + */ + public double getDiscount() { + return discount / 100d; } - public void setDiscount(String discount) { + public void setDiscount(int discount) { this.discount = discount; } - public String getRmb_total_fee() { - return rmb_total_fee; + /** + * 调用接口获取单位为分,get方法转换为元方便使用 + * + * @return 元单位 + */ + public double getRmbTotalFee() { + return rmbTotalFee / 100d; } - public void setRmb_total_fee(String rmb_total_fee) { - this.rmb_total_fee = rmb_total_fee; + public void setRmbTotalFee(int rmbTotalFee) { + this.rmbTotalFee = rmbTotalFee; } - private Map mapData; - public Map getMapData() { return mapData; } @@ -230,16 +276,16 @@ public class Order extends JsonResult { @Override public String toString() { - return "Order [ret_code=" + ret_code + ", ret_msg=" + ret_msg - + ", input_charset=" + input_charset + ", trade_state=" - + trade_state + ", trade_mode=" + trade_mode + ", partner=" - + partner + ", bank_type=" + bank_type + ", bank_billno=" - + bank_billno + ", total_fee=" + total_fee + ", fee_type=" - + fee_type + ", transaction_id=" + transaction_id - + ", out_trade_no=" + out_trade_no + ", is_split=" + is_split - + ", is_refund=" + is_refund + ", attach=" + attach - + ", time_end=" + time_end + ", transport_fee=" + transport_fee - + ", product_fee=" + product_fee + ", discount=" + discount - + ", rmb_total_fee=" + rmb_total_fee + "]"; + return "Order [retCode=" + retCode + ", retMsg=" + retMsg + + ", inputCharset=" + inputCharset + ", tradeState=" + + tradeState + ", tradeMode=" + tradeMode + ", partner=" + + partner + ", bankType=" + bankType + ", bankBillno=" + + bankBillno + ", totalFee=" + totalFee + ", feeType=" + + feeType + ", transactionId=" + transactionId + + ", outTradeNo=" + outTradeNo + ", isSplit=" + isSplit + + ", isRefund=" + isRefund + ", attach=" + attach + + ", timeEnd=" + timeEnd + ", transportFee=" + transportFee + + ", productFee=" + productFee + ", discount=" + discount + + ", rmbTotalFee=" + rmbTotalFee + ", mapData=" + mapData + "]"; } } diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayFeedback.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayFeedback.java index 624b9c23..70fdf431 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayFeedback.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayFeedback.java @@ -38,66 +38,34 @@ public class PayFeedback extends PayBaseInfo { return feedbackId; } - public void setFeedbackId(String feedbackId) { - this.feedbackId = feedbackId; - } - public String getOpenId() { return openId; } - public void setOpenId(String openId) { - this.openId = openId; - } - public String getTransId() { return transId; } - public void setTransId(String transId) { - this.transId = transId; - } - public String getReason() { return reason; } - public void setReason(String reason) { - this.reason = reason; - } - public String getSolution() { return solution; } - public void setSolution(String solution) { - this.solution = solution; - } - public String getExtInfo() { return extInfo; } - public void setExtInfo(String extInfo) { - this.extInfo = extInfo; - } - public String getPicInfo() { return picInfo; } - public void setPicInfo(String picInfo) { - this.picInfo = picInfo; - } - public String getStatus() { return status; } - public void setStatus(String status) { - this.status = status; - } - @Override public String toString() { return "PayFeedback [feedbackId=" + feedbackId + ", openId=" + openId diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayPackageV2.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayPackageV2.java index 60bf5788..6ad0ebe1 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayPackageV2.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayPackageV2.java @@ -72,7 +72,7 @@ public class PayPackageV2 extends PayPackage { } public void setTransport_fee(double transport_fee) { - this.transport_fee = DateUtil.format2fee(transport_fee); + this.transport_fee = DateUtil.formaFee2Fen(transport_fee); } public String getProduct_fee() { @@ -80,7 +80,7 @@ public class PayPackageV2 extends PayPackage { } public void setProduct_fee(double product_fee) { - this.product_fee = DateUtil.format2fee(product_fee); + this.product_fee = DateUtil.formaFee2Fen(product_fee); } public String getInput_charset() { @@ -125,8 +125,8 @@ public class PayPackageV2 extends PayPackage { this.fee_type = "1"; this.input_charset = "UTF-8"; this.transport_fee = transport_fee > 0d ? DateUtil - .format2fee(transport_fee) : null; - this.product_fee = product_fee > 0 ? DateUtil.format2fee(product_fee) + .formaFee2Fen(transport_fee) : null; + this.product_fee = product_fee > 0 ? DateUtil.formaFee2Fen(product_fee) : null; } diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayWarn.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayWarn.java index 0a54b3d6..52f76c85 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayWarn.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayWarn.java @@ -21,26 +21,14 @@ public class PayWarn extends PayBaseInfo { return errortype; } - public void setErrortype(String errortype) { - this.errortype = errortype; - } - public String getDescription() { return description; } - public void setDescription(String description) { - this.description = description; - } - public String getAlarmcontent() { return alarmcontent; } - public void setAlarmcontent(String alarmcontent) { - this.alarmcontent = alarmcontent; - } - @Override public String toString() { return "PayWarn [errortype=" + errortype + ", description=" diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/Order.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/Order.java index a1bc3e4e..209988a7 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/Order.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/Order.java @@ -1,9 +1,12 @@ package com.foxinmy.weixin4j.mp.payment.v3; +import java.util.Date; + import com.foxinmy.weixin4j.mp.payment.ApiResult; import com.foxinmy.weixin4j.mp.type.CurrencyType; import com.foxinmy.weixin4j.mp.type.TradeState; import com.foxinmy.weixin4j.mp.type.TradeType; +import com.foxinmy.weixin4j.util.DateUtil; import com.thoughtworks.xstream.annotations.XStreamAlias; /** @@ -51,7 +54,6 @@ public class Order extends ApiResult { @XStreamAlias("out_rade_no") private String outTradeNo; // 商家数据包 - @XStreamAlias("attach") private String attach; // 支付完成时间,格式为 yyyyMMddhhmmss @XStreamAlias("time_end") @@ -61,96 +63,58 @@ public class Order extends ApiResult { return tradeState; } - public void setTradeState(TradeState tradeState) { - this.tradeState = tradeState; - } - public String getOpenId() { return openId; } - public void setOpenId(String openId) { - this.openId = openId; - } - public String getIsSubscribe() { return isSubscribe; } - public void setIsSubscribe(String isSubscribe) { - this.isSubscribe = isSubscribe; - } - public TradeType getTradeType() { return tradeType; } - public void setTradeType(TradeType tradeType) { - this.tradeType = tradeType; - } - public String getBankType() { return bankType; } - public void setBankType(String bankType) { - this.bankType = bankType; + /** + * 调用接口获取单位为分,get方法转换为元方便使用 + * + * @return 元单位 + */ + public double getTotalFee() { + return totalFee / 100d; } - public int getTotalFee() { - return totalFee; - } - - public void setTotalFee(int totalFee) { - this.totalFee = totalFee; - } - - public int getCouponFee() { - return couponFee; - } - - public void setCouponFee(int couponFee) { - this.couponFee = couponFee; + /** + * 调用接口获取单位为分,get方法转换为元方便使用 + * + * @return 元单位 + */ + public double getCouponFee() { + return couponFee / 100d; } public CurrencyType getFeeType() { return feeType; } - public void setFeeType(CurrencyType feeType) { - this.feeType = feeType; - } - public String getTransactionId() { return transactionId; } - public void setTransactionId(String transactionId) { - this.transactionId = transactionId; - } - public String getOutTradeNo() { return outTradeNo; } - public void setOutTradeNo(String outTradeNo) { - this.outTradeNo = outTradeNo; - } - public String getAttach() { return attach; } - public void setAttach(String attach) { - this.attach = attach; - } - - public String getTimeEnd() { - return timeEnd; - } - - public void setTimeEnd(String timeEnd) { - this.timeEnd = timeEnd; + public Date getTimeEnd() { + return DateUtil.parse2yyyyMMddHHmmss(timeEnd); } @Override diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/Refund.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/Refund.java index b32bb763..e03915e5 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/Refund.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/Refund.java @@ -33,34 +33,18 @@ public class Refund extends ApiResult { return transactionId; } - public void setTransactionId(String transactionId) { - this.transactionId = transactionId; - } - public String getOrderNo() { return orderNo; } - public void setOrderNo(String orderNo) { - this.orderNo = orderNo; - } - public String getSubMchId() { return subMchId; } - public void setSubMchId(String subMchId) { - this.subMchId = subMchId; - } - public int getCount() { return count; } - public void setCount(int count) { - this.count = count; - } - public List getDetails() { return details; } @@ -71,15 +55,14 @@ public class Refund extends ApiResult { @Override public String toString() { - return "Refund [transactionId=" + transactionId + ", subMchId=" - + subMchId + ", orderNo=" + orderNo + ", count=" + count + return "Refund [transactionId=" + transactionId + ", orderNo=" + + orderNo + ", subMchId=" + subMchId + ", count=" + count + ", details=" + details + ", getAppId()=" + getAppId() + ", getMchId()=" + getMchId() + ", getNonceStr()=" + getNonceStr() + ", getSign()=" + getSign() - + ", getDeviceInfo()=" + getDeviceInfo() + ", toString()=" - + super.toString() + ", getReturnCode()=" + getReturnCode() - + ", getReturnMsg()=" + getReturnMsg() + ", getResultCode()=" - + getResultCode() + ", getErrCode()=" + getErrCode() - + ", getErrCodeDes()=" + getErrCodeDes() + "]"; + + ", getDeviceInfo()=" + getDeviceInfo() + ", getReturnCode()=" + + getReturnCode() + ", getReturnMsg()=" + getReturnMsg() + + ", getResultCode()=" + getResultCode() + ", getErrCode()=" + + getErrCode() + ", getErrCodeDes()=" + getErrCodeDes() + "]"; } } diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundDetail.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundDetail.java index 4266b603..007f05b2 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundDetail.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundDetail.java @@ -2,6 +2,9 @@ package com.foxinmy.weixin4j.mp.payment.v3; import java.io.Serializable; +import org.apache.commons.lang3.StringUtils; + +import com.foxinmy.weixin4j.mp.type.RefundChannel; import com.foxinmy.weixin4j.mp.type.RefundStatus; import com.thoughtworks.xstream.annotations.XStreamAlias; @@ -35,50 +38,37 @@ public class RefundDetail implements Serializable { return outRefundNo; } - public void setOutRefundNo(String outRefundNo) { - this.outRefundNo = outRefundNo; - } - public String getRefundId() { return refundId; } - public void setRefundId(String refundId) { - this.refundId = refundId; - } - public String getRefundChannel() { - return refundChannel; + return StringUtils.isBlank(refundChannel) ? RefundChannel.BALANCE + .name() : refundChannel; } - public void setRefundChannel(String refundChannel) { - this.refundChannel = refundChannel; + /** + * 调用接口获取单位为分,get方法转换为元方便使用 + * + * @return 元单位 + */ + public double getRefundFee() { + return refundFee / 100d; } - public int getRefundFee() { - return refundFee; - } - - public void setRefundFee(int refundFee) { - this.refundFee = refundFee; - } - - public int getCouponRefundFee() { - return couponRefundFee; - } - - public void setCouponRefundFee(int couponRefundFee) { - this.couponRefundFee = couponRefundFee; + /** + * 调用接口获取单位为分,get方法转换为元方便使用 + * + * @return 元单位 + */ + public double getCouponRefundFee() { + return couponRefundFee / 100d; } public RefundStatus getRefundStatus() { return refundStatus; } - public void setRefundStatus(RefundStatus refundStatus) { - this.refundStatus = refundStatus; - } - @Override public String toString() { return "RefundDetail [outRefundNo=" + outRefundNo + ", refundId=" diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundResult.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundResult.java new file mode 100644 index 00000000..de5ed3f9 --- /dev/null +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundResult.java @@ -0,0 +1,98 @@ +package com.foxinmy.weixin4j.mp.payment.v3; + +import org.apache.commons.lang3.StringUtils; + +import com.foxinmy.weixin4j.mp.payment.ApiResult; +import com.foxinmy.weixin4j.mp.type.RefundChannel; +import com.thoughtworks.xstream.annotations.XStreamAlias; + +/** + * 退款申请结果 + * + * @className RefundResult + * @author jy + * @date 2014年11月6日 + * @since JDK 1.7 + * @see + */ +@XStreamAlias("xml") +public class RefundResult extends ApiResult { + + private static final long serialVersionUID = -3687863914168618620L; + + // 微信订单号 + @XStreamAlias("transaction_id") + private String transactionId; + // 商户系统内部的订单号 + @XStreamAlias("out_trade_no") + private String outTradeNo; + // 商户退款单号 + @XStreamAlias("out_refund_no") + private String outRefundNo; + // 微信退款单号 + @XStreamAlias("refund_id") + private String refundId; + // 退款渠道 ORIGINAL—原路退款,默认 BALANCE—退回到余额 + @XStreamAlias("refund_channel") + private String refundChannel; + // 退款总金额,单位为元,可以做部分退款 + @XStreamAlias("refund_fee") + private int refundFee; + // 现金券退款金额<=退款金 额,退款金额-现金券退款金 额为现金 + @XStreamAlias("coupon_refund_fee") + private int couponRefundFee; + + public String getTransactionId() { + return transactionId; + } + + public String getOutTradeNo() { + return outTradeNo; + } + + public String getOutRefundNo() { + return outRefundNo; + } + + public String getRefundId() { + return refundId; + } + + public String getRefundChannel() { + return StringUtils.isBlank(refundChannel) ? RefundChannel.BALANCE + .name() : refundChannel; + } + + /** + * 调用接口获取单位为分,get方法转换为元方便使用 + * + * @return 元单位 + */ + public double getRefundFee() { + return refundFee / 100d; + } + + /** + * 调用接口获取单位为分,get方法转换为元方便使用 + * + * @return 元单位 + */ + public double getCouponRefundFee() { + return couponRefundFee / 100d; + } + + @Override + public String toString() { + return "RefundResult [transactionId=" + transactionId + ", outTradeNo=" + + outTradeNo + ", outRefundNo=" + outRefundNo + ", refundId=" + + refundId + ", refundChannel=" + refundChannel + + ", refundFee=" + refundFee + ", couponRefundFee=" + + couponRefundFee + ", getAppId()=" + getAppId() + + ", getMchId()=" + getMchId() + ", getNonceStr()=" + + getNonceStr() + ", getSign()=" + getSign() + + ", getDeviceInfo()=" + getDeviceInfo() + ", getReturnCode()=" + + getReturnCode() + ", getReturnMsg()=" + getReturnMsg() + + ", getResultCode()=" + getResultCode() + ", getErrCode()=" + + getErrCode() + ", getErrCodeDes()=" + getErrCodeDes() + "]"; + } +} diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/IdType.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/IdType.java index 4ffde3ff..bd517fb2 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/IdType.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/IdType.java @@ -12,7 +12,7 @@ package com.foxinmy.weixin4j.mp.type; public enum IdType { REFUNDID("refund_id"), // 微信退款单号 TRANSACTIONID("transaction_id"), // 微信订单号 - ORDERNO("out_trade_no"), // 商户订单号 + TRADENO("out_trade_no"), // 商户订单号 REFUNDNO("out_refund_no"); // 商户退款号 private String name; diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/RefundChannel.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/RefundChannel.java new file mode 100644 index 00000000..672bdcf0 --- /dev/null +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/RefundChannel.java @@ -0,0 +1,15 @@ +package com.foxinmy.weixin4j.mp.type; + +/** + * 退款渠道 + * + * @className RefundChannel + * @author jy + * @date 2014年11月6日 + * @since JDK 1.7 + * @see + */ +public enum RefundChannel { + ORIGINAL, // 原路退款 + BALANCE;// 退回到余额 +} diff --git a/weixin4j-mp/weixin4j-mp-api/src/test/java/com/foxinmy/weixin4j/mp/test/msg/MessagePush.java b/weixin4j-mp/weixin4j-mp-api/src/test/java/com/foxinmy/weixin4j/mp/test/msg/MessagePush.java index 30284374..fd38a509 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/test/java/com/foxinmy/weixin4j/mp/test/msg/MessagePush.java +++ b/weixin4j-mp/weixin4j-mp-api/src/test/java/com/foxinmy/weixin4j/mp/test/msg/MessagePush.java @@ -36,11 +36,11 @@ public class MessagePush { int status = statusLine.getStatusCode(); if (status != HttpStatus.SC_OK) { - throw new WeixinException(status + "", "request fail"); + throw new WeixinException(Integer.toString(status), "request fail"); } if (status == HttpStatus.SC_MOVED_PERMANENTLY || status == HttpStatus.SC_MOVED_TEMPORARILY) { - throw new WeixinException(status + "", "uri moved"); + throw new WeixinException(Integer.toString(status), "uri moved"); } return EntityUtils.toString(httpResponse.getEntity(), StandardCharsets.UTF_8); diff --git a/weixin4j-mp/weixin4j-mp-server/README.md b/weixin4j-mp/weixin4j-mp-server/README.md index c0cb4e87..8f87313c 100644 --- a/weixin4j-mp/weixin4j-mp-server/README.md +++ b/weixin4j-mp/weixin4j-mp-server/README.md @@ -23,7 +23,7 @@ weixin4j-mp-server | media_path | 调用媒体接口时保存媒体文件的物理路径 | | bill_path | 调用支付(`V3`)下载对账单接口保存excel文件的物理路径 | -示例(properties中换行用右斜杆\) +示例(properties中换行用右斜杆\\) > account={"appId":"appId","appSecret":"appSecret", > "token":"开放者的token 非必须","openId":"公众号的openid 非必须", diff --git a/weixin4j-mp/weixin4j-mp-server/src/main/resources/weixin.properties b/weixin4j-mp/weixin4j-mp-server/src/main/resources/weixin.properties index 6f07f4bc..2adb3a3c 100644 --- a/weixin4j-mp/weixin4j-mp-server/src/main/resources/weixin.properties +++ b/weixin4j-mp/weixin4j-mp-server/src/main/resources/weixin.properties @@ -12,4 +12,6 @@ qr_path=/tmp/weixin/qr # \u5a92\u4f53\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84 media_path=/tmp/weixin/media # \u5bf9\u8d26\u5355\u4fdd\u5b58\u8def\u5f84 -bill_path=/tmp/weixin/bill \ No newline at end of file +bill_path=/tmp/weixin/bill +# ca\u8bc1\u4e66\u5b58\u653e\u7684\u5b8c\u6574\u8def\u5f84 +ca_file=/tmp/weixin/xxxxx.p12 \ No newline at end of file