将微信支付模块移到base工程
This commit is contained in:
@@ -3,9 +3,12 @@ package com.foxinmy.weixin4j.api;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinHttpClient;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.token.FileTokenStorager;
|
||||
import com.foxinmy.weixin4j.token.TokenStorager;
|
||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
|
||||
/**
|
||||
* API基础
|
||||
@@ -38,8 +41,19 @@ public abstract class BaseApi {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认使用weixin4j.properties文件中的公众号信息
|
||||
*/
|
||||
public final static WeixinAccount DEFAULT_WEIXIN_ACCOUNT;
|
||||
|
||||
/**
|
||||
* 默认token使用File的方式存储
|
||||
*/
|
||||
public final static TokenStorager DEFAULT_TOKEN_STORAGER = new FileTokenStorager();
|
||||
public final static TokenStorager DEFAULT_TOKEN_STORAGER;
|
||||
|
||||
static {
|
||||
DEFAULT_WEIXIN_ACCOUNT = JSON.parseObject(
|
||||
ConfigUtil.getValue("account"), WeixinAccount.class);
|
||||
DEFAULT_TOKEN_STORAGER = new FileTokenStorager();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,243 @@
|
||||
package com.foxinmy.weixin4j.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 com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.weixin.SSLHttpClinet;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.payment.PayURLConsts;
|
||||
import com.foxinmy.weixin4j.payment.PayUtil;
|
||||
import com.foxinmy.weixin4j.payment.mch.MPPayment;
|
||||
import com.foxinmy.weixin4j.payment.mch.MPPaymentRecord;
|
||||
import com.foxinmy.weixin4j.payment.mch.MPPaymentResult;
|
||||
import com.foxinmy.weixin4j.payment.mch.Redpacket;
|
||||
import com.foxinmy.weixin4j.payment.mch.RedpacketRecord;
|
||||
import com.foxinmy.weixin4j.payment.mch.RedpacketSendResult;
|
||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||
import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
|
||||
/**
|
||||
* 现金API
|
||||
*
|
||||
* @className CashApi
|
||||
* @author jy
|
||||
* @date 2015年3月28日
|
||||
* @since JDK 1.7
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=13_1">现金红包</a>
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/mch_pay.php?chapter=14_1">企业付款</a>
|
||||
*/
|
||||
public class CashApi {
|
||||
|
||||
private final WeixinPayAccount weixinAccount;
|
||||
|
||||
public CashApi(WeixinPayAccount weixinAccount) {
|
||||
this.weixinAccount = weixinAccount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发放红包 企业向微信用户个人发现金红包
|
||||
*
|
||||
* @param caFile
|
||||
* 证书文件(V3版本后缀为*.p12)
|
||||
* @param redpacket
|
||||
* 红包信息
|
||||
* @return 发放结果
|
||||
* @see com.foxinmy.weixin4j.payment.mch.Redpacket
|
||||
* @see com.foxinmy.weixin4j.payment.mch.RedpacketSendResult
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=13_5">发放红包接口说明</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public RedpacketSendResult sendRedpack(File caFile, Redpacket redpacket)
|
||||
throws WeixinException {
|
||||
JSONObject obj = (JSONObject) JSON.toJSON(redpacket);
|
||||
obj.put("nonce_str", RandomUtil.generateString(16));
|
||||
obj.put("mch_id", weixinAccount.getMchId());
|
||||
obj.put("sub_mch_id", weixinAccount.getSubMchId());
|
||||
obj.put("wxappid", weixinAccount.getId());
|
||||
String sign = PayUtil.paysignMd5(obj, weixinAccount.getPaySignKey());
|
||||
obj.put("sign", sign);
|
||||
String param = XmlStream.map2xml(obj);
|
||||
WeixinResponse response = null;
|
||||
InputStream ca = null;
|
||||
try {
|
||||
ca = new FileInputStream(caFile);
|
||||
SSLHttpClinet request = new SSLHttpClinet(weixinAccount.getMchId(),
|
||||
ca);
|
||||
response = request.post(PayURLConsts.MCH_REDPACKSEND_URL, param);
|
||||
} catch (WeixinException e) {
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
throw new WeixinException(e.getMessage());
|
||||
} finally {
|
||||
if (ca != null) {
|
||||
try {
|
||||
ca.close();
|
||||
} catch (IOException e) {
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
return response.getAsObject(new TypeReference<RedpacketSendResult>() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询红包记录
|
||||
*
|
||||
* @param caFile
|
||||
* 证书文件(V3版本后缀为*.p12)
|
||||
* @param outTradeNo
|
||||
* 商户发放红包的商户订单号
|
||||
* @return 红包记录
|
||||
* @see com.foxinmy.weixin4j.payment.mch.RedpacketRecord
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=13_6">查询红包接口说明</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public RedpacketRecord queryRedpack(File caFile, String outTradeNo)
|
||||
throws WeixinException {
|
||||
Map<String, String> para = new HashMap<String, String>();
|
||||
para.put("nonce_str", RandomUtil.generateString(16));
|
||||
para.put("mch_id", weixinAccount.getMchId());
|
||||
para.put("bill_type", "MCHT");
|
||||
para.put("appid", weixinAccount.getId());
|
||||
para.put("mch_billno", outTradeNo);
|
||||
String sign = PayUtil.paysignMd5(para, weixinAccount.getPaySignKey());
|
||||
para.put("sign", sign);
|
||||
String param = XmlStream.map2xml(para);
|
||||
WeixinResponse response = null;
|
||||
InputStream ca = null;
|
||||
try {
|
||||
ca = new FileInputStream(caFile);
|
||||
SSLHttpClinet request = new SSLHttpClinet(weixinAccount.getMchId(),
|
||||
ca);
|
||||
response = request.post(PayURLConsts.MCH_REDPACKQUERY_URL, param);
|
||||
} catch (WeixinException e) {
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
throw new WeixinException(e.getMessage());
|
||||
} finally {
|
||||
if (ca != null) {
|
||||
try {
|
||||
ca.close();
|
||||
} catch (IOException e) {
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
return response.getAsObject(new TypeReference<RedpacketRecord>() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业付款 实现企业向个人付款,针对部分有开发能力的商户, 提供通过API完成企业付款的功能。 比如目前的保险行业向客户退保、给付、理赔。
|
||||
*
|
||||
* @param caFile
|
||||
* 证书文件(V3版本后缀为*.p12)
|
||||
* @param mpPayment
|
||||
* 付款信息
|
||||
* @return 付款结果
|
||||
* @see com.foxinmy.weixin4j.payment.mch.MPPayment
|
||||
* @see com.foxinmy.weixin4j.payment.mch.MPPaymentResult
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/mch_pay.php?chapter=14_1">企业付款</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public MPPaymentResult mpPayment(File caFile, MPPayment mpPayment)
|
||||
throws WeixinException {
|
||||
JSONObject obj = (JSONObject) JSON.toJSON(mpPayment);
|
||||
obj.put("nonce_str", RandomUtil.generateString(16));
|
||||
obj.put("mchid", weixinAccount.getMchId());
|
||||
obj.put("sub_mch_id", weixinAccount.getSubMchId());
|
||||
obj.put("mch_appid", weixinAccount.getId());
|
||||
obj.put("device_info", weixinAccount.getDeviceInfo());
|
||||
String sign = PayUtil.paysignMd5(obj, weixinAccount.getPaySignKey());
|
||||
obj.put("sign", sign);
|
||||
String param = XmlStream.map2xml(obj);
|
||||
WeixinResponse response = null;
|
||||
InputStream ca = null;
|
||||
try {
|
||||
ca = new FileInputStream(caFile);
|
||||
SSLHttpClinet request = new SSLHttpClinet(weixinAccount.getMchId(),
|
||||
ca);
|
||||
response = request.post(PayURLConsts.MCH_ENPAYMENT_URL, param);
|
||||
} catch (WeixinException e) {
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
throw new WeixinException(e.getMessage());
|
||||
} finally {
|
||||
if (ca != null) {
|
||||
try {
|
||||
ca.close();
|
||||
} catch (IOException e) {
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
String text = response.getAsString()
|
||||
.replaceFirst("<mch_appid>", "<appid>")
|
||||
.replaceFirst("</mch_appid>", "</appid>")
|
||||
.replaceFirst("<mchid>", "<mch_id>")
|
||||
.replaceFirst("</mchid>", "</mch_id>");
|
||||
return XmlStream.fromXML(text, MPPaymentResult.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业付款查询 用于商户的企业付款操作进行结果查询,返回付款操作详细结果
|
||||
*
|
||||
* @param caFile
|
||||
* 证书文件(V3版本后缀为*.p12)
|
||||
* @param outTradeNo
|
||||
* 商户调用企业付款API时使用的商户订单号
|
||||
* @return 付款记录
|
||||
* @see com.foxinmy.weixin4j.payment.mch.MPPaymentRecord
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/mch_pay.php?chapter=14_3">企业付款查询</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public MPPaymentRecord mpPaymentQuery(File caFile, String outTradeNo)
|
||||
throws WeixinException {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("nonce_str", RandomUtil.generateString(16));
|
||||
obj.put("mch_id", weixinAccount.getMchId());
|
||||
obj.put("appid", weixinAccount.getId());
|
||||
obj.put("partner_trade_no", outTradeNo);
|
||||
String sign = PayUtil.paysignMd5(obj, weixinAccount.getPaySignKey());
|
||||
obj.put("sign", sign);
|
||||
String param = XmlStream.map2xml(obj);
|
||||
WeixinResponse response = null;
|
||||
InputStream ca = null;
|
||||
try {
|
||||
ca = new FileInputStream(caFile);
|
||||
SSLHttpClinet request = new SSLHttpClinet(weixinAccount.getMchId(),
|
||||
ca);
|
||||
response = request.post(PayURLConsts.MCH_ENPAYQUERY_URL, param);
|
||||
} catch (WeixinException e) {
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
throw new WeixinException(e.getMessage());
|
||||
} finally {
|
||||
if (ca != null) {
|
||||
try {
|
||||
ca.close();
|
||||
} catch (IOException e) {
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
return response.getAsObject(new TypeReference<MPPaymentRecord>() {
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
package com.foxinmy.weixin4j.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 com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.weixin.SSLHttpClinet;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinHttpClient;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.payment.PayURLConsts;
|
||||
import com.foxinmy.weixin4j.payment.PayUtil;
|
||||
import com.foxinmy.weixin4j.payment.coupon.CouponDetail;
|
||||
import com.foxinmy.weixin4j.payment.coupon.CouponResult;
|
||||
import com.foxinmy.weixin4j.payment.coupon.CouponStock;
|
||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
|
||||
/**
|
||||
* 代金券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 {
|
||||
|
||||
private final WeixinHttpClient weixinClient;
|
||||
|
||||
private final WeixinPayAccount weixinAccount;
|
||||
|
||||
public CouponApi(WeixinPayAccount weixinAccount) {
|
||||
this.weixinAccount = weixinAccount;
|
||||
this.weixinClient = new WeixinHttpClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发放代金券(需要证书)
|
||||
*
|
||||
* @param caFile
|
||||
* 证书文件(后缀为*.p12)
|
||||
* @param couponStockId
|
||||
* 代金券批次id
|
||||
* @param partnerTradeNo
|
||||
* 商户发放凭据号(格式:商户id+日期+流水号),商户侧需保持唯一性
|
||||
* @param openId
|
||||
* 用户的openid
|
||||
* @param opUserId
|
||||
* 操作员帐号, 默认为商户号 可在商户平台配置操作员对应的api权限 可为空
|
||||
* @return 发放结果
|
||||
* @see com.foxinmy.weixin4j.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 (StringUtil.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 = XmlStream.map2xml(map);
|
||||
WeixinResponse response = null;
|
||||
InputStream ca = null;
|
||||
try {
|
||||
ca = new FileInputStream(caFile);
|
||||
SSLHttpClinet request = new SSLHttpClinet(weixinAccount.getMchId(),
|
||||
ca);
|
||||
response = request.post(PayURLConsts.MCH_COUPONSEND_URL, param);
|
||||
} catch (WeixinException e) {
|
||||
throw e;
|
||||
} catch (IOException 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.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 = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinClient.post(
|
||||
PayURLConsts.MCH_COUPONSTOCKQUERY_URL, param);
|
||||
return response.getAsObject(new TypeReference<CouponStock>() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询代金券详细
|
||||
*
|
||||
* @param couponId
|
||||
* 代金券ID
|
||||
* @return 代金券详细信息
|
||||
* @see com.foxinmy.weixin4j.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 = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinClient.post(
|
||||
PayURLConsts.MCH_COUPONDETAILQUERY_URL, 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 (StringUtil.isNotBlank(weixinAccount.getDeviceInfo())) {
|
||||
map.put("device_info", weixinAccount.getDeviceInfo());
|
||||
}
|
||||
if (StringUtil.isNotBlank(weixinAccount.getSubMchId())) {
|
||||
map.put("sub_mch_id", weixinAccount.getSubMchId());
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,464 @@
|
||||
package com.foxinmy.weixin4j.api;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.weixin.SSLHttpClinet;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinHttpClient;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.http.weixin.XmlResult;
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
import com.foxinmy.weixin4j.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.payment.PayURLConsts;
|
||||
import com.foxinmy.weixin4j.payment.PayUtil;
|
||||
import com.foxinmy.weixin4j.payment.mch.ApiResult;
|
||||
import com.foxinmy.weixin4j.payment.mch.Order;
|
||||
import com.foxinmy.weixin4j.payment.mch.RefundRecord;
|
||||
import com.foxinmy.weixin4j.payment.mch.RefundResult;
|
||||
import com.foxinmy.weixin4j.type.BillType;
|
||||
import com.foxinmy.weixin4j.type.CurrencyType;
|
||||
import com.foxinmy.weixin4j.type.IdQuery;
|
||||
import com.foxinmy.weixin4j.type.IdType;
|
||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
import com.foxinmy.weixin4j.util.DateUtil;
|
||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer;
|
||||
import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
|
||||
/**
|
||||
* (商户平台版)支付API
|
||||
*
|
||||
* @className Pay3Api
|
||||
* @author jy
|
||||
* @date 2014年10月28日
|
||||
* @since JDK 1.7
|
||||
* @see <a href="http://pay.weixin.qq.com/wiki/doc/api/index.html">商户平台API</a>
|
||||
*/
|
||||
public class Pay3Api {
|
||||
|
||||
private final WeixinHttpClient weixinClient;
|
||||
|
||||
private final WeixinPayAccount weixinAccount;
|
||||
|
||||
public Pay3Api(WeixinPayAccount weixinAccount) {
|
||||
this.weixinAccount = weixinAccount;
|
||||
this.weixinClient = new WeixinHttpClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单查询
|
||||
* <p>
|
||||
* 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;</br> 调用支付接口后,返回系统错误或未知交易状态情况;</br>
|
||||
* 调用被扫支付API,返回USERPAYING的状态;</br> 调用关单或撤销接口API之前,需确认支付状态;
|
||||
* </P>
|
||||
*
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id、out_trade_no 二 选一,如果同时存在优先级:
|
||||
* transaction_id> out_trade_no
|
||||
* @return 订单信息
|
||||
* @see com.foxinmy.weixin4j.payment.mch.Order
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2">订单查询API</a>
|
||||
* @since V3
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public Order orderQuery(IdQuery idQuery) throws WeixinException {
|
||||
Map<String, String> map = baseMap(idQuery);
|
||||
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinClient.post(
|
||||
PayURLConsts.MCH_ORDERQUERY_URL, param);
|
||||
return ListsuffixResultDeserializer.deserialize(response.getAsString(),
|
||||
Order.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请退款(请求需要双向证书)
|
||||
* <p>
|
||||
* 当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付款退还给买家,微信支付将在收到退款请求并且验证成功之后,
|
||||
* 按照退款规则将支付款按原路退到买家帐号上。
|
||||
* </p>
|
||||
* <p style="color:red">
|
||||
* 1.交易时间超过半年的订单无法提交退款;
|
||||
* 2.微信支付退款支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。一笔退款失败后重新提交
|
||||
* ,要采用原来的退款单号。总退款金额不能超过用户实际支付金额。
|
||||
* </p>
|
||||
*
|
||||
* @param caFile
|
||||
* 证书文件(V3版本后缀为*.p12)
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
|
||||
* transaction_id> out_trade_no
|
||||
* @param outRefundNo
|
||||
* 商户系统内部的退款单号,商 户系统内部唯一,同一退款单号多次请求只退一笔
|
||||
* @param totalFee
|
||||
* 订单总金额,单位为元
|
||||
* @param refundFee
|
||||
* 退款总金额,单位为元,可以做部分退款
|
||||
* @param opUserId
|
||||
* 操作员帐号, 默认为商户号
|
||||
*
|
||||
* @return 退款申请结果
|
||||
* @see com.foxinmy.weixin4j.payment.mch.RefundResult
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4">申请退款API</a>
|
||||
* @since V3
|
||||
* @throws WeixinException
|
||||
*/
|
||||
protected RefundResult refundApply(File caFile, IdQuery idQuery,
|
||||
String outRefundNo, double totalFee, double refundFee,
|
||||
String opUserId, Map<String, String> mopara) throws WeixinException {
|
||||
WeixinResponse response = null;
|
||||
InputStream ca = null;
|
||||
try {
|
||||
ca = new FileInputStream(caFile);
|
||||
|
||||
Map<String, String> map = baseMap(idQuery);
|
||||
map.put("out_refund_no", outRefundNo);
|
||||
map.put("total_fee", DateUtil.formaFee2Fen(totalFee));
|
||||
map.put("refund_fee", DateUtil.formaFee2Fen(refundFee));
|
||||
if (StringUtil.isBlank(opUserId)) {
|
||||
opUserId = weixinAccount.getMchId();
|
||||
}
|
||||
map.put("op_user_id", opUserId);
|
||||
if (mopara != null && !mopara.isEmpty()) {
|
||||
map.putAll(mopara);
|
||||
}
|
||||
String sign = PayUtil
|
||||
.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
String param = XmlStream.map2xml(map);
|
||||
SSLHttpClinet request = new SSLHttpClinet(weixinAccount.getMchId(),
|
||||
ca);
|
||||
response = request.post(PayURLConsts.MCH_REFUNDAPPLY_URL, param);
|
||||
} catch (WeixinException e) {
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
throw new WeixinException(e.getMessage());
|
||||
} finally {
|
||||
if (ca != null) {
|
||||
try {
|
||||
ca.close();
|
||||
} catch (IOException e) {
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
return response.getAsObject(new TypeReference<RefundResult>() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款申请
|
||||
*
|
||||
* @param caFile
|
||||
* 证书文件(V3版本后缀为*.p12)
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
|
||||
* transaction_id> out_trade_no
|
||||
* @param outRefundNo
|
||||
* 商户系统内部的退款单号,商 户系统内部唯一,同一退款单号多次请求只退一笔
|
||||
* @param totalFee
|
||||
* 订单总金额,单位为元
|
||||
* @param refundFee
|
||||
* 退款总金额,单位为元,可以做部分退款
|
||||
* @param refundFeeType
|
||||
* 货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY
|
||||
* @param opUserId
|
||||
* 操作员帐号, 默认为商户号
|
||||
* @see {@link com.foxinmy.weixin4j.api.Pay3Api#refundApply(File, IdQuery, String, double, double, String, Map)}
|
||||
*/
|
||||
public RefundResult refundApply(File caFile, IdQuery idQuery,
|
||||
String outRefundNo, double totalFee, double refundFee,
|
||||
CurrencyType refundFeeType, String opUserId) throws WeixinException {
|
||||
Map<String, String> mopara = new HashMap<String, String>();
|
||||
if (refundFeeType == null) {
|
||||
refundFeeType = CurrencyType.CNY;
|
||||
}
|
||||
mopara.put("refund_fee_type", refundFeeType.name());
|
||||
return refundApply(caFile, idQuery, outRefundNo, totalFee, refundFee,
|
||||
opUserId, mopara);
|
||||
}
|
||||
|
||||
/**
|
||||
* 冲正订单(需要证书)</br> 当支付返回失败,或收银系统超时需要取消交易,可以调用该接口</br> 接口逻辑:支
|
||||
* 付失败的关单,支付成功的撤销支付</br> <font color="red">7天以内的单可撤销,其他正常支付的单
|
||||
* 如需实现相同功能请调用退款接口</font></br> <font
|
||||
* color="red">调用扣款接口后请勿立即调用撤销,需要等待5秒以上。先调用查单接口,如果没有确切的返回,再调用撤销</font></br>
|
||||
*
|
||||
* @param caFile
|
||||
* 证书文件(V3版本后缀为*.p12)
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
|
||||
* transaction_id> out_trade_no
|
||||
* @return 撤销结果
|
||||
* @since V3
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public ApiResult reverseOrder(File caFile, IdQuery idQuery)
|
||||
throws WeixinException {
|
||||
InputStream ca = null;
|
||||
try {
|
||||
ca = new FileInputStream(caFile);
|
||||
SSLHttpClinet request = new SSLHttpClinet(weixinAccount.getMchId(),
|
||||
ca);
|
||||
Map<String, String> map = baseMap(idQuery);
|
||||
String sign = PayUtil
|
||||
.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = request.post(
|
||||
PayURLConsts.MCH_ORDERREVERSE_URL, param);
|
||||
return response.getAsObject(new TypeReference<ApiResult>() {
|
||||
});
|
||||
} catch (IOException e) {
|
||||
throw new WeixinException(e.getMessage());
|
||||
} finally {
|
||||
if (ca != null) {
|
||||
try {
|
||||
ca.close();
|
||||
} catch (IOException e) {
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* native支付URL转短链接:用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX),减小二维码数据量
|
||||
* ,提升扫描速度和精确度。
|
||||
*
|
||||
* @param url
|
||||
* 具有native标识的支付URL
|
||||
* @return 转换后的短链接
|
||||
* @throws WeixinException
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_9">转换短链接API</a>
|
||||
*/
|
||||
public String getShorturl(String url) throws WeixinException {
|
||||
Map<String, String> map = baseMap(null);
|
||||
try {
|
||||
map.put("long_url", URLEncoder.encode(url, Consts.UTF_8.name()));
|
||||
} catch (UnsupportedEncodingException ignore) {
|
||||
;
|
||||
}
|
||||
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinClient.post(
|
||||
PayURLConsts.MCH_SHORTURL_URL, param);
|
||||
map = XmlStream.xml2map(response.getAsString());
|
||||
return map.get("short_url");
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭订单
|
||||
* <p>
|
||||
* 商户订单支付失败需要生成新单号重新发起支付,要对原订单号调用关单,避免重复支付;系统下单后,用户支付超时,系统退出不再受理,避免用户继续
|
||||
* ,请调用关单接口,如果关单失败,返回已完 成支付请按正常支付处理。如果出现银行掉单,调用关单成功后,微信后台会主动发起退款。
|
||||
* </p>
|
||||
*
|
||||
* @param outTradeNo
|
||||
* 商户系统内部的订单号
|
||||
* @return 处理结果
|
||||
* @since V3
|
||||
* @throws WeixinException
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_3">关闭订单API</a>
|
||||
*/
|
||||
public ApiResult closeOrder(String outTradeNo) throws WeixinException {
|
||||
Map<String, String> map = baseMap(new IdQuery(outTradeNo,
|
||||
IdType.TRADENO));
|
||||
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinClient.post(
|
||||
PayURLConsts.MCH_CLOSEORDER_URL, param);
|
||||
return response.getAsObject(new TypeReference<ApiResult>() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载对账单<br>
|
||||
* 1.微信侧未成功下单的交易不会出现在对账单中。支付成功后撤销的交易会出现在对账 单中,跟原支付单订单号一致,bill_type 为
|
||||
* REVOKED;<br>
|
||||
* 2.微信在次日 9 点启动生成前一天的对账单,建议商户 9 点半后再获取;<br>
|
||||
* 3.对账单中涉及金额的字段单位为“元”。<br>
|
||||
*
|
||||
* @param billDate
|
||||
* 下载对账单的日期
|
||||
* @param billType
|
||||
* 下载对账单的类型 ALL,返回当日所有订单信息, 默认值 SUCCESS,返回当日成功支付的订单
|
||||
* REFUND,返回当日退款订单
|
||||
* @return excel表格
|
||||
* @since V3
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_6">下载对账单API</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public File downloadbill(Date billDate, BillType billType)
|
||||
throws WeixinException {
|
||||
if (billDate == null) {
|
||||
Calendar now = Calendar.getInstance();
|
||||
now.add(Calendar.DAY_OF_MONTH, -1);
|
||||
billDate = now.getTime();
|
||||
}
|
||||
if (billType == null) {
|
||||
billType = BillType.ALL;
|
||||
}
|
||||
String formatBillDate = DateUtil.fortmat2yyyyMMdd(billDate);
|
||||
String bill_path = ConfigUtil.getValue("bill_path");
|
||||
String fileName = String.format("%s_%s_%s.txt", formatBillDate,
|
||||
billType.name().toLowerCase(), weixinAccount.getId());
|
||||
File file = new File(String.format("%s/%s", bill_path, fileName));
|
||||
if (file.exists()) {
|
||||
return file;
|
||||
}
|
||||
Map<String, String> map = baseMap(null);
|
||||
map.put("bill_date", formatBillDate);
|
||||
map.put("bill_type", billType.name());
|
||||
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinClient.post(
|
||||
PayURLConsts.MCH_DOWNLOADBILL_URL, param);
|
||||
|
||||
BufferedReader reader = null;
|
||||
BufferedWriter writer = null;
|
||||
FileWriter fw = null;
|
||||
try {
|
||||
fw = new FileWriter(file);
|
||||
writer = new BufferedWriter(fw);
|
||||
reader = new BufferedReader(new InputStreamReader(
|
||||
new ByteArrayInputStream(response.getContent()),
|
||||
com.foxinmy.weixin4j.model.Consts.GBK));
|
||||
String line = null;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
writer.write(line);
|
||||
writer.newLine();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new WeixinException(e.getMessage());
|
||||
} finally {
|
||||
try {
|
||||
if (reader != null) {
|
||||
reader.close();
|
||||
}
|
||||
if (writer != null) {
|
||||
writer.close();
|
||||
fw.close();
|
||||
}
|
||||
} catch (IOException ignore) {
|
||||
;
|
||||
}
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款查询
|
||||
*
|
||||
* <p>
|
||||
* 提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,用零钱支付的退款20分钟内到账,银行卡支付的退款3个工作日后重新查询退款状态。
|
||||
* </p>
|
||||
*
|
||||
* @param idQuery
|
||||
* 单号 refund_id、out_refund_no、 out_trade_no 、 transaction_id
|
||||
* 四个参数必填一个,优先级为:
|
||||
* refund_id>out_refund_no>transaction_id>out_trade_no
|
||||
* @return 退款记录
|
||||
* @see com.foxinmy.weixin4j.payment.mch.RefundRecord
|
||||
* @see com.foxinmy.weixin4j.payment.mch.RefundDetail
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_5">退款查询API</a>
|
||||
* @since V3
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public RefundRecord refundQuery(IdQuery idQuery) throws WeixinException {
|
||||
Map<String, String> map = baseMap(idQuery);
|
||||
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinClient.post(
|
||||
PayURLConsts.MCH_REFUNDQUERY_URL, param);
|
||||
return ListsuffixResultDeserializer.deserialize(response.getAsString(),
|
||||
RefundRecord.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口上报
|
||||
*
|
||||
* @param interfaceUrl
|
||||
* 上报对应的接口的完整 URL, 类似: https://api.mch.weixin.q
|
||||
* q.com/pay/unifiedorder
|
||||
* @param executeTime
|
||||
* 接口耗时情况,单位为毫秒
|
||||
* @param outTradeNo
|
||||
* 商户系统内部的订单号,商 户可以在上报时提供相关商户订单号方便微信支付更好 的提高服务质量。
|
||||
* @param ip
|
||||
* 发起接口调用时的机器 IP
|
||||
* @param time
|
||||
* 商户调用该接口时商户自己 系统的时间
|
||||
* @param returnXml
|
||||
* 调用接口返回的基本数据
|
||||
* @return 处理结果
|
||||
* @throws WeixinException
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_8">接口测试上报API</a>
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public XmlResult interfaceReport(String interfaceUrl, int executeTime,
|
||||
String outTradeNo, String ip, Date time, XmlResult returnXml)
|
||||
throws WeixinException {
|
||||
Map<String, String> map = baseMap(null);
|
||||
map.put("interface_url", interfaceUrl);
|
||||
map.put("execute_time_", Integer.toString(executeTime));
|
||||
map.put("out_trade_no", outTradeNo);
|
||||
map.put("user_ip", ip);
|
||||
map.put("time", DateUtil.fortmat2yyyyMMddHHmmss(time));
|
||||
map.putAll((Map<String, String>) JSON.toJSON(returnXml));
|
||||
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinClient.post(
|
||||
PayURLConsts.MCH_PAYREPORT_URL, param);
|
||||
return response.getAsXmlResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* V3接口请求基本数据
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private Map<String, String> baseMap(IdQuery idQuery) {
|
||||
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 (StringUtil.isNotBlank(weixinAccount.getDeviceInfo())) {
|
||||
map.put("device_info", weixinAccount.getDeviceInfo());
|
||||
}
|
||||
if (idQuery != null) {
|
||||
map.put(idQuery.getType().getName(), idQuery.getId());
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -1,15 +1,15 @@
|
||||
package com.foxinmy.weixin4j.page;
|
||||
package com.foxinmy.weixin4j.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.foxinmy.weixin4j.page.Sort.Direction;
|
||||
import com.foxinmy.weixin4j.model.Sort.Direction;
|
||||
|
||||
/**
|
||||
* @className Pageable
|
||||
* @author jy
|
||||
* @date 2014年12月27日
|
||||
* @since JDK 1.7
|
||||
* @see com.foxinmy.weixin4j.page.springframework.data.domain.Pageable
|
||||
* @see com.foxinmy.weixin4j.model.springframework.data.domain.Pageable
|
||||
*/
|
||||
public class Pageable implements Serializable {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.foxinmy.weixin4j.page;
|
||||
package com.foxinmy.weixin4j.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Iterator;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.foxinmy.weixin4j.page;
|
||||
package com.foxinmy.weixin4j.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
@@ -29,6 +29,7 @@ public class WeixinAccount implements Serializable {
|
||||
private String encodingAesKey;
|
||||
|
||||
public WeixinAccount() {
|
||||
|
||||
}
|
||||
|
||||
public WeixinAccount(String id, String secret) {
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
package com.foxinmy.weixin4j.model;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONCreator;
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
|
||||
/**
|
||||
* 微信支付账户
|
||||
*
|
||||
* @className WeixinPayAccount
|
||||
* @author jy
|
||||
* @date 2015年6月26日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class WeixinPayAccount extends WeixinAccount {
|
||||
|
||||
private static final long serialVersionUID = -2791256176906048632L;
|
||||
/**
|
||||
* 公众号支付请求中用于加密的密钥 Key,可验证商户唯一身份,PaySignKey 对应于支付场景中的 appKey 值
|
||||
*/
|
||||
private String paySignKey;
|
||||
/**
|
||||
* 财付通商户身份的标识
|
||||
*/
|
||||
private String partnerId;
|
||||
/**
|
||||
* 财付通商户权限密钥Key
|
||||
*/
|
||||
private String partnerKey;
|
||||
/**
|
||||
* 微信支付分配的商户号(商户平台版)
|
||||
*/
|
||||
private String mchId;
|
||||
/**
|
||||
* 微信支付分配的子商户号,受理模式下必填(商户平台版)
|
||||
*/
|
||||
private String subMchId;
|
||||
/**
|
||||
* 微信支付分配的设备号(商户平台版)
|
||||
*/
|
||||
private String deviceInfo;
|
||||
/**
|
||||
* 微信支付版本号(如果无则按照mchId来做判断)
|
||||
*/
|
||||
private int version;
|
||||
|
||||
/**
|
||||
* 商户平台版本(V3)字段
|
||||
*
|
||||
* @param appId
|
||||
* 公众号唯一的身份ID
|
||||
* @param appSecret
|
||||
* 调用接口的凭证
|
||||
* @param paySignKey
|
||||
* 支付密钥字符串
|
||||
* @param mchId
|
||||
* 微信支付分配的商户号
|
||||
*/
|
||||
@JSONCreator
|
||||
public WeixinPayAccount(@JSONField(name = "appId") String appId,
|
||||
@JSONField(name = "appSecret") String appSecret,
|
||||
@JSONField(name = "paySignKey") String paySignKey,
|
||||
@JSONField(name = "mchId") String mchId) {
|
||||
super(appId, appSecret);
|
||||
this.paySignKey = paySignKey;
|
||||
this.mchId = mchId;
|
||||
}
|
||||
|
||||
/**
|
||||
* V2版本字段
|
||||
*
|
||||
* @param appId
|
||||
* 公众号唯一的身份ID
|
||||
* @param appSecret
|
||||
* 调用接口的凭证
|
||||
* @param paySignKey
|
||||
* 支付密钥字符串
|
||||
* @param partnerId
|
||||
* 财付通账号的ID
|
||||
* @param partnerKey
|
||||
* 财付通账号的key
|
||||
*/
|
||||
@JSONCreator
|
||||
public WeixinPayAccount(@JSONField(name = "appId") String appId,
|
||||
@JSONField(name = "appSecret") String appSecret,
|
||||
@JSONField(name = "paySignKey") String paySignKey,
|
||||
@JSONField(name = "partnerId") String partnerId,
|
||||
@JSONField(name = "partnerKey") String partnerKey) {
|
||||
super(appId, appSecret);
|
||||
this.paySignKey = paySignKey;
|
||||
this.partnerId = partnerId;
|
||||
this.partnerKey = partnerKey;
|
||||
}
|
||||
|
||||
public String getPaySignKey() {
|
||||
return paySignKey;
|
||||
}
|
||||
|
||||
public String getPartnerId() {
|
||||
return partnerId;
|
||||
}
|
||||
|
||||
public String getPartnerKey() {
|
||||
return partnerKey;
|
||||
}
|
||||
|
||||
public String getMchId() {
|
||||
return mchId;
|
||||
}
|
||||
|
||||
public String getSubMchId() {
|
||||
return subMchId;
|
||||
}
|
||||
|
||||
public String getDeviceInfo() {
|
||||
return deviceInfo;
|
||||
}
|
||||
|
||||
public int getVersion() {
|
||||
if (version == 0) {
|
||||
return StringUtil.isNotBlank(mchId) ? 3 : 2;
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WeixinPayAccount [paySignKey=" + paySignKey + ", partnerId="
|
||||
+ partnerId + ", partnerKey=" + partnerKey + ", mchId=" + mchId
|
||||
+ ", subMchId=" + subMchId + ", deviceInfo=" + deviceInfo
|
||||
+ ", version=" + version + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.foxinmy.weixin4j.payment;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
|
||||
/**
|
||||
* JSAPI支付回调时的POST信息
|
||||
*
|
||||
* @className JsPayNotify
|
||||
* @author jy
|
||||
* @date 2014年8月19日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class JsPayNotify extends PayBaseInfo {
|
||||
|
||||
private static final long serialVersionUID = -4659030958445259803L;
|
||||
|
||||
/**
|
||||
* 用户的openid
|
||||
*/
|
||||
@XmlElement(name = "OpenId")
|
||||
private String openid;
|
||||
/**
|
||||
* 是否关注公众号
|
||||
*/
|
||||
@XmlElement(name = "IsSubscribe")
|
||||
private int issubscribe;
|
||||
|
||||
public JsPayNotify() {
|
||||
|
||||
}
|
||||
|
||||
public String getOpenid() {
|
||||
return openid;
|
||||
}
|
||||
|
||||
public void setOpenid(String openid) {
|
||||
this.openid = openid;
|
||||
}
|
||||
|
||||
public int getIssubscribe() {
|
||||
return issubscribe;
|
||||
}
|
||||
|
||||
public void setIssubscribe(int issubscribe) {
|
||||
this.issubscribe = issubscribe;
|
||||
}
|
||||
|
||||
@JSONField(serialize = false, deserialize = false)
|
||||
public boolean getFormatIssubscribe() {
|
||||
return issubscribe == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "openid=" + openid + ", issubscribe=" + getFormatIssubscribe()
|
||||
+ ", " + super.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package com.foxinmy.weixin4j.payment;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||
|
||||
/**
|
||||
* 刷卡支付
|
||||
*
|
||||
* @className MicroPayPackage
|
||||
* @author jy
|
||||
* @date 2014年11月17日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class MicroPayPackage extends PayPackage {
|
||||
|
||||
private static final long serialVersionUID = 8944928173669656177L;
|
||||
/**
|
||||
* 微信分配的公众账号 必须
|
||||
*/
|
||||
private String appid;
|
||||
/**
|
||||
* 微信支付分配的商户号 必须
|
||||
*/
|
||||
@XmlElement(name = "mch_id")
|
||||
@JSONField(name = "mch_id")
|
||||
private String mchId;
|
||||
/**
|
||||
* 微信支付分配的终端设备号 非必须
|
||||
*/
|
||||
@XmlElement(name = "device_info")
|
||||
@JSONField(name = "device_info")
|
||||
private String deviceInfo;
|
||||
/**
|
||||
* 随机字符串,不长于 32 位 必须
|
||||
*/
|
||||
@XmlElement(name = "nonce_str")
|
||||
@JSONField(name = "nonce_str")
|
||||
private String nonceStr;
|
||||
/**
|
||||
* 签名 <font color="red">调用者不必关注</font>
|
||||
*/
|
||||
private String sign;
|
||||
/**
|
||||
* 扫码支付授权码 ,设备读取用户微信中的条码或者二维码信息
|
||||
*/
|
||||
@XmlElement(name = "auth_code")
|
||||
@JSONField(name = "auth_code")
|
||||
private String authCode;
|
||||
|
||||
protected MicroPayPackage(){
|
||||
// jaxb required
|
||||
}
|
||||
|
||||
public MicroPayPackage(WeixinPayAccount weixinAccount, String body,
|
||||
String attach, String outTradeNo, double totalFee,
|
||||
String spbillCreateIp, String authCode) {
|
||||
this(weixinAccount.getId(), weixinAccount.getMchId(), weixinAccount
|
||||
.getDeviceInfo(), RandomUtil.generateString(16), body, attach,
|
||||
outTradeNo, totalFee, spbillCreateIp, null, null, null,
|
||||
authCode);
|
||||
}
|
||||
|
||||
public MicroPayPackage(String appid, String mchId, String deviceInfo,
|
||||
String nonceStr, String body, String attach, String outTradeNo,
|
||||
double totalFee, String spbillCreateIp, Date timeStart,
|
||||
Date timeExpire, String goodsTag, String authCode) {
|
||||
super(body, attach, outTradeNo, totalFee, spbillCreateIp, timeStart,
|
||||
timeExpire, goodsTag, null);
|
||||
this.appid = appid;
|
||||
this.mchId = mchId;
|
||||
this.deviceInfo = deviceInfo;
|
||||
this.nonceStr = nonceStr;
|
||||
this.authCode = authCode;
|
||||
}
|
||||
|
||||
public String getAppid() {
|
||||
return appid;
|
||||
}
|
||||
|
||||
public String getMchId() {
|
||||
return mchId;
|
||||
}
|
||||
|
||||
public String getDeviceInfo() {
|
||||
return deviceInfo;
|
||||
}
|
||||
|
||||
public String getNonceStr() {
|
||||
return nonceStr;
|
||||
}
|
||||
|
||||
public String getSign() {
|
||||
return sign;
|
||||
}
|
||||
|
||||
public void setSign(String sign) {
|
||||
this.sign = sign;
|
||||
}
|
||||
|
||||
public String getAuthCode() {
|
||||
return authCode;
|
||||
}
|
||||
|
||||
public void setAuthCode(String authCode) {
|
||||
this.authCode = authCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MicroPayPackage [appid=" + appid + ", mchId=" + mchId
|
||||
+ ", deviceInfo=" + deviceInfo + ", nonceStr=" + nonceStr
|
||||
+ ", sign=" + sign + ", authCode=" + authCode + ", "
|
||||
+ super.toString() + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package com.foxinmy.weixin4j.payment;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.type.SignType;
|
||||
|
||||
/**
|
||||
* 基本信息
|
||||
*
|
||||
* @className PayBaseInfo
|
||||
* @author jy
|
||||
* @date 2014年11月5日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class PayBaseInfo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1843024880782466990L;
|
||||
|
||||
/**
|
||||
* 公众号ID
|
||||
*/
|
||||
@XmlElement(name = "AppId")
|
||||
private String appId;
|
||||
/**
|
||||
* 时间戳
|
||||
*/
|
||||
@XmlElement(name = "TimeStamp")
|
||||
private String timeStamp;
|
||||
/**
|
||||
* 随机字符串
|
||||
*/
|
||||
@XmlElement(name = "NonceStr")
|
||||
private String nonceStr;
|
||||
/**
|
||||
* 签名结果
|
||||
*/
|
||||
@XmlElement(name = "AppSignature")
|
||||
private String paySign;
|
||||
/**
|
||||
* 签名方式
|
||||
*/
|
||||
@XmlElement(name = "SignMethod")
|
||||
private String signType;
|
||||
|
||||
public String getAppId() {
|
||||
return appId;
|
||||
}
|
||||
|
||||
public void setAppId(String appId) {
|
||||
this.appId = appId;
|
||||
}
|
||||
|
||||
public String getTimeStamp() {
|
||||
return timeStamp;
|
||||
}
|
||||
|
||||
public void setTimeStamp(String timeStamp) {
|
||||
this.timeStamp = timeStamp;
|
||||
}
|
||||
|
||||
public String getNonceStr() {
|
||||
return nonceStr;
|
||||
}
|
||||
|
||||
public void setNonceStr(String nonceStr) {
|
||||
this.nonceStr = nonceStr;
|
||||
}
|
||||
|
||||
public String getPaySign() {
|
||||
return paySign;
|
||||
}
|
||||
|
||||
public void setPaySign(String paySign) {
|
||||
this.paySign = paySign;
|
||||
}
|
||||
|
||||
public String getSignType() {
|
||||
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();
|
||||
} else {
|
||||
this.signType = null;
|
||||
}
|
||||
}
|
||||
|
||||
public PayBaseInfo() {
|
||||
}
|
||||
|
||||
public PayBaseInfo(String appId, String timestamp, String noncestr) {
|
||||
this.appId = appId;
|
||||
this.timeStamp = timestamp;
|
||||
this.nonceStr = noncestr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "appId=" + appId + ", timeStamp=" + timeStamp + ", nonceStr="
|
||||
+ nonceStr + ", paySign=" + paySign + ", signType=" + signType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
package com.foxinmy.weixin4j.payment;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.util.DateUtil;
|
||||
|
||||
/**
|
||||
* 订单信息
|
||||
*
|
||||
* @className PayPackage
|
||||
* @author jy
|
||||
* @date 2014年12月18日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class PayPackage implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 3450161267802545790L;
|
||||
|
||||
/**
|
||||
* 商品描述 必须
|
||||
*/
|
||||
private String body;
|
||||
/**
|
||||
* 商品详情 非必须
|
||||
*/
|
||||
private String detail;
|
||||
/**
|
||||
* 附加数据,原样返回 非必须
|
||||
*/
|
||||
private String attach;
|
||||
/**
|
||||
* 商户系统内部的订单号 ,32 个字符内 、可包含字母 ,确保 在商户系统唯一 必须
|
||||
*/
|
||||
@XmlElement(name = "out_trade_no")
|
||||
@JSONField(name = "out_trade_no")
|
||||
private String outTradeNo;
|
||||
/**
|
||||
* 订单总金额,单位为分,不能带小数点 必须
|
||||
*/
|
||||
@XmlElement(name = "total_fee")
|
||||
@JSONField(name = "total_fee")
|
||||
private String totalFee;
|
||||
/**
|
||||
* 订单生成的机器 IP 必须
|
||||
*/
|
||||
@XmlElement(name = "spbill_create_ip")
|
||||
@JSONField(name = "spbill_create_ip")
|
||||
private String spbillCreateIp;
|
||||
/**
|
||||
* 订单生成时间,格式为 yyyyMMddHHmmss,如 2009 年 12月25日9点10分10秒表示为 20091225091010。时区 为
|
||||
* GMT+8 beijing。该时间取 自商户服务器 非必须
|
||||
*/
|
||||
@XmlElement(name = "time_start")
|
||||
@JSONField(name = "time_start")
|
||||
private String timeStart;
|
||||
/**
|
||||
* 订单失效时间,格为 yyyyMMddHHmmss,如 2009 年 12月27日9点10分10秒表示为 20091227091010。时区 为
|
||||
* GMT+8 beijing。该时间取 自商户服务商品标记 非必须
|
||||
*/
|
||||
@XmlElement(name = "time_expire")
|
||||
@JSONField(name = "time_expire")
|
||||
private String timeExpire;
|
||||
/**
|
||||
* 商品标记,该字段不能随便填,不使用请填空 非必须
|
||||
*/
|
||||
@XmlElement(name = "goods_tag")
|
||||
@JSONField(name = "goods_tag")
|
||||
private String goodsTag;
|
||||
/**
|
||||
* 通知地址接收微信支付成功通知 必须
|
||||
*/
|
||||
@XmlElement(name = "notify_url")
|
||||
@JSONField(name = "notify_url")
|
||||
private String notifyUrl;
|
||||
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public void setBody(String body) {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public String getDetail() {
|
||||
return detail;
|
||||
}
|
||||
|
||||
public void setDetail(String detail) {
|
||||
this.detail = detail;
|
||||
}
|
||||
|
||||
public String getAttach() {
|
||||
return attach;
|
||||
}
|
||||
|
||||
public void setAttach(String attach) {
|
||||
this.attach = attach;
|
||||
}
|
||||
|
||||
public String getOutTradeNo() {
|
||||
return outTradeNo;
|
||||
}
|
||||
|
||||
public void setOutTradeNo(String outTradeNo) {
|
||||
this.outTradeNo = outTradeNo;
|
||||
}
|
||||
|
||||
public String getTotalFee() {
|
||||
return totalFee;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">单位为元,自动格式化为分</font>
|
||||
*
|
||||
* @param totalFee
|
||||
* 订单总额 单位为元
|
||||
*/
|
||||
public void setTotalFee(double totalFee) {
|
||||
this.totalFee = DateUtil.formaFee2Fen(totalFee);
|
||||
}
|
||||
|
||||
public String getSpbillCreateIp() {
|
||||
return spbillCreateIp;
|
||||
}
|
||||
|
||||
public void setSpbillCreateIp(String spbillCreateIp) {
|
||||
this.spbillCreateIp = spbillCreateIp;
|
||||
}
|
||||
|
||||
public String getTimeStart() {
|
||||
return timeStart;
|
||||
}
|
||||
|
||||
public void setTimeStart(String timeStart) {
|
||||
this.timeStart = timeStart;
|
||||
}
|
||||
|
||||
public void setTimeExpire(String timeExpire) {
|
||||
this.timeExpire = timeExpire;
|
||||
}
|
||||
|
||||
public void setTimeStart(Date timeStart) {
|
||||
this.timeStart = timeStart != null ? DateUtil
|
||||
.fortmat2yyyyMMddHHmmss(timeStart) : null;
|
||||
}
|
||||
|
||||
public String getTimeExpire() {
|
||||
return timeExpire;
|
||||
}
|
||||
|
||||
public void setTimeExpire(Date timeExpire) {
|
||||
this.timeExpire = timeExpire != null ? DateUtil
|
||||
.fortmat2yyyyMMddHHmmss(timeExpire) : null;
|
||||
}
|
||||
|
||||
public String getGoodsTag() {
|
||||
return goodsTag;
|
||||
}
|
||||
|
||||
public void setGoodsTag(String goodsTag) {
|
||||
this.goodsTag = goodsTag;
|
||||
}
|
||||
|
||||
public String getNotifyUrl() {
|
||||
return notifyUrl;
|
||||
}
|
||||
|
||||
public void setNotifyUrl(String notifyUrl) {
|
||||
this.notifyUrl = notifyUrl;
|
||||
}
|
||||
|
||||
protected PayPackage(){
|
||||
// jaxb required
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单对象
|
||||
*
|
||||
* @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) {
|
||||
this.body = body;
|
||||
this.attach = attach;
|
||||
this.outTradeNo = outTradeNo;
|
||||
this.totalFee = DateUtil.formaFee2Fen(totalFee);
|
||||
this.spbillCreateIp = spbillCreateIp;
|
||||
this.timeStart = timeStart != null ? DateUtil
|
||||
.fortmat2yyyyMMddHHmmss(timeStart) : null;
|
||||
this.timeExpire = timeExpire != null ? DateUtil
|
||||
.fortmat2yyyyMMddHHmmss(timeExpire) : null;
|
||||
this.goodsTag = goodsTag;
|
||||
this.notifyUrl = notifyUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PayPackage [body=" + body + ", detail=" + detail + ", attach="
|
||||
+ attach + ", outTradeNo=" + outTradeNo + ", totalFee="
|
||||
+ totalFee + ", spbillCreateIp=" + spbillCreateIp
|
||||
+ ", timeStart=" + timeStart + ", timeExpire=" + timeExpire
|
||||
+ ", goodsTag=" + goodsTag + ", notifyUrl=" + notifyUrl + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.foxinmy.weixin4j.payment;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.util.DateUtil;
|
||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class PayRequest extends PayBaseInfo {
|
||||
|
||||
private static final long serialVersionUID = -453746488398523883L;
|
||||
|
||||
/**
|
||||
* 订单详情扩展 订单信息组成该字符串
|
||||
*/
|
||||
@XmlElement(name = "Package")
|
||||
@JSONField(name = "package")
|
||||
private String packageInfo;
|
||||
|
||||
public PayRequest() {
|
||||
super(null, DateUtil.timestamp2string(), RandomUtil.generateString(16));
|
||||
}
|
||||
|
||||
public PayRequest(String appId, String packageInfo) {
|
||||
super(appId, DateUtil.timestamp2string(), RandomUtil.generateString(16));
|
||||
this.packageInfo = packageInfo;
|
||||
}
|
||||
|
||||
public String getPackageInfo() {
|
||||
return packageInfo;
|
||||
}
|
||||
|
||||
public void setPackageInfo(String packageInfo) {
|
||||
this.packageInfo = packageInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "package" + packageInfo + ", " + super.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.foxinmy.weixin4j.payment;
|
||||
|
||||
/**
|
||||
* 支付URL常量类
|
||||
*
|
||||
* @className PayURLConsts
|
||||
* @author jy
|
||||
* @date 2014年12月3日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public final class PayURLConsts {
|
||||
|
||||
private static final String MCH_BASE_URL = "https://api.mch.weixin.qq.com";
|
||||
|
||||
/**
|
||||
* 商户平台下统一订单生成的url
|
||||
*/
|
||||
public static final String MCH_UNIFIEDORDER_URL = MCH_BASE_URL
|
||||
+ "/pay/unifiedorder";
|
||||
/**
|
||||
* 订单查询(商户平台)
|
||||
*/
|
||||
public static final String MCH_ORDERQUERY_URL = MCH_BASE_URL
|
||||
+ "/pay/orderquery";
|
||||
/**
|
||||
* 关闭订单(商户平台)
|
||||
*/
|
||||
public static final String MCH_CLOSEORDER_URL = MCH_BASE_URL
|
||||
+ "/pay/closeorder";
|
||||
/**
|
||||
* 对账单下载(商户平台)
|
||||
*/
|
||||
public static final String MCH_DOWNLOADBILL_URL = MCH_BASE_URL
|
||||
+ "/pay/downloadbill";
|
||||
/**
|
||||
* 退款查询(商户平台)
|
||||
*/
|
||||
public static final String MCH_REFUNDQUERY_URL = MCH_BASE_URL
|
||||
+ "/pay/refundquery";
|
||||
/**
|
||||
* 退款申请(商户平台)
|
||||
*/
|
||||
public static final String MCH_REFUNDAPPLY_URL = MCH_BASE_URL
|
||||
+ "/secapi/pay/refund";
|
||||
/**
|
||||
* 冲正撤销(商户平台)
|
||||
*/
|
||||
public static final String MCH_ORDERREVERSE_URL = MCH_BASE_URL
|
||||
+ "/secapi/pay/reverse";
|
||||
/**
|
||||
* 被扫支付&刷卡支付(商户平台)
|
||||
*/
|
||||
public static final String MCH_MICROPAY_URL = MCH_BASE_URL
|
||||
+ "/pay/micropay";
|
||||
/**
|
||||
* 接口上报(商户平台)
|
||||
*/
|
||||
public static final String MCH_PAYREPORT_URL = MCH_BASE_URL
|
||||
+ "/payitil/report";
|
||||
/**
|
||||
* 发送现金红包(商户平台)
|
||||
*/
|
||||
public static final String MCH_REDPACKSEND_URL = MCH_BASE_URL
|
||||
+ "/mmpaymkttransfers/sendredpack";
|
||||
/**
|
||||
* 查询现金红包(商户平台)
|
||||
*/
|
||||
public static final String MCH_REDPACKQUERY_URL = MCH_BASE_URL
|
||||
+ "/mmpaymkttransfers/gethbinfo";
|
||||
/**
|
||||
* 企业向个人付款(商户平台)
|
||||
*/
|
||||
public static final String MCH_ENPAYMENT_URL = MCH_BASE_URL
|
||||
+ "/mmpaymkttransfers/promotion/transfers";
|
||||
/**
|
||||
* 企业付款查询(商户平台)
|
||||
*/
|
||||
public static final String MCH_ENPAYQUERY_URL = MCH_BASE_URL
|
||||
+ "/mmpaymkttransfers/gettransferinfo";
|
||||
/**
|
||||
* 发放代金券(商户平台)
|
||||
*/
|
||||
public static final String MCH_COUPONSEND_URL = MCH_BASE_URL
|
||||
+ "/mmpaymkttransfers/send_coupon";
|
||||
/**
|
||||
* 查询代金券批次信息(商户平台)
|
||||
*/
|
||||
public static final String MCH_COUPONSTOCKQUERY_URL = MCH_BASE_URL
|
||||
+ "/mmpaymkttransfers/query_coupon_stock";
|
||||
/**
|
||||
* 查询代金券详细信息(商户平台)
|
||||
*/
|
||||
public static final String MCH_COUPONDETAILQUERY_URL = MCH_BASE_URL
|
||||
+ "/promotion/query_coupon";
|
||||
/**
|
||||
* 长链接转换(商户平台)
|
||||
*/
|
||||
public static final String MCH_SHORTURL_URL = MCH_BASE_URL
|
||||
+ "/tools/shorturl";
|
||||
/**
|
||||
* 商户平台下native支付的url
|
||||
*/
|
||||
public static final String MCH_NATIVE_URL = "weixin://wxpay/bizpayurl?sign=%s&appid=%s&mch_id=%s&product_id=%s&time_stamp=%s&nonce_str=%s";
|
||||
}
|
||||
@@ -0,0 +1,290 @@
|
||||
package com.foxinmy.weixin4j.payment;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.PayException;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinHttpClient;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
import com.foxinmy.weixin4j.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.payment.mch.MchPayPackage;
|
||||
import com.foxinmy.weixin4j.payment.mch.MchPayRequest;
|
||||
import com.foxinmy.weixin4j.payment.mch.Order;
|
||||
import com.foxinmy.weixin4j.payment.mch.PrePay;
|
||||
import com.foxinmy.weixin4j.type.SignType;
|
||||
import com.foxinmy.weixin4j.type.TradeType;
|
||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
import com.foxinmy.weixin4j.util.DateUtil;
|
||||
import com.foxinmy.weixin4j.util.DigestUtil;
|
||||
import com.foxinmy.weixin4j.util.MapUtil;
|
||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
|
||||
/**
|
||||
* 支付工具类(JSAPI,NATIVE,MicroPay)
|
||||
*
|
||||
* @className PayUtil
|
||||
* @author jy
|
||||
* @date 2014年10月28日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class PayUtil {
|
||||
|
||||
/**
|
||||
* md5签名(一般用于V3.x支付接口)
|
||||
*
|
||||
* @param obj
|
||||
* 签名对象
|
||||
* @param paySignKey
|
||||
* 支付API的密钥
|
||||
* @return
|
||||
*/
|
||||
public static String paysignMd5(Object obj, String paySignKey) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
// a--->string1
|
||||
sb.append(MapUtil.toJoinString(obj, false, false, null));
|
||||
// b--->
|
||||
// 在 string1 最后拼接上 key=paternerKey 得到 stringSignTemp 字符串,并 对
|
||||
// stringSignTemp 进行 md5 运算
|
||||
// 再将得到的 字符串所有字符转换为大写 ,得到 sign 值 signValue。
|
||||
sb.append("&key=").append(paySignKey);
|
||||
return DigestUtil.MD5(sb.toString()).toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成V3.x版本JSAPI支付字符串
|
||||
*
|
||||
* @param openId
|
||||
* 用户ID
|
||||
* @param body
|
||||
* 订单描述
|
||||
* @param orderNo
|
||||
* 订单号
|
||||
* @param orderFee
|
||||
* 订单总额 按实际金额传入即可(元) 构造函数会转换为分
|
||||
* @param notifyUrl
|
||||
* 支付通知地址
|
||||
* @param ip
|
||||
* ip地址
|
||||
* @param weixinAccount
|
||||
* 商户信息
|
||||
* @return 支付json串
|
||||
* @throws PayException
|
||||
*/
|
||||
public static String createPayJsRequestJson(String openId, String body,
|
||||
String orderNo, double orderFee, String notifyUrl, String ip,
|
||||
WeixinPayAccount weixinAccount) throws PayException {
|
||||
MchPayPackage payPackage = new MchPayPackage(weixinAccount, openId,
|
||||
body, orderNo, orderFee, ip, TradeType.JSAPI);
|
||||
payPackage.setNotifyUrl(notifyUrl);
|
||||
return createPayJsRequestJson(payPackage, weixinAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成V3.x版本JSAPI支付字符串
|
||||
*
|
||||
* @param payPackage
|
||||
* 订单信息
|
||||
* @param weixinAccount
|
||||
* 商户信息
|
||||
* @return 支付json串
|
||||
* @throws PayException
|
||||
*/
|
||||
public static String createPayJsRequestJson(MchPayPackage payPackage,
|
||||
WeixinPayAccount weixinAccount) throws PayException {
|
||||
String paySignKey = weixinAccount.getPaySignKey();
|
||||
payPackage.setSign(paysignMd5(payPackage, paySignKey));
|
||||
PrePay prePay = createPrePay(payPackage, paySignKey);
|
||||
MchPayRequest jsPayRequest = new MchPayRequest(prePay);
|
||||
jsPayRequest.setSignType(SignType.MD5);
|
||||
jsPayRequest.setPaySign(paysignMd5(jsPayRequest, paySignKey));
|
||||
return JSON.toJSONString(jsPayRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一下单接口</br>
|
||||
* 除被扫支付场景以外,商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易回话标识后再按扫码、JSAPI
|
||||
* 、APP等不同场景生成交易串调起支付。
|
||||
*
|
||||
* @param payPackage
|
||||
* 包含订单信息的对象
|
||||
* @param paySignKey
|
||||
* <font color="red">如果sign为空 则拿paysignkey进行签名</font>
|
||||
* @see com.foxinmy.weixin4j.payment.mch.MchPayPackage
|
||||
* @see com.foxinmy.weixin4j.payment.mch.PrePay
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1">统一下单接口</a>
|
||||
* @return 预支付对象
|
||||
*/
|
||||
private final static WeixinHttpClient httpClient = new WeixinHttpClient();
|
||||
|
||||
public static PrePay createPrePay(MchPayPackage payPackage,
|
||||
String paySignKey) throws PayException {
|
||||
if (StringUtil.isBlank(payPackage.getSign())) {
|
||||
payPackage.setSign(paysignMd5(payPackage, paySignKey));
|
||||
}
|
||||
String payJsRequestXml = XmlStream.toXML(payPackage);
|
||||
try {
|
||||
WeixinResponse response = httpClient.post(
|
||||
PayURLConsts.MCH_UNIFIEDORDER_URL, payJsRequestXml);
|
||||
PrePay prePay = response.getAsObject(new TypeReference<PrePay>() {
|
||||
});
|
||||
if (!prePay.getReturnCode().equalsIgnoreCase(Consts.SUCCESS)) {
|
||||
throw new PayException(prePay.getReturnMsg(),
|
||||
prePay.getReturnCode());
|
||||
}
|
||||
if (!prePay.getResultCode().equalsIgnoreCase(Consts.SUCCESS)) {
|
||||
throw new PayException(prePay.getResultCode(),
|
||||
prePay.getErrCodeDes());
|
||||
}
|
||||
return prePay;
|
||||
} catch (WeixinException e) {
|
||||
throw new PayException(e.getErrorCode(), e.getErrorMsg());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 生成编辑地址请求
|
||||
* </p>
|
||||
*
|
||||
* err_msg edit_address:ok获取编辑收货地址成功</br> edit_address:fail获取编辑收货地址失败</br>
|
||||
* userName 收货人姓名</br> telNumber 收货人电话</br> addressPostalCode 邮编</br>
|
||||
* proviceFirstStageName 国标收货地址第一级地址</br> addressCitySecondStageName
|
||||
* 国标收货地址第二级地址</br> addressCountiesThirdStageName 国标收货地址第三级地址</br>
|
||||
* addressDetailInfo 详细收货地址信息</br> nationalCode 收货地址国家码</br>
|
||||
*
|
||||
* @param appId
|
||||
* 公众号的ID
|
||||
* @param url
|
||||
* 当前访问页的URL
|
||||
* @param accessToken
|
||||
* snsapi_base授权时产生的token
|
||||
* @return
|
||||
*/
|
||||
public static String createAddressRequestJson(String appId, String url,
|
||||
String accessToken) {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put("appId", appId);
|
||||
map.put("timeStamp", DateUtil.timestamp2string());
|
||||
map.put("nonceStr", RandomUtil.generateString(16));
|
||||
map.put("url", url);
|
||||
map.put("accessToken", accessToken);
|
||||
String sign = DigestUtil.SHA1(MapUtil.toJoinString(map, false, true,
|
||||
null));
|
||||
map.remove("url");
|
||||
map.remove("accessToken");
|
||||
map.put("scope", "jsapi_address");
|
||||
map.put("signType", SignType.SHA1.name().toLowerCase());
|
||||
map.put("addrSign", sign);
|
||||
|
||||
return JSON.toJSONString(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建V3.x NativePay支付(扫码支付)链接
|
||||
*
|
||||
* @param weixinAccount
|
||||
* 支付配置信息
|
||||
* @param productId
|
||||
* 与订单ID等价
|
||||
* @return 支付链接
|
||||
* @see <a href="http://pay.weixin.qq.com/wiki/doc/api/native.php">扫码支付</a>
|
||||
*/
|
||||
public static String createNativePayRequestURL(
|
||||
WeixinPayAccount weixinAccount, String productId) {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
String timestamp = DateUtil.timestamp2string();
|
||||
String noncestr = RandomUtil.generateString(16);
|
||||
map.put("appid", weixinAccount.getId());
|
||||
map.put("mch_id", weixinAccount.getMchId());
|
||||
map.put("time_stamp", timestamp);
|
||||
map.put("nonce_str", noncestr);
|
||||
map.put("product_id", productId);
|
||||
String sign = paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
return String.format(PayURLConsts.MCH_NATIVE_URL, sign,
|
||||
weixinAccount.getId(), weixinAccount.getMchId(), productId,
|
||||
timestamp, noncestr);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交被扫支付
|
||||
*
|
||||
* @param authCode
|
||||
* 扫码支付授权码 ,设备读取用户微信中的条码或者二维码信息
|
||||
* @param body
|
||||
* 商品描述
|
||||
* @param attach
|
||||
* 附加数据
|
||||
* @param orderNo
|
||||
* 商户内部唯一订单号
|
||||
* @param orderFee
|
||||
* 商品总额 单位元
|
||||
* @param ip
|
||||
* 订单生成的机器 IP
|
||||
* @param weixinAccount
|
||||
* 商户信息
|
||||
* @return 支付的订单信息
|
||||
* @see {@link com.foxinmy.weixin4j.payment.PayUtil#createMicroPay(MicroPayPackage, WeixinPayAccount)}
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public static Order createMicroPay(String authCode, String body,
|
||||
String attach, String orderNo, double orderFee, String ip,
|
||||
WeixinPayAccount weixinAccount) throws WeixinException {
|
||||
MicroPayPackage payPackage = new MicroPayPackage(weixinAccount, body,
|
||||
attach, orderNo, orderFee, ip, authCode);
|
||||
return createMicroPay(payPackage, weixinAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交被扫支付:收银员使用扫码设备读取微信用户刷卡授权码以后,二维码或条码信息传送至商户收银台,由商户收银台或者商户后台调用该接口发起支付.
|
||||
*
|
||||
* @param payPackage
|
||||
* 订单信息
|
||||
* @param weixinAccount
|
||||
* 商户信息
|
||||
* @return 支付的订单信息
|
||||
* @throws WeixinException
|
||||
* @see com.foxinmy.weixin4j.payment.mch.Order
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_10">提交被扫支付API</a>
|
||||
*/
|
||||
public static Order createMicroPay(MicroPayPackage payPackage,
|
||||
WeixinPayAccount weixinAccount) throws WeixinException {
|
||||
String sign = paysignMd5(payPackage, weixinAccount.getPaySignKey());
|
||||
payPackage.setSign(sign);
|
||||
String para = XmlStream.toXML(payPackage);
|
||||
WeixinResponse response = httpClient.post(
|
||||
PayURLConsts.MCH_MICROPAY_URL, para);
|
||||
return response
|
||||
.getAsObject(new TypeReference<com.foxinmy.weixin4j.payment.mch.Order>() {
|
||||
});
|
||||
}
|
||||
|
||||
private static String JSAPI() throws PayException {
|
||||
WeixinPayAccount weixinAccount = JSON.parseObject(
|
||||
ConfigUtil.getValue("account"), WeixinPayAccount.class);
|
||||
return createPayJsRequestJson("oyFLst1bqtuTcxK-ojF8hOGtLQao", "支付测试",
|
||||
"JSAPI01", 0.01d, "http://127.0.0.1/jsapi/notify", "127.0.0.0",
|
||||
weixinAccount);
|
||||
}
|
||||
|
||||
private static String NATIVE() {
|
||||
WeixinPayAccount weixinAccount = JSON.parseObject(
|
||||
ConfigUtil.getValue("account"), WeixinPayAccount.class);
|
||||
return createNativePayRequestURL(weixinAccount, "P1");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws PayException {
|
||||
// V3版本下的JS支付
|
||||
System.out.println(JSAPI());
|
||||
// V3版本下的原生支付
|
||||
System.out.println(NATIVE());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
支付模块【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版本(商户平台)`支付**
|
||||
|
||||
[PayUtil](./PayUtil.java)
|
||||
-------------------------
|
||||
|
||||
* createPayJsRequestJson: 创建V3版本(商户平台)的JSAPI支付串
|
||||
|
||||
* createNativePayRequestURL: 创建V3版本(商户平台)的扫码支付链接
|
||||
|
||||
* createPrePay: 调用V3版本(商户平台)的统一订单接口生成预订单数据
|
||||
|
||||
* createMicroPay: 创建刷卡支付(商户平台)请求
|
||||
|
||||
* createAddressRequestJson: 生成编辑收货地址请求串
|
||||
|
||||
|
||||
[Pay3Api](../api/Pay3Api.java)
|
||||
-------------------------
|
||||
|
||||
* orderQuery: 订单查询接口
|
||||
|
||||
* refundOrder: 退款申请接口
|
||||
|
||||
* reverseOrder: 冲正订单接口
|
||||
|
||||
* closeOrder: 关闭订单接口
|
||||
|
||||
* downloadbill: 下载对账单接口
|
||||
|
||||
* refundQuery: 退款查询接口
|
||||
|
||||
|
||||
[Pay2Api](../api/Pay2Api.java)
|
||||
-------------------------
|
||||
|
||||
* orderQuery: 订单查询接口
|
||||
|
||||
* refundOrder: 退款申请接口
|
||||
|
||||
* downloadbill: 下载对账单接口
|
||||
|
||||
* refundQuery: 退款查询接口
|
||||
@@ -0,0 +1,492 @@
|
||||
package com.foxinmy.weixin4j.payment;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Date;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.foxinmy.weixin4j.api.CashApi;
|
||||
import com.foxinmy.weixin4j.api.CouponApi;
|
||||
import com.foxinmy.weixin4j.api.Pay3Api;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.weixin.XmlResult;
|
||||
import com.foxinmy.weixin4j.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.payment.coupon.CouponDetail;
|
||||
import com.foxinmy.weixin4j.payment.coupon.CouponResult;
|
||||
import com.foxinmy.weixin4j.payment.coupon.CouponStock;
|
||||
import com.foxinmy.weixin4j.payment.mch.ApiResult;
|
||||
import com.foxinmy.weixin4j.payment.mch.MPPayment;
|
||||
import com.foxinmy.weixin4j.payment.mch.MPPaymentRecord;
|
||||
import com.foxinmy.weixin4j.payment.mch.MPPaymentResult;
|
||||
import com.foxinmy.weixin4j.payment.mch.Order;
|
||||
import com.foxinmy.weixin4j.payment.mch.Redpacket;
|
||||
import com.foxinmy.weixin4j.payment.mch.RedpacketRecord;
|
||||
import com.foxinmy.weixin4j.payment.mch.RedpacketSendResult;
|
||||
import com.foxinmy.weixin4j.payment.mch.RefundRecord;
|
||||
import com.foxinmy.weixin4j.type.BillType;
|
||||
import com.foxinmy.weixin4j.type.CurrencyType;
|
||||
import com.foxinmy.weixin4j.type.IdQuery;
|
||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
|
||||
/**
|
||||
* 微信支付接口实现
|
||||
*
|
||||
* @className WeixinPayProxy
|
||||
* @author jy
|
||||
* @date 2015年1月3日
|
||||
* @since JDK 1.7
|
||||
* @see com.foxinmy.weixin4j.api.Pay2Api
|
||||
* @see com.foxinmy.weixin4j.api.Pay3Api
|
||||
* @see <a href="http://pay.weixin.qq.com/wiki/doc/api/index.html">商户平台支付API</a>
|
||||
*/
|
||||
public class WeixinPayProxy {
|
||||
|
||||
private final Pay3Api pay3Api;
|
||||
private final CouponApi couponApi;
|
||||
private final CashApi cashApi;
|
||||
|
||||
private final File DEFAULT_CA_FILE;
|
||||
|
||||
/**
|
||||
* 使用weixin4j.properties配置的账号信息
|
||||
*/
|
||||
public WeixinPayProxy() {
|
||||
this(JSON.parseObject(ConfigUtil.getValue("account"),
|
||||
WeixinPayAccount.class));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param weixinAccount
|
||||
* 支付相关的公众号账号信息
|
||||
*
|
||||
*/
|
||||
public WeixinPayProxy(WeixinPayAccount weixinAccount) {
|
||||
this.pay3Api = new Pay3Api(weixinAccount);
|
||||
this.couponApi = new CouponApi(weixinAccount);
|
||||
this.cashApi = new CashApi(weixinAccount);
|
||||
this.DEFAULT_CA_FILE = new File(ConfigUtil.getClassPathValue("ca_file"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单查询
|
||||
* <p>
|
||||
* 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;</br> 调用支付接口后,返回系统错误或未知交易状态情况;</br>
|
||||
* 调用被扫支付API,返回USERPAYING的状态;</br> 调用关单或撤销接口API之前,需确认支付状态;
|
||||
* </P>
|
||||
*
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id、out_trade_no 二 选一,如果同时存在优先级:
|
||||
* transaction_id> out_trade_no
|
||||
* @since V3
|
||||
* @see com.foxinmy.weixin4j.payment.mch.Order
|
||||
* @see com.foxinmy.weixin4j.api.PayApi
|
||||
* @see com.foxinmy.weixin4j.api.Pay3Api
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2">订单查询API</a>
|
||||
* @return 订单详情
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public Order orderQuery(IdQuery idQuery) throws WeixinException {
|
||||
return pay3Api.orderQuery(idQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请退款(请求需要双向证书)</br>
|
||||
* <p>
|
||||
* 当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付款退还给买家,微信支付将在收到退款请求并且验证成功之后,
|
||||
* 按照退款规则将支付款按原路退到买家帐号上。
|
||||
* </p>
|
||||
* <p style="color:red">
|
||||
* 1.交易时间超过半年的订单无法提交退款;
|
||||
* 2.微信支付退款支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。一笔退款失败后重新提交
|
||||
* ,要采用原来的退款单号。总退款金额不能超过用户实际支付金额。
|
||||
* </p>
|
||||
*
|
||||
* @param caFile
|
||||
* 证书文件(后缀为*.p12)
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
|
||||
* transaction_id> out_trade_no
|
||||
* @param outRefundNo
|
||||
* 商户系统内部的退款单号,商 户系统内部唯一,同一退款单号多次请求只退一笔
|
||||
* @param totalFee
|
||||
* 订单总金额,单位为元
|
||||
* @param refundFee
|
||||
* 退款总金额,单位为元,可以做部分退款
|
||||
* @param refundFeeType
|
||||
* 货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY
|
||||
* @param opUserId
|
||||
* 操作员帐号, 默认为商户号
|
||||
*
|
||||
* @return 退款申请结果
|
||||
* @see com.foxinmy.weixin4j.payment.mch.RefundResult
|
||||
* @see com.foxinmy.weixin4j.api.PayApi
|
||||
* @see com.foxinmy.weixin4j.api.Pay3Api
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4">申请退款API</a>
|
||||
* @since V3
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public com.foxinmy.weixin4j.payment.mch.RefundResult refundApply(
|
||||
File caFile, IdQuery idQuery, String outRefundNo, double totalFee,
|
||||
double refundFee, CurrencyType refundFeeType, String opUserId)
|
||||
throws WeixinException {
|
||||
return pay3Api.refundApply(caFile, idQuery, outRefundNo, totalFee,
|
||||
refundFee, refundFeeType, opUserId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款申请采用properties中配置的ca文件
|
||||
*
|
||||
* @see {@link com.foxinmy.weixin4j.payment.WeixinPayProxy#refundV3(File, IdQuery, String, double, double,CurrencyType, String)}
|
||||
*/
|
||||
public com.foxinmy.weixin4j.payment.mch.RefundResult refundApply(
|
||||
IdQuery idQuery, String outRefundNo, double totalFee,
|
||||
double refundFee, String opUserId) throws WeixinException {
|
||||
return pay3Api.refundApply(DEFAULT_CA_FILE, idQuery, outRefundNo,
|
||||
totalFee, refundFee, CurrencyType.CNY, opUserId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款查询
|
||||
* <p>
|
||||
* 提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,用零钱支付的退款20分钟内到账,银行卡支付的退款3个工作日后重新查询退款状态。
|
||||
* </p>
|
||||
*
|
||||
* @param idQuery
|
||||
* 单号 refund_id、out_refund_no、 out_trade_no 、 transaction_id
|
||||
* 四个参数必填一个,优先级为:
|
||||
* refund_id>out_refund_no>transaction_id>out_trade_no
|
||||
* @return 退款记录
|
||||
* @see com.foxinmy.weixin4j.api.PayApi
|
||||
* @see com.foxinmy.weixin4j.api.Pay3Api
|
||||
* @see com.foxinmy.weixin4j.payment.mch.RefundRecord
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_5">退款查询API</a>
|
||||
* @since V3
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public RefundRecord refundQueryV3(IdQuery idQuery) throws WeixinException {
|
||||
return pay3Api.refundQuery(idQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载对账单<br>
|
||||
* 1.微信侧未成功下单的交易不会出现在对账单中。支付成功后撤销的交易会出现在对账 单中,跟原支付单订单号一致,bill_type 为
|
||||
* REVOKED;<br>
|
||||
* 2.微信在次日 9 点启动生成前一天的对账单,建议商户 9 点半后再获取;<br>
|
||||
* 3.对账单中涉及金额的字段单位为“元”。<br>
|
||||
*
|
||||
* @param billDate
|
||||
* 下载对账单的日期
|
||||
* @param billType
|
||||
* 下载对账单的类型 ALL,返回当日所有订单信息, 默认值 SUCCESS,返回当日成功支付的订单
|
||||
* REFUND,返回当日退款订单
|
||||
* @return excel表格
|
||||
* @since V2 & V3
|
||||
* @see com.foxinmy.weixin4j.api.PayApi
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_6">下载对账单API</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public File downloadbill(Date billDate, BillType billType)
|
||||
throws WeixinException {
|
||||
return pay3Api.downloadbill(billDate, billType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 冲正订单(需要证书)</br> 当支付返回失败,或收银系统超时需要取消交易,可以调用该接口</br> 接口逻辑:支
|
||||
* 付失败的关单,支付成功的撤销支付</br> <font color="red">7天以内的单可撤销,其他正常支付的单
|
||||
* 如需实现相同功能请调用退款接口</font></br> <font
|
||||
* color="red">调用扣款接口后请勿立即调用撤销,需要等待5秒以上。先调用查单接口,如果没有确切的返回,再调用撤销</font></br>
|
||||
*
|
||||
* @param ca
|
||||
* 证书文件(V2版本后缀为*.pfx,V3版本后缀为*.p12)
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
|
||||
* transaction_id> out_trade_no
|
||||
* @return 撤销结果
|
||||
* @see com.foxinmy.weixin4j.api.PayApi
|
||||
* @see com.foxinmy.weixin4j.api.Pay2Api
|
||||
* @see com.foxinmy.weixin4j.api.Pay3Api
|
||||
* @since V3
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public ApiResult reverseOrder(File caFile, IdQuery idQuery)
|
||||
throws WeixinException {
|
||||
return pay3Api.reverseOrder(caFile, idQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 冲正撤销:默认采用properties中配置的ca文件
|
||||
*
|
||||
* @param idQuery
|
||||
* transaction_id、out_trade_no 二选一
|
||||
* @return 撤销结果
|
||||
* @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#reverse(File, IdQuery)}
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public ApiResult reverseOrder(IdQuery idQuery) throws WeixinException {
|
||||
return pay3Api.reverseOrder(DEFAULT_CA_FILE, idQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭订单
|
||||
* <p>
|
||||
* 商户订单支付失败需要生成新单号重新发起支付,要对原订单号调用关单,避免重复支付;系统下单后,用户支付超时,系统退出不再受理,避免用户继续
|
||||
* ,请调用关单接口,如果关单失败,返回已完 成支付请按正常支付处理。如果出现银行掉单,调用关单成功后,微信后台会主动发起退款。
|
||||
* </p>
|
||||
*
|
||||
* @param outTradeNo
|
||||
* 商户系统内部的订单号
|
||||
* @return 执行结果
|
||||
* @see com.foxinmy.weixin4j.api.PayApi
|
||||
* @see com.foxinmy.weixin4j.api.Pay3Api
|
||||
* @since V3
|
||||
* @throws WeixinException
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_3">关闭订单API</a>
|
||||
*/
|
||||
public ApiResult closeOrder(String outTradeNo) throws WeixinException {
|
||||
return pay3Api.closeOrder(outTradeNo);
|
||||
}
|
||||
|
||||
/**
|
||||
* native支付URL转短链接:用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX),减小二维码数据量
|
||||
* ,提升扫描速度和精确度。
|
||||
*
|
||||
* @param url
|
||||
* 具有native标识的支付URL
|
||||
* @return 转换后的短链接
|
||||
* @see com.foxinmy.weixin4j.api.PayApi
|
||||
* @see com.foxinmy.weixin4j.api.Pay2Api
|
||||
* @see com.foxinmy.weixin4j.api.Pay3Api
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_9">转换短链接API</a>
|
||||
* @since V3
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public String getPayShorturl(String url) throws WeixinException {
|
||||
return pay3Api.getShorturl(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口上报
|
||||
*
|
||||
* @param interfaceUrl
|
||||
* 上报对应的接口的完整 URL, 类似: https://api.mch.weixin.q
|
||||
* q.com/pay/unifiedorder
|
||||
* @param executeTime
|
||||
* 接口耗时情况,单位为毫秒
|
||||
* @param outTradeNo
|
||||
* 商户系统内部的订单号,商 户可以在上报时提供相关商户订单号方便微信支付更好 的提高服务质量。
|
||||
* @param ip
|
||||
* 发起接口调用时的机器 IP
|
||||
* @param time
|
||||
* 商户调用该接口时商户自己 系统的时间
|
||||
* @param returnXml
|
||||
* 调用接口返回的基本数据
|
||||
* @return 处理结果
|
||||
* @see com.foxinmy.weixin4j.api.PayApi
|
||||
* @see com.foxinmy.weixin4j.api.Pay3Api
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_8">接口测试上报API</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public XmlResult interfaceReport(String interfaceUrl, int executeTime,
|
||||
String outTradeNo, String ip, Date time, XmlResult returnXml)
|
||||
throws WeixinException {
|
||||
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.api.CouponApi
|
||||
* @see com.foxinmy.weixin4j.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.payment.WeixinPayProxy#sendCoupon(File, String, String, String, String)}
|
||||
*/
|
||||
public CouponResult sendCoupon(String couponStockId, String partnerTradeNo,
|
||||
String openId) throws WeixinException {
|
||||
return couponApi.sendCoupon(DEFAULT_CA_FILE, couponStockId,
|
||||
partnerTradeNo, openId, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询代金券批次
|
||||
*
|
||||
* @param couponStockId
|
||||
* 代金券批次ID
|
||||
* @return 代金券批次信息
|
||||
* @see com.foxinmy.weixin4j.api.CouponApi
|
||||
* @see com.foxinmy.weixin4j.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.api.CouponApi
|
||||
* @see com.foxinmy.weixin4j.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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发放红包 企业向微信用户个人发现金红包
|
||||
*
|
||||
* @param caFile
|
||||
* 证书文件(V3版本后缀为*.p12)
|
||||
* @param redpacket
|
||||
* 红包信息
|
||||
* @return 发放结果
|
||||
* @see com.foxinmy.weixin4j.api.CashApi
|
||||
* @see com.foxinmy.weixin4j.payment.mch.Redpacket
|
||||
* @see com.foxinmy.weixin4j.payment.mch.RedpacketSendResult
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=13_5">红包接口说明</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public RedpacketSendResult sendRedpack(File caFile, Redpacket redpacket)
|
||||
throws WeixinException {
|
||||
return cashApi.sendRedpack(caFile, redpacket);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发放红包采用properties中配置的ca文件
|
||||
*
|
||||
* @see {@link com.foxinmy.weixin4j.payment.WeixinPayProxy#sendRedpack(File, Redpacket)}
|
||||
*/
|
||||
public RedpacketSendResult sendRedpack(Redpacket redpacket)
|
||||
throws WeixinException {
|
||||
return cashApi.sendRedpack(DEFAULT_CA_FILE, redpacket);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询红包记录
|
||||
*
|
||||
* @param caFile
|
||||
* 证书文件(V3版本后缀为*.p12)
|
||||
* @param outTradeNo
|
||||
* 商户发放红包的商户订单号
|
||||
* @return 红包记录
|
||||
* @see com.foxinmy.weixin4j.api.CashApi
|
||||
* @see com.foxinmy.weixin4j.payment.mch.RedpacketRecord
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=13_6">查询红包接口说明</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public RedpacketRecord queryRedpack(File caFile, String outTradeNo)
|
||||
throws WeixinException {
|
||||
return cashApi.queryRedpack(caFile, outTradeNo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询红包采用properties中配置的ca文件
|
||||
*
|
||||
* @see {@link com.foxinmy.weixin4j.payment.WeixinPayProxy#queryRedpack(File,String)}
|
||||
*/
|
||||
public RedpacketRecord queryRedpack(String outTradeNo)
|
||||
throws WeixinException {
|
||||
return cashApi.queryRedpack(DEFAULT_CA_FILE, outTradeNo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业付款 实现企业向个人付款,针对部分有开发能力的商户, 提供通过API完成企业付款的功能。 比如目前的保险行业向客户退保、给付、理赔。
|
||||
*
|
||||
* @param caFile
|
||||
* 证书文件(V3版本后缀为*.p12)
|
||||
* @param mpPayment
|
||||
* 付款信息
|
||||
* @return 付款结果
|
||||
* @see com.foxinmy.weixin4j.api.CashApi
|
||||
* @see com.foxinmy.weixin4j.payment.mch.MPPayment
|
||||
* @see com.foxinmy.weixin4j.payment.mch.MPPaymentResult
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/mch_pay.php?chapter=14_1">企业付款</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public MPPaymentResult mpPayment(File caFile, MPPayment mpPayment)
|
||||
throws WeixinException {
|
||||
return cashApi.mpPayment(caFile, mpPayment);
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业付款采用properties中配置的ca文件
|
||||
*
|
||||
* @see {@link com.foxinmy.weixin4j.payment.WeixinPayProxy#mpPayment(File, MPPayment)}
|
||||
*/
|
||||
public MPPaymentResult mpPayment(MPPayment mpPayment)
|
||||
throws WeixinException {
|
||||
return cashApi.mpPayment(DEFAULT_CA_FILE, mpPayment);
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业付款查询 用于商户的企业付款操作进行结果查询,返回付款操作详细结果
|
||||
*
|
||||
* @param caFile
|
||||
* 证书文件(V3版本后缀为*.p12)
|
||||
* @param outTradeNo
|
||||
* 商户调用企业付款API时使用的商户订单号
|
||||
* @return 付款记录
|
||||
* @see com.foxinmy.weixin4j.api.CashApi
|
||||
* @see com.foxinmy.weixin4j.payment.mch.MPPaymentRecord
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/mch_pay.php?chapter=14_3">企业付款查询</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public MPPaymentRecord mpPaymentQuery(File caFile, String outTradeNo)
|
||||
throws WeixinException {
|
||||
return cashApi.mpPaymentQuery(caFile, outTradeNo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业付款查询采用properties中配置的ca文件
|
||||
*
|
||||
* @see {@link com.foxinmy.weixin4j.payment.WeixinPayProxy#mpPaymentQuery(File, String)}
|
||||
*/
|
||||
public MPPaymentRecord mpPaymentQuery(String outTradeNo)
|
||||
throws WeixinException {
|
||||
return cashApi.mpPaymentQuery(DEFAULT_CA_FILE, outTradeNo);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,380 @@
|
||||
package com.foxinmy.weixin4j.payment.coupon;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.payment.mch.ApiResult;
|
||||
import com.foxinmy.weixin4j.type.CouponStatus;
|
||||
import com.foxinmy.weixin4j.type.CouponStockType;
|
||||
import com.foxinmy.weixin4j.type.CouponType;
|
||||
import com.foxinmy.weixin4j.util.DateUtil;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
|
||||
/**
|
||||
* 代金券详细
|
||||
*
|
||||
* @className CouponDetail
|
||||
* @author jy
|
||||
* @date 2015年3月27日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class CouponDetail extends ApiResult {
|
||||
|
||||
private static final long serialVersionUID = -311265355895457070L;
|
||||
|
||||
/**
|
||||
* 代金券批次Id
|
||||
*/
|
||||
@XmlElement(name = "coupon_stock_id")
|
||||
@JSONField(name = "coupon_stock_id")
|
||||
private String couponStockId;
|
||||
|
||||
/**
|
||||
* 批次类型;1-批量型,2-触发型
|
||||
*/
|
||||
@XmlElement(name = "coupon_stock_type")
|
||||
@JSONField(name = "coupon_stock_type")
|
||||
private int couponStockType;
|
||||
|
||||
/**
|
||||
* 代金券id
|
||||
*/
|
||||
@XmlElement(name = "coupon_id")
|
||||
@JSONField(name = "coupon_id")
|
||||
private String couponId;
|
||||
/**
|
||||
* 代金券面值,单位是分
|
||||
*/
|
||||
@XmlElement(name = "coupon_value")
|
||||
@JSONField(name = "coupon_value")
|
||||
private int couponValue;
|
||||
|
||||
/**
|
||||
* 代金券使用最低限额,单位是分
|
||||
*/
|
||||
@XmlElement(name = "coupon_mininum")
|
||||
@JSONField(name = "coupon_mininum")
|
||||
private int couponMininum;
|
||||
/**
|
||||
* 代金券名称
|
||||
*/
|
||||
@XmlElement(name = "coupon_name")
|
||||
@JSONField(name = "coupon_name")
|
||||
private String couponName;
|
||||
/**
|
||||
* 代金券状态:2-已激活,4-已锁定,8-已实扣
|
||||
*/
|
||||
@XmlElement(name = "coupon_state")
|
||||
@JSONField(name = "coupon_state")
|
||||
private int couponStatus;
|
||||
/**
|
||||
* 代金券类型:1-代金券无门槛,2-代金券有门槛互斥,3-代金券有门槛叠加,
|
||||
*/
|
||||
@XmlElement(name = "coupon_type")
|
||||
@JSONField(name = "coupon_type")
|
||||
private int couponType;
|
||||
|
||||
/**
|
||||
* 代金券描述
|
||||
*/
|
||||
@XmlElement(name = "coupon_desc")
|
||||
@JSONField(name = "coupon_desc")
|
||||
private String couponDesc;
|
||||
|
||||
/**
|
||||
* 代金券实际使用金额
|
||||
*/
|
||||
@XmlElement(name = "coupon_use_value")
|
||||
@JSONField(name = "coupon_use_value")
|
||||
private int couponUseValue;
|
||||
|
||||
/**
|
||||
* 代金券剩余金额:部分使用情况下,可能会存在券剩余金额
|
||||
*/
|
||||
@XmlElement(name = "coupon_remain_value")
|
||||
@JSONField(name = "coupon_remain_value")
|
||||
private int couponRemainValue;
|
||||
|
||||
/**
|
||||
* 生效开始时间:格式为yyyyMMddhhmmss,如2009年12月27日9点10分10秒表示为20091227091010。
|
||||
*/
|
||||
@XmlElement(name = "begin_time")
|
||||
@JSONField(name = "begin_time")
|
||||
private String beginTime;
|
||||
|
||||
/**
|
||||
* 生效结束时间:格式为yyyyMMddhhmmss,如2009年12月27日9点10分10秒表示为20091227091010。
|
||||
*/
|
||||
@XmlElement(name = "end_time")
|
||||
@JSONField(name = "end_time")
|
||||
private String endTime;
|
||||
|
||||
/**
|
||||
* 发放时间:格式为yyyyMMddhhmmss,如2009年12月27日9点10分10秒表示为20091227091010。
|
||||
*/
|
||||
@XmlElement(name = "send_time")
|
||||
@JSONField(name = "send_time")
|
||||
private String sendTime;
|
||||
|
||||
/**
|
||||
* 使用时间:格式为yyyyMMddhhmmss,如2009年12月27日9点10分10秒表示为20091227091010。
|
||||
*/
|
||||
@XmlElement(name = "use_time")
|
||||
@JSONField(name = "use_time")
|
||||
private String useTime;
|
||||
|
||||
/**
|
||||
* 使用单号:代金券使用后,关联的大单收单单号
|
||||
*/
|
||||
@XmlElement(name = "trade_no")
|
||||
@JSONField(name = "trade_no")
|
||||
private String tradeNo;
|
||||
|
||||
/**
|
||||
* 消耗方商户id:代金券使用后,消耗方商户id
|
||||
*/
|
||||
@XmlElement(name = "consumer_mch_id")
|
||||
@JSONField(name = "consumer_mch_id")
|
||||
private String consumerMchId;
|
||||
|
||||
/**
|
||||
* 消耗方商户名称:代金券使用后,消耗方商户名称
|
||||
*/
|
||||
@XmlElement(name = "consumer_mch_name")
|
||||
@JSONField(name = "consumer_mch_name")
|
||||
private String consumerMchName;
|
||||
|
||||
/**
|
||||
* 消耗方商户appid:代金券使用后,消耗方商户appid
|
||||
*/
|
||||
@XmlElement(name = "consumer_mch_appid")
|
||||
@JSONField(name = "consumer_mch_appid")
|
||||
private String consumerMchAppid;
|
||||
|
||||
/**
|
||||
* 发放来源:代金券发放来源
|
||||
*/
|
||||
@XmlElement(name = "send_source")
|
||||
@JSONField(name = "send_source")
|
||||
private String sendSource;
|
||||
|
||||
/**
|
||||
* 是否允许部分使用:该代金券是否允许部分使用标识:1-表示支持部分使用
|
||||
*/
|
||||
@XmlElement(name = "is_partial_use")
|
||||
@JSONField(name = "is_partial_use")
|
||||
private int isPartialUse;
|
||||
|
||||
public CouponDetail(){
|
||||
|
||||
}
|
||||
|
||||
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 StringUtil.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()
|
||||
+ "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.foxinmy.weixin4j.payment.coupon;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
|
||||
/**
|
||||
* 代金券信息(订单,退款中体现)
|
||||
*
|
||||
* @className CouponInfo
|
||||
* @author jy
|
||||
* @date 2015年3月24日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class CouponInfo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -8744999305258786901L;
|
||||
|
||||
/**
|
||||
* 代金券或立减优惠批次ID
|
||||
*/
|
||||
@XmlElement(name = "coupon_batch_id")
|
||||
@JSONField(name = "coupon_batch_id")
|
||||
private String couponBatchId;
|
||||
/**
|
||||
* 代金券或立减优惠ID
|
||||
*/
|
||||
@XmlElement(name = "coupon_id")
|
||||
@JSONField(name = "coupon_id")
|
||||
private String couponId;
|
||||
/**
|
||||
* 单个代金券或立减优惠支付金额
|
||||
*/
|
||||
@XmlElement(name = "coupon_fee")
|
||||
@JSONField(name = "coupon_fee")
|
||||
private Integer couponFee;
|
||||
|
||||
public CouponInfo(){
|
||||
|
||||
}
|
||||
|
||||
public String getCouponBatchId() {
|
||||
return couponBatchId;
|
||||
}
|
||||
|
||||
public String getCouponId() {
|
||||
return couponId;
|
||||
}
|
||||
|
||||
public Integer getCouponFee() {
|
||||
return couponFee;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(serialize = false, deserialize = false)
|
||||
public double getFormatCouponFee() {
|
||||
return couponFee / 100d;
|
||||
}
|
||||
|
||||
public void setCouponId(String couponId) {
|
||||
this.couponId = couponId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "couponBatchId=" + couponBatchId + ", couponId=" + couponId
|
||||
+ ", couponFee=" + couponFee;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package com.foxinmy.weixin4j.payment.coupon;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.payment.mch.ApiResult;
|
||||
|
||||
/**
|
||||
* 代金券发放结果
|
||||
*
|
||||
* @className CouponResult
|
||||
* @author jy
|
||||
* @date 2015年3月25日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class CouponResult extends ApiResult {
|
||||
|
||||
private static final long serialVersionUID = -1996967923720149124L;
|
||||
|
||||
/**
|
||||
* 代金券批次id
|
||||
*/
|
||||
@XmlElement(name = "coupon_stock_id")
|
||||
@JSONField(name = "coupon_stock_id")
|
||||
private String couponStockId;
|
||||
/**
|
||||
* 返回记录数
|
||||
*/
|
||||
@XmlElement(name = "resp_count")
|
||||
@JSONField(name = "resp_count")
|
||||
private int responseCount;
|
||||
/**
|
||||
* 成功记录数
|
||||
*/
|
||||
@XmlElement(name = "success_count")
|
||||
@JSONField(name = "success_count")
|
||||
private int successCount;
|
||||
/**
|
||||
* 失败记录数
|
||||
*/
|
||||
@XmlElement(name = "failed_count")
|
||||
@JSONField(name = "failed_count")
|
||||
private int failedCount;
|
||||
/**
|
||||
* 用户在商户appid下的唯一标识
|
||||
*/
|
||||
@XmlElement(name = "openid")
|
||||
@JSONField(name = "openid")
|
||||
private String openId;
|
||||
/**
|
||||
* 返回码 SUCCESS或者FAILED
|
||||
*/
|
||||
@XmlElement(name = "ret_code")
|
||||
@JSONField(name = "ret_code")
|
||||
private String retCode;
|
||||
/**
|
||||
* 代金券id
|
||||
*/
|
||||
@XmlElement(name = "coupon_id")
|
||||
@JSONField(name = "coupon_id")
|
||||
private String couponId;
|
||||
/**
|
||||
* 失败描述信息,例如:“用户已达领用上限”
|
||||
*/
|
||||
@XmlElement(name = "ret_msg")
|
||||
@JSONField(name = "ret_msg")
|
||||
private String retMsg;
|
||||
|
||||
public CouponResult(){
|
||||
|
||||
}
|
||||
|
||||
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,306 @@
|
||||
package com.foxinmy.weixin4j.payment.coupon;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.payment.mch.ApiResult;
|
||||
import com.foxinmy.weixin4j.type.CouponStockStatus;
|
||||
import com.foxinmy.weixin4j.type.CouponType;
|
||||
import com.foxinmy.weixin4j.util.DateUtil;
|
||||
|
||||
/**
|
||||
* 代金券信息
|
||||
*
|
||||
* @className CouponStock
|
||||
* @author jy
|
||||
* @date 2015年3月27日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class CouponStock extends ApiResult {
|
||||
|
||||
private static final long serialVersionUID = -8627202879200080499L;
|
||||
|
||||
/**
|
||||
* 代金券批次ID
|
||||
*/
|
||||
@XmlElement(name = "coupon_stock_id")
|
||||
@JSONField(name = "coupon_stock_id")
|
||||
private String couponStockId;
|
||||
/**
|
||||
* 代金券名称
|
||||
*/
|
||||
@XmlElement(name = "coupon_name")
|
||||
@JSONField(name = "coupon_name")
|
||||
private String couponName;
|
||||
/**
|
||||
* 代金券面额
|
||||
*/
|
||||
@XmlElement(name = "coupon_value")
|
||||
@JSONField(name = "coupon_value")
|
||||
private int couponValue;
|
||||
/**
|
||||
* 代金券使用最低限额
|
||||
*/
|
||||
@XmlElement(name = "coupon_mininumn")
|
||||
@JSONField(name = "coupon_mininumn")
|
||||
private Integer couponMininumn;
|
||||
/**
|
||||
* 代金券类型:1-代金券无门槛,2-代金券有门槛互斥,3-代金券有门槛叠加
|
||||
*/
|
||||
@XmlElement(name = "coupon_type")
|
||||
@JSONField(name = "coupon_type")
|
||||
private int couponType;
|
||||
/**
|
||||
* 批次状态: 1-未激活;2-审批中;4-已激活;8-已作废;16-中止发放;
|
||||
*/
|
||||
@XmlElement(name = "coupon_stock_status")
|
||||
@JSONField(name = "coupon_stock_status")
|
||||
private int couponStockStatus;
|
||||
/**
|
||||
* 代金券数量
|
||||
*/
|
||||
@XmlElement(name = "coupon_total")
|
||||
@JSONField(name = "coupon_total")
|
||||
private int couponTotal;
|
||||
/**
|
||||
* 代金券每个人最多能领取的数量, 如果为0,则表示没有限制
|
||||
*/
|
||||
@XmlElement(name = "max_quota")
|
||||
@JSONField(name = "max_quota")
|
||||
private Integer maxQuota;
|
||||
/**
|
||||
* 代金券锁定数量
|
||||
*/
|
||||
@XmlElement(name = "locked_num")
|
||||
@JSONField(name = "locked_num")
|
||||
private Integer lockedNum;
|
||||
/**
|
||||
* 代金券已使用数量
|
||||
*/
|
||||
@XmlElement(name = "used_num")
|
||||
@JSONField(name = "used_num")
|
||||
private Integer usedNum;
|
||||
/**
|
||||
* 代金券已经发送的数量
|
||||
*/
|
||||
@XmlElement(name = "is_send_num")
|
||||
@JSONField(name = "is_send_num")
|
||||
private Integer sendNum;
|
||||
/**
|
||||
* 生效开始时间 格式为yyyyMMddhhmmss,如2009年12月27日9点10分10秒表示为20091227091010。
|
||||
*/
|
||||
@XmlElement(name = "begin_time")
|
||||
@JSONField(name = "begin_time")
|
||||
private String beginTime;
|
||||
/**
|
||||
* 生效结束时间 格式为yyyyMMddhhmmss,如2009年12月27日9点10分10秒表示为20091227091010。
|
||||
*/
|
||||
@XmlElement(name = "end_time")
|
||||
@JSONField(name = "end_time")
|
||||
private String endTime;
|
||||
/**
|
||||
* 创建时间 格式为yyyyMMddhhmmss,如2009年12月27日9点10分10秒表示为20091227091010。
|
||||
*/
|
||||
@XmlElement(name = "create_time")
|
||||
@JSONField(name = "create_time")
|
||||
private String createTime;
|
||||
/**
|
||||
* 代金券预算额度
|
||||
*/
|
||||
@XmlElement(name = "coupon_budget")
|
||||
@JSONField(name = "coupon_budget")
|
||||
private Integer couponBudget;
|
||||
|
||||
public CouponStock(){
|
||||
|
||||
}
|
||||
|
||||
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() + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
package com.foxinmy.weixin4j.payment.mch;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.http.weixin.XmlResult;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
|
||||
/**
|
||||
* 调用V3.x接口返回的公用字段
|
||||
*
|
||||
* @className ApiResult
|
||||
* @author jy
|
||||
* @date 2014年10月21日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class ApiResult extends XmlResult {
|
||||
|
||||
private static final long serialVersionUID = -8430005768959715444L;
|
||||
|
||||
/**
|
||||
* 微信分配的公众账号 ID商户号 非空
|
||||
*/
|
||||
@XmlElement(name = "appid")
|
||||
@JSONField(name = "appid")
|
||||
private String appId;
|
||||
/**
|
||||
* 微信支付分配的商户号 非空
|
||||
*/
|
||||
@XmlElement(name = "mch_id")
|
||||
@JSONField(name = "mch_id")
|
||||
private String mchId;
|
||||
/**
|
||||
* 代理模式下分配的商户号 可能为空
|
||||
*/
|
||||
@XmlElement(name = "sub_mch_id")
|
||||
@JSONField(name = "sub_mch_id")
|
||||
private String subMchId;
|
||||
/**
|
||||
* 随机字符串 非空
|
||||
*/
|
||||
@XmlElement(name = "nonce_str")
|
||||
@JSONField(name = "nonce_str")
|
||||
private String nonceStr;
|
||||
/**
|
||||
* 签名 <font color="red">调用者无需关心</font>
|
||||
*/
|
||||
private String sign;
|
||||
/**
|
||||
* 微信支付分配的终端设备号 可能为空
|
||||
*/
|
||||
@XmlElement(name = "device_info")
|
||||
@JSONField(name = "device_info")
|
||||
private String deviceInfo;
|
||||
/**
|
||||
* 是否需要继续调用接口 Y- 需要,N-不需要
|
||||
*/
|
||||
private String recall;
|
||||
|
||||
protected ApiResult() {
|
||||
|
||||
}
|
||||
|
||||
public ApiResult(String returnCode, String returnMsg) {
|
||||
super(returnCode, returnMsg);
|
||||
}
|
||||
|
||||
public String getAppId() {
|
||||
return appId;
|
||||
}
|
||||
|
||||
public void setAppId(String appId) {
|
||||
this.appId = appId;
|
||||
}
|
||||
|
||||
public String getMchId() {
|
||||
return mchId;
|
||||
}
|
||||
|
||||
public void setMchId(String mchId) {
|
||||
this.mchId = mchId;
|
||||
}
|
||||
|
||||
public String getSubMchId() {
|
||||
return StringUtil.isNotBlank(subMchId) ? subMchId : null;
|
||||
}
|
||||
|
||||
public void setSubMchId(String subMchId) {
|
||||
this.subMchId = subMchId;
|
||||
}
|
||||
|
||||
public String getNonceStr() {
|
||||
return nonceStr;
|
||||
}
|
||||
|
||||
public void setNonceStr(String nonceStr) {
|
||||
this.nonceStr = nonceStr;
|
||||
}
|
||||
|
||||
public String getSign() {
|
||||
return sign;
|
||||
}
|
||||
|
||||
public void setSign(String sign) {
|
||||
this.sign = sign;
|
||||
}
|
||||
|
||||
public String getDeviceInfo() {
|
||||
return deviceInfo;
|
||||
}
|
||||
|
||||
public void setDeviceInfo(String deviceInfo) {
|
||||
this.deviceInfo = deviceInfo;
|
||||
}
|
||||
|
||||
public String getRecall() {
|
||||
return recall;
|
||||
}
|
||||
|
||||
public void setRecall(String recall) {
|
||||
this.recall = recall;
|
||||
}
|
||||
|
||||
@JSONField(deserialize = false, serialize = false)
|
||||
public boolean getFormatRecall() {
|
||||
return recall != null && recall.equalsIgnoreCase("y");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "appId=" + appId + ", mchId=" + mchId + ", subMchId=" + subMchId
|
||||
+ ", nonceStr=" + nonceStr + ", sign=" + sign + ", deviceInfo="
|
||||
+ deviceInfo + ", recall=" + getFormatRecall() + ", "
|
||||
+ super.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package com.foxinmy.weixin4j.payment.mch;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.type.MPPaymentCheckNameType;
|
||||
import com.foxinmy.weixin4j.util.DateUtil;
|
||||
|
||||
/**
|
||||
* 企业付款
|
||||
*
|
||||
* @className MPPayment
|
||||
* @author jy
|
||||
* @date 2015年4月1日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class MPPayment implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 3734639674346425312L;
|
||||
/**
|
||||
* 商户订单号
|
||||
*/
|
||||
@XmlElement(name = "partner_trade_no")
|
||||
@JSONField(name = "partner_trade_no")
|
||||
private String outTradeNo;
|
||||
/**
|
||||
* 接收红包的用户的openid
|
||||
*/
|
||||
private String openid;
|
||||
/**
|
||||
* 校验用户姓名选项
|
||||
*
|
||||
* @see com.foxinmy.weixin4j.mp.type.MPPaymentCheckNameType
|
||||
*/
|
||||
@XmlElement(name = "check_name")
|
||||
@JSONField(name = "check_name")
|
||||
private MPPaymentCheckNameType checkNameType;
|
||||
/**
|
||||
* 收款用户真实姓名。 如果check_name设置为FORCE_CHECK或OPTION_CHECK,则必填用户真实姓名 可选
|
||||
*/
|
||||
@XmlElement(name = "re_user_name")
|
||||
@JSONField(name = "re_user_name")
|
||||
private String userName;
|
||||
/**
|
||||
* 企业付款描述信息
|
||||
*/
|
||||
private String desc;
|
||||
/**
|
||||
* 付款金额
|
||||
*/
|
||||
private String amount;
|
||||
/**
|
||||
* 调用接口的机器Ip地址
|
||||
*/
|
||||
@XmlElement(name = "spbill_create_ip")
|
||||
@JSONField(name = "spbill_create_ip")
|
||||
private String clientIp;
|
||||
|
||||
protected MPPayment() {
|
||||
// jaxb required
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业付款
|
||||
* @param outTradeNo 商户的订单号
|
||||
* @param openid 用户的openid
|
||||
* @param checkNameType 校验用户姓名选项
|
||||
* @param desc 描述
|
||||
* @param amount 金额
|
||||
* @param clientIp 调用接口IP
|
||||
*/
|
||||
public MPPayment(String outTradeNo, String openid,
|
||||
MPPaymentCheckNameType checkNameType, String desc, double amount,
|
||||
String clientIp) {
|
||||
this.outTradeNo = outTradeNo;
|
||||
this.openid = openid;
|
||||
this.checkNameType = checkNameType;
|
||||
this.desc = desc;
|
||||
this.amount = DateUtil.formaFee2Fen(amount);
|
||||
this.clientIp = clientIp;
|
||||
}
|
||||
|
||||
public String getOutTradeNo() {
|
||||
return outTradeNo;
|
||||
}
|
||||
|
||||
public String getOpenid() {
|
||||
return openid;
|
||||
}
|
||||
|
||||
public MPPaymentCheckNameType getCheckNameType() {
|
||||
return checkNameType;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
}
|
||||
|
||||
public String getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public String getClientIp() {
|
||||
return clientIp;
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MPPayment [outTradeNo=" + outTradeNo + ", openid=" + openid
|
||||
+ ", checkNameType=" + checkNameType + ", userName=" + userName
|
||||
+ ", desc=" + desc + ", amount=" + amount + ", clientIp="
|
||||
+ clientIp + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
package com.foxinmy.weixin4j.payment.mch;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.type.MPPaymentCheckNameType;
|
||||
import com.foxinmy.weixin4j.util.DateUtil;
|
||||
|
||||
/**
|
||||
* 企业付款记录
|
||||
*
|
||||
* @className MPPaymentRecord
|
||||
* @author jy
|
||||
* @date 2015年6月23日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class MPPaymentRecord extends ApiResult {
|
||||
|
||||
private static final long serialVersionUID = -1926873539419750498L;
|
||||
|
||||
/**
|
||||
* 微信订单订单号
|
||||
*/
|
||||
@JSONField(name = "detail_id")
|
||||
@XmlElement(name = "detail_id")
|
||||
private String transactionId;
|
||||
/**
|
||||
* 商户订单号
|
||||
*/
|
||||
@JSONField(name = "partner_trade_no")
|
||||
@XmlElement(name = "partner_trade_no")
|
||||
private String outTradeNo;
|
||||
/**
|
||||
* 交易状态 SUCCESS:转账成功 FAILED:转账失败
|
||||
*/
|
||||
@JSONField(name = "status")
|
||||
@XmlElement(name = "status")
|
||||
private String transactionStatus;
|
||||
/**
|
||||
* 如果失败则应该有原因
|
||||
*/
|
||||
@JSONField(name = "reason")
|
||||
@XmlElement(name = "reason")
|
||||
private String failureReason;
|
||||
/**
|
||||
* 收款用户openid
|
||||
*/
|
||||
private String openid;
|
||||
/**
|
||||
* 收款用户姓名
|
||||
*/
|
||||
@JSONField(name = "transfer_name")
|
||||
@XmlElement(name = "transfer_name")
|
||||
private String transferName;
|
||||
/**
|
||||
* 付款金额(单位为分)
|
||||
*/
|
||||
@JSONField(name = "payment_amount")
|
||||
@XmlElement(name = "payment_amount")
|
||||
private int paymentAmount;
|
||||
/**
|
||||
* 转账时间
|
||||
*/
|
||||
@JSONField(name = "transfer_time")
|
||||
@XmlElement(name = "transfer_time")
|
||||
private String transferTime;
|
||||
/**
|
||||
* 校验用户姓名选项
|
||||
*
|
||||
* @see com.foxinmy.weixin4j.mp.type.MPPaymentCheckNameType
|
||||
*/
|
||||
@XmlElement(name = "check_name")
|
||||
@JSONField(name = "check_name")
|
||||
private MPPaymentCheckNameType checkNameType;
|
||||
/**
|
||||
* 企业付款描述信息
|
||||
*/
|
||||
private String desc;
|
||||
/**
|
||||
* 实名验证结果 PASS:通过 FAILED:不通过
|
||||
*/
|
||||
@JSONField(name = "check_name_result")
|
||||
@XmlElement(name = "check_name_result")
|
||||
private String checkNameResult;
|
||||
|
||||
protected MPPaymentRecord() {
|
||||
// jaxb required
|
||||
}
|
||||
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
public String getOutTradeNo() {
|
||||
return outTradeNo;
|
||||
}
|
||||
|
||||
public String getTransactionStatus() {
|
||||
return transactionStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化交易状态
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
public boolean getFormatTransactionStatus() {
|
||||
return "success".equalsIgnoreCase(transactionStatus);
|
||||
}
|
||||
|
||||
public String getFailureReason() {
|
||||
return failureReason;
|
||||
}
|
||||
|
||||
public String getOpenid() {
|
||||
return openid;
|
||||
}
|
||||
|
||||
public String getTransferName() {
|
||||
return transferName;
|
||||
}
|
||||
|
||||
public int getPaymentAmount() {
|
||||
return paymentAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
public double getFormatPaymentAmount() {
|
||||
return paymentAmount / 100d;
|
||||
}
|
||||
|
||||
public String getTransferTime() {
|
||||
return transferTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化转账时间
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
public Date getFormatTransferTime() {
|
||||
return DateUtil.parse2yyyyMMddHHmmss(transferTime);
|
||||
}
|
||||
|
||||
public MPPaymentCheckNameType getCheckNameType() {
|
||||
return checkNameType;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
}
|
||||
|
||||
public String getCheckNameResult() {
|
||||
return checkNameResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化交易状态
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
public boolean getFormatCheckNameResult() {
|
||||
return "pass".equalsIgnoreCase(checkNameResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MPPaymentRecord [transactionId=" + transactionId
|
||||
+ ", outTradeNo=" + outTradeNo + ", transactionStatus="
|
||||
+ getFormatTransactionStatus() + ", failureReason="
|
||||
+ failureReason + ", openid=" + openid + ", transferName="
|
||||
+ transferName + ", paymentAmount=" + getFormatPaymentAmount()
|
||||
+ ", transferTime=" + transferTime + ", checkNameType="
|
||||
+ checkNameType + ", desc=" + desc + ", checkNameResult="
|
||||
+ getFormatCheckNameResult() + ", " + super.toString() + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.foxinmy.weixin4j.payment.mch;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
|
||||
/**
|
||||
* 企业付款结果
|
||||
*
|
||||
* @className MPPaymentResult
|
||||
* @author jy
|
||||
* @date 2015年4月1日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class MPPaymentResult extends ApiResult {
|
||||
|
||||
private static final long serialVersionUID = 1110472826089211646L;
|
||||
|
||||
/**
|
||||
* 微信订单订单号
|
||||
*/
|
||||
@JSONField(name = "payment_no")
|
||||
@XmlElement(name = "payment_no")
|
||||
private String transactionId;
|
||||
/**
|
||||
* 商户订单号
|
||||
*/
|
||||
@JSONField(name = "partner_trade_no")
|
||||
@XmlElement(name = "partner_trade_no")
|
||||
private String outTradeNo;
|
||||
/**
|
||||
* 支付时间
|
||||
*/
|
||||
@JSONField(name = "payment_time")
|
||||
@XmlElement(name = "payment_time")
|
||||
private String paymentTime;
|
||||
|
||||
protected MPPaymentResult() {
|
||||
// jaxb required
|
||||
}
|
||||
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
public String getOutTradeNo() {
|
||||
return outTradeNo;
|
||||
}
|
||||
|
||||
public String getPaymentTime() {
|
||||
return paymentTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MPPaymentResult [transactionId=" + transactionId
|
||||
+ ", outTradeNo=" + outTradeNo + ", paymentTime=" + paymentTime
|
||||
+ "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
package com.foxinmy.weixin4j.payment.mch;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.payment.PayPackage;
|
||||
import com.foxinmy.weixin4j.type.TradeType;
|
||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||
|
||||
/**
|
||||
* 支付的订单详情
|
||||
*
|
||||
* @className MchPayPackage
|
||||
* @author jy
|
||||
* @date 2014年10月21日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class MchPayPackage extends PayPackage {
|
||||
|
||||
private static final long serialVersionUID = 8944928173669656177L;
|
||||
|
||||
/**
|
||||
* 微信分配的公众账号 必须
|
||||
*/
|
||||
private String appid;
|
||||
/**
|
||||
* 微信支付分配的商户号 必须
|
||||
*/
|
||||
@XmlElement(name = "mch_id")
|
||||
@JSONField(name = "mch_id")
|
||||
private String mchId;
|
||||
/**
|
||||
* 微信支付分配的终端设备号 非必须
|
||||
*/
|
||||
@XmlElement(name = "device_info")
|
||||
@JSONField(name = "device_info")
|
||||
private String deviceInfo;
|
||||
/**
|
||||
* 随机字符串,不长于 32 位 必须
|
||||
*/
|
||||
@XmlElement(name = "nonce_str")
|
||||
@JSONField(name = "nonce_str")
|
||||
private String nonceStr;
|
||||
/**
|
||||
* 签名 <font color="red">调用者无需关心</font>
|
||||
*/
|
||||
private String sign;
|
||||
/**
|
||||
* 交易类型JSAPI、NATIVE、APP 必须
|
||||
*/
|
||||
@XmlElement(name = "trade_type")
|
||||
@JSONField(name = "trade_type")
|
||||
private String tradeType;
|
||||
/**
|
||||
* 用户在商户 appid 下的唯一 标识, trade_type 为 JSAPI 时,此参数必传
|
||||
*/
|
||||
private String openid;
|
||||
/**
|
||||
* 只在 trade_type 为 NATIVE 时需要填写 非必须
|
||||
*/
|
||||
@XmlElement(name = "product_id")
|
||||
@JSONField(name = "product_id")
|
||||
private String productId;
|
||||
|
||||
protected MchPayPackage() {
|
||||
// jaxb required
|
||||
}
|
||||
|
||||
public MchPayPackage(WeixinPayAccount weixinAccount, String openId,
|
||||
String body, String outTradeNo, double totalFee,
|
||||
String spbillCreateIp, TradeType tradeType) {
|
||||
this(weixinAccount, openId, body, null, outTradeNo, totalFee, null,
|
||||
spbillCreateIp, tradeType);
|
||||
}
|
||||
|
||||
public MchPayPackage(WeixinPayAccount weixinAccount, String openId,
|
||||
String body, String attach, String outTradeNo, double totalFee,
|
||||
String notifyUrl, String spbillCreateIp, TradeType tradeType) {
|
||||
this(weixinAccount.getId(), weixinAccount.getMchId(), weixinAccount
|
||||
.getDeviceInfo(), RandomUtil.generateString(16), body, attach,
|
||||
outTradeNo, totalFee, spbillCreateIp, null, null, null,
|
||||
notifyUrl, tradeType, openId, null);
|
||||
}
|
||||
|
||||
public MchPayPackage(String appid, String mchId, String deviceInfo,
|
||||
String nonceStr, String body, String attach, String outTradeNo,
|
||||
double totalFee, String spbillCreateIp, Date timeStart,
|
||||
Date timeExpire, String goodsTag, String notifyUrl,
|
||||
TradeType tradeType, String openid, String productId) {
|
||||
super(body, attach, outTradeNo, totalFee, spbillCreateIp, timeStart,
|
||||
timeExpire, goodsTag, notifyUrl);
|
||||
this.appid = appid;
|
||||
this.mchId = mchId;
|
||||
this.deviceInfo = deviceInfo;
|
||||
this.nonceStr = nonceStr;
|
||||
this.tradeType = tradeType.name();
|
||||
this.openid = openid;
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
public String getAppid() {
|
||||
return appid;
|
||||
}
|
||||
|
||||
public String getMchId() {
|
||||
return mchId;
|
||||
}
|
||||
|
||||
public String getDeviceInfo() {
|
||||
return deviceInfo;
|
||||
}
|
||||
|
||||
public String getNonceStr() {
|
||||
return nonceStr;
|
||||
}
|
||||
|
||||
public String getSign() {
|
||||
return sign;
|
||||
}
|
||||
|
||||
public void setSign(String sign) {
|
||||
this.sign = sign;
|
||||
}
|
||||
|
||||
public String getTradeType() {
|
||||
return tradeType;
|
||||
}
|
||||
|
||||
public String getOpenid() {
|
||||
return openid;
|
||||
}
|
||||
|
||||
public String getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
public void setProductId(String productId) {
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MchPayPackage [appid=" + appid + ", mchId=" + mchId
|
||||
+ ", deviceInfo=" + deviceInfo + ", nonceStr=" + nonceStr
|
||||
+ ", sign=" + sign + ", tradeType=" + tradeType + ", openid="
|
||||
+ openid + ", productId=" + productId + ", " + super.toString()
|
||||
+ "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.foxinmy.weixin4j.payment.mch;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.PayException;
|
||||
import com.foxinmy.weixin4j.payment.PayRequest;
|
||||
|
||||
/**
|
||||
* JS支付:get_brand_wcpay_request</br>
|
||||
* <p>
|
||||
* get_brand_wcpay_request:ok 支付成功<br>
|
||||
* get_brand_wcpay_request:cancel 支付过程中用户取消<br>
|
||||
* get_brand_wcpay_request:fail 支付失败
|
||||
* </p>
|
||||
* <p>
|
||||
* NATIVE支付:PayRequest.TradeType=NATIVE
|
||||
* </p>
|
||||
*
|
||||
* @className PayRequest
|
||||
* @author jy
|
||||
* @date 2014年8月17日
|
||||
* @since JDK 1.7
|
||||
* @see com.foxinmy.weixin4j.payment.mch.PrePay
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class MchPayRequest extends PayRequest {
|
||||
|
||||
private static final long serialVersionUID = -5972173459255255197L;
|
||||
|
||||
protected MchPayRequest() {
|
||||
// jaxb required
|
||||
}
|
||||
|
||||
public MchPayRequest(PrePay prePay) throws PayException {
|
||||
this.setAppId(prePay.getAppId());
|
||||
this.setPackageInfo("prepay_id=" + prePay.getPrepayId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MchPayRequest [" + super.toString() + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.foxinmy.weixin4j.payment.mch;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
/**
|
||||
* Native支付回调时POST的信息
|
||||
*
|
||||
* @className PayNativeNotify
|
||||
* @author jy
|
||||
* @date 2014年10月30日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class NativePayNotify extends ApiResult {
|
||||
|
||||
private static final long serialVersionUID = 4515471400239795492L;
|
||||
|
||||
/**
|
||||
* 产品ID 可视为订单ID
|
||||
*/
|
||||
@XmlElement(name = "product_id")
|
||||
private String productId;
|
||||
|
||||
protected NativePayNotify() {
|
||||
// jaxb required
|
||||
}
|
||||
|
||||
public String getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NativePayNotify [productId=" + productId + ", "
|
||||
+ super.toString() + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.foxinmy.weixin4j.payment.mch;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.exception.PayException;
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
import com.foxinmy.weixin4j.payment.PayUtil;
|
||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||
|
||||
/**
|
||||
* Native支付时的回调响应
|
||||
*
|
||||
* @className NativePayResponseV3
|
||||
* @author jy
|
||||
* @date 2014年10月28日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class NativePayResponse extends ApiResult {
|
||||
|
||||
private static final long serialVersionUID = 6119895998783333012L;
|
||||
|
||||
@XmlTransient
|
||||
@JSONField(serialize = false)
|
||||
private PrePay prePay;
|
||||
|
||||
private String prepay_id;
|
||||
|
||||
protected NativePayResponse() {
|
||||
// jaxb required
|
||||
}
|
||||
|
||||
/**
|
||||
* 一般作为校验失败时返回
|
||||
*
|
||||
* @param returnMsg
|
||||
* 失败消息
|
||||
* @param resultMsg
|
||||
* 结果消息
|
||||
* @throws PayException
|
||||
*/
|
||||
public NativePayResponse(String returnMsg, String resultMsg) {
|
||||
super.setReturnMsg(returnMsg);
|
||||
super.setReturnCode(Consts.FAIL);
|
||||
super.setErrCodeDes(resultMsg);
|
||||
super.setResultCode(Consts.FAIL);
|
||||
}
|
||||
|
||||
/**
|
||||
* 作为return_code 为 SUCCESS 的时候返回
|
||||
*
|
||||
* @param payPackage
|
||||
* 订单信息
|
||||
* @throws PayException
|
||||
*/
|
||||
public NativePayResponse(MchPayPackage payPackage, String paysignKey)
|
||||
throws PayException {
|
||||
super.setReturnCode(Consts.SUCCESS);
|
||||
this.setResultCode(Consts.SUCCESS);
|
||||
this.setMchId(payPackage.getMchId());
|
||||
this.setAppId(payPackage.getAppid());
|
||||
this.setNonceStr(RandomUtil.generateString(16));
|
||||
this.prePay = PayUtil.createPrePay(payPackage, paysignKey);
|
||||
this.prepay_id = prePay.getPrepayId();
|
||||
}
|
||||
|
||||
public String getPrepay_id() {
|
||||
return prepay_id;
|
||||
}
|
||||
|
||||
public void setPrepay_id(String prepay_id) {
|
||||
this.prepay_id = prepay_id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NativePayResponseV3 [prePay=" + prePay + ", prepay_id="
|
||||
+ prepay_id + ", " + super.toString() + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
package com.foxinmy.weixin4j.payment.mch;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.payment.coupon.CouponInfo;
|
||||
import com.foxinmy.weixin4j.type.CurrencyType;
|
||||
import com.foxinmy.weixin4j.type.TradeState;
|
||||
import com.foxinmy.weixin4j.type.TradeType;
|
||||
import com.foxinmy.weixin4j.util.DateUtil;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.foxinmy.weixin4j.xml.ListsuffixResult;
|
||||
|
||||
/**
|
||||
* V3订单信息
|
||||
*
|
||||
* @className Order
|
||||
* @author jy
|
||||
* @date 2014年11月2日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class Order extends ApiResult {
|
||||
|
||||
private static final long serialVersionUID = 5636828325595317079L;
|
||||
/**
|
||||
* 交易状态
|
||||
*
|
||||
* @see com.foxinmy.weixin4j.mp.type.TradeState
|
||||
*/
|
||||
@XmlElement(name = "trade_state")
|
||||
@JSONField(name = "trade_state")
|
||||
private TradeState tradeState;
|
||||
/**
|
||||
* 用户的openid
|
||||
*/
|
||||
@XmlElement(name = "openid")
|
||||
@JSONField(name = "openid")
|
||||
private String openId;
|
||||
/**
|
||||
* 用户是否关注公众账号,Y- 关注,N-未关注,仅在公众 账号类型支付有效
|
||||
*/
|
||||
@XmlElement(name = "is_subscribe")
|
||||
@JSONField(name = "is_subscribe")
|
||||
private String isSubscribe;
|
||||
/**
|
||||
* 交易类型
|
||||
*
|
||||
* @see com.foxinmy.weixin4j.mp.type.TradeType
|
||||
*/
|
||||
@XmlElement(name = "trade_type")
|
||||
@JSONField(name = "trade_type")
|
||||
private TradeType tradeType;
|
||||
/**
|
||||
* 银行类型
|
||||
*/
|
||||
@XmlElement(name = "bank_type")
|
||||
@JSONField(name = "bank_type")
|
||||
private String bankType;
|
||||
/**
|
||||
* 订单总金额,单位为分
|
||||
*/
|
||||
@XmlElement(name = "total_fee")
|
||||
@JSONField(name = "total_fee")
|
||||
private int totalFee;
|
||||
/**
|
||||
* 现金券支付金额<=订单总金 额,订单总金额-现金券金额 为现金支付金额
|
||||
*/
|
||||
@XmlElement(name = "coupon_fee")
|
||||
@JSONField(name = "coupon_fee")
|
||||
private Integer couponFee;
|
||||
/**
|
||||
* 代金券或立减优惠使用数量
|
||||
*/
|
||||
@XmlElement(name = "coupon_count")
|
||||
@JSONField(name = "coupon_count")
|
||||
private Integer couponCount;
|
||||
/**
|
||||
* 代金券信息 验证签名有点麻烦
|
||||
*/
|
||||
@ListsuffixResult
|
||||
private List<CouponInfo> couponList;
|
||||
/**
|
||||
* 现金支付金额
|
||||
*/
|
||||
@XmlElement(name = "cash_fee")
|
||||
@JSONField(name = "cash_fee")
|
||||
private int cashFee;
|
||||
/**
|
||||
* 货币类型,符合 ISO 4217 标准的三位字母代码,默认人民币:CNY
|
||||
*
|
||||
* @see com.foxinmy.weixin4j.mp.type.CurrencyType
|
||||
*/
|
||||
@XmlElement(name = "fee_type")
|
||||
@JSONField(name = "fee_type")
|
||||
private CurrencyType feeType;
|
||||
/**
|
||||
* 微信支付订单号
|
||||
*/
|
||||
@XmlElement(name = "transaction_id")
|
||||
@JSONField(name = "transaction_id")
|
||||
private String transactionId;
|
||||
/**
|
||||
* 商户订单号
|
||||
*/
|
||||
@XmlElement(name = "out_trade_no")
|
||||
@JSONField(name = "out_trade_no")
|
||||
private String outTradeNo;
|
||||
/**
|
||||
* 商家数据包
|
||||
*/
|
||||
private String attach;
|
||||
/**
|
||||
* 支付完成时间,格式为 yyyyMMddhhmmss
|
||||
*/
|
||||
@XmlElement(name = "time_end")
|
||||
@JSONField(name = "time_end")
|
||||
private String timeEnd;
|
||||
/**
|
||||
* 交易状态描述
|
||||
*/
|
||||
@XmlElement(name = "trade_state_desc")
|
||||
@JSONField(name = "trade_state_desc")
|
||||
private String tradeStateDesc;
|
||||
|
||||
protected Order() {
|
||||
// jaxb required
|
||||
}
|
||||
|
||||
public TradeState getTradeState() {
|
||||
return tradeState;
|
||||
}
|
||||
|
||||
public String getOpenId() {
|
||||
return openId;
|
||||
}
|
||||
|
||||
public String getIsSubscribe() {
|
||||
return isSubscribe;
|
||||
}
|
||||
|
||||
@JSONField(serialize = false, deserialize = false)
|
||||
public boolean getFormatIsSubscribe() {
|
||||
return isSubscribe != null && isSubscribe.equalsIgnoreCase("y");
|
||||
}
|
||||
|
||||
public TradeType getTradeType() {
|
||||
return tradeType;
|
||||
}
|
||||
|
||||
public String getBankType() {
|
||||
return bankType;
|
||||
}
|
||||
|
||||
public int getTotalFee() {
|
||||
return totalFee;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(serialize = false, deserialize = false)
|
||||
public double getFormatTotalFee() {
|
||||
return totalFee / 100d;
|
||||
}
|
||||
|
||||
public Integer getCouponFee() {
|
||||
return couponFee;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(serialize = false, deserialize = false)
|
||||
public double getFormatCouponFee() {
|
||||
return couponFee != null ? couponFee / 100d : 0d;
|
||||
}
|
||||
|
||||
public Integer getCouponCount() {
|
||||
return couponCount;
|
||||
}
|
||||
|
||||
@JSONField(serialize = false, deserialize = false)
|
||||
public int getFormatCouponCount() {
|
||||
return couponCount != null ? couponCount.intValue() : 0;
|
||||
}
|
||||
|
||||
public int getCashFee() {
|
||||
return cashFee;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(serialize = false, deserialize = false)
|
||||
public double getFormatCashFee() {
|
||||
return cashFee / 100d;
|
||||
}
|
||||
|
||||
public CurrencyType getFeeType() {
|
||||
return feeType;
|
||||
}
|
||||
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
public String getOutTradeNo() {
|
||||
return outTradeNo;
|
||||
}
|
||||
|
||||
public String getAttach() {
|
||||
return attach;
|
||||
}
|
||||
|
||||
public String getTimeEnd() {
|
||||
return timeEnd;
|
||||
}
|
||||
|
||||
@JSONField(serialize = false, deserialize = false)
|
||||
public Date getFormatTimeEnd() {
|
||||
if (StringUtil.isNotBlank(timeEnd)) {
|
||||
return DateUtil.parse2yyyyMMddHHmmss(timeEnd);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getTradeStateDesc() {
|
||||
return tradeStateDesc;
|
||||
}
|
||||
|
||||
public List<CouponInfo> getCouponList() {
|
||||
return couponList;
|
||||
}
|
||||
|
||||
public void setCouponList(List<CouponInfo> couponList) {
|
||||
this.couponList = couponList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Order [tradeState=" + tradeState + ", openId=" + openId
|
||||
+ ", isSubscribe=" + getFormatIsSubscribe() + ", tradeType="
|
||||
+ tradeType + ", bankType=" + bankType + ", feeType=" + feeType
|
||||
+ ", transactionId=" + transactionId + ", outTradeNo="
|
||||
+ outTradeNo + ", attach=" + attach + ", timeEnd=" + timeEnd
|
||||
+ ", totalFee=" + getFormatTotalFee() + ", couponFee="
|
||||
+ getFormatCouponFee() + ", couponCount="
|
||||
+ getFormatCouponCount() + ", couponList=" + couponList
|
||||
+ ", cashFee=" + getFormatCashFee() + ", timeEnd="
|
||||
+ getFormatTimeEnd() + ", tradeStateDesc=" + tradeStateDesc
|
||||
+ ", " + super.toString() + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.foxinmy.weixin4j.payment.mch;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.foxinmy.weixin4j.type.TradeType;
|
||||
|
||||
/**
|
||||
* V3预订单信息
|
||||
*
|
||||
* @className PrePay
|
||||
* @author jy
|
||||
* @date 2014年10月21日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class PrePay extends ApiResult {
|
||||
|
||||
private static final long serialVersionUID = -8430005768959715444L;
|
||||
|
||||
/**
|
||||
* 调用接口提交的交易类型,取值如下:JSAPI,NATIVE,APP,
|
||||
*
|
||||
* @see com.foxinmy.weixin4j.mp.type.TradeType
|
||||
*/
|
||||
@XmlElement(name = "trade_type")
|
||||
private TradeType tradeType;
|
||||
/**
|
||||
* 微信生成的预支付回话标识,用于后续接口调用中使用,该值有效期为2小时
|
||||
*/
|
||||
@XmlElement(name = "prepay_id")
|
||||
private String prepayId;
|
||||
/**
|
||||
* trade_type 为 NATIVE 是有 返回,此参数可直接生成二 维码展示出来进行扫码支付 可能为空
|
||||
*/
|
||||
@XmlElement(name = "code_url")
|
||||
private String codeUrl;
|
||||
|
||||
protected PrePay() {
|
||||
// jaxb required
|
||||
}
|
||||
|
||||
public PrePay(String returnCode, String returnMsg) {
|
||||
super(returnCode, returnMsg);
|
||||
}
|
||||
|
||||
public TradeType getTradeType() {
|
||||
return tradeType;
|
||||
}
|
||||
|
||||
public void setTradeType(TradeType tradeType) {
|
||||
this.tradeType = tradeType;
|
||||
}
|
||||
|
||||
public String getPrepayId() {
|
||||
return prepayId;
|
||||
}
|
||||
|
||||
public void setPrepayId(String prepayId) {
|
||||
this.prepayId = prepayId;
|
||||
}
|
||||
|
||||
public String getCodeUrl() {
|
||||
return codeUrl;
|
||||
}
|
||||
|
||||
public void setCodeUrl(String codeUrl) {
|
||||
this.codeUrl = codeUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PrePay [tradeType=" + tradeType + ", prepayId=" + prepayId
|
||||
+ ", codeUrl=" + codeUrl + ", " + super.toString() + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,279 @@
|
||||
package com.foxinmy.weixin4j.payment.mch;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.util.DateUtil;
|
||||
|
||||
/**
|
||||
* 红包
|
||||
*
|
||||
* @className Redpacket
|
||||
* @author jy
|
||||
* @date 2015年3月28日
|
||||
* @since JDK 1.7
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=13_1">红包简介</a>
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class Redpacket implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -7021352305575714281L;
|
||||
/**
|
||||
* 商户订单号(每个订单号必须唯一) 组成: mch_id+yyyymmdd+10位一天内不能重复的数字。
|
||||
*/
|
||||
@XmlElement(name = "mch_billno")
|
||||
@JSONField(name = "mch_billno")
|
||||
private String outTradeNo;
|
||||
/**
|
||||
* 提供方名称 必填
|
||||
*/
|
||||
@XmlElement(name = "nick_name")
|
||||
@JSONField(name = "nick_name")
|
||||
private String nickName;
|
||||
/**
|
||||
* 红包发送者名称 必填
|
||||
*/
|
||||
@XmlElement(name = "send_name")
|
||||
@JSONField(name = "send_name")
|
||||
private String sendName;
|
||||
/**
|
||||
* 接收红包的用户的openid
|
||||
*/
|
||||
@XmlElement(name = "re_openid")
|
||||
@JSONField(name = "re_openid")
|
||||
private String openid;
|
||||
/**
|
||||
* 付款金额,单位分
|
||||
*/
|
||||
@XmlElement(name = "total_amount")
|
||||
@JSONField(name = "total_amount")
|
||||
private String totalAmount;
|
||||
/**
|
||||
* 最小红包金额,单位分
|
||||
*/
|
||||
@XmlElement(name = "min_value")
|
||||
@JSONField(name = "min_value")
|
||||
private String minValue;
|
||||
/**
|
||||
* 最大红包金额,单位分( 最小金额等于最大金额: min_value=max_value =total_amount)
|
||||
*/
|
||||
@XmlElement(name = "max_value")
|
||||
@JSONField(name = "max_value")
|
||||
private String maxValue;
|
||||
/**
|
||||
* 红包发放总人数
|
||||
*/
|
||||
@XmlElement(name = "total_num")
|
||||
@JSONField(name = "total_num")
|
||||
private int totalNum;
|
||||
/**
|
||||
* 红包祝福语
|
||||
*/
|
||||
private String wishing;
|
||||
/**
|
||||
* ip地址
|
||||
*/
|
||||
@XmlElement(name = "client_ip")
|
||||
@JSONField(name = "client_ip")
|
||||
private String clientIp;
|
||||
/**
|
||||
* 活动名称
|
||||
*/
|
||||
@XmlElement(name = "act_name")
|
||||
@JSONField(name = "act_name")
|
||||
private String actName;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
/**
|
||||
* 商户logo的url 非必填
|
||||
*/
|
||||
@XmlElement(name = "logo_imgurl")
|
||||
@JSONField(name = "logo_imgurl")
|
||||
private String logoUrl;
|
||||
/**
|
||||
* 分享文案 非必填
|
||||
*/
|
||||
@XmlElement(name = "share_content")
|
||||
@JSONField(name = "share_content")
|
||||
private String shareContent;
|
||||
/**
|
||||
* 分享链接 非必填
|
||||
*/
|
||||
@XmlElement(name = "share_url")
|
||||
@JSONField(name = "share_url")
|
||||
private String shareUrl;
|
||||
/**
|
||||
* 分享的图片 非必填
|
||||
*/
|
||||
@XmlElement(name = "share_imgurl")
|
||||
@JSONField(name = "share_imgurl")
|
||||
private String shareImageUrl;
|
||||
|
||||
protected Redpacket() {
|
||||
// jaxb required
|
||||
}
|
||||
|
||||
/**
|
||||
* 红包
|
||||
*
|
||||
* @param outTradeNo
|
||||
* 商户侧一天内不可重复的订单号 接口根据商户订单号支持重入 如出现超时可再调用
|
||||
* @param nickName
|
||||
* 提供方名称
|
||||
* @param sendName
|
||||
* 红包发送者名称
|
||||
* @param openid
|
||||
* 接受收红包的用户的openid
|
||||
* @param totalAmount
|
||||
* 付款金额 <font color="red">单位为元,自动格式化为分</font>
|
||||
*/
|
||||
public Redpacket(String outTradeNo, String nickName, String sendName,
|
||||
String openid, double totalAmount) {
|
||||
this.outTradeNo = outTradeNo;
|
||||
this.nickName = nickName;
|
||||
this.sendName = sendName;
|
||||
this.openid = openid;
|
||||
this.totalAmount = DateUtil.formaFee2Fen(totalAmount);
|
||||
}
|
||||
|
||||
public String getOutTradeNo() {
|
||||
return outTradeNo;
|
||||
}
|
||||
|
||||
public String getNickName() {
|
||||
return nickName;
|
||||
}
|
||||
|
||||
public String getSendName() {
|
||||
return sendName;
|
||||
}
|
||||
|
||||
public String getOpenid() {
|
||||
return openid;
|
||||
}
|
||||
|
||||
public String getTotalAmount() {
|
||||
return totalAmount;
|
||||
}
|
||||
|
||||
public String getMinValue() {
|
||||
return minValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">单位为元,自动格式化为分</font>
|
||||
*
|
||||
* @param minValue
|
||||
* 最小红包 单位为元
|
||||
*/
|
||||
public void setMinValue(double minValue) {
|
||||
this.minValue = DateUtil.formaFee2Fen(minValue);
|
||||
}
|
||||
|
||||
public String getMaxValue() {
|
||||
return maxValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">单位为元,自动格式化为分</font>
|
||||
*
|
||||
* @param minValue
|
||||
* 最大红包 单位为元
|
||||
*/
|
||||
public void setMaxValue(double maxValue) {
|
||||
this.maxValue = DateUtil.formaFee2Fen(maxValue);
|
||||
}
|
||||
|
||||
public int getTotalNum() {
|
||||
return totalNum;
|
||||
}
|
||||
|
||||
public void setTotalNum(int totalNum) {
|
||||
this.totalNum = totalNum;
|
||||
}
|
||||
|
||||
public String getWishing() {
|
||||
return wishing;
|
||||
}
|
||||
|
||||
public void setWishing(String wishing) {
|
||||
this.wishing = wishing;
|
||||
}
|
||||
|
||||
public String getClientIp() {
|
||||
return clientIp;
|
||||
}
|
||||
|
||||
public void setClientIp(String clientIp) {
|
||||
this.clientIp = clientIp;
|
||||
}
|
||||
|
||||
public String getActName() {
|
||||
return actName;
|
||||
}
|
||||
|
||||
public void setActName(String actName) {
|
||||
this.actName = actName;
|
||||
}
|
||||
|
||||
public String getRemark() {
|
||||
return remark;
|
||||
}
|
||||
|
||||
public void setRemark(String remark) {
|
||||
this.remark = remark;
|
||||
}
|
||||
|
||||
public String getLogoUrl() {
|
||||
return logoUrl;
|
||||
}
|
||||
|
||||
public void setLogoUrl(String logoUrl) {
|
||||
this.logoUrl = logoUrl;
|
||||
}
|
||||
|
||||
public String getShareContent() {
|
||||
return shareContent;
|
||||
}
|
||||
|
||||
public void setShareContent(String shareContent) {
|
||||
this.shareContent = shareContent;
|
||||
}
|
||||
|
||||
public String getShareUrl() {
|
||||
return shareUrl;
|
||||
}
|
||||
|
||||
public void setShareUrl(String shareUrl) {
|
||||
this.shareUrl = shareUrl;
|
||||
}
|
||||
|
||||
public String getShareImageUrl() {
|
||||
return shareImageUrl;
|
||||
}
|
||||
|
||||
public void setShareImageUrl(String shareImageUrl) {
|
||||
this.shareImageUrl = shareImageUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Redpacket [ nickName=" + nickName + ", sendName=" + sendName
|
||||
+ ", openid=" + openid + ", totalAmount=" + totalAmount
|
||||
+ ", minValue=" + minValue + ", maxValue=" + maxValue
|
||||
+ ", totalNum=" + totalNum + ", wishing=" + wishing
|
||||
+ ", clientIp=" + clientIp + ", actName=" + actName
|
||||
+ ", remark=" + remark + ", logoUrl=" + logoUrl
|
||||
+ ", shareContent=" + shareContent + ", shareUrl=" + shareUrl
|
||||
+ ", shareImageUrl=" + shareImageUrl + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,305 @@
|
||||
package com.foxinmy.weixin4j.payment.mch;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlElementWrapper;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.http.weixin.XmlResult;
|
||||
import com.foxinmy.weixin4j.type.RedpacketSendType;
|
||||
import com.foxinmy.weixin4j.type.RedpacketStatus;
|
||||
import com.foxinmy.weixin4j.type.RedpacketType;
|
||||
import com.foxinmy.weixin4j.util.DateUtil;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
|
||||
/**
|
||||
* 红包记录
|
||||
*
|
||||
* @className RedpacketRecord
|
||||
* @author jy
|
||||
* @date 2015年6月4日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class RedpacketRecord extends XmlResult {
|
||||
|
||||
private static final long serialVersionUID = 929959747323918458L;
|
||||
|
||||
/**
|
||||
* 商户订单号(每个订单号必须唯一) 组成: mch_id+yyyymmdd+10位一天内不能重复的数字。
|
||||
*/
|
||||
@XmlElement(name = "mch_billno")
|
||||
@JSONField(name = "mch_billno")
|
||||
private String outTradeNo;
|
||||
/**
|
||||
* 微信支付分配的商户号
|
||||
*/
|
||||
@XmlElement(name = "mch_id")
|
||||
@JSONField(name = "mch_id")
|
||||
private String mchId;
|
||||
|
||||
/**
|
||||
* 红包单号
|
||||
*/
|
||||
@XmlElement(name = "detail_id")
|
||||
@JSONField(name = "detail_id")
|
||||
private String repacketId;
|
||||
/**
|
||||
* 红包状态
|
||||
*/
|
||||
@XmlElement(name = "status")
|
||||
private RedpacketStatus status;
|
||||
/**
|
||||
* 发放类型
|
||||
*/
|
||||
@XmlElement(name = "send_type")
|
||||
@JSONField(name = "send_type")
|
||||
private RedpacketSendType sendType;
|
||||
/**
|
||||
* 红包类型
|
||||
*/
|
||||
@XmlElement(name = "hb_type")
|
||||
@JSONField(name = "hb_type")
|
||||
private RedpacketType type;
|
||||
/**
|
||||
* 红包个数
|
||||
*/
|
||||
@XmlElement(name = "total_num")
|
||||
@JSONField(name = "total_num")
|
||||
private int totalNum;
|
||||
/**
|
||||
* 红包总金额(单位分)
|
||||
*/
|
||||
@XmlElement(name = "total_amount")
|
||||
@JSONField(name = "total_amount")
|
||||
private int totalAmount;
|
||||
/**
|
||||
* 发送失败原因
|
||||
*/
|
||||
@XmlElement(name = "reason")
|
||||
private String reason;
|
||||
/**
|
||||
* 发放时间
|
||||
*/
|
||||
@XmlElement(name = "send_time")
|
||||
@JSONField(name = "send_time")
|
||||
private String sendTime;
|
||||
/**
|
||||
* 红包退款时间
|
||||
*/
|
||||
@XmlElement(name = "refund_time")
|
||||
@JSONField(name = "refund_time")
|
||||
private String refundTime;
|
||||
/**
|
||||
* 红包退款金额
|
||||
*/
|
||||
@XmlElement(name = "refund_amount")
|
||||
@JSONField(name = "refund_amount")
|
||||
private Integer refundAmount;
|
||||
/**
|
||||
* 祝福语
|
||||
*/
|
||||
@XmlElement(name = "wishing")
|
||||
private String wishing;
|
||||
/**
|
||||
* 活动描述
|
||||
*/
|
||||
@XmlElement(name = "remark")
|
||||
private String remark;
|
||||
/**
|
||||
* 活动名称
|
||||
*/
|
||||
@XmlElement(name = "act_name")
|
||||
@JSONField(name = "act_name")
|
||||
private String actName;
|
||||
/**
|
||||
* 裂变红包领取列表
|
||||
*/
|
||||
@XmlElement(name = "hbinfo")
|
||||
@XmlElementWrapper(name = "hblist")
|
||||
@JSONField(name = "hblist")
|
||||
private List<RedpacketReceiver> receivers;
|
||||
|
||||
public String getOutTradeNo() {
|
||||
return outTradeNo;
|
||||
}
|
||||
|
||||
public String getMchId() {
|
||||
return mchId;
|
||||
}
|
||||
|
||||
public String getRepacketId() {
|
||||
return repacketId;
|
||||
}
|
||||
|
||||
public RedpacketStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public RedpacketSendType getSendType() {
|
||||
return sendType;
|
||||
}
|
||||
|
||||
public RedpacketType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public int getTotalNum() {
|
||||
return totalNum;
|
||||
}
|
||||
|
||||
public int getTotalAmount() {
|
||||
return totalAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(serialize = false, deserialize = false)
|
||||
public double getFormatTotalAmount() {
|
||||
return totalAmount / 100d;
|
||||
}
|
||||
|
||||
public String getReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
public String getSendTime() {
|
||||
return sendTime;
|
||||
}
|
||||
|
||||
@JSONField(serialize = false, deserialize = false)
|
||||
public Date getFormatSendTime() {
|
||||
return DateUtil.parse2yyyyMMddHHmmss(sendTime);
|
||||
}
|
||||
|
||||
public String getRefundTime() {
|
||||
return refundTime;
|
||||
}
|
||||
|
||||
@JSONField(serialize = false, deserialize = false)
|
||||
public Date getFormatRefundTime() {
|
||||
if (StringUtil.isNotBlank(refundTime)) {
|
||||
return DateUtil.parse2yyyyMMddHHmmss(refundTime);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Integer getRefundAmount() {
|
||||
return refundAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(serialize = false, deserialize = false)
|
||||
public double getFormatRefundAmount() {
|
||||
if (refundAmount != null) {
|
||||
return refundAmount.intValue() / 100d;
|
||||
}
|
||||
return 0d;
|
||||
}
|
||||
|
||||
public String getWishing() {
|
||||
return wishing;
|
||||
}
|
||||
|
||||
public String getRemark() {
|
||||
return remark;
|
||||
}
|
||||
|
||||
public String getActName() {
|
||||
return actName;
|
||||
}
|
||||
|
||||
public List<RedpacketReceiver> getReceivers() {
|
||||
return receivers;
|
||||
}
|
||||
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public static class RedpacketReceiver {
|
||||
/**
|
||||
* 领取红包的Openid
|
||||
*/
|
||||
@XmlElement(name = "openid")
|
||||
private String openid;
|
||||
/**
|
||||
* 领取状态
|
||||
*/
|
||||
@XmlElement(name = "status")
|
||||
private RedpacketStatus status;
|
||||
/**
|
||||
* 领取金额
|
||||
*/
|
||||
private int amount;
|
||||
/**
|
||||
* 领取时间
|
||||
*/
|
||||
@XmlElement(name = "rcv_time")
|
||||
@JSONField(name = "rcv_time")
|
||||
private String receiveTime;
|
||||
|
||||
public String getOpenid() {
|
||||
return openid;
|
||||
}
|
||||
|
||||
public RedpacketStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public int getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public String getReceiveTime() {
|
||||
return receiveTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(serialize = false, deserialize = false)
|
||||
public double getFormatAmount() {
|
||||
return amount / 100d;
|
||||
}
|
||||
|
||||
@JSONField(serialize = false, deserialize = false)
|
||||
public Date getFormatReceiveTime() {
|
||||
return DateUtil.parse2yyyyMMddHHmmss(receiveTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RedpacketReceiver [openid=" + openid + ", status=" + status
|
||||
+ ", amount=" + getFormatAmount() + ", receiveTime="
|
||||
+ receiveTime + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RedpacketRecord [outTradeNo=" + outTradeNo + ", mchId=" + mchId
|
||||
+ ", repacketId=" + repacketId + ", status=" + status
|
||||
+ ", sendType=" + sendType + ", type=" + type + ", totalNum="
|
||||
+ totalNum + ", totalAmount=" + getFormatTotalAmount()
|
||||
+ ", reason=" + reason + ", sendTime=" + sendTime
|
||||
+ ", refundTime=" + refundTime + ", refundAmount="
|
||||
+ getFormatRefundAmount() + ", wishing=" + wishing
|
||||
+ ", remark=" + remark + ", actName=" + actName
|
||||
+ ", receivers=" + receivers + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package com.foxinmy.weixin4j.payment.mch;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.http.weixin.XmlResult;
|
||||
|
||||
/**
|
||||
* 发送红包结果
|
||||
*
|
||||
* @className RedpacketSendResult
|
||||
* @author jy
|
||||
* @date 2015年4月1日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class RedpacketSendResult extends XmlResult {
|
||||
|
||||
private static final long serialVersionUID = 5611847899634131711L;
|
||||
/**
|
||||
* 微信分配的公众账号
|
||||
*/
|
||||
@XmlElement(name = "wxappid")
|
||||
@JSONField(name = "wxappid")
|
||||
private String appid;
|
||||
/**
|
||||
* 微信支付分配的商户号
|
||||
*/
|
||||
@XmlElement(name = "mch_id")
|
||||
@JSONField(name = "mch_id")
|
||||
private String mchId;
|
||||
/**
|
||||
* 商户订单号(每个订单号必须唯一) 组成: mch_id+yyyymmdd+10位一天内不能重复的数字。
|
||||
*/
|
||||
@XmlElement(name = "mch_billno")
|
||||
@JSONField(name = "mch_billno")
|
||||
private String outTradeNo;
|
||||
/**
|
||||
* 接收红包的用户的openid
|
||||
*/
|
||||
@XmlElement(name = "re_openid")
|
||||
@JSONField(name = "re_openid")
|
||||
private String openid;
|
||||
/**
|
||||
* 付款金额 单位为分
|
||||
*/
|
||||
@XmlElement(name = "total_amount")
|
||||
@JSONField(name = "total_amount")
|
||||
private int totalAmount;
|
||||
|
||||
protected RedpacketSendResult() {
|
||||
// jaxb required
|
||||
}
|
||||
|
||||
public String getAppid() {
|
||||
return appid;
|
||||
}
|
||||
|
||||
public String getMchId() {
|
||||
return mchId;
|
||||
}
|
||||
|
||||
public String getOutTradeNo() {
|
||||
return outTradeNo;
|
||||
}
|
||||
|
||||
public String getOpenid() {
|
||||
return openid;
|
||||
}
|
||||
|
||||
public int getTotalAmount() {
|
||||
return totalAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(serialize = false, deserialize = false)
|
||||
public double getFormatTotalAmount() {
|
||||
return totalAmount / 100d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RedpacketSendResult [appid=" + appid + ", mchId=" + mchId
|
||||
+ ", outTradeNo=" + outTradeNo + ", openid=" + openid
|
||||
+ ", totalAmount=" + totalAmount + ", " + super.toString()
|
||||
+ "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,288 @@
|
||||
package com.foxinmy.weixin4j.payment.mch;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.payment.coupon.CouponInfo;
|
||||
import com.foxinmy.weixin4j.type.CurrencyType;
|
||||
import com.foxinmy.weixin4j.type.RefundChannel;
|
||||
import com.foxinmy.weixin4j.type.RefundStatus;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.foxinmy.weixin4j.xml.ListsuffixResult;
|
||||
|
||||
/**
|
||||
* V3退款详细
|
||||
*
|
||||
* @className RefundDetail
|
||||
* @author jy
|
||||
* @date 2014年11月6日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class RefundDetail extends ApiResult {
|
||||
|
||||
private static final long serialVersionUID = -3687863914168618620L;
|
||||
|
||||
/**
|
||||
* 商户退款单号
|
||||
*/
|
||||
@XmlElement(name = "out_refund_no")
|
||||
@JSONField(name = "out_refund_no")
|
||||
private String outRefundNo;
|
||||
/**
|
||||
* 微信退款单号
|
||||
*/
|
||||
@XmlElement(name = "refund_id")
|
||||
@JSONField(name = "refund_id")
|
||||
private String refundId;
|
||||
/**
|
||||
* 退款渠道:ORIGINAL—原路退款,默认 BALANCE—退回到余额
|
||||
*/
|
||||
@XmlElement(name = "refund_channel")
|
||||
@JSONField(name = "refund_channel")
|
||||
private String refundChannel;
|
||||
/**
|
||||
* 退款总金额,单位为分,可以做部分退款
|
||||
*/
|
||||
@XmlElement(name = "refund_fee")
|
||||
@JSONField(name = "refund_fee")
|
||||
private int refundFee;
|
||||
/**
|
||||
* 退款货币种类
|
||||
*
|
||||
* @see com.foxinmy.weixin4j.mp.type.CurrencyType
|
||||
*/
|
||||
@XmlElement(name = "refund_fee_type")
|
||||
@JSONField(name = "refund_fee_type")
|
||||
private CurrencyType refundFeeType;
|
||||
/**
|
||||
* 订单总金额
|
||||
*/
|
||||
@XmlElement(name = "total_fee")
|
||||
@JSONField(name = "total_fee")
|
||||
private int totalFee;
|
||||
/**
|
||||
* 订单金额货币种类
|
||||
*
|
||||
* @see com.foxinmy.weixin4j.mp.type.CurrencyType
|
||||
*/
|
||||
@XmlElement(name = "fee_type")
|
||||
@JSONField(name = "fee_type")
|
||||
private CurrencyType feeType;
|
||||
/**
|
||||
* 现金支付金额
|
||||
*/
|
||||
@XmlElement(name = "cash_fee")
|
||||
@JSONField(name = "cash_fee")
|
||||
private int cashFee;
|
||||
/**
|
||||
* 现金支付货币种类
|
||||
*
|
||||
* @see com.foxinmy.weixin4j.mp.type.CurrencyType
|
||||
*/
|
||||
@XmlElement(name = "cash_fee_type")
|
||||
@JSONField(name = "cash_fee_type")
|
||||
private CurrencyType cashFeeType;
|
||||
/**
|
||||
* 现金退款金额
|
||||
*/
|
||||
@XmlElement(name = "cash_refund_fee")
|
||||
@JSONField(name = "cash_refund_fee")
|
||||
private Integer cashRefundFee;
|
||||
/**
|
||||
* 现金退款货币类型
|
||||
*
|
||||
* @see com.foxinmy.weixin4j.mp.type.CurrencyType
|
||||
*/
|
||||
@XmlElement(name = "cash_refund_fee_type")
|
||||
@JSONField(name = "cash_refund_fee_type")
|
||||
private CurrencyType cashRefundFeeType;
|
||||
/**
|
||||
* 退款状态
|
||||
*/
|
||||
@XmlElement(name = "refund_status")
|
||||
@JSONField(name = "refund_status")
|
||||
private String refundStatus;
|
||||
/**
|
||||
* 现金券退款金额<=退款金额,退款金额-现金券退款金额为现金
|
||||
*/
|
||||
@XmlElement(name = "coupon_refund_fee")
|
||||
@JSONField(name = "coupon_refund_fee")
|
||||
private Integer couponRefundFee;
|
||||
/**
|
||||
* 代金券或立减优惠使用数量 <font
|
||||
* color="red">微信支付文档上写的coupon_count,而实际测试拿到的是coupon_refund_count,做个记号。
|
||||
* </font>
|
||||
*/
|
||||
@XmlElement(name = "coupon_refund_count")
|
||||
@JSONField(name = "coupon_refund_count")
|
||||
private Integer couponRefundCount;
|
||||
/**
|
||||
* 代金券信息
|
||||
*
|
||||
* @see com.foxinmy.weixin4j.payment.coupon.CouponInfo
|
||||
*/
|
||||
@ListsuffixResult
|
||||
private List<CouponInfo> couponList;
|
||||
|
||||
protected RefundDetail() {
|
||||
// jaxb required
|
||||
}
|
||||
|
||||
public String getOutRefundNo() {
|
||||
return outRefundNo;
|
||||
}
|
||||
|
||||
public String getRefundId() {
|
||||
return refundId;
|
||||
}
|
||||
|
||||
public String getRefundChannel() {
|
||||
return refundChannel;
|
||||
}
|
||||
|
||||
@JSONField(deserialize = false, serialize = false)
|
||||
public RefundChannel getFormatRefundChannel() {
|
||||
if (StringUtil.isNotBlank(refundChannel)) {
|
||||
return RefundChannel.valueOf(refundChannel.toUpperCase());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getRefundFee() {
|
||||
return refundFee;
|
||||
}
|
||||
|
||||
public CurrencyType getFeeType() {
|
||||
return feeType;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(deserialize = false, serialize = false)
|
||||
public double getFormatRefundFee() {
|
||||
return refundFee / 100d;
|
||||
}
|
||||
|
||||
public String getRefundStatus() {
|
||||
return refundStatus;
|
||||
}
|
||||
|
||||
@JSONField(deserialize = false, serialize = false)
|
||||
public RefundStatus getFormatRefundStatus() {
|
||||
if (StringUtil.isNotBlank(refundStatus)) {
|
||||
return RefundStatus.valueOf(refundStatus);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Integer getCouponRefundFee() {
|
||||
return couponRefundFee;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(deserialize = false, serialize = false)
|
||||
public double getFormatCouponRefundFee() {
|
||||
return couponRefundFee != null ? couponRefundFee.intValue() / 100d : 0d;
|
||||
}
|
||||
|
||||
public CurrencyType getRefundFeeType() {
|
||||
return refundFeeType;
|
||||
}
|
||||
|
||||
public int getTotalFee() {
|
||||
return totalFee;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(deserialize = false, serialize = false)
|
||||
public double getFormatTotalFee() {
|
||||
return totalFee / 100d;
|
||||
}
|
||||
|
||||
public int getCashFee() {
|
||||
return cashFee;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(deserialize = false, serialize = false)
|
||||
public double getFormatCashFee() {
|
||||
return cashFee / 100d;
|
||||
}
|
||||
|
||||
public CurrencyType getCashFeeType() {
|
||||
return cashFeeType;
|
||||
}
|
||||
|
||||
public Integer getCashRefundFee() {
|
||||
return cashRefundFee;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(deserialize = false, serialize = false)
|
||||
public double getFormatCashRefundFee() {
|
||||
return cashRefundFee != null ? cashRefundFee.intValue() / 100d : 0d;
|
||||
}
|
||||
|
||||
public CurrencyType getCashRefundFeeType() {
|
||||
return cashRefundFeeType;
|
||||
}
|
||||
|
||||
public Integer getCouponRefundCount() {
|
||||
return couponRefundCount;
|
||||
}
|
||||
|
||||
@JSONField(deserialize = false, serialize = false)
|
||||
public int getFormatCouponRefundCount() {
|
||||
return couponRefundCount != null ? couponRefundCount.intValue() : 0;
|
||||
}
|
||||
|
||||
public List<CouponInfo> getCouponList() {
|
||||
return couponList;
|
||||
}
|
||||
|
||||
public void setCouponList(List<CouponInfo> couponList) {
|
||||
this.couponList = couponList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RefundDetail [outRefundNo=" + outRefundNo + ", refundId="
|
||||
+ refundId + ", refundChannel=" + refundChannel
|
||||
+ ", refundFee=" + getFormatRefundFee() + ", refundFeeType="
|
||||
+ refundFeeType + ", totalFee=" + getFormatTotalFee()
|
||||
+ ", feeType=" + feeType + ", cashFee=" + getFormatCashFee()
|
||||
+ ", cashFeeType=" + cashFeeType + ", cashRefundFee="
|
||||
+ getFormatCashRefundFee() + ", cashRefundFeeType="
|
||||
+ cashRefundFeeType + ", refundStatus=" + refundStatus
|
||||
+ ", couponRefundFee=" + getFormatCouponRefundFee()
|
||||
+ ", couponCount=" + getCouponRefundCount() + ", couponList="
|
||||
+ couponList + ", " + super.toString() + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
package com.foxinmy.weixin4j.payment.mch;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.type.CurrencyType;
|
||||
import com.foxinmy.weixin4j.xml.ListsuffixResult;
|
||||
|
||||
/**
|
||||
* V3退款记录
|
||||
*
|
||||
* @className RefundRecord
|
||||
* @author jy
|
||||
* @date 2014年11月1日
|
||||
* @since JDK 1.7
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class RefundRecord extends ApiResult {
|
||||
|
||||
private static final long serialVersionUID = -2971132874939642721L;
|
||||
|
||||
/**
|
||||
* 微信订单号
|
||||
*/
|
||||
@XmlElement(name = "transaction_id")
|
||||
@JSONField(name = "transaction_id")
|
||||
private String transactionId;
|
||||
/**
|
||||
* 商户订单号
|
||||
*/
|
||||
@XmlElement(name = "out_trade_no")
|
||||
@JSONField(name = "out_trade_no")
|
||||
private String outTradeNo;
|
||||
/**
|
||||
* 订单总金额
|
||||
*/
|
||||
@XmlElement(name = "total_fee")
|
||||
@JSONField(name = "total_fee")
|
||||
private int totalFee;
|
||||
/**
|
||||
* 订单金额货币种类
|
||||
*
|
||||
* @see com.foxinmy.weixin4j.mp.type.CurrencyType
|
||||
*/
|
||||
@XmlElement(name = "fee_type")
|
||||
@JSONField(name = "fee_type")
|
||||
private CurrencyType feeType;
|
||||
/**
|
||||
* 现金支付金额
|
||||
*/
|
||||
@XmlElement(name = "cash_fee")
|
||||
@JSONField(name = "cash_fee")
|
||||
private int cashFee;
|
||||
/**
|
||||
* 现金支付金额货币种类
|
||||
*
|
||||
* @see com.foxinmy.weixin4j.mp.type.CurrencyType
|
||||
*/
|
||||
@XmlElement(name = "cash_fee_type")
|
||||
@JSONField(name = "cash_fee_type")
|
||||
private CurrencyType cashFeeType;
|
||||
/**
|
||||
* 退款总金额
|
||||
*/
|
||||
@XmlElement(name = "refund_fee")
|
||||
@JSONField(name = "refund_fee")
|
||||
private int refundFee;
|
||||
/**
|
||||
* 代金券或立减优惠退款金额=订单金额-现金退款金额,注意:满立减金额不会退回
|
||||
*/
|
||||
@XmlElement(name = "coupon_refund_fee")
|
||||
@JSONField(name = "coupon_refund_fee")
|
||||
private Integer couponRefundFee;
|
||||
/**
|
||||
* 退款笔数
|
||||
*/
|
||||
@XmlElement(name = "refund_count")
|
||||
@JSONField(name = "refund_count")
|
||||
private int refundCount;
|
||||
/**
|
||||
* 退款详情
|
||||
*
|
||||
* @see com.foxinmy.weixin4j.payment.mch.RefundDetail
|
||||
*/
|
||||
@ListsuffixResult({ "^out_refund_no(_\\d)$", "^refund_.*(_\\d)$" })
|
||||
private List<RefundDetail> refundList;
|
||||
|
||||
protected RefundRecord() {
|
||||
// jaxb required
|
||||
}
|
||||
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
public String getOutTradeNo() {
|
||||
return outTradeNo;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(serialize = false, deserialize = false)
|
||||
public double getFormatCashFee() {
|
||||
return cashFee / 100d;
|
||||
}
|
||||
|
||||
public int getCashFee() {
|
||||
return cashFee;
|
||||
}
|
||||
|
||||
public CurrencyType getFeeType() {
|
||||
return feeType;
|
||||
}
|
||||
|
||||
public CurrencyType getCashFeeType() {
|
||||
return cashFeeType;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(serialize = false, deserialize = false)
|
||||
public double getFormatCouponRefundFee() {
|
||||
return couponRefundFee != null ? couponRefundFee.intValue() / 100d : 0d;
|
||||
}
|
||||
|
||||
public Integer getCouponRefundFee() {
|
||||
return couponRefundFee;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(serialize = false, deserialize = false)
|
||||
public double getFormatTotalFee() {
|
||||
return totalFee / 100d;
|
||||
}
|
||||
|
||||
public int getTotalFee() {
|
||||
return totalFee;
|
||||
}
|
||||
|
||||
public int getRefundCount() {
|
||||
return refundCount;
|
||||
}
|
||||
|
||||
public List<RefundDetail> getRefundList() {
|
||||
return refundList;
|
||||
}
|
||||
|
||||
public void setRefundList(List<RefundDetail> refundList) {
|
||||
this.refundList = refundList;
|
||||
}
|
||||
|
||||
public int getRefundFee() {
|
||||
return refundFee;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(serialize = false, deserialize = false)
|
||||
public double getFormatRefundFee() {
|
||||
return refundFee / 100d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RefundRecord [transactionId=" + transactionId + ", outTradeNo="
|
||||
+ outTradeNo + ", totalFee=" + getFormatTotalFee()
|
||||
+ ", feeType=" + feeType + ", cashFee=" + getFormatCashFee()
|
||||
+ ", cashFeeType=" + cashFeeType + ", refundFee="
|
||||
+ getFormatRefundFee() + ", couponRefundFee="
|
||||
+ getFormatCouponRefundFee() + ", refundCount=" + refundCount
|
||||
+ ", refundList=" + refundList + ", " + super.toString() + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.foxinmy.weixin4j.payment.mch;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
|
||||
/**
|
||||
* V3退款申请结果
|
||||
*
|
||||
* @className RefundResult
|
||||
* @author jy
|
||||
* @date 2014年11月6日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class RefundResult extends RefundDetail {
|
||||
|
||||
private static final long serialVersionUID = -3687863914168618620L;
|
||||
|
||||
/**
|
||||
* 微信订单号
|
||||
*/
|
||||
@XmlElement(name = "transaction_id")
|
||||
@JSONField(name = "transaction_id")
|
||||
private String transactionId;
|
||||
/**
|
||||
* 商户系统内部的订单号
|
||||
*/
|
||||
@XmlElement(name = "out_trade_no")
|
||||
@JSONField(name = "out_trade_no")
|
||||
private String outTradeNo;
|
||||
|
||||
protected RefundResult() {
|
||||
// jaxb required
|
||||
}
|
||||
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
public String getOutTradeNo() {
|
||||
return outTradeNo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RefundResult [transactionId=" + transactionId + ", outTradeNo="
|
||||
+ outTradeNo + ", " + super.toString() + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.foxinmy.weixin4j.type;
|
||||
|
||||
/**
|
||||
* 对账单类型
|
||||
*
|
||||
* @className BillType
|
||||
* @author jy
|
||||
* @date 2014年10月31日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public enum BillType {
|
||||
/**
|
||||
* 全部
|
||||
*/
|
||||
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.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.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.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.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,23 @@
|
||||
package com.foxinmy.weixin4j.type;
|
||||
|
||||
/**
|
||||
* 币种
|
||||
*
|
||||
* @className CurrencyType
|
||||
* @author jy
|
||||
* @date 2014年11月2日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public enum CurrencyType {
|
||||
CNY("人民币"), HKD("港元"), TWD("台币"), EUR("欧元"), USD("美元"), GBP("英镑"), JPY("日元");
|
||||
private String desc;
|
||||
|
||||
CurrencyType(String desc) {
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.foxinmy.weixin4j.type;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* ID查询
|
||||
*
|
||||
* @className IdQuery
|
||||
* @author jy
|
||||
* @date 2014年11月1日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
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() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public IdType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(IdType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public IdQuery(String id, IdType idType) {
|
||||
this.id = id;
|
||||
this.type = idType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s=%s", type.getName(), id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.foxinmy.weixin4j.type;
|
||||
|
||||
/**
|
||||
* ID类型
|
||||
*
|
||||
* @className IdType
|
||||
* @author jy
|
||||
* @date 2014年11月1日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public enum IdType {
|
||||
/**
|
||||
* 微信退款单号
|
||||
*/
|
||||
REFUNDID("refund_id"),
|
||||
/**
|
||||
* 微信订单号
|
||||
*/
|
||||
TRANSACTIONID("transaction_id"),
|
||||
/**
|
||||
* 商户订单号
|
||||
*/
|
||||
TRADENO("out_trade_no"),
|
||||
/**
|
||||
* 商户退款号
|
||||
*/
|
||||
REFUNDNO("out_refund_no");
|
||||
private String name;
|
||||
|
||||
IdType(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.foxinmy.weixin4j.type;
|
||||
|
||||
/**
|
||||
* 企业付款检查收款人姓名的策略
|
||||
*
|
||||
* @className MPPaymentCheckType
|
||||
* @author jy
|
||||
* @date 2015年4月1日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public enum MPPaymentCheckNameType {
|
||||
/**
|
||||
* 不校验真实姓名
|
||||
*/
|
||||
NO_CHECK,
|
||||
/**
|
||||
* 强校验真实姓名(未实名认证的用户会校验失败,无法转账)
|
||||
*/
|
||||
FORCE_CHECK,
|
||||
/**
|
||||
* 针对已实名认证的用户才校验真实姓名(未实名认证用户不校验,可以转账成功)
|
||||
*/
|
||||
OPTION_CHECK;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.foxinmy.weixin4j.type;
|
||||
|
||||
/**
|
||||
* 二维码类型
|
||||
*
|
||||
* @className QRType
|
||||
* @author jy
|
||||
* @date 2014年11月4日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public enum QRType {
|
||||
/**
|
||||
* 临时二维码
|
||||
*/
|
||||
QR_SCENE,
|
||||
/**
|
||||
* 永久二维码(场景值为数字范围在1-100000之间)
|
||||
*/
|
||||
QR_LIMIT_SCENE,
|
||||
/**
|
||||
* 永久二维码(场景值为字符串长度在1-64之间)
|
||||
*/
|
||||
QR_LIMIT_STR_SCENE;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.foxinmy.weixin4j.type;
|
||||
|
||||
/**
|
||||
* 红包发放类型
|
||||
*
|
||||
* @className RedpacketSendType
|
||||
* @author jy
|
||||
* @date 2015年6月4日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public enum RedpacketSendType {
|
||||
/**
|
||||
* 通过API接口发放
|
||||
*/
|
||||
API,
|
||||
/**
|
||||
* 通过上传文件方式发放
|
||||
*/
|
||||
UPLOAD,
|
||||
/**
|
||||
* 通过活动方式发放
|
||||
*/
|
||||
ACTIVITY;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.foxinmy.weixin4j.type;
|
||||
|
||||
/**
|
||||
* 红包状态
|
||||
* @className RedpacketStatus
|
||||
* @author jy
|
||||
* @date 2015年6月4日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public enum RedpacketStatus {
|
||||
/**
|
||||
* 发放中
|
||||
*/
|
||||
SENDING,
|
||||
/**
|
||||
* 已发放待领取
|
||||
*/
|
||||
SENT,
|
||||
/**
|
||||
* 发放失败
|
||||
*/
|
||||
FAILED,
|
||||
/**
|
||||
* 已领取
|
||||
*/
|
||||
RECEIVED,
|
||||
/**
|
||||
* 已退款
|
||||
*/
|
||||
REFUND;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.foxinmy.weixin4j.type;
|
||||
|
||||
/**
|
||||
* 红包类型
|
||||
*
|
||||
* @className RedpacketType
|
||||
* @author jy
|
||||
* @date 2015年6月4日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public enum RedpacketType {
|
||||
/**
|
||||
* 裂变红包
|
||||
*/
|
||||
GROUP,
|
||||
/**
|
||||
* 普通红包
|
||||
*/
|
||||
NORMAL;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.foxinmy.weixin4j.type;
|
||||
|
||||
/**
|
||||
* 退款渠道
|
||||
*
|
||||
* @className RefundChannel
|
||||
* @author jy
|
||||
* @date 2014年11月6日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public enum RefundChannel {
|
||||
/**
|
||||
* 原路退款
|
||||
*/
|
||||
ORIGINAL,
|
||||
/**
|
||||
* 退回到余额
|
||||
*/
|
||||
BALANCE,
|
||||
/**
|
||||
* 财付通
|
||||
*/
|
||||
TENPAY,
|
||||
/**
|
||||
* 银行
|
||||
*/
|
||||
BANK;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.foxinmy.weixin4j.type;
|
||||
|
||||
/**
|
||||
* 退款状态
|
||||
*
|
||||
* @className RefundStatus
|
||||
* @author jy
|
||||
* @date 2014年11月2日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public enum RefundStatus {
|
||||
/**
|
||||
* 退款成功
|
||||
*/
|
||||
SUCCESS,
|
||||
/**
|
||||
* 退款失败
|
||||
*/
|
||||
FAIL,
|
||||
/**
|
||||
* 退款处理中
|
||||
*/
|
||||
PROCESSING,
|
||||
/**
|
||||
* 未确定,需要商户 原退款单号重新发起
|
||||
*/
|
||||
NOTSURE,
|
||||
/**
|
||||
* 转入代发,退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败,资金回流到商户的现金帐号,需要商户人工干预,通过线下或者财付通转
|
||||
* 账的方式进行退款。
|
||||
*/
|
||||
CHANGE;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.foxinmy.weixin4j.type;
|
||||
|
||||
/**
|
||||
* 退款类型
|
||||
*
|
||||
* @className RefundType
|
||||
* @author jy
|
||||
* @date 2014年12月31日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public enum RefundType {
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.foxinmy.weixin4j.type;
|
||||
|
||||
/**
|
||||
* 签名类型
|
||||
* @className SignType
|
||||
* @author jy
|
||||
* @date 2014年11月5日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public enum SignType {
|
||||
SHA1,MD5
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.foxinmy.weixin4j.type;
|
||||
|
||||
/**
|
||||
* 交易状态
|
||||
*
|
||||
* @className TradeState
|
||||
* @author jy
|
||||
* @date 2014年11月2日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public enum TradeState {
|
||||
/**
|
||||
* 支付成功
|
||||
*/
|
||||
SUCCESS,
|
||||
/**
|
||||
* 转入退款
|
||||
*/
|
||||
REFUND,
|
||||
/**
|
||||
* 未支付
|
||||
*/
|
||||
NOTPAY,
|
||||
/**
|
||||
* 已关闭
|
||||
*/
|
||||
CLOSED,
|
||||
/**
|
||||
* 已撤销
|
||||
*/
|
||||
REVOKED,
|
||||
/**
|
||||
* 用户支付中
|
||||
*/
|
||||
USERPAYING,
|
||||
/**
|
||||
* 未支付(输入密码或 确认支付超时)
|
||||
*/
|
||||
NOPAY,
|
||||
/**
|
||||
* 支付失败(其他 原因,如银行返回失败)
|
||||
*/
|
||||
PAYERROR;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.foxinmy.weixin4j.type;
|
||||
|
||||
/**
|
||||
* 微信支付类型
|
||||
*
|
||||
* @className TradeType
|
||||
* @author jy
|
||||
* @date 2014年10月21日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public enum TradeType {
|
||||
/**
|
||||
* H5页面上的JSAPI支付
|
||||
*/
|
||||
JSAPI,
|
||||
/**
|
||||
* 刷卡支付
|
||||
*/
|
||||
MICROPAY,
|
||||
/**
|
||||
* 扫描支付
|
||||
*/
|
||||
NATIVE,
|
||||
/**
|
||||
* APP支付
|
||||
*/
|
||||
APP;
|
||||
}
|
||||
Reference in New Issue
Block a user