新增代金券接口&字段上的单行注释调整为文档多行注释

This commit is contained in:
jinyu
2015-03-29 22:45:50 +08:00
parent 5557141b93
commit 464359ae7a
155 changed files with 3825 additions and 591 deletions
+9 -1
View File
@@ -31,6 +31,8 @@ weixin4j-mp-api
* Pay3Api `V3支付API`
* CouponApi `代金券API`
* DataApi `数据统计API`
* OauthApi `oauth授权API`
@@ -171,4 +173,10 @@ weixin.properties说明
* 2015-03-25
+ 根据《微信商户平台文档》修缮[Pay3Api](./weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/Pay3Api.java)类
+ 根据《微信商户平台文档》修缮[Pay3Api](./weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/Pay3Api.java)类
* 2015-03-29
+ 单行注释调整为多行文档注释
+ 新增(CouponApi)[./src/main/java/com/foxinmy/weixin4j/mp/api/CouponApi.java]代金券接口
@@ -7,9 +7,13 @@ import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.JsonResult;
import com.foxinmy.weixin4j.http.XmlResult;
import com.foxinmy.weixin4j.model.WeixinMpAccount;
import com.foxinmy.weixin4j.mp.api.CouponApi;
import com.foxinmy.weixin4j.mp.api.Pay2Api;
import com.foxinmy.weixin4j.mp.api.Pay3Api;
import com.foxinmy.weixin4j.mp.api.PayApi;
import com.foxinmy.weixin4j.mp.payment.coupon.CouponDetail;
import com.foxinmy.weixin4j.mp.payment.coupon.CouponResult;
import com.foxinmy.weixin4j.mp.payment.coupon.CouponStock;
import com.foxinmy.weixin4j.mp.payment.v3.ApiResult;
import com.foxinmy.weixin4j.mp.type.BillType;
import com.foxinmy.weixin4j.mp.type.CurrencyType;
@@ -34,9 +38,11 @@ import com.foxinmy.weixin4j.util.ConfigUtil;
* @see <a href="http://pay.weixin.qq.com/wiki/doc/api/index.html">商户平台支付API</a>
*/
public class WeixinPayProxy {
private final PayApi payApi;
private final Pay2Api pay2Api;
private final Pay3Api pay3Api;
private final CouponApi couponApi;
public WeixinPayProxy() {
this(ConfigUtil.getWeixinMpAccount(), new FileTokenHolder(
@@ -60,6 +66,7 @@ public class WeixinPayProxy {
} else {
this.payApi = this.pay3Api;
}
this.couponApi = new CouponApi(weixinAccount);
}
/**
@@ -293,7 +300,7 @@ public class WeixinPayProxy {
* @see com.foxinmy.weixin4j.mp.api.Pay3Api
* @see <a
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4">申请退款API</a>
* @since V3 TODO
* @since V3
* @throws WeixinException
*/
public com.foxinmy.weixin4j.mp.payment.v3.RefundResult refundV3(
@@ -471,4 +478,77 @@ public class WeixinPayProxy {
return pay3Api.interfaceReport(interfaceUrl, executeTime, outTradeNo,
ip, time, returnXml);
}
/**
* 发放代金券(需要证书)
*
* @param caFile
* 证书文件(后缀为*.p12)
* @param couponStockId
* 代金券批次id
* @param partnerTradeNo
* 商户发放凭据号(格式:商户id+日期+流水号),商户侧需保持唯一性
* @param openId
* 用户的openid
* @param opUserId
* 操作员帐号, 默认为商户号 可在商户平台配置操作员对应的api权限 可为空
* @return 发放结果
* @see com.foxinmy.weixin4j.mp.api.CouponApi
* @see com.foxinmy.weixin4j.mp.payment.coupon.CouponResult
* @see <a
* href="http://pay.weixin.qq.com/wiki/doc/api/sp_coupon.php?chapter=12_3">发放代金券接口</a>
* @throws WeixinException
*/
public CouponResult sendCoupon(File caFile, String couponStockId,
String partnerTradeNo, String openId, String opUserId)
throws WeixinException {
return couponApi.sendCoupon(caFile, couponStockId, partnerTradeNo,
openId, opUserId);
}
/**
* 发放代金券采用properties中配置的ca文件
*
* @see {@link com.foxinmy.weixin4j.mp.WeixinPayProxy#sendCoupon(File, String, String, String, String)}
*/
public CouponResult sendCoupon(String couponStockId, String partnerTradeNo,
String openId) throws WeixinException {
File caFile = new File(ConfigUtil.getClassPathValue("ca_file"));
return couponApi.sendCoupon(caFile, couponStockId, partnerTradeNo,
openId, null);
}
/**
* 查询代金券批次
*
* @param couponStockId
* 代金券批次ID
* @return 代金券批次信息
* @see com.foxinmy.weixin4j.mp.api.CouponApi
* @see com.foxinmy.weixin4j.mp.payment.coupon.CouponStock
* @see <a
* href="http://pay.weixin.qq.com/wiki/doc/api/sp_coupon.php?chapter=12_4">查询代金券信息</a>
* @throws WeixinException
*/
public CouponStock queryCouponStock(String couponStockId)
throws WeixinException {
return couponApi.queryCouponStock(couponStockId);
}
/**
* 查询代金券详细
*
* @param couponId
* 代金券ID
* @return 代金券详细信息
* @see com.foxinmy.weixin4j.mp.api.CouponApi
* @see com.foxinmy.weixin4j.mp.payment.coupon.CouponDetail
* @see <a
* href="http://pay.weixin.qq.com/wiki/doc/api/sp_coupon.php?chapter=12_5">查询代金券详细信息</a>
* @throws WeixinException
*/
public CouponDetail queryCouponDetail(String couponId)
throws WeixinException {
return couponApi.queryCouponDetail(couponId);
}
}
@@ -349,7 +349,7 @@ public class WeixinProxy {
* 客服消息对象
* @throws WeixinException
* @see <a
* href="http://mp.weixin.qq.com/wiki/7/12a5a320ae96fecdf0e15cb06123de9f.html">发送客服消息</a>
* href="http://mp.weixin.qq.com/wiki/1/70a29afed17f56d537c833f89be979c9.html#.E5.AE.A2.E6.9C.8D.E6.8E.A5.E5.8F.A3-.E5.8F.91.E6.B6.88.E6.81.AF">发送客服消息</a>
* @see com.foxinmy.weixin4j.msg.model.Text
* @see com.foxinmy.weixin4j.msg.model.Image
* @see com.foxinmy.weixin4j.msg.model.Voice
@@ -0,0 +1,169 @@
package com.foxinmy.weixin4j.mp.api;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import com.alibaba.fastjson.TypeReference;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.Response;
import com.foxinmy.weixin4j.http.SSLHttpRequest;
import com.foxinmy.weixin4j.model.WeixinMpAccount;
import com.foxinmy.weixin4j.mp.payment.PayUtil;
import com.foxinmy.weixin4j.mp.payment.coupon.CouponDetail;
import com.foxinmy.weixin4j.mp.payment.coupon.CouponResult;
import com.foxinmy.weixin4j.mp.payment.coupon.CouponStock;
import com.foxinmy.weixin4j.util.RandomUtil;
/**
* 代金券API
*
* @className CouponApi
* @author jy
* @date 2015年3月25日
* @since JDK 1.7
* @see <a href="http://pay.weixin.qq.com/wiki/doc/api/sp_coupon.php">代金券文档</a>
*/
public class CouponApi extends MpApi {
private final WeixinMpAccount weixinAccount;
public CouponApi(WeixinMpAccount weixinAccount) {
this.weixinAccount = weixinAccount;
}
/**
* 发放代金券(需要证书)
*
* @param caFile
* 证书文件(后缀为*.p12)
* @param couponStockId
* 代金券批次id
* @param partnerTradeNo
* 商户发放凭据号(格式:商户id+日期+流水号),商户侧需保持唯一性
* @param openId
* 用户的openid
* @param opUserId
* 操作员帐号, 默认为商户号 可在商户平台配置操作员对应的api权限 可为空
* @return 发放结果
* @see com.foxinmy.weixin4j.mp.payment.coupon.CouponResult
* @see <a
* href="http://pay.weixin.qq.com/wiki/doc/api/sp_coupon.php?chapter=12_3">发放代金券接口</a>
* @throws WeixinException
*/
public CouponResult sendCoupon(File caFile, String couponStockId,
String partnerTradeNo, String openId, String opUserId)
throws WeixinException {
Map<String, String> map = baseMap();
map.put("coupon_stock_id", couponStockId);
map.put("partner_trade_no", partnerTradeNo);
map.put("openid", openId);
// openid记录数(目前支持num=1
map.put("openid_count", "1");
// 操作员帐号, 默认为商户号 可在商户平台配置操作员对应的api权限
if (StringUtils.isBlank(opUserId)) {
opUserId = weixinAccount.getMchId();
}
map.put("op_user_id", opUserId);
map.put("version", "1.0");
map.put("type", "XML");
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
map.put("sign", sign);
String param = map2xml(map);
String coupon_send_uri = getRequestUri("coupon_send_uri");
Response response = null;
InputStream ca = null;
try {
ca = new FileInputStream(caFile);
SSLHttpRequest request = new SSLHttpRequest(
weixinAccount.getMchId(), ca);
response = request.post(coupon_send_uri, param);
} catch (WeixinException e) {
throw e;
} catch (Exception e) {
throw new WeixinException(e.getMessage());
} finally {
if (ca != null) {
try {
ca.close();
} catch (IOException e) {
;
}
}
}
return response.getAsObject(new TypeReference<CouponResult>() {
});
}
/**
* 查询代金券批次
*
* @param couponStockId
* 代金券批次ID
* @return 代金券批次信息
* @see com.foxinmy.weixin4j.mp.payment.coupon.CouponStock
* @see <a
* href="http://pay.weixin.qq.com/wiki/doc/api/sp_coupon.php?chapter=12_4">查询代金券批次信息</a>
* @throws WeixinException
*/
public CouponStock queryCouponStock(String couponStockId)
throws WeixinException {
Map<String, String> map = baseMap();
map.put("coupon_stock_id", couponStockId);
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
map.put("sign", sign);
String param = map2xml(map);
String couponstock_query_uri = getRequestUri("couponstock_query_uri");
Response response = request.post(couponstock_query_uri, param);
return response.getAsObject(new TypeReference<CouponStock>() {
});
}
/**
* 查询代金券详细
*
* @param couponId
* 代金券ID
* @return 代金券详细信息
* @see com.foxinmy.weixin4j.mp.payment.coupon.CouponDetail
* @see <a
* href="http://pay.weixin.qq.com/wiki/doc/api/sp_coupon.php?chapter=12_5">查询代金券详细信息</a>
* @throws WeixinException
*/
public CouponDetail queryCouponDetail(String couponId)
throws WeixinException {
Map<String, String> map = baseMap();
map.put("coupon_id", couponId);
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
map.put("sign", sign);
String param = map2xml(map);
String coupondetail_query_uri = getRequestUri("coupondetail_query_uri");
Response response = request.post(coupondetail_query_uri, param);
return response.getAsObject(new TypeReference<CouponDetail>() {
});
}
/**
* 接口请求基本数据
*
* @return
*/
private Map<String, String> baseMap() {
Map<String, String> map = new HashMap<String, String>();
map.put("appid", weixinAccount.getId());
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 (StringUtils.isNotBlank(weixinAccount.getSubMchId())) {
map.put("sub_mch_id", weixinAccount.getSubMchId());
}
return map;
}
}
@@ -16,7 +16,7 @@ import com.foxinmy.weixin4j.token.TokenHolder;
* @date 2014年9月26日
* @since JDK 1.7
* @see <a
* href="http://mp.weixin.qq.com/wiki/7/12a5a320ae96fecdf0e15cb06123de9f.html">客服消息</a>
* href="http://mp.weixin.qq.com/wiki/1/70a29afed17f56d537c833f89be979c9.html#.E5.AE.A2.E6.9C.8D.E6.8E.A5.E5.8F.A3-.E5.8F.91.E6.B6.88.E6.81.AF">客服消息</a>
* @see com.foxinmy.weixin4j.mp.message.NotifyMessage
*/
public class NotifyApi extends MpApi {
@@ -34,7 +34,7 @@ public class NotifyApi extends MpApi {
* 客服消息对象
* @throws WeixinException
* @see <a
* href="http://mp.weixin.qq.com/wiki/7/12a5a320ae96fecdf0e15cb06123de9f.html">发送客服消息</a>
* href="http://mp.weixin.qq.com/wiki/1/70a29afed17f56d537c833f89be979c9.html#.E5.AE.A2.E6.9C.8D.E6.8E.A5.E5.8F.A3-.E5.8F.91.E6.B6.88.E6.81.AF">发送客服消息</a>
* @see com.foxinmy.weixin4j.msg.model.Text
* @see com.foxinmy.weixin4j.msg.model.Image
* @see com.foxinmy.weixin4j.msg.model.Voice
@@ -47,7 +47,7 @@ import com.foxinmy.weixin4j.util.DateUtil;
import com.foxinmy.weixin4j.util.RandomUtil;
/**
* V3支付API
* V3(商户平台版)支付API
*
* @className Pay3Api
* @author jy
@@ -1 +1,29 @@
API的实现
* MediaApi `上传/下载媒体文件API`
* NotifyApi `客服消息API`
* CustomApi `多客服API`
* MassApi `群发消息API`
* UserApi `用户管理API`
* GroupApi `分组管理API`
* MenuApi `底部菜单API`
* QrApi `二维码API`
* TmplApi `模板消息API`
* HelperApi `辅助API`
* Pay2Api `V2支付API`
* Pay3Api `V3支付API`
* CouponApi `代金券API`
* DataApi `数据统计API`
* OauthApi `oauth授权API`
@@ -159,4 +159,13 @@ material_media_del_uri={api_cgi_url}/material/del_material?access_token=%s
# \u83b7\u53d6\u5a92\u4f53\u7d20\u6750\u603b\u6570
material_media_count_uri={api_cgi_url}/material/get_materialcount?access_token=%s
# \u83b7\u53d6\u5a92\u4f53\u7d20\u6750\u5217\u8868
material_media_list_uri={api_cgi_url}/material/batchget_material?access_token=%s
material_media_list_uri={api_cgi_url}/material/batchget_material?access_token=%s
# \u53d1\u653e\u4ee3\u91d1\u5238
coupon_send_uri={mch_base_url}/mmpaymkttransfers/send_coupon
# \u67e5\u8be2\u4ee3\u91d1\u5238\u6279\u6b21\u4fe1\u606f
couponstock_query_uri={mch_base_url}/mmpaymkttransfers/query_coupon_stock
# \u67e5\u8be2\u4ee3\u91d1\u5238\u8be6\u7ec6\u4fe1\u606f
coupondetail_query_uri={mch_base_url}/promotion/query_coupon
# \u53d1\u73b0\u91d1\u7ea2\u5305
redpack_send_uri={mch_base_url}/mmpaymkttransfers/sendredpack
@@ -4,26 +4,59 @@ import java.io.Serializable;
import com.alibaba.fastjson.annotation.JSONField;
/**
* 图文数据
*
* @className ArticleDatacube1
* @author jy
* @date 2015年3月29日
* @since JDK 1.7
* @see
*/
public class ArticleDatacube1 implements Serializable {
private static final long serialVersionUID = 4140706754295502971L;
/**
* 图文页(点击群发图文卡片进入的页面)的阅读人数
*/
@JSONField(name = "int_page_read_user")
private int intPageReadUser;// 图文页(点击群发图文卡片进入的页面)的阅读人数
private int intPageReadUser;
/**
* 图文页的阅读次数
*/
@JSONField(name = "int_page_read_count")
private int intPageReadCount;// 图文页的阅读次数
private int intPageReadCount;
/**
* 原文页(点击图文页“阅读原文”进入的页面)的阅读人数,无原文页时此处数据为0
*/
@JSONField(name = "ori_page_read_user")
private int oriPageReadUser;// 原文页(点击图文页“阅读原文”进入的页面)的阅读人数,无原文页时此处数据为0
private int oriPageReadUser;
/**
* 原文页的阅读次数
*/
@JSONField(name = "ori_page_read_count")
private int oriPageReadCount;// 原文页的阅读次数
private int oriPageReadCount;
/**
* 分享的人数
*/
@JSONField(name = "shareUser")
private int shareUser; // 分享的人数
private int shareUser;
/**
* 分享的次数
*/
@JSONField(name = "shareCount")
private int shareCount;// 分享的次数
private int shareCount;
/**
* 收藏的人数
*/
@JSONField(name = "add_to_fav_user")
private int favUser;// 收藏的人数
private int favUser;
/**
* 收藏的次数
*/
@JSONField(name = "add_to_fav_count")
private int favCount;// 收藏的次数
private int favCount;
public int getIntPageReadUser() {
return intPageReadUser;
@@ -4,11 +4,26 @@ import java.util.Date;
import com.alibaba.fastjson.annotation.JSONField;
/**
* 图文数据
*
* @className ArticleDatacube2
* @author jy
* @date 2015年3月29日
* @since JDK 1.7
* @see
*/
public class ArticleDatacube2 extends ArticleDatacube1 {
private static final long serialVersionUID = -2924534868674264316L;
/**
* 统计的日期
*/
@JSONField(name = "stat_date")
private Date statDate;
/**
* 送达人数,一般约等于总粉丝数(需排除黑名单或其他异常情况下无法收到消息的粉丝)
*/
@JSONField(name = "target_user")
private int targetUser;
@@ -33,5 +48,4 @@ public class ArticleDatacube2 extends ArticleDatacube1 {
return "statDate=" + statDate + ", targetUser=" + targetUser + ", "
+ super.toString();
}
}
@@ -1,12 +1,14 @@
package com.foxinmy.weixin4j.mp.datacube;
import java.io.Serializable;
import java.util.Date;
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.mp.type.ShareSourceType;
/**
* 数据统计:图文分享数据
*
* @className ArticleDatacubeShare
* @author jy
* @date 2015年1月30日
@@ -16,22 +18,37 @@ import com.foxinmy.weixin4j.mp.type.ShareSourceType;
public class ArticleDatacubeShare implements Serializable {
private static final long serialVersionUID = 3841239305410294553L;
/**
* 数据的日期
*/
@JSONField(name = "ref_date")
private String refDate; // 数据的日期
private Date refDate;
/**
* 数据的小时,包括从000到2300,分别代表的是[000,100)到[2300,2400),即每日的第1小时和最后1小时
*/
@JSONField(name = "ref_hour")
private int refHour; // 数据的小时,包括从000到2300,分别代表的是[000,100)到[2300,2400),即每日的第1小时和最后1小时
private int refHour;
/**
* 分享的人数
*/
@JSONField(name = "shareUser")
private int shareUser; // 分享的人数
private int shareUser;
/**
* 分享的次数
*/
@JSONField(name = "shareCount")
private int shareCount;// 分享的次数
private int shareCount;
/**
* 分享的场景
*/
@JSONField(name = "share_scene")
private int shareScene;// 分享的场景
private int shareScene;
public String getRefDate() {
public Date getRefDate() {
return refDate;
}
public void setRefDate(String refDate) {
public void setRefDate(Date refDate) {
this.refDate = refDate;
}
@@ -1,5 +1,7 @@
package com.foxinmy.weixin4j.mp.datacube;
import java.util.Date;
import com.alibaba.fastjson.annotation.JSONField;
/**
@@ -13,22 +15,31 @@ import com.alibaba.fastjson.annotation.JSONField;
*/
public class ArticleSummary extends ArticleDatacube1 {
private static final long serialVersionUID = 4820605570501368550L;
/**
* 数据的日期
*/
@JSONField(name = "ref_date")
private String refDate; // 数据的日期
private Date refDate;
/**
* 数据的小时,包括从000到2300,分别代表的是[000,100)到[2300,2400),即每日的第1小时和最后1小时
*/
@JSONField(name = "ref_hour")
private int refHour; // 数据的小时,包括从000到2300,分别代表的是[000,100)到[2300,2400),即每日的第1小时和最后1小时
private int refHour;
/**
* 这里的msgid实际上是由msgid(图文消息id)和index(消息次序索引)组成, 例如12003_3,
* 其中12003是msgid,即一次群发的id消息的; 3为index,假设该次群发的图文消息共5个文章(因为可能为多图文), 3表示5个中的第3个
*/
private String msgid;
private String title;// 图文消息的标题
/**
* 图文消息的标题
*/
private String title;
public String getRefDate() {
public Date getRefDate() {
return refDate;
}
public void setRefDate(String refDate) {
public void setRefDate(Date refDate) {
this.refDate = refDate;
}
@@ -1,6 +1,7 @@
package com.foxinmy.weixin4j.mp.datacube;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import com.alibaba.fastjson.annotation.JSONField;
@@ -17,21 +18,30 @@ import com.alibaba.fastjson.annotation.JSONField;
public class ArticleTotal implements Serializable {
private static final long serialVersionUID = -6820948857241500950L;
/**
* 数据的日期
*/
@JSONField(name = "ref_date")
private String refDate; // 数据的日期
private Date refDate;
/**
* 这里的msgid实际上是由msgid(图文消息id)和index(消息次序索引)组成, 例如12003_3,
* 其中12003是msgid,即一次群发的id消息的; 3为index,假设该次群发的图文消息共5个文章(因为可能为多图文), 3表示5个中的第3个
*/
private String msgid;
private String title;// 图文消息的标题
/**
* 图文消息的标题
*/
private String title;
/**
* 详细信息
*/
private List<ArticleDatacube2> details;
public String getRefDate() {
public Date getRefDate() {
return refDate;
}
public void setRefDate(String refDate) {
public void setRefDate(Date refDate) {
this.refDate = refDate;
}
@@ -18,18 +18,36 @@ public class InterfaceSummary implements Serializable {
private static final long serialVersionUID = -8812979112580350988L;
/**
* 引用的日期
*/
@JSONField(name = "ref_date")
private Date refDate; // 引用的日期
private Date refDate;
/**
* 数据的小时,包括从000到2300,分别代表的是[000,100)到[2300,2400),即每日的第1小时和最后1小时
*/
@JSONField(name = "ref_hour")
private int refHour; // 数据的小时,包括从000到2300,分别代表的是[000,100)到[2300,2400),即每日的第1小时和最后1小时
private int refHour;
/**
* 通过服务器配置地址获得消息后,被动回复用户消息的次数
*/
@JSONField(name = "callback_count")
private int callbackCount; // 通过服务器配置地址获得消息后,被动回复用户消息的次数
private int callbackCount;
/**
* 上述动作的失败次数
*/
@JSONField(name = "fail_count")
private int failCount; // 上述动作的失败次数
private int failCount;
/**
* 总耗时,除以callback_count即为平均耗时
*/
@JSONField(name = "total_time_cost")
private int totalTimeCost;// 总耗时,除以callback_count即为平均耗时
private int totalTimeCost;
/**
* 最大耗时
*/
@JSONField(name = "max_time_cost")
private int maxTimeCost;// 最大耗时
private int maxTimeCost;
public Date getRefDate() {
return refDate;
@@ -18,16 +18,32 @@ import com.foxinmy.weixin4j.type.MessageType;
public class UpstreamMsg implements Serializable {
private static final long serialVersionUID = -2605207523094962029L;
/**
* 引用的日期
*/
@JSONField(name = "ref_date")
private Date refDate; // 引用的日期
private Date refDate;
/**
* 数据的小时,包括从000到2300,分别代表的是[000,100)到[2300,2400),即每日的第1小时和最后1小时
*/
@JSONField(name = "ref_hour")
private int refHour; // 数据的小时,包括从000到2300,分别代表的是[000,100)到[2300,2400),即每日的第1小时和最后1小时
private int refHour;
/**
* 消息类型
*/
@JSONField(name = "msg_type")
private int msgType; // 消息类型
private int msgType;
/**
* 上行发送了(向公众号发送了)消息的用户数
*/
@JSONField(name = "msg_user")
private int msgUser; // 上行发送了(向公众号发送了)消息的用户数
private int msgUser;
/**
* 上行发送了消息的消息总数
*/
@JSONField(name = "msg_count")
private int msgCount;// 上行发送了消息的消息总数
private int msgCount;
public Date getRefDate() {
return refDate;
@@ -4,6 +4,7 @@ import java.io.Serializable;
import java.util.Date;
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.mp.type.DatacuteCountIntervalType;
/**
* 数据统计:消息发送分布数据
@@ -17,10 +18,16 @@ import com.alibaba.fastjson.annotation.JSONField;
public class UpstreamMsgDist implements Serializable {
private static final long serialVersionUID = -2605207523094962029L;
/**
* 引用的日期
*/
@JSONField(name = "ref_date")
private Date refDate; // 引用的日期
private Date refDate;
/**
* 上行发送了(向公众号发送了)消息的用户数
*/
@JSONField(name = "msg_user")
private int msgUser; // 上行发送了(向公众号发送了)消息的用户数
private int msgUser;
/**
* 当日发送消息量分布的区间,0代表 “0”,1代表“1-5”,2代表“6-10”,3代表“10次以上
*/
@@ -43,8 +50,8 @@ public class UpstreamMsgDist implements Serializable {
this.msgUser = msgUser;
}
public int getCountInterval() {
return countInterval;
public DatacuteCountIntervalType getCountInterval() {
return DatacuteCountIntervalType.values()[countInterval];
}
public void setCountInterval(int countInterval) {
@@ -18,17 +18,31 @@ import com.foxinmy.weixin4j.mp.type.UserSourceType;
public class UserSummary implements Serializable {
private static final long serialVersionUID = 5303181828798568052L;
/**
* 数据的日期
*/
@JSONField(name = "ref_date")
private Date refDate; // 数据的日期
private Date refDate;
/**
* 用户的渠道
*/
@JSONField(name = "user_source")
private int userSource; // 用户的渠道,数值代表的含义如下:0代表其他 30代表扫二维码 17代表名片分享
// 35代表搜号码(即微信添加朋友页的搜索) 39代表查询微信公众帐号 43代表图文页右上角菜单
private int userSource;
/**
* 新增的用户数量
*/
@JSONField(name = "new_user")
private int newUser; // 新增的用户数量
private int newUser;
/**
* 取消关注的用户数量,new_user减去cancel_user即为净增用户数量
*/
@JSONField(name = "cancel_user")
private int cancelUser; // 取消关注的用户数量,new_user减去cancel_user即为净增用户数量
private int cancelUser;
/**
* 总用户量
*/
@JSONField(name = "cumulate_user")
private int cumulateUser; // 总用户量
private int cumulateUser;
public Date getRefDate() {
return refDate;
@@ -20,15 +20,21 @@ import com.foxinmy.weixin4j.msg.model.Base;
* @see com.foxinmy.weixin4j.msg.model.Music
* @see com.foxinmy.weixin4j.msg.model.News
* @see <a
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E5%8F%91%E9%80%81%E5%AE%A2%E6%9C%8D%E6%B6%88%E6%81%AF">发送客服消息</a>
* href="http://mp.weixin.qq.com/wiki/1/70a29afed17f56d537c833f89be979c9.html#.E5.AE.A2.E6.9C.8D.E6.8E.A5.E5.8F.A3-.E5.8F.91.E6.B6.88.E6.81.AF">发送客服消息</a>
*/
public class NotifyMessage implements Serializable {
private static final long serialVersionUID = 7190233634431087729L;
/**
* 用户的openid
*/
private String touser;
/**
* 消息对象
*/
@JSONField(name = "%s")
private Base box;// 消息项
private Base box;
public NotifyMessage(Base box) {
this(null, box);
@@ -1,5 +1,3 @@
NotifyMessage: 客服消息
NotifyMessage: (客服消息)[http://mp.weixin.qq.com/wiki/1/70a29afed17f56d537c833f89be979c9.html#.E5.AE.A2.E6.9C.8D.E6.8E.A5.E5.8F.A3-.E5.8F.91.E6.B6.88.E6.81.AF]
ResponseMessage: 被动消息
TemplateMessage: 模板消息
TemplateMessage: (模板消息)[http://mp.weixin.qq.com/wiki/17/304c1885ea66dbedf7dc170d84999a9d.html]
@@ -12,16 +12,31 @@ import java.util.Map;
* @date 2014年9月29日
* @since JDK 1.7
* @see <a
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E6%A8%A1%E6%9D%BF%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3">模板消息</a>
* href="http://mp.weixin.qq.com/wiki/17/304c1885ea66dbedf7dc170d84999a9d.html">模板消息</a>
*/
public class TemplateMessage implements Serializable {
private static final long serialVersionUID = 7950608393821661436L;
/**
* 用户的openid
*/
private String touser;
/**
* 模板ID
*/
private String template_id;
/**
* 点击消息跳转的url
*/
private String url;
/**
* 顶部的颜色值
*/
private String topcolor = "#FF0000";
/**
* 数据项
*/
private Map<String, Item> data;
public void pushData(String key, String value) {
@@ -37,9 +52,24 @@ public class TemplateMessage implements Serializable {
pushData("first", title);
}
/**
* 模板消息的数据项
*
* @className Item
* @author jy
* @date 2015年3月29日
* @since JDK 1.7
* @see
*/
private static class Item implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 字段值
*/
private String value;
/**
* 颜色值
*/
private String color;
public Item(String value) {
@@ -16,11 +16,27 @@ import com.foxinmy.weixin4j.mp.type.CustomRecordOperCode;
public class CustomRecord implements Serializable {
private static final long serialVersionUID = -4024147769411601325L;
private String worker;// 客服账号
private String openid;// 用户的标识
private CustomRecordOperCode opercode;// 操作ID(会话状态)
private Date time;// 操作时间
private String text;// 聊天记录
/**
* 客服账号
*/
private String worker;
/**
* 用户的标识
*/
private String openid;
/**
* 操作ID(会话状态)
*/
private CustomRecordOperCode opercode;
/**
* 操作时间
*/
private Date time;
/**
* 聊天记录
*/
private String text;
public String getWorker() {
return worker;
@@ -8,6 +8,7 @@ import com.alibaba.fastjson.annotation.JSONField;
/**
* 关注信息
*
* @author jy.hu
* @date 2014年4月4日
* @since JDK 1.7
@@ -16,12 +17,29 @@ public class Following implements Serializable {
private static final long serialVersionUID = 1917454368271027134L;
/**
* 关注总数
*/
private int total;
/**
* 拉取的OPENID个数,最大值为10000
*/
private int count;
/**
* 列表数据,OPENID的列表
*/
@JSONField(name = "data")
private JSONObject dataJson;
/**
* 拉取列表的后一个用户的OPENID
*/
@JSONField(name = "next_openid")
private String nextOpenId;
/**
* 用户详情列表
*
* @see com.foxinmy.weixin4j.mp.model.User
*/
private List<User> userList;
public int getTotal() {
@@ -13,8 +13,17 @@ public class Group implements Serializable {
private static final long serialVersionUID = 6979565973974005954L;
/**
* 分组id,由微信分配
*/
private int id;
/**
* 分组名
*/
private String name;
/**
* 分组内用户数量
*/
private int count;
public int getId() {
@@ -18,22 +18,42 @@ public class KfAccount implements Serializable {
private static final long serialVersionUID = -4565570894727129245L;
/**
* 客服账号@微信别名 微信别名如有修改,旧账号返回旧的微信别名,新增的账号返回新的微信别名
*/
@JSONField(name = "kf_account")
// 客服账号@微信别名 微信别名如有修改,旧账号返回旧的微信别名,新增的账号返回新的微信别名
private String account;
/**
* 客服昵称
*/
@JSONField(name = "kf_nick")
private String nickName;// 客服昵称
private String nickName;
/**
* 客服工号
*/
@JSONField(name = "kf_id")
private String id;// 客服工号
private String id;
/**
* 客服头像
*/
@JSONField(name = "kf_headimg")
private String headImg; //客服头像
private String headImg;
// 以下字段是调用在线客服状态返回的字段
private KfOnlineStatus status; // 客服在线状态 1:pc在线,2:手机在线 若pc和手机同时在线则为 1+2=3
/**
* 客服在线状态 1:pc在线,2:手机在线 若pc和手机同时在线则为 1+2=3
*/
private KfOnlineStatus status;
/**
* 客服设置的最大自动接入数
*/
@JSONField(name = "auto_accept")
private int autoAccept;// 客服设置的最大自动接入数
private int autoAccept;
/**
* 客服当前正在接待的会话数
*/
@JSONField(name = "accepted_case")
private int acceptedCase;// 客服当前正在接待的会话数
private int acceptedCase;
public String getAccount() {
return account;
@@ -18,12 +18,21 @@ public class KfSession implements Serializable {
private static final long serialVersionUID = 7236468333492555458L;
/**
* 客服账号
*/
@JSONField(name = "kf_account")
private String kfAccount; // 客服账号
private String kfAccount;
/**
* 用户ID
*/
@JSONField(name = "openid")
private String userOpenId; // 用户ID
private String userOpenId;
/**
* 创建时间
*/
@JSONField(name = "createtime")
private Date createTime; // 创建时间
private Date createTime;
public String getKfAccount() {
return kfAccount;
@@ -17,14 +17,26 @@ public class MediaCounter implements Serializable {
private static final long serialVersionUID = -1752502821323552783L;
/**
* 语音总数量
*/
@JSONField(name = "voice_count")
private long voiceCount;// 语音总数量
private long voiceCount;
/**
* 视频总数量
*/
@JSONField(name = "video_count")
private long videoCount;// 视频总数量
private long videoCount;
/**
* 图片总数量
*/
@JSONField(name = "image_count")
private long imageCount; // 图片总数量
private long imageCount;
/**
* 图文总数量
*/
@JSONField(name = "news_count")
private long newsCount; // 图文总数量
private long newsCount;
public long getVoiceCount() {
return voiceCount;
@@ -20,13 +20,25 @@ public class MediaItem implements Serializable {
private static final long serialVersionUID = -2923028664954250134L;
/**
* 媒体素材ID
*/
@JSONField(name = "media_id")
private String mediaId; // 媒体素材ID
private String name; // 媒体素材名称
private String mediaId;
/**
* 媒体素材名称
*/
private String name;
/**
* 媒体素材最后更新时间
*/
@JSONField(name = "update_time")
private Date updateTime; // 媒体素材最后更新时间
private Date updateTime;
/**
* 图文素材列表
*/
@JSONField(name = "news_item")
private List<MpArticle> articles; // 图文素材列表
private List<MpArticle> articles;
public String getMediaId() {
return mediaId;
@@ -19,14 +19,26 @@ public class MediaRecord implements Serializable {
private static final long serialVersionUID = 7017503153256241457L;
/**
* 该类型的素材的总数
*/
@JSONField(name = "total_count")
private int totalCount;// 该类型的素材的总数
private int totalCount;
/**
* 本次调用获取的素材的数量
*/
@JSONField(name = "item_count")
private int itemCount;// 本次调用获取的素材的数量
private int itemCount;
/**
* 媒体类型
*/
@JSONField(serialize = false)
private MediaType mediaType; // 媒体类型
private MediaType mediaType;
/**
* 媒体信息
*/
@JSONField(name = "item")
private List<MediaItem> items; // 媒体信息
private List<MediaItem> items;
public int getTotalCount() {
return totalCount;
@@ -17,8 +17,14 @@ public class OauthToken extends Token {
private static final long serialVersionUID = 1L;
/**
* 用户的openi
*/
private String openid;
/**
* 刷新token时的凭证
*/
@JSONField(name = "refresh_token")
private String refreshToken;
@@ -22,9 +22,18 @@ public class QRParameter implements Serializable {
private static final long serialVersionUID = 6611187606558274253L;
private int expireSeconds; // 该二维码有效时间,以秒为单位。 最大不超过1800。
private QRType qrType; // 二维码类型,QR_SCENE为临时,QR_LIMIT_SCENE为永久
private int sceneId; // 场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000(目前参数只支持1--100000
/**
* 该二维码有效时间,以秒为单位。 最大不超过1800。
*/
private int expireSeconds;
/**
* 二维码类型,QR_SCENE为临时,QR_LIMIT_SCENE为永久
*/
private QRType qrType;
/**
* 场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000(目前参数只支持1--100000
*/
private int sceneId;
public int getExpireSeconds() {
return expireSeconds;
@@ -19,19 +19,33 @@ public class SemQuery implements Serializable {
private static final long serialVersionUID = 679548284525912436L;
private JSONObject jsonObj;
// 输入文本串
/**
* 输入文本串
*
* @param query
*/
public SemQuery(String query) {
jsonObj = new JSONObject();
jsonObj.put("query", query);
}
// 城市名称,与经纬度二选一传入
/**
* 城市名称,与经纬度二选一传入
*
* @param city
* @return
*/
public SemQuery city(String city) {
jsonObj.put("city", city);
return this;
}
// 需要使用的服务类别,多个用,隔开,不能为空
/**
* 需要使用的服务类别,多个用,隔开,不能为空
*
* @param categorys
* @return
*/
public SemQuery category(SemCategory... categorys) {
StringBuilder category = new StringBuilder();
if (categorys.length == 1) {
@@ -46,33 +60,59 @@ public class SemQuery implements Serializable {
return this;
}
// App id,开发者的唯一标识,用于区分开放者, 如果为空,则没法使用上下文理解功能。
/**
* App id,开发者的唯一标识,用于区分开放者, 如果为空,则没法使用上下文理解功能。
*
* @param appid
* @return
*/
public SemQuery appid(String appid) {
jsonObj.put("appid", appid);
return this;
}
// 用户唯一 id(并非开发者 id),用于区分该开发者下不同用户,如果为空,则没法使用上下文理解功能。appid 和 uid
// 同时存在的情况下,才可以使用上下文理解功能。
/**
* 用户唯一 id(并非开发者 id),用于区分该开发者下不同用户,如果为空,则没法使用上下文理解功能。appid 和
* uid同时存在的情况下,才可以使用上下文理解功能。
*
* @param uid
* @return
*/
public SemQuery uid(String uid) {
jsonObj.put("uid", uid);
return this;
}
// 区域名称,在城市存在的情况下可省;与经纬度 二选一传入
/**
* 区域名称,在城市存在的情况下可省;与经纬度 二选一传入
*
* @param region
* @return
*/
public SemQuery region(String region) {
jsonObj.put("region", region);
return this;
}
// 纬度经度;与城市二选一传入
/**
* 纬度经度;与城市二选一传入
*
* @param latitude
* @param longitude
* @return
*/
public SemQuery location(float latitude, float longitude) {
jsonObj.put("latitude", latitude);
jsonObj.put("longitude", longitude);
return this;
}
// 输入文本串
/**
* 输入文本串
*
* @param query
* @return
*/
public static SemQuery build(String query) {
return new SemQuery(query);
}
@@ -17,17 +17,29 @@ import com.foxinmy.weixin4j.http.JsonResult;
public class SemResult extends JsonResult {
private static final long serialVersionUID = 9051214458161068387L;
// 用户的输入字符串
/**
* 用户的输入字符串
*/
private String query;
// 服务的全局类型id,详见协议文档中垂直服务协议定义
/**
* 服务的全局类型id,详见协议文档中垂直服务协议定义
*/
private String type;
// 语义理解后的结构化标识,各服务不同
/**
* 语义理解后的结构化标识,各服务不同
*/
private JSONObject semantic;
// 部分类别的结果
/**
* 部分类别的结果
*/
private JSONArray result;
// 部分类别的结果html5展示,目前不支持
/**
* 部分类别的结果html5展示,目前不支持
*/
private String answer;
// 特殊回复说明
/**
* 特殊回复说明
*/
private String text;
public String getQuery() {
@@ -24,21 +24,57 @@ public class User implements Serializable {
private static final long serialVersionUID = 1638176217299286265L;
private String openid; // 用户的唯一标识
private String nickname; // 用户昵称
/**
* 用户的唯一标识
*/
private String openid;
/**
* 用户昵称
*/
private String nickname;
/**
* 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
*/
@JSONField(name = "sex")
private Gender gender; // 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
private String province; // 用户个人资料填写的省份
private String city; // 普通用户个人资料填写的城市
private String country; // 国家,如中国为CN
private String headimgurl; // 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空
private String privilege; // 用户特权信息,json 数组,如微信沃卡用户为(chinaunicom
private Gender gender;
/**
* 用户个人资料填写的省份
*/
private String province;
/**
* 普通用户个人资料填写的城市
*/
private String city;
/**
* 国家,如中国为CN
*/
private String country;
/**
* 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空
*/
private String headimgurl;
/**
* 用户特权信息,json 数组,如微信沃卡用户为(chinaunicom
*/
private String privilege;
/**
* 用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息。
*/
@JSONField(name = "subscribe")
private boolean isSubscribe; // 用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息。
private boolean isSubscribe;
/**
* 关注时间
*/
@JSONField(name = "subscribe_time")
private Date subscribeTime; // 关注时间
private Lang language; // 使用语言
private String unionid; // 只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段
private Date subscribeTime;
/**
* 使用语言
*/
private Lang language;
/**
* 只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段
*/
private String unionid;
public String getOpenid() {
return openid;
@@ -1,5 +1,6 @@
package com.foxinmy.weixin4j.mp.payment;
import com.alibaba.fastjson.annotation.JSONField;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
@@ -15,9 +16,14 @@ public class JsPayNotify extends PayBaseInfo {
private static final long serialVersionUID = -4659030958445259803L;
/**
* 用户的openid
*/
@XStreamAlias("OpenId")
private String openid; // 用户ID
private String openid;
/**
* 是否关注公众号
*/
@XStreamAlias("IsSubscribe")
private int issubscribe;
@@ -37,9 +43,14 @@ public class JsPayNotify extends PayBaseInfo {
this.issubscribe = issubscribe;
}
@JSONField(serialize = false, deserialize = false)
public boolean getFormatIssubscribe() {
return issubscribe == 1;
}
@Override
public String toString() {
return "openid=" + openid + ", issubscribe=" + issubscribe
return "openid=" + openid + ", issubscribe=" + getFormatIssubscribe()
+ ", " + super.toString();
}
}
@@ -20,21 +20,38 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
public class MicroPayPackage extends PayPackage {
private static final long serialVersionUID = 8944928173669656177L;
private String appid; // 微信分配的公众账号 必须
/**
* 微信分配的公众账号 必须
*/
private String appid;
/**
* 微信支付分配的商户号 必须
*/
@XStreamAlias("mch_id")
@JSONField(name = "mch_id")
private String mchId; // 微信支付分配的商户号 必须
private String mchId;
/**
* 微信支付分配的终端设备号 非必须
*/
@XStreamAlias("device_info")
@JSONField(name = "device_info")
private String deviceInfo; // 微信支付分配的终端设备号 非必须
private String deviceInfo;
/**
* 随机字符串,不长于 32 位 必须
*/
@XStreamAlias("nonce_str")
@JSONField(name = "nonce_str")
private String nonceStr; // 随机字符串,不长于 32 位 必须
private String sign; // 签名 必须
private String nonceStr;
/**
* 签名 <font color="red">调用者不必关注</font>
*/
private String sign;
/**
* 扫码支付授权码 ,设备读取用户微信中的条码或者二维码信息
*/
@XStreamAlias("auth_code")
@JSONField(name = "auth_code")
private String authCode; // 扫码支付授权码 ,设备读取用 户微信中的条码或者二维码 信息
private String authCode;
public MicroPayPackage() {
@@ -82,7 +99,7 @@ public class MicroPayPackage extends PayPackage {
return deviceInfo;
}
public void setDevice_info(String deviceInfo) {
public void setDeviceInfo(String deviceInfo) {
this.deviceInfo = deviceInfo;
}
@@ -2,6 +2,7 @@ package com.foxinmy.weixin4j.mp.payment;
import java.io.Serializable;
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.mp.type.SignType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
@@ -17,20 +18,32 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
public class PayBaseInfo implements Serializable {
private static final long serialVersionUID = 1843024880782466990L;
/**
* 公众号ID
*/
@XStreamAlias("AppId")
private String appId; // 公众号ID
private String appId;
/**
* 时间戳
*/
@XStreamAlias("TimeStamp")
private String timeStamp; // 时间戳
private String timeStamp;
/**
* 随机字符串
*/
@XStreamAlias("NonceStr")
private String nonceStr; // 随机字符串
private String nonceStr;
/**
* 签名结果
*/
@XStreamAlias("AppSignature")
private String paySign; // 签名结果
private String paySign;
/**
* 签名方式
*/
@XStreamAlias("SignMethod")
private String signType; // 签名方式
private String signType;
public String getAppId() {
return appId;
@@ -68,6 +81,11 @@ public class PayBaseInfo implements Serializable {
return signType;
}
@JSONField(serialize = false, deserialize = false)
public SignType getFormatSignType() {
return SignType.valueOf(signType.toUpperCase());
}
public void setSignType(SignType signType) {
if (signType != null) {
this.signType = signType.name();
@@ -87,8 +105,7 @@ public class PayBaseInfo implements Serializable {
@Override
public String toString() {
return "appId=" + appId + ", timeStamp=" + timeStamp
+ ", nonceStr=" + nonceStr + ", paySign=" + paySign
+ ", signType=" + signType;
return "appId=" + appId + ", timeStamp=" + timeStamp + ", nonceStr="
+ nonceStr + ", paySign=" + paySign + ", signType=" + signType;
}
}
@@ -20,34 +20,62 @@ public class PayPackage implements Serializable {
private static final long serialVersionUID = 3450161267802545790L;
private String body; // 商品描述 必须
private String detail; // 商品详情 非必须
private String attach; // 附加数据,原样返回 非必须
/**
* 商品描述 必须
*/
private String body;
/**
* 商品详情 非必须
*/
private String detail;
/**
* 附加数据,原样返回 非必须
*/
private String attach;
/**
* 商户系统内部的订单号 ,32 个字符内 、可包含字母 ,确保 在商户系统唯一 必须
*/
@XStreamAlias("out_trade_no")
@JSONField(name = "out_trade_no")
private String outTradeNo; // 商户系统内部的订单号 ,32 个字符内 、可包含字母 ,确保 在商户系统唯一 必须
private String outTradeNo;
/**
* 订单总金额,单位为分,不能带小数点 必须
*/
@XStreamAlias("total_fee")
@JSONField(name = "total_fee")
private String totalFee; // 订单总金额,单位为分,不 能带小数点 必须
private String totalFee;
/**
* 订单生成的机器 IP 必须
*/
@XStreamAlias("spbill_create_ip")
@JSONField(name = "spbill_create_ip")
private String spbillCreateIp; // 订单生成的机器 IP 必须
private String spbillCreateIp;
/**
* 订单生成时间,格式为 yyyyMMddHHmmss,如 2009 年 12月25日9点10分10秒表示为 20091225091010。时区 为
* GMT+8 beijing。该时间取 自商户服务器 非必须
*/
@XStreamAlias("time_start")
@JSONField(name = "time_start")
private String timeStart; // 订单生成时间,格式 为 yyyyMMddHHmmss,如 2009 年
// 12月25日9点10分10秒表 示为 20091225091010。时区 为 GMT+8
// beijing。该时间取 自商户服务器 非必须
private String timeStart;
/**
* 订单失效时间,格为 yyyyMMddHHmmss,如 2009 年 12月27日9点10分10秒表示为 20091227091010。时区 为
* GMT+8 beijing。该时间取 自商户服务商品标记 非必须
*/
@XStreamAlias("time_expire")
@JSONField(name = "time_expire")
private String timeExpire; // 订单失效时间,格式 为 yyyyMMddHHmmss,如 2009 年
// 12月27日9点10分10秒表 示为 20091227091010。时区 为 GMT+8
// beijing。该时间取 自商户服务商品标记 非必须
private String timeExpire;
/**
* 商品标记,该字段不能随便填,不使用请填空 非必须
*/
@XStreamAlias("goods_tag")
@JSONField(name = "goods_tag")
private String goodsTag; // 商品标记,该字段不能随便 填,不使用请填空 非必须
private String goodsTag;
/**
* 通知地址接收微信支付成功通知 必须
*/
@XStreamAlias("notify_url")
@JSONField(name = "notify_url")
private String notifyUrl; // 通知地址接收微信支付成功通知 必须
private String notifyUrl;
public String getBody() {
return body;
@@ -85,6 +113,12 @@ public class PayPackage implements Serializable {
return totalFee;
}
/**
* <font color="red">单位为元,自动格式化为分</font>
*
* @param totalFee
* 订单总额 单位为元
*/
public void setTotalFee(double totalFee) {
this.totalFee = DateUtil.formaFee2Fen(totalFee);
}
@@ -142,6 +176,28 @@ public class PayPackage implements Serializable {
public PayPackage() {
}
/**
* 订单对象
*
* @param body
* 订单描述
* @param attach
* 附加数据
* @param outTradeNo
* 商户内部ID
* @param totalFee
* 订单总额 <font color="red">单位为元</font>
* @param spbillCreateIp
* 生成订单数据的机器IP
* @param timeStart
* 订单生成时间
* @param timeExpire
* 订单失效时间
* @param goodsTag
* 订单标记
* @param notifyUrl
* 回调地址
*/
public PayPackage(String body, String attach, String outTradeNo,
double totalFee, String spbillCreateIp, Date timeStart,
Date timeExpire, String goodsTag, String notifyUrl) {
@@ -9,7 +9,9 @@ public class PayRequest extends PayBaseInfo {
private static final long serialVersionUID = -453746488398523883L;
// 订单详情扩展 订单信息组成该字符串
/**
* 订单详情扩展 订单信息组成该字符串
*/
@XStreamAlias("Package")
@JSONField(name = "package")
private String packageInfo;
@@ -1,7 +1,54 @@
支付模块【JSAPI】【NATIVE】
支付模块【JSAPI】【NATIVE】【MICROPAY】
微信公众平台[V2版本支付](https://mp.weixin.qq.com/paymch/readtemplate?t=mp/business/course2_tmpl&lang=zh_CN)文档
微信公众平台[V3版本支付](https://mp.weixin.qq.com/paymch/readtemplate?t=mp/business/course3_tmpl&lang=zh_CN)文档
**在`2014年10月9号`之前申请并审核通过的支付接口应该属于`V2版本`支付,而之后申请的接口则为`V3版本`支付**
**在`2014年10月9号`之前申请并审核通过的支付接口应该属于`V2版本`支付,而之后申请的接口则为`V3版本`支付**
[PayUtil](./PayUtil.java)
-------------------------
* createPayJsRequestJson: 创建JSAPI支付串
* createPayJsRequestJsonV2: 创建V2版本的JSAPI支付串
* createNativePayRequestURLV2: 创建V2版本的扫码支付链接
* createPayJsRequestJsonV3: 创建V3版本(商户平台)的JSAPI支付串
* createNativePayRequestURLV3: 创建V3版本(商户平台)的扫码支付链接
* createPrePay: 调用V3版本(商户平台)的统一订单接口生成预订单数据
* createMicroPay: 创建刷卡支付(商户平台)请求
* createAddressRequestJson: 生成编辑收货地址请求串
[Pay3Api](./Pay3Api.java)
-------------------------
* orderQuery: 订单查询接口
* refund: 退款申请接口
* reverse: 冲正订单接口
* closeOrder: 关闭订单接口
* downloadbill: 下载对账单接口
* refundQuery: 退款查询接口
[Pay2Api](./Pay2Api.java)
-------------------------
* orderQuery: 订单查询接口
* refund: 退款申请接口
* downloadbill: 下载对账单接口
* refundQuery: 退款查询接口
@@ -0,0 +1,371 @@
package com.foxinmy.weixin4j.mp.payment.coupon;
import java.util.Date;
import org.apache.commons.lang3.StringUtils;
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.mp.payment.v3.ApiResult;
import com.foxinmy.weixin4j.mp.type.CouponStatus;
import com.foxinmy.weixin4j.mp.type.CouponStockType;
import com.foxinmy.weixin4j.mp.type.CouponType;
import com.foxinmy.weixin4j.util.DateUtil;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 代金券详细
*
* @className CouponDetail
* @author jy
* @date 2015年3月27日
* @since JDK 1.7
* @see
*/
public class CouponDetail extends ApiResult {
private static final long serialVersionUID = -311265355895457070L;
/**
* 代金券批次Id
*/
@XStreamAlias("coupon_stock_id")
@JSONField(name = "coupon_stock_id")
private String couponStockId;
/**
* 批次类型;1-批量型,2-触发型
*/
@XStreamAlias("coupon_stock_type")
@JSONField(name = "coupon_stock_type")
private int couponStockType;
/**
* 代金券id
*/
@XStreamAlias("coupon_id")
@JSONField(name = "coupon_id")
private String couponId;
/**
* 代金券面值,单位是分
*/
@XStreamAlias("coupon_value")
@JSONField(name = "coupon_value")
private int couponValue;
/**
* 代金券使用最低限额,单位是分
*/
@XStreamAlias("coupon_mininum")
@JSONField(name = "coupon_mininum")
private int couponMininum;
/**
* 代金券名称
*/
@XStreamAlias("coupon_name")
@JSONField(name = "coupon_name")
private String couponName;
/**
* 代金券状态:2-已激活,4-已锁定,8-已实扣
*/
@XStreamAlias("coupon_state")
@JSONField(name = "coupon_state")
private int couponStatus;
/**
* 代金券类型:1-代金券无门槛,2-代金券有门槛互斥,3-代金券有门槛叠加,
*/
@XStreamAlias("coupon_type")
@JSONField(name = "coupon_type")
private int couponType;
/**
* 代金券描述
*/
@XStreamAlias("coupon_desc")
@JSONField(name = "coupon_desc")
private String couponDesc;
/**
* 代金券实际使用金额
*/
@XStreamAlias("coupon_use_value")
@JSONField(name = "coupon_use_value")
private int couponUseValue;
/**
* 代金券剩余金额:部分使用情况下,可能会存在券剩余金额
*/
@XStreamAlias("coupon_remain_value")
@JSONField(name = "coupon_remain_value")
private int couponRemainValue;
/**
* 生效开始时间:格式为yyyyMMddhhmmss,如2009年12月27日9点10分10秒表示为20091227091010。
*/
@XStreamAlias("begin_time")
@JSONField(name = "begin_time")
private String beginTime;
/**
* 生效结束时间:格式为yyyyMMddhhmmss,如2009年12月27日9点10分10秒表示为20091227091010。
*/
@XStreamAlias("end_time")
@JSONField(name = "end_time")
private String endTime;
/**
* 发放时间:格式为yyyyMMddhhmmss,如2009年12月27日9点10分10秒表示为20091227091010。
*/
@XStreamAlias("send_time")
@JSONField(name = "send_time")
private String sendTime;
/**
* 使用时间:格式为yyyyMMddhhmmss,如2009年12月27日9点10分10秒表示为20091227091010。
*/
@XStreamAlias("use_time")
@JSONField(name = "use_time")
private String useTime;
/**
* 使用单号:代金券使用后,关联的大单收单单号
*/
@XStreamAlias("trade_no")
@JSONField(name = "trade_no")
private String tradeNo;
/**
* 消耗方商户id:代金券使用后,消耗方商户id
*/
@XStreamAlias("consumer_mch_id")
@JSONField(name = "consumer_mch_id")
private String consumerMchId;
/**
* 消耗方商户名称:代金券使用后,消耗方商户名称
*/
@XStreamAlias("consumer_mch_name")
@JSONField(name = "consumer_mch_name")
private String consumerMchName;
/**
* 消耗方商户appid:代金券使用后,消耗方商户appid
*/
@XStreamAlias("consumer_mch_appid")
@JSONField(name = "consumer_mch_appid")
private String consumerMchAppid;
/**
* 发放来源:代金券发放来源
*/
@XStreamAlias("send_source")
@JSONField(name = "send_source")
private String sendSource;
/**
* 是否允许部分使用:该代金券是否允许部分使用标识:1-表示支持部分使用
*/
@XStreamAlias("is_partial_use")
@JSONField(name = "is_partial_use")
private int isPartialUse;
public String getCouponStockId() {
return couponStockId;
}
public int getCouponStockType() {
return couponStockType;
}
@JSONField(deserialize = false, serialize = false)
public CouponStockType getFormatCouponStockType() {
for (CouponStockType couponStockType : CouponStockType.values()) {
if (couponStockType.getVal() == this.couponStockType) {
return couponStockType;
}
}
return null;
}
public String getCouponId() {
return couponId;
}
public int getCouponValue() {
return couponValue;
}
/**
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
*
* @return 元单位
*/
@JSONField(deserialize = false, serialize = false)
public double getFormatCouponValue() {
return couponValue / 100d;
}
public int getCouponMininum() {
return couponMininum;
}
/**
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
*
* @return 元单位
*/
@JSONField(deserialize = false, serialize = false)
public double getFormatCouponMininum() {
return couponMininum / 100d;
}
public String getCouponName() {
return couponName;
}
public int getCouponStatus() {
return couponStatus;
}
@JSONField(deserialize = false, serialize = false)
public CouponStatus getFormatCouponStatus() {
for (CouponStatus couponStatus : CouponStatus.values()) {
if (couponStatus.getVal() == this.couponStatus) {
return couponStatus;
}
}
return null;
}
public int getCouponType() {
return couponType;
}
@JSONField(deserialize = false, serialize = false)
public CouponType getFormatCouponType() {
for (CouponType couponType : CouponType.values()) {
if (couponType.getVal() == this.couponType) {
return couponType;
}
}
return null;
}
public String getCouponDesc() {
return couponDesc;
}
public int getCouponUseValue() {
return couponUseValue;
}
/**
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
*
* @return 元单位
*/
@JSONField(deserialize = false, serialize = false)
public double getFormatCouponUseValue() {
return couponUseValue / 100d;
}
public int getCouponRemainValue() {
return couponRemainValue;
}
/**
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
*
* @return 元单位
*/
@JSONField(deserialize = false, serialize = false)
public double getFormatCouponRemainValue() {
return couponRemainValue / 100d;
}
public String getBeginTime() {
return beginTime;
}
@JSONField(deserialize = false, serialize = false)
public Date getFormatBeginTime() {
return DateUtil.parse2yyyyMMddHHmmss(beginTime);
}
public String getEndTime() {
return endTime;
}
@JSONField(deserialize = false, serialize = false)
public Date getFormatEndTime() {
return DateUtil.parse2yyyyMMddHHmmss(endTime);
}
public String getSendTime() {
return sendTime;
}
@JSONField(deserialize = false, serialize = false)
public Date getFormatSendTime() {
return DateUtil.parse2yyyyMMddHHmmss(sendTime);
}
public String getUseTime() {
return useTime;
}
@JSONField(deserialize = false, serialize = false)
public Date getFormatUseTime() {
return StringUtils.isNotBlank(useTime) ? DateUtil
.parse2yyyyMMddHHmmss(useTime) : null;
}
public String getTradeNo() {
return tradeNo;
}
public String getConsumerMchId() {
return consumerMchId;
}
public String getConsumerMchName() {
return consumerMchName;
}
public String getConsumerMchAppid() {
return consumerMchAppid;
}
public String getSendSource() {
return sendSource;
}
public int getIsPartialUse() {
return isPartialUse;
}
@JSONField(deserialize = false, serialize = false)
public boolean getFormatIsPartialUse() {
return isPartialUse == 1;
}
@Override
public String toString() {
return "CouponDetail [couponStockId=" + couponStockId
+ ", couponStockType=" + getFormatCouponStockType()
+ ", couponId=" + couponId + ", couponValue="
+ getFormatCouponValue() + ", couponMininum="
+ getFormatCouponMininum() + ", couponName=" + couponName
+ ", couponStatus=" + getCouponStatus() + ", couponType="
+ getFormatCouponType() + ", couponDesc=" + couponDesc
+ ", couponUseValue=" + getFormatCouponUseValue()
+ ", couponRemainValue=" + getFormatCouponRemainValue()
+ ", beginTime=" + getFormatBeginTime() + ", endTime="
+ getFormatEndTime() + ", sendTime=" + getFormatSendTime()
+ ", useTime=" + getFormatUseTime() + ", tradeNo=" + tradeNo
+ ", consumerMchId=" + consumerMchId + ", consumerMchName="
+ consumerMchName + ", consumerMchAppid=" + consumerMchAppid
+ ", sendSource=" + sendSource + ", isPartialUse="
+ getFormatIsPartialUse() + ", " + super.toString()
+ "]";
}
}
@@ -6,9 +6,9 @@ import com.alibaba.fastjson.annotation.JSONField;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 代金券信息
* 代金券信息(订单,退款中体现)
*
* @className CouponBase
* @className CouponInfo
* @author jy
* @date 2015年3月24日
* @since JDK 1.7
@@ -18,15 +18,21 @@ public class CouponInfo implements Serializable {
private static final long serialVersionUID = -8744999305258786901L;
// 代金券或立减优惠批次ID
/**
* 代金券或立减优惠批次ID
*/
@XStreamAlias("coupon_batch_id")
@JSONField(name = "coupon_batch_id")
private String couponBatchId;
// 代金券或立减优惠ID
/**
* 代金券或立减优惠ID
*/
@XStreamAlias("coupon_id")
@JSONField(name = "coupon_id")
private String couponId;
// 单个代金券或立减优惠支付金额
/**
* 单个代金券或立减优惠支付金额
*/
@XStreamAlias("coupon_fee")
@JSONField(name = "coupon_fee")
private Integer couponFee;
@@ -0,0 +1,117 @@
package com.foxinmy.weixin4j.mp.payment.coupon;
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.mp.payment.v3.ApiResult;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 代金券发放结果
*
* @className CouponResult
* @author jy
* @date 2015年3月25日
* @since JDK 1.7
* @see
*/
public class CouponResult extends ApiResult {
private static final long serialVersionUID = -1996967923720149124L;
/**
* 代金券批次id
*/
@XStreamAlias("coupon_stock_id")
@JSONField(name = "coupon_stock_id")
private String couponStockId;
/**
* 返回记录数
*/
@XStreamAlias("resp_count")
@JSONField(name = "resp_count")
private int responseCount;
/**
* 成功记录数
*/
@XStreamAlias("success_count")
@JSONField(name = "success_count")
private int successCount;
/**
* 失败记录数
*/
@XStreamAlias("failed_count")
@JSONField(name = "failed_count")
private int failedCount;
/**
* 用户在商户appid下的唯一标识
*/
@XStreamAlias("openid")
@JSONField(name = "openid")
private String openId;
/**
* 返回码 SUCCESS或者FAILED
*/
@XStreamAlias("ret_code")
@JSONField(name = "ret_code")
private String retCode;
/**
* 代金券id
*/
@XStreamAlias("coupon_id")
@JSONField(name = "coupon_id")
private String couponId;
/**
* 失败描述信息,例如:“用户已达领用上限”
*/
@XStreamAlias("ret_msg")
@JSONField(name = "ret_msg")
private String retMsg;
public String getCouponStockId() {
return couponStockId;
}
public int getResponseCount() {
return responseCount;
}
public int getSuccessCount() {
return successCount;
}
public int getFailedCount() {
return failedCount;
}
public String getOpenId() {
return openId;
}
public String getRetCode() {
return retCode;
}
public String getCouponId() {
return couponId;
}
public String getRetMsg() {
return retMsg;
}
@Override
public String toString() {
return "CouponResult [couponStockId=" + couponStockId
+ ", responseCount=" + responseCount + ", successCount="
+ successCount + ", failedCount=" + failedCount + ", openId="
+ openId + ", retCode=" + retCode + ", couponId=" + couponId
+ ", retMsg=" + retMsg + "]";
}
}
@@ -0,0 +1,296 @@
package com.foxinmy.weixin4j.mp.payment.coupon;
import java.util.Date;
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.mp.payment.v3.ApiResult;
import com.foxinmy.weixin4j.mp.type.CouponStockStatus;
import com.foxinmy.weixin4j.mp.type.CouponType;
import com.foxinmy.weixin4j.util.DateUtil;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 代金券信息
*
* @className CouponStock
* @author jy
* @date 2015年3月27日
* @since JDK 1.7
* @see
*/
public class CouponStock extends ApiResult {
private static final long serialVersionUID = -8627202879200080499L;
/**
* 代金券批次ID
*/
@XStreamAlias("coupon_stock_id")
@JSONField(name = "coupon_stock_id")
private String couponStockId;
/**
* 代金券名称
*/
@XStreamAlias("coupon_name")
@JSONField(name = "coupon_name")
private String couponName;
/**
* 代金券面额
*/
@XStreamAlias("coupon_value")
@JSONField(name = "coupon_value")
private int couponValue;
/**
* 代金券使用最低限额
*/
@XStreamAlias("coupon_mininumn")
@JSONField(name = "coupon_mininumn")
private Integer couponMininumn;
/**
* 代金券类型:1-代金券无门槛,2-代金券有门槛互斥,3-代金券有门槛叠加
*/
@XStreamAlias("coupon_type")
@JSONField(name = "coupon_type")
private int couponType;
/**
* 批次状态: 1-未激活;2-审批中;4-已激活;8-已作废;16-中止发放;
*/
@XStreamAlias("coupon_stock_status")
@JSONField(name = "coupon_stock_status")
private int couponStockStatus;
/**
* 代金券数量
*/
@XStreamAlias("coupon_total")
@JSONField(name = "coupon_total")
private int couponTotal;
/**
* 代金券每个人最多能领取的数量, 如果为0,则表示没有限制
*/
@XStreamAlias("max_quota")
@JSONField(name = "max_quota")
private Integer maxQuota;
/**
* 代金券锁定数量
*/
@XStreamAlias("locked_num")
@JSONField(name = "locked_num")
private Integer lockedNum;
/**
* 代金券已使用数量
*/
@XStreamAlias("used_num")
@JSONField(name = "used_num")
private Integer usedNum;
/**
* 代金券已经发送的数量
*/
@XStreamAlias("is_send_num")
@JSONField(name = "is_send_num")
private Integer sendNum;
/**
* 生效开始时间 格式为yyyyMMddhhmmss,如2009年12月27日9点10分10秒表示为20091227091010。
*/
@XStreamAlias("begin_time")
@JSONField(name = "begin_time")
private String beginTime;
/**
* 生效结束时间 格式为yyyyMMddhhmmss,如2009年12月27日9点10分10秒表示为20091227091010。
*/
@XStreamAlias("end_time")
@JSONField(name = "end_time")
private String endTime;
/**
* 创建时间 格式为yyyyMMddhhmmss,如2009年12月27日9点10分10秒表示为20091227091010。
*/
@XStreamAlias("create_time")
@JSONField(name = "create_time")
private String createTime;
/**
* 代金券预算额度
*/
@XStreamAlias("coupon_budget")
@JSONField(name = "coupon_budget")
private Integer couponBudget;
public String getCouponStockId() {
return couponStockId;
}
public String getCouponName() {
return couponName;
}
public int getCouponValue() {
return couponValue;
}
/**
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
*
* @return 元单位
*/
@JSONField(deserialize = false, serialize = false)
public double getFormatCouponValue() {
return couponValue / 100d;
}
public Integer getCouponMininumn() {
return couponMininumn;
}
/**
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
*
* @return 元单位
*/
@JSONField(deserialize = false, serialize = false)
public double getFormatCouponMininumn() {
return couponMininumn != null ? couponMininumn.intValue() / 100d : 0d;
}
public int getCouponType() {
return couponType;
}
@JSONField(deserialize = false, serialize = false)
public CouponType getFormatCouponType() {
for (CouponType couponType : CouponType.values()) {
if (couponType.getVal() == this.couponType) {
return couponType;
}
}
return null;
}
public int getCouponStockStatus() {
return couponStockStatus;
}
@JSONField(deserialize = false, serialize = false)
public CouponStockStatus getFormatCouponStockStatus() {
for (CouponStockStatus couponStockStatus : CouponStockStatus.values()) {
if (couponStockStatus.getVal() == this.couponStockStatus) {
return couponStockStatus;
}
}
return null;
}
public int getCouponTotal() {
return couponTotal;
}
public Integer getMaxQuota() {
return maxQuota;
}
/**
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
*
* @return 元单位
*/
@JSONField(deserialize = false, serialize = false)
public double getFormatMaxQuota() {
return maxQuota != null ? maxQuota.intValue() / 100d : 0d;
}
public Integer getLockedNum() {
return lockedNum;
}
/**
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
*
* @return 元单位
*/
@JSONField(deserialize = false, serialize = false)
public double getFormatLockedNum() {
return lockedNum != null ? lockedNum.intValue() / 100d : 0d;
}
public Integer getUsedNum() {
return usedNum;
}
/**
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
*
* @return 元单位
*/
@JSONField(deserialize = false, serialize = false)
public double getFormatUsedNum() {
return usedNum != null ? usedNum.intValue() / 100d : 0d;
}
public Integer getSendNum() {
return sendNum;
}
/**
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
*
* @return 元单位
*/
@JSONField(deserialize = false, serialize = false)
public double getFormatSendNum() {
return sendNum != null ? sendNum.intValue() / 100d : 0d;
}
public String getBeginTime() {
return beginTime;
}
@JSONField(deserialize = false, serialize = false)
public Date getFormatBeginTime() {
return DateUtil.parse2yyyyMMddHHmmss(beginTime);
}
public String getEndTime() {
return endTime;
}
@JSONField(deserialize = false, serialize = false)
public Date getFormatEndTime() {
return DateUtil.parse2yyyyMMddHHmmss(endTime);
}
public String getCreateTime() {
return createTime;
}
@JSONField(deserialize = false, serialize = false)
public Date getFormatCreateTime() {
return DateUtil.parse2yyyyMMddHHmmss(createTime);
}
public Integer getCouponBudget() {
return couponBudget;
}
/**
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
*
* @return 元单位
*/
@JSONField(deserialize = false, serialize = false)
public double getFormatCouponBudget() {
return couponBudget != null ? couponBudget.intValue() / 100d : 0d;
}
@Override
public String toString() {
return "CouponDetail [couponStockId=" + couponStockId + ", couponName="
+ couponName + ", couponValue=" + getFormatCouponValue()
+ ", couponMininumn=" + getFormatCouponMininumn()
+ ", couponType=" + getFormatCouponType()
+ ", couponStockStatus=" + getFormatCouponStockStatus()
+ ", couponTotal=" + couponTotal + ", maxQuota="
+ getFormatMaxQuota() + ", lockedNum=" + getFormatLockedNum()
+ ", usedNum=" + getFormatUsedNum() + ", sendNum="
+ getFormatSendNum() + ", beginTime=" + beginTime
+ ", endTime=" + endTime + ", createTime=" + createTime
+ ", couponBudget=" + getFormatCouponBudget() + ", "
+ super.toString() + "]";
}
}
@@ -20,27 +20,44 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
public class ApiResult implements Serializable {
private static final long serialVersionUID = -2876899595643466203L;
// 是查询结果状态码,0 表明成功,其他表明错误;
/**
* 是查询结果状态码,0 表明成功,其他表明错误;
*/
@JSONField(name = "ret_code")
@XStreamAlias("retcode")
private int retCode;
// 是查询结果出错信息;
/**
* 是查询结果出错信息;
*/
@JSONField(name = "ret_msg")
@XStreamAlias("retmsg")
private String retMsg;
// 是返回信息中的编码方式;
/**
* 是返回信息中的编码方式;
*/
@JSONField(name = "input_charset")
@XStreamAlias("input_charset")
private String inputCharset;
// 是财付通商户号,即前文的 partnerid;
/**
* 是财付通商户号,即前文的 partnerid;
*/
private String partner;
/**
* 多密钥支持的密钥序号,默认 1
*/
@XStreamAlias("sign_key_index")
@JSONField(name = "sign_key_index")
private Integer signKeyIndex; // 多密钥支持的密钥序号,默认 1
private String sign;// 签名
private Integer signKeyIndex;
/**
* 签名 <font color="red">调用者无需关注</font>
*/
private String sign;
/**
* 签名类型,取值:MD5、RSA
*/
@JSONField(name = "sign_type")
@XStreamAlias("sign_type")
private SignType signType; // 签名类型,取值:MD5、RSA
private SignType signType;
public int getRetCode() {
return retCode;
@@ -15,6 +15,10 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
public class NativePayNotifyV2 extends JsPayNotify {
private static final long serialVersionUID = 1868431159301749988L;
/**
* 产品ID 可视为订单ID
*/
@XStreamAlias("ProductId")
private String productId;
@@ -16,8 +16,14 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
public class NativePayResponseV2 extends JsPayRequestV2 {
private static final long serialVersionUID = 6119895998783333012L;
/**
* 返回码
*/
@XStreamAlias("RetCode")
private String retCode;
/**
* 返回消息
*/
@XStreamAlias("RetErrMsg")
private String retMsg;
@@ -20,50 +20,82 @@ public class Order extends ApiResult {
private static final long serialVersionUID = 4543552984506609920L;
// 是订单状态,0 为成功,其他为失败;
/**
* 是订单状态,0 为成功,其他为失败;
*/
@JSONField(name = "trade_state")
private int tradeState;
// 是交易模式,1 为即时到帐,其他保留;
/**
* 是交易模式,1 为即时到帐,其他保留;
*/
@JSONField(name = "trade_mode")
private int tradeMode;
// 是银行类型;
/**
* 是银行类型;
*/
@JSONField(name = "bank_type")
private String bankType;
// 是银行订单号;
/**
* 是银行订单号;
*/
@JSONField(name = "bank_billno")
private String bankBillno;
// 是总金额,单位为分;
/**
* 是总金额,单位为分;
*/
@JSONField(name = "total_fee")
private int totalFee;
// 是币种,1 为人民币;
/**
* 是币种,1 为人民币;
*/
@JSONField(name = "fee_type")
private int feeType;
// 是财付通订单号;
/**
* 是财付通订单号;
*/
@JSONField(name = "transaction_id")
private String transactionId;
// 是第三方订单号;
/**
* 是第三方订单号;
*/
@JSONField(name = "out_trade_no")
private String outTradeNo;
// 表明是否分账,false 为无分账,true 为有分账;
/**
* 表明是否分账,false 为无分账,true 为有分账;
*/
@JSONField(name = "is_split")
private boolean isSplit;
// 表明是否退款,false 为无退款,ture 为退款;
/**
* 表明是否退款,false 为无退款,ture 为退款;
*/
@JSONField(name = "is_refund")
private boolean isRefund;
// attach 是商户数据包,即生成订单package 时商户填入的 attach;
/**
* attach 是商户数据包,即生成订单package 时商户填入的 attach;
*/
private String attach;
// 支付完成时间;
/**
* 支付完成时间;
*/
@JSONField(name = "time_end")
private String timeEnd;
// 物流费用,单位为分;
/**
* 物流费用,单位为分;
*/
@JSONField(name = "transport_fee")
private int transportFee;
// 物品费用,单位为分;
/**
* 物品费用,单位为分;
*/
@JSONField(name = "product_fee")
private int productFee;
// 折扣价格,单位为分;
/**
* 折扣价格,单位为分;
*/
private int discount;
// 换算成人民币之后的总金额,单位为分,一般看 total_fee 即可。
/**
* 换算成人民币之后的总金额,单位为分,一般看 total_fee 即可。
*/
@JSONField(name = "rmb_total_fee")
private Integer rmbTotalFee;
@@ -276,14 +308,12 @@ public class Order extends ApiResult {
+ isRefund + ", attach=" + attach + ", timeEnd=" + timeEnd
+ ", transportFee=" + transportFee + ", productFee="
+ productFee + ", discount=" + discount + ", rmbTotalFee="
+ rmbTotalFee + ", getFormatTradeState()="
+ getFormatTradeState() + ", getFormatTotalFee()="
+ getFormatTotalFee() + ", getFormatFeeType()="
+ getFormatFeeType() + ", getFormatTimeEnd()="
+ getFormatTimeEnd() + ", getFormatTransportFee()="
+ getFormatTransportFee() + ", getFormatProductFee()="
+ getFormatProductFee() + ", getFormatDiscount()="
+ getFormatDiscount() + ", getFormatRmbTotalFee()="
+ getFormatRmbTotalFee() + ", " + super.toString() + "]";
+ rmbTotalFee + ", tradeState=" + getFormatTradeState()
+ ", totalFee=" + getFormatTotalFee() + ", feeType="
+ getFormatFeeType() + ", timeEnd=" + getFormatTimeEnd()
+ ", transportFee=" + getFormatTransportFee() + ", productFee="
+ getFormatProductFee() + ", discount=" + getFormatDiscount()
+ ", rmbTotalFee=" + getFormatRmbTotalFee() + ", "
+ super.toString() + "]";
}
}
@@ -17,20 +17,44 @@ public class PayFeedback extends PayBaseInfo {
private static final long serialVersionUID = 7230049346213966310L;
/**
* 投诉单号
*/
@XStreamAlias("FeedBackId")
private String feedbackId;
/**
* 用户ID
*/
@XStreamAlias("OpenId")
private String openId;
/**
* 订单交易单号
*/
@XStreamAlias("TransId")
private String transId;
/**
* 投诉原因
*/
@XStreamAlias("Reason")
private String reason;
/**
* 用户希望解决方案
*/
@XStreamAlias("Solution")
private String solution;
/**
* 备注信息+电话
*/
@XStreamAlias("ExtInfo")
private String extInfo;
/**
* 用户上传的图片凭证,最多五张
*/
@XStreamAlias("PicInfo")
private String picInfo;
/**
* 通知类型 request 用户提交投诉 confirm 用户确认消除 投诉 reject 用户拒绝消除投诉
*/
@XStreamAlias("MsgType")
private String status;
@@ -71,7 +95,6 @@ public class PayFeedback extends PayBaseInfo {
return "PayFeedback [feedbackId=" + feedbackId + ", openId=" + openId
+ ", transId=" + transId + ", reason=" + reason + ", solution="
+ solution + ", extInfo=" + extInfo + ", picInfo=" + picInfo
+ ", status=" + status + ", " + super.toString()
+ "]";
+ ", status=" + status + ", " + super.toString() + "]";
}
}
@@ -20,27 +20,37 @@ public class PayPackageV2 extends PayPackage {
private static final long serialVersionUID = 5557542103637795834L;
// 银行通道类型 固定为"WX" 非空
/**
* 银行通道类型 固定为"WX" 非空
*/
@XStreamAlias("bank_type")
@JSONField(name = "bank_type")
private String bankType;
// 商户号 注册时分配的财付通商户号 非空
/**
* 商户号 注册时分配的财付通商户号 非空
*/
private String partner;
// 支付币种 默认值是"1" 非空
/**
* 支付币种 默认值是"1" 非空
*/
@XStreamAlias("fee_type")
@JSONField(name = "fee_type")
private String feeType;
// 物流费用 可为空 如果有值,必须保 证 transport_fee + product_fee=total_fee【传进来的参数按照实际金额即可
// 也就是元为单位】
/**
* 物流费用 可为空 如果有值,必须保 证 transport_fee + product_fee=total_fee
*/
@XStreamAlias("transport_fee")
@JSONField(name = "transport_fee")
private String transportFee;
// 商品费用 可为空 商品费用,单位为分。如果有值,必须保 证 transport_fee +
// product_fee=total_fee;【传进来的参数按照实际金额即可 也就是元为单位】
/**
* 商品费用 可为空 商品费用,单位为分。如果有值,必须保 证 transport_fee +product_fee=total_fee;
*/
@XStreamAlias("product_fee")
@JSONField(name = "product_fee")
private String productFee;
// 传入参数字符编码 取值范围:"GBK"、"UTF-8",默认:"GBK" 可为空
/**
* 传入参数字符编码 取值范围:"GBK"、"UTF-8",默认:"GBK" 可为空
*/
@XStreamAlias("input_charset")
@JSONField(name = "input_charset")
private String inputCharset;
@@ -49,7 +59,7 @@ public class PayPackageV2 extends PayPackage {
return bankType;
}
public void setBank_type(String bankType) {
public void setBankType(String bankType) {
this.bankType = bankType;
}
@@ -73,6 +83,12 @@ public class PayPackageV2 extends PayPackage {
return transportFee;
}
/**
* <font color="red">单位为元,自动格式化为分</font>
*
* @param transportFee
* 物流费用 单位为元
*/
public void setTransportFee(double transportFee) {
this.transportFee = DateUtil.formaFee2Fen(transportFee);
}
@@ -81,6 +97,12 @@ public class PayPackageV2 extends PayPackage {
return productFee;
}
/**
* <font color="red">单位为元,自动格式化为分</font>
*
* @param productFee
* 商品 单位为元
*/
public void setProductFee(double productFee) {
this.productFee = DateUtil.formaFee2Fen(productFee);
}
@@ -89,7 +111,7 @@ public class PayPackageV2 extends PayPackage {
return inputCharset;
}
public void setInput_charset(String inputCharset) {
public void setInputCharset(String inputCharset) {
this.inputCharset = inputCharset;
}
@@ -5,6 +5,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* V2告警通知
*
* @className PayWarn
* @author jy
* @date 2014年12月31日
@@ -16,12 +17,19 @@ public class PayWarn extends PayBaseInfo {
private static final long serialVersionUID = 2334592957844332640L;
/**
* 错误代号 1001=发货超时
*/
@XStreamAlias("ErrorType")
private String errortype;
/**
* 错误描述
*/
@XStreamAlias("Description")
private String description;
/**
* 错误详情
*/
@XStreamAlias("AlarmContent")
private String alarmcontent;
@@ -20,27 +20,48 @@ public class RefundDetail extends ApiResult {
private static final long serialVersionUID = -3687863914168618620L;
/**
* 商户退款单号
*/
@XStreamAlias("out_refund_no")
@JSONField(name = "out_refund_no")
private String outRefundNo; // 商户退款单号
private String outRefundNo;
/**
* 微信退款单号
*/
@XStreamAlias("refund_id")
@JSONField(name = "refund_id")
private String refundId; // 微信退款单号
private String refundId;
/**
* 退款渠道 0:退到财付通、1:退到银行;
*/
@XStreamAlias("refund_channel")
@JSONField(name = "refund_channel")
private int refundChannel; // 退款渠道 0:退到财付通、1:退到银行;
private int refundChannel;
/**
* 退款总金额,单位为分,可以做部分退款
*/
@XStreamAlias("refund_fee")
@JSONField(name = "refund_fee")
private int refundFee; // 退款总金额,单位为分,可以做部分退款
private int refundFee;
/**
* 退款状态
*/
@XStreamAlias("refund_status")
@JSONField(name = "refund_status")
private int refundStatus; // 退款状态
private int refundStatus;
/**
* 转账退款接收退款的财付通帐号
*/
@XStreamAlias("recv_user_id")
@JSONField(name = "recv_user_id")
private String recvUserId;// 转账退款接收退款的财付通帐号
private String recvUserId;
/**
* 转账退款接收退款的姓名(需与接收退款的财付通帐号绑定的姓名一致)
*/
@XStreamAlias("reccv_user_name")
@JSONField(name = "reccv_user_name")
private String reccvUserName;// 转账退款接收退款的姓名(需与接收退款的财 付通帐号绑定的姓名一致)
private String reccvUserName;
public String getOutRefundNo() {
return outRefundNo;
@@ -115,9 +136,9 @@ public class RefundDetail extends ApiResult {
+ ", refundChannel=" + refundChannel + ", refundFee="
+ refundFee + ", refundStatus=" + refundStatus
+ ", recvUserId=" + recvUserId + ", reccvUserName="
+ reccvUserName + ", getFormatRefundChannel()="
+ getFormatRefundChannel() + ", getFormatRefundFee()="
+ getFormatRefundFee() + ", getFormatRefundStatus()="
+ reccvUserName + ", refundChannel="
+ getFormatRefundChannel() + ", refundFee="
+ getFormatRefundFee() + ", refundStatus="
+ getFormatRefundStatus();
}
}
@@ -22,18 +22,30 @@ public class RefundRecord extends ApiResult {
private static final long serialVersionUID = -2971132874939642721L;
/**
* 微信订单号
*/
@XStreamAlias("transaction_id")
@JSONField(name = "transaction_id")
private String transactionId;// 微信订单号
private String transactionId;
/**
* 商户订单号
*/
@XStreamAlias("out_trade_no")
@JSONField(name = "out_trade_no")
private String outTradeNo;// 商户订单号
private String outTradeNo;
/**
* 退款笔数
*/
@XStreamAlias("refund_count")
@JSONField(name = "refund_count")
private int count;// 退款笔数
private int count;
/**
* 退款详情
*/
@XStreamOmitField
@JSONField(serialize = false, deserialize = false)
private List<RefundDetail> details; // 退款详情
private List<RefundDetail> details;
public String getTransactionId() {
return transactionId;
@@ -17,12 +17,18 @@ public class RefundResult extends RefundDetail {
private static final long serialVersionUID = -3687863914168618620L;
/**
* 微信订单号
*/
@XStreamAlias("transaction_id")
@JSONField(name = "transaction_id")
private String transactionId; // 微信订单号
private String transactionId;
/**
* 商户系统内部的订单号
*/
@XStreamAlias("out_trade_no")
@JSONField(name = "out_trade_no")
private String outTradeNo;// 商户系统内部的订单号
private String outTradeNo;
public String getTransactionId() {
return transactionId;
@@ -19,23 +19,44 @@ public class ApiResult extends XmlResult {
private static final long serialVersionUID = -8430005768959715444L;
/**
* 微信分配的公众账号 ID商户号 非空
*/
@XStreamAlias("appid")
@JSONField(name = "appid")
private String appId;// 微信分配的公众账号 ID商户号 非空
private String appId;
/**
* 微信支付分配的商户号 非空
*/
@XStreamAlias("mch_id")
@JSONField(name = "mch_id")
private String mchId;// 微信支付分配的商户号 非空
private String mchId;
/**
* 代理模式下分配的商户号 可能为空
*/
@XStreamAlias("sub_mch_id")
@JSONField(name = "sub_mch_id")
private String subMchId; // 未知 可能为空
private String subMchId;
/**
* 随机字符串 非空
*/
@XStreamAlias("nonce_str")
@JSONField(name = "nonce_str")
private String nonceStr;// 随机字符串 非空
private String sign;// 签名 非空
private String nonceStr;
/**
* 签名 <font color="red">调用者无需关心</font>
*/
private String sign;
/**
* 微信支付分配的终端设备号 可能为空
*/
@XStreamAlias("device_info")
@JSONField(name = "device_info")
private String deviceInfo;// 微信支付分配的终端设备号 可能为空
private String recall;// 是否需要继续调用接口 Y- 需要,N-不需要
private String deviceInfo;
/**
* 是否需要继续调用接口 Y- 需要,N-不需要
*/
private String recall;
public ApiResult() {
@@ -110,6 +131,7 @@ public class ApiResult extends XmlResult {
public String toString() {
return "appId=" + appId + ", mchId=" + mchId + ", subMchId=" + subMchId
+ ", nonceStr=" + nonceStr + ", sign=" + sign + ", deviceInfo="
+ deviceInfo + ", recall=" + getFormatRecall() + ", " + super.toString();
+ deviceInfo + ", recall=" + getFormatRecall() + ", "
+ super.toString();
}
}
@@ -16,6 +16,9 @@ public class NativePayNotifyV3 extends ApiResult {
private static final long serialVersionUID = 4515471400239795492L;
/**
* 产品ID 可视为订单ID
*/
@XStreamAlias("product_id")
private String productId;
@@ -25,66 +25,103 @@ import com.thoughtworks.xstream.annotations.XStreamOmitField;
public class Order extends ApiResult {
private static final long serialVersionUID = 5636828325595317079L;
// SUCCESS—支付成功 REFUND—转入退款 NOTPAY—未支付 CLOSED—已关闭 REVOKED—已撤销
// USERPAYING--用户支付中 NOPAY--未支付(输入密码或 确认支付超时) PAYERROR--支付失败(其他 原因,如银行返回失败)
// 以下字段在 return_code 和 result_code 都为 SUCCESS 的时候有返回
/**
* 交易状态
*
* @see com.foxinmy.weixin4j.mp.type.TradeState
*/
@XStreamAlias("trade_state")
@JSONField(name = "trade_state")
private TradeState tradeState;
// 用户标识ID
/**
* 用户的openid
*/
@XStreamAlias("openid")
@JSONField(name = "openid")
private String openId;
// 用户是否关注公众账号,Y- 关注,N-未关注,仅在公众 账号类型支付有效
/**
* 用户是否关注公众账号,Y- 关注,N-未关注,仅在公众 账号类型支付有效
*/
@XStreamAlias("is_subscribe")
@JSONField(name = "is_subscribe")
private String isSubscribe;
// 交易类型
/**
* 交易类型
*
* @see com.foxinmy.weixin4j.mp.type.TradeType
*/
@XStreamAlias("trade_type")
@JSONField(name = "trade_type")
private TradeType tradeType;
// 银行类型
/**
* 银行类型
*/
@XStreamAlias("bank_type")
@JSONField(name = "bank_type")
private String bankType;
// 订单总金额,单位为分
/**
* 订单总金额,单位为分
*/
@XStreamAlias("total_fee")
@JSONField(name = "total_fee")
private int totalFee;
// 现金券支付金额<=订单总金 额,订单总金额-现金券金额 为现金支付金额
/**
* 现金券支付金额<=订单总金 额,订单总金额-现金券金额 为现金支付金额
*/
@XStreamAlias("coupon_fee")
@JSONField(name = "coupon_fee")
private Integer couponFee;
// 代金券或立减优惠使用数量
/**
* 代金券或立减优惠使用数量
*/
@XStreamAlias("coupon_count")
@JSONField(name = "coupon_count")
private Integer couponCount;
// 代金券信息
/**
* 代金券信息
*/
@XStreamOmitField
@JSONField(serialize = false)
private List<CouponInfo> couponList;
/**
* 现金支付金额
*/
@XStreamAlias("cash_fee")
@JSONField(name = "cash_fee")
private int cashFee;
// 货币类型,符合 ISO 4217 标准的三位字母代码,默认人民币:CNY
/**
* 货币类型,符合 ISO 4217 标准的三位字母代码,默认人民币:CNY
*
* @see com.foxinmy.weixin4j.mp.type.CurrencyType
*/
@XStreamAlias("fee_type")
@JSONField(name = "fee_type")
private CurrencyType feeType;
// 微信支付订单号
/**
* 微信支付订单号
*/
@XStreamAlias("transaction_id")
@JSONField(name = "transaction_id")
private String transactionId;
// 商户订单号
/**
* 商户订单号
*/
@XStreamAlias("out_trade_no")
@JSONField(name = "out_trade_no")
private String outTradeNo;
// 商家数据包
/**
* 商家数据包
*/
private String attach;
// 支付完成时间,格式为 yyyyMMddhhmmss
/**
* 支付完成时间,格式为 yyyyMMddhhmmss
*/
@XStreamAlias("time_end")
@JSONField(name = "time_end")
private String timeEnd;
// 交易状态描述
/**
* 交易状态描述
*/
@XStreamAlias("trade_state_desc")
@JSONField(name = "trade_state_desc")
private String tradeStateDesc;
@@ -23,24 +23,48 @@ public class PayPackageV3 extends PayPackage {
private static final long serialVersionUID = 8944928173669656177L;
private String appid; // 微信分配的公众账号 必须
/**
* 微信分配的公众账号 必须
*/
private String appid;
/**
* 微信支付分配的商户号 必须
*/
@XStreamAlias("mch_id")
@JSONField(name = "mch_id")
private String mchId; // 微信支付分配的商户号 必须
private String mchId;
/**
* 微信支付分配的终端设备号 非必须
*/
@XStreamAlias("device_info")
@JSONField(name = "device_info")
private String deviceInfo; // 微信支付分配的终端设备号 非必须
private String deviceInfo;
/**
* 随机字符串,不长于 32 位 必须
*/
@XStreamAlias("nonce_str")
@JSONField(name = "nonce_str")
private String nonceStr; // 随机字符串,不长于 32 位 必须
private String sign; // 签名 必须
private String nonceStr;
/**
* 签名 <font color="red">调用者无需关心</font>
*/
private String sign;
/**
* 交易类型JSAPI、NATIVE、APP 必须
*/
@XStreamAlias("trade_type")
@JSONField(name = "trade_type")
private String tradeType; // 交易类型JSAPI、NATIVE、APP 必须
private String openid; // 用户在商户 appid 下的唯一 标识, trade_type 为 JSAPI 时,此参数必传
private String tradeType;
/**
* 用户在商户 appid 下的唯一 标识, trade_type 为 JSAPI 时,此参数必传
*/
private String openid;
/**
* 只在 trade_type 为 NATIVE 时需要填写 非必须
*/
@XStreamAlias("product_id")
@JSONField(name = "product_id")
private String productId; // 只在 trade_type 为 NATIVE 时需要填写 非必须
private String productId;
public PayPackageV3() {
@@ -23,6 +23,7 @@ import com.foxinmy.weixin4j.mp.payment.PayRequest;
public class PayRequestV3 extends PayRequest {
private static final long serialVersionUID = -5972173459255255197L;
public PayRequestV3(PrePay prePay) throws PayException {
this.setAppId(prePay.getAppId());
this.setPackageInfo("prepay_id=" + prePay.getPrepayId());
@@ -17,20 +17,22 @@ public class PrePay extends ApiResult {
private static final long serialVersionUID = -8430005768959715444L;
@XStreamAlias("trade_type")
/**
* 调用接口提交的交易类型,取值如下:JSAPI,NATIVEAPP
*
* @see com.foxinmy.weixin4j.mp.type.TradeType
*/
@XStreamAlias("trade_type")
private TradeType tradeType;
@XStreamAlias("prepay_id")
/**
* 微信生成的预支付回话标识,用于后续接口调用中使用,该值有效期为2小时
*/
@XStreamAlias("prepay_id")
private String prepayId;
@XStreamAlias("code_url")
/**
* trade_type 为 NATIVE 是有 返回,此参数可直接生成二 维码展示出来进行扫码支付 可能为空
*/
@XStreamAlias("code_url")
private String codeUrl;
public PrePay() {
@@ -24,55 +24,107 @@ public class RefundDetail extends ApiResult {
private static final long serialVersionUID = -3687863914168618620L;
/**
* 商户退款单号
*/
@XStreamAlias("out_refund_no")
@JSONField(name = "out_refund_no")
private String outRefundNo; // 商户退款单号
private String outRefundNo;
/**
* 微信退款单号
*/
@XStreamAlias("refund_id")
@JSONField(name = "refund_id")
private String refundId; // 微信退款单号
private String refundId;
/**
* 退款渠道:ORIGINAL—原路退款,默认 BALANCE—退回到余额
*/
@XStreamAlias("refund_channel")
@JSONField(name = "refund_channel")
private String refundChannel;// 退款渠道:ORIGINAL—原路退款,默认 BALANCE—退回到余额
private String refundChannel;
/**
* 退款总金额,单位为分,可以做部分退款
*/
@XStreamAlias("refund_fee")
@JSONField(name = "refund_fee")
private int refundFee; // 退款总金额,单位为分,可以做部分退款
private int refundFee;
/**
* 退款货币种类
*
* @see com.foxinmy.weixin4j.mp.type.CurrencyType
*/
@XStreamAlias("refund_fee_type")
@JSONField(name = "refund_fee_type")
private CurrencyType refundFeeType; // 退款货币种类
private CurrencyType refundFeeType;
/**
* 订单总金额
*/
@XStreamAlias("total_fee")
@JSONField(name = "total_fee")
private int totalFee; // 订单总金额
private int totalFee;
/**
* 订单金额货币种类
*
* @see com.foxinmy.weixin4j.mp.type.CurrencyType
*/
@XStreamAlias("fee_type")
@JSONField(name = "fee_type")
private CurrencyType feeType; // 订单金额货币种类
private CurrencyType feeType;
/**
* 现金支付金额
*/
@XStreamAlias("cash_fee")
@JSONField(name = "cash_fee")
private int cashFee; // 现金支付金额
private int cashFee;
/**
* 现金支付货币种类
*
* @see com.foxinmy.weixin4j.mp.type.CurrencyType
*/
@XStreamAlias("cash_fee_type")
@JSONField(name = "cash_fee_type")
private CurrencyType cashFeeType; // 现金支付货币种类
private CurrencyType cashFeeType;
/**
* 现金退款金额
*/
@XStreamAlias("cash_refund_fee")
@JSONField(name = "cash_refund_fee")
private Integer cashRefundFee; // 现金退款金额
private Integer cashRefundFee;
/**
* 现金退款货币类型
*
* @see com.foxinmy.weixin4j.mp.type.CurrencyType
*/
@XStreamAlias("cash_refund_fee_type")
@JSONField(name = "cash_refund_fee_type")
private CurrencyType cashRefundFeeType; // 现金退款货币类型
private CurrencyType cashRefundFeeType;
/**
* 退款状态
*/
@XStreamAlias("refund_status")
@JSONField(name = "refund_status")
private String refundStatus; // 退款状态
private String refundStatus;
/**
* 现金券退款金额<=退款金额,退款金额-现金券退款金额为现金
*/
@XStreamAlias("coupon_refund_fee")
@JSONField(name = "coupon_refund_fee")
private Integer couponRefundFee; // 现金券退款金额<=退款金额,退款金额-现金券退款金额为现金
private Integer couponRefundFee;
/**
* <font
* 代金券或立减优惠使用数量 <font
* color="red">微信支付文档上写的coupon_count,而实际测试拿到的是coupon_refund_count,做个记号。
* </font>
*/
@XStreamAlias("coupon_refund_count")
@JSONField(name = "coupon_refund_count")
private Integer couponRefundCount; // 代金券或立减优惠使用数量
private Integer couponRefundCount;
/**
* 代金券信息
*
* @see com.foxinmy.weixin4j.mp.payment.coupon.CouponInfo
*/
@JSONField(serialize = false)
private List<CouponInfo> couponList; // 代金券信息
private List<CouponInfo> couponList;
public String getOutRefundNo() {
return outRefundNo;
@@ -21,36 +21,70 @@ public class RefundRecord extends ApiResult {
private static final long serialVersionUID = -2971132874939642721L;
/**
* 微信订单号
*/
@XStreamAlias("transaction_id")
@JSONField(name = "transaction_id")
private String transactionId;// 微信订单号
private String transactionId;
/**
* 商户订单号
*/
@XStreamAlias("out_trade_no")
@JSONField(name = "out_trade_no")
private String outTradeNo;// 商户订单号
private String outTradeNo;
/**
* 订单总金额
*/
@XStreamAlias("total_fee")
@JSONField(name = "total_fee")
private int totalFee; // 订单总金额
private int totalFee;
/**
* 订单金额货币种类
*
* @see com.foxinmy.weixin4j.mp.type.CurrencyType
*/
@XStreamAlias("fee_type")
@JSONField(name = "fee_type")
private CurrencyType feeType; // 订单金额货币种类
private CurrencyType feeType;
/**
* 现金支付金额
*/
@XStreamAlias("cash_fee")
@JSONField(name = "cash_fee")
private int cashFee; // 现金支付金额
private int cashFee;
/**
* 现金支付金额货币种类
*
* @see com.foxinmy.weixin4j.mp.type.CurrencyType
*/
@XStreamAlias("cash_fee_type")
@JSONField(name = "cash_fee_type")
private CurrencyType cashFeeType; // 现金支付金额货币种类
private CurrencyType cashFeeType;
/**
* 退款总金额
*/
@XStreamAlias("refund_fee")
@JSONField(name = "refund_fee")
private int refundFee; // 退款总金额
private int refundFee;
/**
* 代金券或立减优惠退款金额=订单金额-现金退款金额,注意:满立减金额不会退回
*/
@XStreamAlias("coupon_refund_fee")
@JSONField(name = "coupon_refund_fee")
private Integer couponRefundFee; // 代金券或立减优惠退款金额=订单金额-现金退款金额,注意:满立减金额不会退回
private Integer couponRefundFee;
/**
* 退款笔数
*/
@XStreamAlias("refund_count")
@JSONField(name = "refund_count")
private int count;// 退款笔数
private int count;
/**
* 退款详情
*/
@XStreamOmitField
@JSONField(serialize = false, deserialize = false)
private List<RefundDetail> details; // 退款详情
private List<RefundDetail> details;
public String getTransactionId() {
return transactionId;
@@ -17,12 +17,18 @@ public class RefundResult extends RefundDetail {
private static final long serialVersionUID = -3687863914168618620L;
/**
* 微信订单号
*/
@XStreamAlias("transaction_id")
@JSONField(name = "transaction_id")
private String transactionId;// 微信订单号
private String transactionId;
/**
* 商户系统内部的订单号
*/
@XStreamAlias("out_trade_no")
@JSONField(name = "out_trade_no")
private String outTradeNo;// 商户系统内部的订单号
private String outTradeNo;
public String getTransactionId() {
return transactionId;
@@ -10,12 +10,24 @@ package com.foxinmy.weixin4j.mp.type;
* @see
*/
public enum BillType {
ALL(0), SUCCESS(1), REFUND(2);
/**
* 全部
*/
ALL(0),
/**
* 成功订单
*/
SUCCESS(1),
/**
* 退款订单
*/
REFUND(2);
private int val;
BillType(int val) {
this.val = val;
}
public int getVal() {
return val;
}
@@ -0,0 +1,34 @@
package com.foxinmy.weixin4j.mp.type;
/**
* 代金券状态
*
* @className CouponStatus
* @author jy
* @date 2015年3月27日
* @since JDK 1.7
* @see
*/
public enum CouponStatus {
/**
* 已激活
*/
ACTIVATED(2),
/**
* 已锁定
*/
LOCKED(4),
/**
* 已实扣
*/
USED(8);
private int val;
CouponStatus(int val) {
this.val = val;
}
public int getVal() {
return val;
}
}
@@ -0,0 +1,42 @@
package com.foxinmy.weixin4j.mp.type;
/**
* 代金券批次状态
*
* @className CouponStockStatus
* @author jy
* @date 2015年3月27日
* @since JDK 1.7
* @see
*/
public enum CouponStockStatus {
/**
* 未激活
*/
INACTIVE(1),
/**
* 审批中
*/
APPROVAL_PROCESS(2),
/**
* 已激活
*/
ACTIVATED(4),
/**
* 已作废
*/
SUPERSEDED(8),
/**
* 中止发放
*/
SUSPEND(16);
private int val;
CouponStockStatus(int val) {
this.val = val;
}
public int getVal() {
return val;
}
}
@@ -0,0 +1,30 @@
package com.foxinmy.weixin4j.mp.type;
/**
* 代金券批次类型
*
* @className CouponStockType
* @author jy
* @date 2015年3月27日
* @since JDK 1.7
* @see
*/
public enum CouponStockType {
/**
* 批量型
*/
BATCH(1),
/**
* 触发型
*/
TRIGGER(2);
private int val;
CouponStockType(int val) {
this.val = val;
}
public int getVal() {
return val;
}
}
@@ -0,0 +1,34 @@
package com.foxinmy.weixin4j.mp.type;
/**
* 代金券类型
*
* @className CouponType
* @author jy
* @date 2015年3月27日
* @since JDK 1.7
* @see
*/
public enum CouponType {
/**
* 使用无门槛
*/
NO_THRESHOLD(1),
/**
* 使用有门槛
*/
HAS_THRESHOLD(2),
/**
* 门槛叠加
*/
THRESHOLD_PLUS(3);
private int val;
CouponType(int val) {
this.val = val;
}
public int getVal() {
return val;
}
}
@@ -0,0 +1,29 @@
package com.foxinmy.weixin4j.mp.type;
/**
* 消息量分布的区间
*
* @className DatacuteCountIntervalType
* @author jy
* @date 2015年3月29日
* @since JDK 1.7
* @see
*/
public enum DatacuteCountIntervalType {
/**
* 0
*/
ZERO,
/**
* 1-5
*/
ONE2FIVE,
/**
* 6-10
*/
SIX2TEN,
/**
* 10次以上
*/
MORE_THAN_TEN
}
@@ -2,6 +2,7 @@ package com.foxinmy.weixin4j.mp.type;
/**
* 头像大小
*
* @className FaceSize
* @author jy
* @date 2014年11月5日
@@ -9,7 +10,22 @@ package com.foxinmy.weixin4j.mp.type;
* @see
*/
public enum FaceSize {
small(46), middle1(64), middle2(96), big(132);
/**
* 46x46
*/
small(46),
/**
* 64x64
*/
middle1(64),
/**
* 96x96
*/
middle2(96),
/**
* 132x132
*/
big(132);
private int size;
FaceSize(int size) {
@@ -14,7 +14,15 @@ import java.io.Serializable;
public class IdQuery implements Serializable {
private static final long serialVersionUID = -5273675987521807370L;
/**
* id值
*/
private String id;
/**
* id类型
*
* @see com.foxinmy.weixin4j.mp.type.IdType
*/
private IdType type;
public String getId() {
@@ -42,5 +50,4 @@ public class IdQuery implements Serializable {
public String toString() {
return String.format("%s=%s", type.getName(), id);
}
}
@@ -10,10 +10,22 @@ package com.foxinmy.weixin4j.mp.type;
* @see
*/
public enum IdType {
REFUNDID("refund_id"), // 微信退款单号
TRANSACTIONID("transaction_id"), // 微信订单号
TRADENO("out_trade_no"), // 商户订单号
REFUNDNO("out_refund_no"); // 商户退款号
/**
* 微信退款单号
*/
REFUNDID("refund_id"),
/**
* 微信订单号
*/
TRANSACTIONID("transaction_id"),
/**
* 商户订单号
*/
TRADENO("out_trade_no"),
/**
* 商户退款号
*/
REFUNDNO("out_refund_no");
private String name;
IdType(String name) {
@@ -2,6 +2,7 @@ package com.foxinmy.weixin4j.mp.type;
/**
* 二维码类型
*
* @className QRType
* @author jy
* @date 2014年11月4日
@@ -9,8 +10,14 @@ package com.foxinmy.weixin4j.mp.type;
* @see
*/
public enum QRType {
TEMPORARY("QR_SCENE"), // 临时
PERMANENCE("QR_LIMIT_SCENE"); // 永久
/**
* 临时二维码
*/
TEMPORARY("QR_SCENE"),
/**
* 永久二维码
*/
PERMANENCE("QR_LIMIT_SCENE");
private String name;
QRType(String name) {
@@ -10,9 +10,20 @@ package com.foxinmy.weixin4j.mp.type;
* @see
*/
public enum RefundChannel {
ORIGINAL, // 原路退款
BALANCE,// 退回到余额
TENPAY, // 财付通
BANK; // 银行
/**
* 原路退款
*/
ORIGINAL,
/**
* 退回到余额
*/
BALANCE,
/**
* 财付通
*/
TENPAY,
/**
* 银行
*/
BANK;
}
@@ -10,10 +10,25 @@ package com.foxinmy.weixin4j.mp.type;
* @see
*/
public enum RefundStatus {
SUCCESS, // 退款成功
FAIL, // 退款失败
PROCESSING, // 退款处理中
NOTSURE, // 未确定,需要商户 原退款单号重新发起
CHANGE; // 转入代发,退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败,资金回流到商户的现金帐号,需要商户人工干预,通过线下或者财付通转
// 账的方式进行退款。
/**
* 退款成功
*/
SUCCESS,
/**
* 退款失败
*/
FAIL,
/**
* 退款处理中
*/
PROCESSING,
/**
* 未确定,需要商户 原退款单号重新发起
*/
NOTSURE,
/**
* 转入代发,退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败,资金回流到商户的现金帐号,需要商户人工干预,通过线下或者财付通转
* 账的方式进行退款。
*/
CHANGE;
}
@@ -10,15 +10,25 @@ package com.foxinmy.weixin4j.mp.type;
* @see
*/
public enum RefundType {
BALANCE(1), // 1:商户号余额退款;
CASH(2), // 2:现金帐号 退款;
BOTH(3);// 3:优先商户号退款,若商户号余额不足, 再做现金帐号退款。
// 使用 2 或 3 时,需联系财 付通开通此功能
/**
* 1:商户号余额退款;
*/
BALANCE(1),
/**
* 2:现金帐号 退款;
*/
CASH(2),
/**
* 3:优先商户号退款,若商户号余额不足, 再做现金帐号退款。 使用 2 或 3 时,需联系财 付通开通此功能
*/
BOTH(3);
private int val;
RefundType(int val) {
this.val = val;
}
public int getVal() {
return val;
}
@@ -10,27 +10,39 @@ package com.foxinmy.weixin4j.mp.type;
* @see
*/
public enum SemCategory {
// 生活类
/**
* 生活类
*/
restaurant("生活类", "餐馆", "查询餐馆的服务,例如:中关村附近的面馆"), map("生活类", "地图",
"查询地图服务,例如:从银科大厦到天坛公园怎么走"), nearby("生活类", "周边",
"查询周边的服务,例如:我想去打保龄球"), coupon("生活类", "优惠券/团购",
"查询优惠券/团购的服务,例如:“附 近有什么优惠券”;如果查已有类别 的优惠券,比如:“附近有什么酒店 优惠券”,那么就会优先是酒店类。"),
// 旅行类
/**
* 旅行类
*/
hotel("旅行类", "酒店", "查询酒店服务,例如:查一下中关村附近有没有七天酒店"), travel("旅行类", "旅游",
"查询旅游服务,例如:故宫门票多少钱"), flight("旅行类", "航班", "查询航班的服务,例如:明天从北京到上海的机票"), train(
"旅行类", "火车", "查询火车服务,例如:查一下从北京到西安的火车"),
// 娱乐类
/**
* 娱乐类
*/
movie("娱乐类", "上映电影", "查询上映电影的服务,例如:最近有什么好看的电影"), music("娱乐类", "音乐",
"查询音乐的服务,例如:来点刘德华的歌"), video("娱乐类", "视频", "查询视频服务,例如:我想看甄嬛传"), novel(
"娱乐类", "小说", "查询小说的服务,例如:来点言情小说看看"),
// 工具类
/**
* 工具类
*/
weather("工具类", "天气", "查询天气的服务,例如:明天北京天气"), stock("工具类", "股票",
"查询股票的服务,例如:腾讯股价多少了"), remind("工具类", "提醒", "提醒服务,例如:提醒我明天上午十点开会"), telephone(
"工具类", "常用电影", "查询常用电话号码服务,例如:查询一下招行信用卡的电话"),
// 知识类
/**
* 知识类
*/
cookbook("知识类", "菜谱", "查询菜谱服务,例如:宫保鸡丁怎么做"), baike("知识类", "百科",
"查询百科服务,例如:查一下刘德华的百科资料"), news("知识类", "资讯", "查询新闻服务,例如:今天有什么新闻"),
// 其他类
/**
* 其他类
*/
tv("其他类", "电视节目预告", "查询电视节目服务,例如:湖南台今晚有什么节目"), instruction("其他类", "通用指令",
"通用指令服务,例如:把声音调高一点"), tv_instruction("其他类", "电视指令",
"电视指令服务,例如:切换到中央五台"), car_instruction("其他类", "车载指令",
@@ -10,8 +10,20 @@ package com.foxinmy.weixin4j.mp.type;
* @see
*/
public enum ShareSourceType {
FRIENDFORWARD, // 好友转发
FRIENDSCIRCLE, // 朋友圈
TENCENTWEIBO, // 腾讯微博
OTHER // 其它
/**
* 好友转发
*/
FRIENDFORWARD,
/**
* 朋友圈
*/
FRIENDSCIRCLE,
/**
* 腾讯微博
*/
TENCENTWEIBO,
/**
* 其它
*/
OTHER;
}
@@ -10,12 +10,36 @@ package com.foxinmy.weixin4j.mp.type;
* @see
*/
public enum TradeState {
SUCCESS, // 支付成功
REFUND, // 转入退款
NOTPAY, // 未支付
CLOSED, // 已关闭
REVOKED, // 已撤销
USERPAYING, // 用户支付中
NOPAY, // 未支付(输入密码或 确认支付超时)
PAYERROR;// 支付失败(其他 原因,如银行返回失败)
/**
* 支付成功
*/
SUCCESS,
/**
* 转入退款
*/
REFUND,
/**
* 未支付
*/
NOTPAY,
/**
* 已关闭
*/
CLOSED,
/**
* 已撤销
*/
REVOKED,
/**
* 用户支付中
*/
USERPAYING,
/**
* 未支付(输入密码或 确认支付超时)
*/
NOPAY,
/**
* 支付失败(其他 原因,如银行返回失败)
*/
PAYERROR;
}
@@ -10,5 +10,20 @@ package com.foxinmy.weixin4j.mp.type;
* @see
*/
public enum TradeType {
JSAPI, MICROPAY, NATIVE, APP;
/**
* H5页面上的JSAPI支付
*/
JSAPI,
/**
* 刷卡支付
*/
MICROPAY,
/**
* 扫描支付
*/
NATIVE,
/**
* APP支付
*/
APP;
}
@@ -0,0 +1,64 @@
package com.foxinmy.weixin4j.mp.test;
import java.io.File;
import java.util.Date;
import org.junit.Assert;
import org.junit.Test;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.model.WeixinMpAccount;
import com.foxinmy.weixin4j.mp.WeixinPayProxy;
import com.foxinmy.weixin4j.mp.payment.coupon.CouponDetail;
import com.foxinmy.weixin4j.mp.payment.coupon.CouponResult;
import com.foxinmy.weixin4j.mp.payment.coupon.CouponStock;
import com.foxinmy.weixin4j.token.FileTokenHolder;
import com.foxinmy.weixin4j.token.WeixinTokenCreator;
import com.foxinmy.weixin4j.type.AccountType;
import com.foxinmy.weixin4j.util.DateUtil;
/**
* 代金券测试
*
* @className CouponTest
* @author jy
* @date 2015年3月25日
* @since JDK 1.7
* @see
*/
public class CouponTest {
private final static WeixinPayProxy WEIXINPAY;
private final static WeixinMpAccount ACCOUNT;
static {
ACCOUNT = new WeixinMpAccount("wx0d1d598c0c03c999",
"2513ac683f1beabdb6b98d9ddd9e5755",
"GATFzDwbQdbbci3QEQxX2rUBvwTrsMiZ", "10020674");
WEIXINPAY = new WeixinPayProxy(ACCOUNT, new FileTokenHolder(
new WeixinTokenCreator(ACCOUNT.getId(), ACCOUNT.getSecret(),
AccountType.MP)));
}
private final File caFile = new File(
"/Users/jy/workspace/feican/canyi-weixin-parent/canyi-weixin-service/src/main/resources/10020674.p12");
@Test
public void sendCoupon() throws WeixinException {
String partnerTradeNo = String.format("%s%s%s", ACCOUNT.getMchId(),
DateUtil.fortmat2yyyyMMdd(new Date()), "1");
CouponResult result = WEIXINPAY.sendCoupon(caFile, "123",
partnerTradeNo, "oyFLst1bqtuTcxK-ojF8hOGtLQao", null);
Assert.assertTrue(result.getRetCode().equalsIgnoreCase(Consts.SUCCESS));
}
@Test
public void queryCouponStock() throws WeixinException {
CouponStock couponStock = WEIXINPAY.queryCouponStock("couponStockId");
System.err.println(couponStock);
}
@Test
public void queryCouponDetail() throws WeixinException {
CouponDetail couponDetail = WEIXINPAY.queryCouponDetail("couponId");
System.err.println(couponDetail);
}
}