Merge pull request #182 from kit-lee/feature/刷脸支付后端获取调用凭证API
微信刷脸支付后端API
This commit is contained in:
commit
24bead1a8e
1
pom.xml
1
pom.xml
@ -47,6 +47,7 @@
|
||||
<module>weixin4j-server</module>
|
||||
<module>weixin4j-example</module>
|
||||
<module>weixin4j-serverX</module>
|
||||
<module>weixin4j-pay</module>
|
||||
</modules>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
||||
@ -45,7 +45,9 @@ import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_1">
|
||||
* 企业付款</a>
|
||||
* @deprecated 商户平台API迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public class CashApi extends MchApi {
|
||||
|
||||
public CashApi(WeixinPayAccount weixinAccount) {
|
||||
@ -92,7 +94,7 @@ public class CashApi extends MchApi {
|
||||
/**
|
||||
* 批量发放红包 企业向微信用户个人发现金红包
|
||||
*
|
||||
* @param redpacket
|
||||
* @param redpackets
|
||||
* 多个红包信息
|
||||
* @return 发放结果
|
||||
* @see #sendRedpacks(Redpacket...)
|
||||
|
||||
@ -21,7 +21,9 @@ import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
* @since JDK 1.6
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/tools/sp_coupon.php?chapter=12_1">代金券</a>
|
||||
* @deprecated 商户平台API迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public class CouponApi extends MchApi {
|
||||
|
||||
public CouponApi(WeixinPayAccount weixinAccount) {
|
||||
|
||||
@ -22,7 +22,9 @@ import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
* @date 2016年3月67日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 商户平台API迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public class CustomsApi extends MchApi {
|
||||
|
||||
public CustomsApi(WeixinPayAccount weixinAccount) {
|
||||
|
||||
@ -27,7 +27,9 @@ import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
* @date 2016年3月26日
|
||||
* @since JDK 1.6
|
||||
* @see <a href="https://pay.weixin.qq.com/wiki/doc/api/index.html">商户支付平台</a>
|
||||
* @deprecated 商户平台API迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public class MchApi extends BaseApi {
|
||||
|
||||
private final static ResourceBundle WEIXIN_BUNDLE;
|
||||
|
||||
@ -60,7 +60,9 @@ import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @date 2014年10月28日
|
||||
* @since JDK 1.6
|
||||
* @deprecated 商户平台API迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public class PayApi extends MchApi {
|
||||
|
||||
public PayApi(WeixinPayAccount weixinAccount) {
|
||||
|
||||
@ -39,6 +39,7 @@ import com.foxinmy.weixin4j.logging.InternalLogLevel;
|
||||
import com.foxinmy.weixin4j.logging.InternalLogger;
|
||||
import com.foxinmy.weixin4j.logging.InternalLoggerFactory;
|
||||
import com.foxinmy.weixin4j.util.Consts;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import static java.util.regex.Pattern.CASE_INSENSITIVE;
|
||||
|
||||
@ -218,11 +219,14 @@ public class WeixinRequestExecutor {
|
||||
try {
|
||||
XmlResult xmlResult = XmlMessageConverter.GLOBAL.convert(
|
||||
XmlResult.class, response);
|
||||
// 微信最新的刷脸支付API中已没有返回resultCode,需做非空判断,否则抛异常
|
||||
if(StringUtil.isNotBlank(xmlResult.getResultCode())) {
|
||||
if (!SUCCESS_CODE.contains(String.format(",%s,", xmlResult
|
||||
.getResultCode().toLowerCase()))) {
|
||||
throw new WeixinException(xmlResult.getErrCode(),
|
||||
xmlResult.getErrCodeDes());
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
;
|
||||
}
|
||||
|
||||
@ -16,6 +16,10 @@
|
||||
package com.foxinmy.weixin4j.logging;
|
||||
|
||||
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
|
||||
import java.util.logging.ConsoleHandler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
@ -27,6 +31,15 @@ public class JdkLoggerFactory extends InternalLoggerFactory {
|
||||
|
||||
@Override
|
||||
public InternalLogger newInstance(String name) {
|
||||
return new JdkLogger(Logger.getLogger(name));
|
||||
Logger logger = Logger.getLogger(name);
|
||||
Level level = Weixin4jConfigUtil.getJdkLoggerLevel();
|
||||
logger.setLevel(level);
|
||||
if(logger.getHandlers().length==0) {
|
||||
ConsoleHandler consoleHandler = new ConsoleHandler();
|
||||
consoleHandler.setLevel(level);
|
||||
logger.addHandler(consoleHandler);
|
||||
}
|
||||
|
||||
return new JdkLogger(logger);
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,7 +12,9 @@ import com.foxinmy.weixin4j.util.StringUtil;
|
||||
* @date 2015年6月26日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 支付相关的类现已迁移到weixin4j-pay子模块
|
||||
*/
|
||||
@Deprecated
|
||||
public class WeixinPayAccount extends WeixinAccount {
|
||||
|
||||
private static final long serialVersionUID = -2791256176906048632L;
|
||||
|
||||
@ -15,7 +15,9 @@ import com.alibaba.fastjson.annotation.JSONField;
|
||||
* @date 2014年8月19日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class JsPayNotify extends PayBaseInfo {
|
||||
|
||||
@ -19,7 +19,9 @@ import com.foxinmy.weixin4j.type.SignType;
|
||||
* @date 2014年11月5日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class PayBaseInfo implements Serializable {
|
||||
|
||||
@ -18,7 +18,9 @@ import com.foxinmy.weixin4j.util.DateUtil;
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @date 2014年12月18日
|
||||
* @since JDK 1.6
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class PayPackage extends MerchantResult {
|
||||
|
||||
@ -10,6 +10,7 @@ import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.util.DateUtil;
|
||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class PayRequest extends PayBaseInfo {
|
||||
|
||||
@ -56,7 +56,9 @@ import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
* @date 2015年1月3日
|
||||
* @since JDK 1.6
|
||||
* @see <a href="http://pay.weixin.qq.com/wiki/doc/api/index.html">商户平台支付API</a>
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public class WeixinPayProxy {
|
||||
|
||||
/**
|
||||
|
||||
@ -22,7 +22,9 @@ import com.foxinmy.weixin4j.util.DateUtil;
|
||||
* @date 2015年3月27日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class CouponDetail extends MerchantResult {
|
||||
|
||||
@ -16,7 +16,9 @@ import com.foxinmy.weixin4j.payment.mch.MerchantResult;
|
||||
* @date 2015年3月25日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class CouponResult extends MerchantResult {
|
||||
|
||||
@ -21,7 +21,9 @@ import com.foxinmy.weixin4j.util.DateUtil;
|
||||
* @date 2015年3月27日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class CouponStock extends MerchantResult {
|
||||
|
||||
@ -18,7 +18,9 @@ import com.foxinmy.weixin4j.type.mch.CouponType;
|
||||
* @date 2015年3月24日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class OrderCouponInfo implements Serializable {
|
||||
|
||||
@ -17,7 +17,9 @@ import com.alibaba.fastjson.annotation.JSONField;
|
||||
* @date 2015年3月24日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class RefundCouponInfo implements Serializable {
|
||||
|
||||
@ -21,7 +21,9 @@ import com.foxinmy.weixin4j.util.MapUtil;
|
||||
* @see com.foxinmy.weixin4j.payment.PayRequest
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_1">APP支付</a>
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public class APPPayRequest extends AbstractPayRequest {
|
||||
public APPPayRequest(String prePayId, WeixinPayAccount payAccount) {
|
||||
super(prePayId, payAccount);
|
||||
|
||||
@ -4,6 +4,7 @@ import com.foxinmy.weixin4j.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.sign.WeixinPaymentSignature;
|
||||
import com.foxinmy.weixin4j.sign.WeixinSignature;
|
||||
|
||||
@Deprecated
|
||||
public abstract class AbstractPayRequest implements MchPayRequest {
|
||||
|
||||
private final String prePayId;
|
||||
|
||||
@ -17,7 +17,9 @@ import com.foxinmy.weixin4j.util.DateUtil;
|
||||
* @date 2015年4月1日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class CorpPayment extends MerchantResult {
|
||||
|
||||
@ -19,7 +19,9 @@ import com.foxinmy.weixin4j.util.DateUtil;
|
||||
* @date 2015年6月23日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class CorpPaymentRecord extends MerchantResult {
|
||||
|
||||
@ -18,7 +18,9 @@ import com.foxinmy.weixin4j.util.DateUtil;
|
||||
* @date 2015年4月1日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class CorpPaymentResult extends MerchantResult {
|
||||
|
||||
@ -15,7 +15,9 @@ import com.foxinmy.weixin4j.type.CustomsCity;
|
||||
* @date 2016年3月27日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public class CustomsOrder extends MerchantResult {
|
||||
|
||||
private static final long serialVersionUID = 799510373861612386L;
|
||||
|
||||
@ -15,7 +15,9 @@ import com.foxinmy.weixin4j.xml.ListsuffixResult;
|
||||
* @date 2016年3月27日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public class CustomsOrderRecord extends MerchantResult {
|
||||
|
||||
private static final long serialVersionUID = -1675090110657154049L;
|
||||
|
||||
@ -16,7 +16,9 @@ import com.foxinmy.weixin4j.util.DateUtil;
|
||||
* @date 2016年3月27日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public class CustomsOrderResult extends MerchantResult {
|
||||
|
||||
private static final long serialVersionUID = 799510373861612386L;
|
||||
|
||||
@ -22,7 +22,9 @@ import com.foxinmy.weixin4j.type.TradeType;
|
||||
* @see com.foxinmy.weixin4j.payment.PayRequest
|
||||
* @see <a
|
||||
* href="https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1">网页端调起支付API</a>
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public class JSAPIPayRequest extends AbstractPayRequest {
|
||||
|
||||
public JSAPIPayRequest(String prePayId, WeixinPayAccount payAccount) {
|
||||
|
||||
@ -18,7 +18,9 @@ import com.foxinmy.weixin4j.type.TradeType;
|
||||
* @see com.foxinmy.weixin4j.payment.PayRequest
|
||||
* @see <a
|
||||
* href="https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=5_1">刷卡支付</a>
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public class MICROPayRequest extends Order implements MchPayRequest {
|
||||
|
||||
private static final long serialVersionUID = 6147576305404111278L;
|
||||
|
||||
@ -20,7 +20,9 @@ import com.foxinmy.weixin4j.type.TradeType;
|
||||
* @date 2014年10月21日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class MchPayPackage extends PayPackage {
|
||||
|
||||
@ -16,7 +16,9 @@ import com.foxinmy.weixin4j.type.TradeType;
|
||||
* @see MICROPayRequest 刷卡支付
|
||||
* @see APPPayRequest APP支付
|
||||
* @see WAPPayRequest WAP支付
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public interface MchPayRequest {
|
||||
/**
|
||||
* 预支付交易ID
|
||||
|
||||
@ -17,7 +17,9 @@ import com.foxinmy.weixin4j.type.SignType;
|
||||
* @date 2014年10月21日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class MerchantResult extends XmlResult {
|
||||
|
||||
@ -13,7 +13,9 @@ import com.foxinmy.weixin4j.type.CurrencyType;
|
||||
* @date 2016年7月21日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public class MerchantTradeResult extends MerchantResult {
|
||||
|
||||
private static final long serialVersionUID = 4205906286092873877L;
|
||||
|
||||
@ -15,7 +15,9 @@ import com.foxinmy.weixin4j.type.TradeType;
|
||||
* @see com.foxinmy.weixin4j.payment.PayRequest
|
||||
* @see <a
|
||||
* href="https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1">NATIVE扫码支付(模式二)</a>
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public class NATIVEPayRequest extends AbstractPayRequest {
|
||||
|
||||
private final String codeUrl;
|
||||
|
||||
@ -15,7 +15,9 @@ import com.alibaba.fastjson.annotation.JSONField;
|
||||
* @date 2014年10月30日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class NativePayNotify extends OpenIdResult {
|
||||
|
||||
@ -19,7 +19,9 @@ import com.foxinmy.weixin4j.util.RandomUtil;
|
||||
* @date 2014年10月28日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class NativePayResponse extends MerchantResult {
|
||||
|
||||
@ -15,7 +15,9 @@ import com.alibaba.fastjson.annotation.JSONField;
|
||||
* @date 2015年7月23日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class OpenIdResult extends MerchantResult {
|
||||
|
||||
@ -25,7 +25,9 @@ import com.foxinmy.weixin4j.xml.ListsuffixResult;
|
||||
* @date 2014年11月2日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class Order extends MerchantTradeResult {
|
||||
|
||||
@ -16,7 +16,9 @@ import com.foxinmy.weixin4j.type.TradeType;
|
||||
* @date 2014年10月21日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class PrePay extends MerchantResult {
|
||||
|
||||
@ -20,7 +20,9 @@ import com.foxinmy.weixin4j.util.DateUtil;
|
||||
* href="https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_1">普通红包</a>
|
||||
* @see <a
|
||||
* href="https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=16_1">裂变红包</a>
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class Redpacket extends MerchantResult {
|
||||
|
||||
@ -25,7 +25,9 @@ import com.foxinmy.weixin4j.util.DateUtil;
|
||||
* @date 2015年6月4日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class RedpacketRecord extends XmlResult {
|
||||
|
||||
@ -17,7 +17,9 @@ import com.foxinmy.weixin4j.util.MapUtil;
|
||||
* @date 2017年1月4日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public class RedpacketRisk {
|
||||
private Map<String, String> risk;
|
||||
|
||||
|
||||
@ -18,7 +18,9 @@ import com.foxinmy.weixin4j.util.DateUtil;
|
||||
* @date 2015年4月1日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class RedpacketSendResult extends MerchantResult {
|
||||
|
||||
@ -24,7 +24,9 @@ import com.foxinmy.weixin4j.xml.ListsuffixResult;
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @date 2016年7月21日
|
||||
* @since JDK 1.6
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class RefundDetail implements Serializable {
|
||||
|
||||
@ -17,7 +17,9 @@ import com.foxinmy.weixin4j.xml.ListsuffixResult;
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @date 2014年11月1日
|
||||
* @since JDK 1.6
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class RefundRecord extends MerchantTradeResult {
|
||||
|
||||
@ -19,7 +19,9 @@ import com.foxinmy.weixin4j.xml.ListsuffixResult;
|
||||
* @date 2014年11月6日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class RefundResult extends MerchantTradeResult {
|
||||
|
||||
@ -4,6 +4,7 @@ import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class SceneInfoApp {
|
||||
|
||||
@ -7,6 +7,7 @@ import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
|
||||
@Deprecated
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class SceneInfoStore {
|
||||
|
||||
@ -17,6 +17,7 @@ import com.foxinmy.weixin4j.util.DateUtil;
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
@Deprecated
|
||||
public class SettlementRecord extends MerchantResult {
|
||||
|
||||
private static final long serialVersionUID = 7952659545609519979L;
|
||||
|
||||
@ -16,6 +16,7 @@ import com.foxinmy.weixin4j.type.TradeType;
|
||||
* @see <a
|
||||
* href="https://pay.weixin.qq.com/wiki/doc/api/wap.php?chapter=15_1">WAP支付</a>
|
||||
*/
|
||||
@Deprecated
|
||||
public class WAPPayRequest extends AbstractPayRequest {
|
||||
/**
|
||||
* 微信支付URL
|
||||
|
||||
@ -10,7 +10,9 @@ import com.foxinmy.weixin4j.util.MapUtil;
|
||||
* @date 2016年3月26日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class AbstractWeixinSignature implements WeixinSignature {
|
||||
/**
|
||||
* 是否编码
|
||||
|
||||
@ -12,7 +12,9 @@ import com.foxinmy.weixin4j.util.DigestUtil;
|
||||
* @since JDK 1.6
|
||||
* @see <a
|
||||
* href="https://pay.weixin.qq.com/wiki/doc/api/external/jsapi.php?chapter=4_3">支付签名说明</a>
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public class WeixinPaymentSignature extends AbstractWeixinSignature {
|
||||
/**
|
||||
* 支付密钥
|
||||
|
||||
@ -10,7 +10,9 @@ import com.foxinmy.weixin4j.type.SignType;
|
||||
* @date 2016年3月26日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public interface WeixinSignature {
|
||||
/**
|
||||
* 是否编码
|
||||
|
||||
@ -9,7 +9,9 @@ package com.foxinmy.weixin4j.type;
|
||||
* @date 2015年8月19日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public enum BankType {
|
||||
/**
|
||||
* 工商银行(借记卡)
|
||||
|
||||
@ -8,7 +8,9 @@ package com.foxinmy.weixin4j.type;
|
||||
* @date 2016年3月27日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public enum CredentialType {
|
||||
IDCARD("身份证");
|
||||
CredentialType(String name) {
|
||||
|
||||
@ -8,7 +8,9 @@ package com.foxinmy.weixin4j.type;
|
||||
* @date 2014年11月2日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public enum CurrencyType {
|
||||
CNY("人民币"), HKD("港元"), TWD("台币"), EUR("欧元"), USD("美元"), GBP("英镑"), JPY("日元"), CAD(
|
||||
"加拿大元"), AUD("澳大利亚元"), NZD("新西兰元"), KRW("韩元"), THB("泰铢");
|
||||
|
||||
@ -8,7 +8,9 @@ package com.foxinmy.weixin4j.type;
|
||||
* @date 2016年3月27日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public enum CustomsCity {
|
||||
NO("无需上报海关"), GUANGZHOU("广州"), HANGZHOU("杭州"), NINGBO("宁波"), ZHENGZHOU_BS(
|
||||
"郑州(保税物流中心)"), CHONGQING("重庆"), XIAN("西安"), SHANGHAI("上海"), ZHENGZHOU_ZH(
|
||||
|
||||
@ -8,7 +8,9 @@ package com.foxinmy.weixin4j.type;
|
||||
* @date 2016年3月27日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public enum CustomsSatus {
|
||||
UNDECLARED("未申报"), SUBMITTED("申报已提交"), PROCESSING("申报中"), SUCCESS("申报成功"), FAIL(
|
||||
"申报失败"), EXCEPT("海关接口异常");
|
||||
|
||||
@ -10,7 +10,9 @@ import java.io.Serializable;
|
||||
* @date 2014年11月1日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public class IdQuery implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -5273675987521807370L;
|
||||
|
||||
@ -8,7 +8,9 @@ package com.foxinmy.weixin4j.type;
|
||||
* @date 2014年11月1日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public enum IdType {
|
||||
/**
|
||||
* 微信退款单号
|
||||
|
||||
@ -8,7 +8,9 @@ package com.foxinmy.weixin4j.type;
|
||||
* @date 2014年11月5日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public enum SignType {
|
||||
SHA1, MD5, HMAC$SHA256
|
||||
}
|
||||
|
||||
@ -8,7 +8,9 @@ package com.foxinmy.weixin4j.type;
|
||||
* @date 2016年12月21日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public enum TarType {
|
||||
GZIP
|
||||
}
|
||||
|
||||
@ -8,7 +8,9 @@ package com.foxinmy.weixin4j.type;
|
||||
* @date 2014年11月2日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public enum TradeState {
|
||||
/**
|
||||
* 支付成功
|
||||
|
||||
@ -8,7 +8,9 @@ package com.foxinmy.weixin4j.type;
|
||||
* @date 2014年10月21日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到weixin4j-pay子模块
|
||||
*/
|
||||
@Deprecated
|
||||
public enum TradeType {
|
||||
/**
|
||||
* JS支付
|
||||
|
||||
@ -8,7 +8,9 @@ package com.foxinmy.weixin4j.type.mch;
|
||||
* @date 2014年10月31日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public enum BillType {
|
||||
/**
|
||||
* 全部
|
||||
|
||||
@ -8,7 +8,9 @@ package com.foxinmy.weixin4j.type.mch;
|
||||
* @date 2015年4月1日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public enum CorpPaymentCheckNameType {
|
||||
/**
|
||||
* 不校验真实姓名
|
||||
|
||||
@ -8,7 +8,9 @@ package com.foxinmy.weixin4j.type.mch;
|
||||
* @date 2015年3月27日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public enum CouponStatus {
|
||||
/**
|
||||
* 已激活
|
||||
|
||||
@ -8,7 +8,9 @@ package com.foxinmy.weixin4j.type.mch;
|
||||
* @date 2015年3月27日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public enum CouponStockStatus {
|
||||
/**
|
||||
* 未激活
|
||||
|
||||
@ -8,7 +8,9 @@ package com.foxinmy.weixin4j.type.mch;
|
||||
* @date 2015年3月27日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public enum CouponStockType {
|
||||
/**
|
||||
* 批量型
|
||||
|
||||
@ -8,7 +8,9 @@ package com.foxinmy.weixin4j.type.mch;
|
||||
* @date 2015年3月27日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public enum CouponType {
|
||||
/**
|
||||
* 使用无门槛
|
||||
|
||||
@ -7,7 +7,9 @@ package com.foxinmy.weixin4j.type.mch;
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @date 2017年1月4日
|
||||
* @since JDK 1.6
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public enum RedpacketSceneType {
|
||||
/**
|
||||
* 商品促销
|
||||
|
||||
@ -8,7 +8,9 @@ package com.foxinmy.weixin4j.type.mch;
|
||||
* @date 2015年6月4日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public enum RedpacketSendType {
|
||||
/**
|
||||
* 通过API接口发放
|
||||
|
||||
@ -7,7 +7,9 @@ package com.foxinmy.weixin4j.type.mch;
|
||||
* @date 2015年6月4日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public enum RedpacketStatus {
|
||||
/**
|
||||
* 发放中
|
||||
|
||||
@ -8,7 +8,9 @@ package com.foxinmy.weixin4j.type.mch;
|
||||
* @date 2015年6月4日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public enum RedpacketType {
|
||||
/**
|
||||
* 裂变红包
|
||||
|
||||
@ -5,7 +5,9 @@ package com.foxinmy.weixin4j.type.mch;
|
||||
* @className RefundAccountType
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @date 2016年12月12日
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public enum RefundAccountType {
|
||||
/**
|
||||
* ---未结算资金退款(默认使用未结算资金退款)
|
||||
|
||||
@ -8,7 +8,9 @@ package com.foxinmy.weixin4j.type.mch;
|
||||
* @date 2014年11月6日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public enum RefundChannel {
|
||||
/**
|
||||
* 原路退款
|
||||
|
||||
@ -8,7 +8,9 @@ package com.foxinmy.weixin4j.type.mch;
|
||||
* @date 2014年11月2日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public enum RefundStatus {
|
||||
/**
|
||||
* 退款成功
|
||||
|
||||
@ -8,7 +8,9 @@ package com.foxinmy.weixin4j.type.mch;
|
||||
* @date 2014年12月31日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @deprecated 迁移到子模块weixin4j-pay
|
||||
*/
|
||||
@Deprecated
|
||||
public enum RefundType {
|
||||
/**
|
||||
* 1:商户号余额退款;
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
package com.foxinmy.weixin4j.util;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
@ -57,4 +60,26 @@ public final class DigestUtil {
|
||||
byte[] data = StringUtil.getBytesUtf8(content);
|
||||
return HexUtil.encodeHexString(getDigest(Consts.MD5).digest(data));
|
||||
}
|
||||
|
||||
/**
|
||||
* HMAC-SHA256签名
|
||||
*
|
||||
* @param content
|
||||
* 待签名字符串
|
||||
* @param key
|
||||
* 支付密钥
|
||||
* @return
|
||||
* @throws InvalidKeyException
|
||||
*/
|
||||
public static String HMACSHA256(String content, String key) throws InvalidKeyException{
|
||||
try {
|
||||
Mac mac = Mac.getInstance("HmacSHA256");
|
||||
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(), "HmacSHA256");
|
||||
mac.init(secret_key);
|
||||
byte[] bytes = mac.doFinal(content.getBytes());
|
||||
return HexUtil.encodeHexString(bytes);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,8 +29,6 @@ public class MapUtil {
|
||||
* 是否编码
|
||||
* @param lowerCase
|
||||
* 是否转换小写
|
||||
* @param extra
|
||||
* 附加对象
|
||||
* @return
|
||||
*/
|
||||
public static String toJoinString(Object object, boolean encoder,
|
||||
|
||||
@ -2,6 +2,7 @@ package com.foxinmy.weixin4j.util;
|
||||
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
@ -112,4 +113,13 @@ public class Weixin4jConfigUtil {
|
||||
}
|
||||
return account;
|
||||
}
|
||||
|
||||
public static Level getJdkLoggerLevel(){
|
||||
try {
|
||||
Level level = Level.parse(getValue("jdkLogger.level", "OFF"));
|
||||
return level;
|
||||
}catch (IllegalArgumentException ex){
|
||||
return Level.OFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,59 +1,64 @@
|
||||
# \u5fae\u4fe1\u5546\u6237\u5e73\u53f0\u6587\u6863\u8bf4\u660e
|
||||
# \u5FAE\u4FE1\u5546\u6237\u5E73\u53F0\u6587\u6863\u8BF4\u660E
|
||||
# https://pay.weixin.qq.com/
|
||||
# https://pay.weixin.qq.com/wiki/doc/api/index.php
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
mch_base_url=https://api.mch.weixin.qq.com
|
||||
payapp_base_url=https://payapp.weixin.qq.com
|
||||
|
||||
# \u53d1\u9001\u73b0\u91d1\u7ea2\u5305
|
||||
# \u53D1\u9001\u73B0\u91D1\u7EA2\u5305
|
||||
redpack_send_uri={mch_base_url}/mmpaymkttransfers/sendredpack
|
||||
# \u53d1\u9001\u73b0\u91d1\u88c2\u53d8\u7ea2\u5305
|
||||
# \u53D1\u9001\u73B0\u91D1\u88C2\u53D8\u7EA2\u5305
|
||||
groupredpack_send_uri={mch_base_url}/mmpaymkttransfers/sendgroupredpack
|
||||
# \u67e5\u8be2\u73b0\u91d1\u7ea2\u5305
|
||||
# \u67E5\u8BE2\u73B0\u91D1\u7EA2\u5305
|
||||
redpack_query_uri={mch_base_url}/mmpaymkttransfers/gethbinfo
|
||||
# \u7edf\u4e00\u8ba2\u5355\u751f\u6210
|
||||
# \u7EDF\u4E00\u8BA2\u5355\u751F\u6210
|
||||
order_create_uri={mch_base_url}/pay/unifiedorder
|
||||
# \u88ab\u626b\u652f\u4ed8
|
||||
# \u88AB\u626B\u652F\u4ED8
|
||||
micropay_uri={mch_base_url}/pay/micropay
|
||||
# \u8ba2\u5355\u67e5\u8be2
|
||||
# \u8BA2\u5355\u67E5\u8BE2
|
||||
order_query_uri={mch_base_url}/pay/orderquery
|
||||
# \u5173\u95ed\u8ba2\u5355
|
||||
# \u5173\u95ED\u8BA2\u5355
|
||||
order_close_uri={mch_base_url}/pay/closeorder
|
||||
# \u5bf9\u8d26\u5355\u4e0b\u8f7d
|
||||
# \u5BF9\u8D26\u5355\u4E0B\u8F7D
|
||||
downloadbill_uri={mch_base_url}/pay/downloadbill
|
||||
# \u9000\u6b3e\u67e5\u8be2
|
||||
# \u9000\u6B3E\u67E5\u8BE2
|
||||
refund_query_uri={mch_base_url}/pay/refundquery
|
||||
# \u9000\u6b3e\u7533\u8bf7
|
||||
# \u9000\u6B3E\u7533\u8BF7
|
||||
refund_apply_uri={mch_base_url}/secapi/pay/refund
|
||||
# \u51b2\u6b63\u64a4\u9500
|
||||
# \u51B2\u6B63\u64A4\u9500
|
||||
order_reverse_uri={mch_base_url}/secapi/pay/reverse
|
||||
# \u957f\u94fe\u63a5\u8f6c\u6362
|
||||
# \u957F\u94FE\u63A5\u8F6C\u6362
|
||||
longurl_convert_uri={mch_base_url}/tools/shorturl
|
||||
# \u53d1\u653e\u4ee3\u91d1\u5238
|
||||
# \u53D1\u653E\u4EE3\u91D1\u5238
|
||||
coupon_send_uri={mch_base_url}/mmpaymkttransfers/send_coupon
|
||||
# \u67e5\u8be2\u4ee3\u91d1\u5238\u6279\u6b21\u4fe1\u606f
|
||||
# \u67E5\u8BE2\u4EE3\u91D1\u5238\u6279\u6B21\u4FE1\u606F
|
||||
couponstock_query_uri={mch_base_url}/mmpaymkttransfers/query_coupon_stock
|
||||
# \u67e5\u8be2\u4ee3\u91d1\u5238\u8be6\u7ec6\u4fe1\u606f
|
||||
# \u67E5\u8BE2\u4EE3\u91D1\u5238\u8BE6\u7EC6\u4FE1\u606F
|
||||
coupondetail_query_uri={mch_base_url}/mmpaymkttransfers/querycouponsinfo
|
||||
# \u53d1\u9001\u73b0\u91d1\u7ea2\u5305
|
||||
redpack_send_uri={mch_base_url}/mmpaymkttransfers/sendredpack
|
||||
# \u67e5\u8be2\u73b0\u91d1\u7ea2\u5305
|
||||
redpack_query_uri={mch_base_url}/mmpaymkttransfers/gethbinfo
|
||||
# \u4f01\u4e1a\u5411\u4e2a\u4eba\u4ed8\u6b3e
|
||||
# \u4F01\u4E1A\u5411\u4E2A\u4EBA\u4ED8\u6B3E
|
||||
corppayment_send_uri={mch_base_url}/mmpaymkttransfers/promotion/transfers
|
||||
# \u4f01\u4e1a\u4ed8\u6b3e\u67e5\u8be2
|
||||
# \u4F01\u4E1A\u4ED8\u6B3E\u67E5\u8BE2
|
||||
corppayment_query_uri={mch_base_url}/mmpaymkttransfers/gettransferinfo
|
||||
# \u63a5\u53e3\u4e0a\u62a5
|
||||
# \u63A5\u53E3\u4E0A\u62A5
|
||||
interface_report_uri={mch_base_url}/payitil/report
|
||||
# \u6388\u6743\u7801\u67e5\u8be2OPENID\u63a5\u53e3
|
||||
# \u6388\u6743\u7801\u67E5\u8BE2OPENID\u63A5\u53E3
|
||||
authcode_openid_uri={mch_base_url}/tools/authcodetoopenid
|
||||
# native\u652f\u4ed8url(\u6a21\u5f0f1)
|
||||
# native\u652F\u4ED8url(\u6A21\u5F0F1)
|
||||
native_pay_uri=weixin://wxpay/bizpayurl?sign=%s&appid=%s&mch_id=%s&product_id=%s&time_stamp=%s&nonce_str=%s
|
||||
# \u67e5\u8be2\u7ed3\u7b97\u8d44\u91d1
|
||||
# \u67E5\u8BE2\u7ED3\u7B97\u8D44\u91D1
|
||||
settlement_query_uri={mch_base_url}/pay/settlementquery
|
||||
# \u67e5\u8be2\u6c47\u7387
|
||||
# \u67E5\u8BE2\u6C47\u7387
|
||||
exchagerate_query_uri={mch_base_url}/pay/queryexchagerate
|
||||
# \u8ba2\u5355\u9644\u52a0\u4fe1\u606f\u63d0\u4ea4
|
||||
# \u8BA2\u5355\u9644\u52A0\u4FE1\u606F\u63D0\u4EA4
|
||||
customsorder_declare_uri={mch_base_url}/mch/customs/customdeclareorder
|
||||
# \u8ba2\u5355\u9644\u52a0\u4fe1\u606f\u67e5\u8be2
|
||||
# \u8BA2\u5355\u9644\u52A0\u4FE1\u606F\u67E5\u8BE2
|
||||
customsorder_query_uri={mch_base_url}/mch/customs/customdeclarequery
|
||||
# \u5237\u8138\u652F\u4ED8\u4EA4\u4E92\u6D41\u7A0B--\u83B7\u53D6\u8C03\u7528\u51ED\u8BC1
|
||||
get_wxpayface_authinfo_uri={payapp_base_url}/face/get_wxpayface_authinfo
|
||||
# \u65E7\u7248\u5237\u8138\u652F\u4ED8\u63A5\u53E3
|
||||
facepay_url={mch_base_url}/pay/facepay
|
||||
# \u652F\u4ED8\u62BC\u91D1\uFF08\u4EBA\u8138\uFF09
|
||||
deposit_facepay_uri={mch_base_url}/deposit/facepay
|
||||
# \u652F\u4ED8\u62BC\u91D1\uFF08\u4ED8\u6B3E\u7801\uFF09
|
||||
deposit_micropay_uri={mch_base_url}/deposit/micropay
|
||||
47
weixin4j-pay/pom.xml
Normal file
47
weixin4j-pay/pom.xml
Normal file
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>weixin4j</artifactId>
|
||||
<groupId>com.foxinmy</groupId>
|
||||
<version>1.9.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<name>weixin4j-pay</name>
|
||||
<artifactId>weixin4j-pay</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<url>https://github.com/foxinmy/weixin4j/tree/master/weixin4j-pay</url>
|
||||
<description>微信支付商户平台API</description>
|
||||
<developers>
|
||||
<developer>
|
||||
<id>kit-lee</id>
|
||||
<name>Kit lee</name>
|
||||
<email>ryuji.cn@gmail.com</email>
|
||||
<url>https://github.com/kit-lee</url>
|
||||
<properties>
|
||||
<contact>kit_21cn@21cn.com</contact>
|
||||
<forkRepo>https://github.com/kit-lee/weixin4j</forkRepo>
|
||||
</properties>
|
||||
</developer>
|
||||
</developers>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.foxinmy</groupId>
|
||||
<artifactId>weixin4j-base</artifactId>
|
||||
<version>1.9.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@ -0,0 +1,47 @@
|
||||
支付模块【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版本(商户平台)`支付**
|
||||
|
||||
|
||||
[WeixinPayProxy](WeixinPayProxy.java)
|
||||
-------------------------
|
||||
|
||||
* createPayJsRequestJson: 创建V3版本(商户平台)的JSAPI支付串
|
||||
|
||||
* createNativePayRequestURL: 创建V3版本(商户平台)的扫码支付链接
|
||||
|
||||
* createPrePay: 调用V3版本(商户平台)的统一订单接口生成预订单数据
|
||||
|
||||
* createMicroPay: 创建刷卡支付(商户平台)请求
|
||||
|
||||
* orderQuery: 订单查询接口
|
||||
|
||||
* refundOrder: 退款申请接口
|
||||
|
||||
* reverseOrder: 冲正订单接口
|
||||
|
||||
* closeOrder: 关闭订单接口
|
||||
|
||||
* downloadBill: 下载对账单接口
|
||||
|
||||
* refundQuery: 退款查询接口
|
||||
|
||||
|
||||
[Pay2Api](https://github.com/foxinmy/weixin4j/blob/master/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/Pay2Api.java)
|
||||
-------------------------
|
||||
|
||||
* createPayJsRequestJson: 创建V2版本的JSAPI支付串
|
||||
|
||||
* createNativePayRequestURL: 创建V2版本的扫码支付链接
|
||||
|
||||
* orderQuery: 订单查询接口
|
||||
|
||||
* refundOrder: 退款申请接口
|
||||
|
||||
* downloadBill: 下载对账单接口
|
||||
|
||||
* refundQuery: 退款查询接口
|
||||
@ -0,0 +1,890 @@
|
||||
package com.foxinmy.weixin4j.pay;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.foxinmy.weixin4j.pay.api.*;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.weixin.XmlResult;
|
||||
import com.foxinmy.weixin4j.pay.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.model.paging.Pageable;
|
||||
import com.foxinmy.weixin4j.pay.payment.coupon.*;
|
||||
import com.foxinmy.weixin4j.pay.payment.face.PayfaceAuthinfo;
|
||||
import com.foxinmy.weixin4j.pay.payment.face.PayfaceAuthinfoRequest;
|
||||
import com.foxinmy.weixin4j.pay.payment.mch.*;
|
||||
import com.foxinmy.weixin4j.pay.sign.WeixinSignature;
|
||||
import com.foxinmy.weixin4j.pay.type.*;
|
||||
import com.foxinmy.weixin4j.pay.type.mch.BillType;
|
||||
import com.foxinmy.weixin4j.pay.type.mch.RefundAccountType;
|
||||
import com.foxinmy.weixin4j.util.Consts;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
/**
|
||||
* 微信支付接口实现
|
||||
*
|
||||
* @className WeixinPayProxy
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @date 2015年1月3日
|
||||
* @since JDK 1.6
|
||||
* @see <a href="http://pay.weixin.qq.com/wiki/doc/api/index.html">商户平台支付API</a>
|
||||
*/
|
||||
public class WeixinPayProxy {
|
||||
|
||||
/**
|
||||
* 微信支付API:js支付、扫码支付等接口
|
||||
*/
|
||||
private final PayApi payApi;
|
||||
/**
|
||||
* 代金券API
|
||||
*/
|
||||
private final CouponApi couponApi;
|
||||
/**
|
||||
* 现金API
|
||||
*/
|
||||
private final CashApi cashApi;
|
||||
/**
|
||||
* 海关API
|
||||
*/
|
||||
private final CustomsApi customsApi;
|
||||
/**
|
||||
* 商户信息
|
||||
*/
|
||||
private final WeixinPayAccount weixinPayAccount;
|
||||
|
||||
/**
|
||||
* 微信支付接口实现(使用weixin4j.properties配置的account商户信息)
|
||||
*/
|
||||
public WeixinPayProxy() {
|
||||
this(JSON.parseObject(Weixin4jConfigUtil.getValue("account"),
|
||||
WeixinPayAccount.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信支付接口实现
|
||||
*
|
||||
* @param weixinPayAccount
|
||||
* 微信商户信息
|
||||
*/
|
||||
public WeixinPayProxy(WeixinPayAccount weixinPayAccount) {
|
||||
if (weixinPayAccount == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"weixinPayAccount must not be empty");
|
||||
}
|
||||
this.weixinPayAccount = weixinPayAccount;
|
||||
this.payApi = new PayApi(weixinPayAccount);
|
||||
this.couponApi = new CouponApi(weixinPayAccount);
|
||||
this.cashApi = new CashApi(weixinPayAccount);
|
||||
this.customsApi = new CustomsApi(weixinPayAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信商户账号信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public WeixinPayAccount getWeixinPayAccount() {
|
||||
return weixinPayAccount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信签名类
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public WeixinSignature getWeixinSignature() {
|
||||
return payApi.getWeixinSignature();
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一下单接口</br>
|
||||
* 除被扫支付场景以外,商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易回话标识后再按扫码、JSAPI
|
||||
* 、APP等不同场景生成交易串调起支付。
|
||||
*
|
||||
* @param payPackage
|
||||
* 包含订单信息的对象
|
||||
* @see PayApi
|
||||
* @see MchPayPackage
|
||||
* @see PrePay
|
||||
* @see <a href=
|
||||
* "http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1">统一下单接口
|
||||
* </a>
|
||||
* @return 预支付对象
|
||||
*/
|
||||
public PrePay createPrePay(MchPayPackage payPackage) throws WeixinException {
|
||||
return payApi.createPrePay(payPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建支付请求对象
|
||||
*
|
||||
* @param payPackage
|
||||
* 支付详情
|
||||
* @return 支付请求对象
|
||||
* @see PayApi
|
||||
* @see JSAPIPayRequest JS支付
|
||||
* @see NATIVEPayRequest 扫码支付
|
||||
* @see MICROPayRequest 刷卡支付
|
||||
* @see APPPayRequest APP支付
|
||||
* @see WAPPayRequest WAP支付
|
||||
* @see MchPayRequest#toRequestString()
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public MchPayRequest createPayRequest(MchPayPackage payPackage)
|
||||
throws WeixinException {
|
||||
return payApi.createPayRequest(payPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建JSAPI支付请求对象
|
||||
*
|
||||
* @param openId
|
||||
* 用户ID
|
||||
* @param body
|
||||
* 订单描述
|
||||
* @param outTradeNo
|
||||
* 订单号
|
||||
* @param totalFee
|
||||
* 订单总额(元)
|
||||
* @param notifyUrl
|
||||
* 支付通知地址
|
||||
* @param createIp
|
||||
* ip地址
|
||||
* @param attach
|
||||
* 附加数据 非必填
|
||||
* @see PayApi
|
||||
* @see JSAPIPayRequest
|
||||
* @see MchPayRequest#toRequestString()
|
||||
* @return JSAPI支付对象
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public MchPayRequest createJSPayRequest(String openId, String body,
|
||||
String outTradeNo, double totalFee, String notifyUrl,
|
||||
String createIp, String attach) throws WeixinException {
|
||||
return payApi.createJSPayRequest(openId, body, outTradeNo, totalFee,
|
||||
notifyUrl, createIp, attach);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Native支付(扫码支付)链接【模式一】
|
||||
*
|
||||
* @param productId
|
||||
* 与订单ID等价
|
||||
* @return 支付链接
|
||||
* @see PayApi
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1">扫码支付
|
||||
* </a>
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4">模式一
|
||||
* </a>
|
||||
*/
|
||||
public String createNativePayRequest(String productId) {
|
||||
return payApi.createNativePayRequest(productId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Native支付(扫码支付)回调对象【模式一】
|
||||
*
|
||||
* @param productId
|
||||
* 商品ID
|
||||
* @param body
|
||||
* 商品描述
|
||||
* @param outTradeNo
|
||||
* 商户内部唯一订单号
|
||||
* @param totalFee
|
||||
* 商品总额 单位元
|
||||
* @param notifyUrl
|
||||
* 支付回调URL
|
||||
* @param createIp
|
||||
* 订单生成的机器 IP
|
||||
* @param attach
|
||||
* 附加数据 非必填
|
||||
* @return Native回调对象
|
||||
* @see PayApi
|
||||
* @see NativePayResponse
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1">扫码支付
|
||||
* </a>
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4">模式一
|
||||
* </a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public NativePayResponse createNativePayResponse(String productId,
|
||||
String body, String outTradeNo, double totalFee, String notifyUrl,
|
||||
String createIp, String attach) throws WeixinException {
|
||||
return payApi.createNativePayResponse(productId, body, outTradeNo,
|
||||
totalFee, notifyUrl, createIp, attach);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Native支付(扫码支付)链接【模式二】
|
||||
*
|
||||
* @param productId
|
||||
* 商品ID
|
||||
* @param body
|
||||
* 商品描述
|
||||
* @param outTradeNo
|
||||
* 商户内部唯一订单号
|
||||
* @param totalFee
|
||||
* 商品总额 单位元
|
||||
* @param notifyUrl
|
||||
* 支付回调URL
|
||||
* @param createIp
|
||||
* 订单生成的机器 IP
|
||||
* @param attach
|
||||
* 附加数据 非必填
|
||||
* @return Native支付对象
|
||||
* @see PayApi
|
||||
* @see NATIVEPayRequest
|
||||
* @see MchPayRequest#toRequestString()
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1">扫码支付
|
||||
* </a>
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_5">模式二
|
||||
* </a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public MchPayRequest createNativePayRequest(String productId, String body,
|
||||
String outTradeNo, double totalFee, String notifyUrl,
|
||||
String createIp, String attach) throws WeixinException {
|
||||
return payApi.createNativePayRequest(productId, body, outTradeNo,
|
||||
totalFee, notifyUrl, createIp, attach);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建APP支付请求对象
|
||||
*
|
||||
* @param body
|
||||
* 商品描述
|
||||
* @param outTradeNo
|
||||
* 商户内部唯一订单号
|
||||
* @param totalFee
|
||||
* 商品总额 单位元
|
||||
* @param notifyUrl
|
||||
* 支付回调URL
|
||||
* @param createIp
|
||||
* 订单生成的机器 IP
|
||||
* @param attach
|
||||
* 附加数据 非必填
|
||||
* @param store
|
||||
* 门店信息 非必填
|
||||
* @return APP支付对象
|
||||
* @see PayApi
|
||||
* @see SceneInfoStore
|
||||
* @see APPPayRequest
|
||||
* @see MchPayRequest#toRequestString()
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_1">
|
||||
* APP支付</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public MchPayRequest createAppPayRequest(String body, String outTradeNo,
|
||||
double totalFee, String notifyUrl, String createIp, String attach,
|
||||
SceneInfoStore store) throws WeixinException {
|
||||
return payApi.createAppPayRequest(body, outTradeNo, totalFee,
|
||||
notifyUrl, createIp, attach, store);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建WAP支付请求对象
|
||||
*
|
||||
* @param body
|
||||
* 商品描述
|
||||
* @param outTradeNo
|
||||
* 商户内部唯一订单号
|
||||
* @param totalFee
|
||||
* 商品总额 单位元
|
||||
* @param notifyUrl
|
||||
* 支付回调URL
|
||||
* @param createIp
|
||||
* 订单生成的机器 IP
|
||||
* @param attach
|
||||
* 附加数据 非必填
|
||||
* @param app
|
||||
* 应用信息
|
||||
* @return WAP支付对象
|
||||
* @see PayApi
|
||||
* @see SceneInfoApp
|
||||
* @see WAPPayRequest
|
||||
* @see MchPayRequest#toRequestString()
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/wap.php?chapter=15_1">WAP支付
|
||||
* </a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public MchPayRequest createWapPayRequest(String body, String outTradeNo,
|
||||
double totalFee, String notifyUrl, String createIp, String attach,
|
||||
SceneInfoApp app) throws WeixinException {
|
||||
return payApi.createWapPayRequest(body, outTradeNo, totalFee,
|
||||
notifyUrl, createIp, attach, app);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交被扫支付
|
||||
*
|
||||
* @param authCode
|
||||
* 扫码支付授权码 ,设备读取用户微信中的条码或者二维码信息
|
||||
* @param body
|
||||
* 商品描述
|
||||
* @param outTradeNo
|
||||
* 商户内部唯一订单号
|
||||
* @param totalFee
|
||||
* 商品总额 单位元
|
||||
* @param createIp
|
||||
* 订单生成的机器 IP
|
||||
* @param attach
|
||||
* 附加数据 非必填
|
||||
* @param store
|
||||
* 门店信息 非必填
|
||||
* @return 支付的订单信息
|
||||
* @see PayApi
|
||||
* @see Order
|
||||
* @see SceneInfoStore
|
||||
* @see MICROPayRequest
|
||||
* @see MchPayRequest#toRequestString()
|
||||
* @see <a href=
|
||||
* "http://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_10">
|
||||
* 提交被扫支付API</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public MchPayRequest createMicroPayRequest(String authCode, String body,
|
||||
String outTradeNo, double totalFee, String createIp, String attach,
|
||||
SceneInfoStore store) throws WeixinException {
|
||||
return payApi.createMicroPayRequest(authCode, body, outTradeNo,
|
||||
totalFee, createIp, attach, store);
|
||||
}
|
||||
|
||||
/**
|
||||
* 旧版刷脸支付接口
|
||||
*
|
||||
* @param faceCode
|
||||
* 人脸凭证
|
||||
* @param body
|
||||
* 商品或支付单简要描述,格式要求:门店品牌名-城市分店名-实际商品名称
|
||||
* @param outTradeNo
|
||||
* 商户系统内部的订单号,32个字符内、可包含字母;更换授权码必须要换新的商户订单号
|
||||
* @param totalFee
|
||||
* 订单总金额,单位元
|
||||
* @param createIp
|
||||
* 调用微信支付API的机器IP
|
||||
* @param openId
|
||||
* 用户在商户appid 下的唯一标识
|
||||
* @param attach
|
||||
* 附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据
|
||||
* @return
|
||||
* @throws WeixinException
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/wxfacepay/develop/backend.html#刷脸支付后端接口">
|
||||
* 刷脸支付后端接口</a>
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/wxfacepay/develop/sdk-android.html#人脸支付凭证-getwxpayfacecode"
|
||||
* 获取人脸支付凭证</a>
|
||||
*/
|
||||
public MchPayRequest createFacePayRequest(String faceCode, String body,
|
||||
String outTradeNo, double totalFee, String createIp, String openId,
|
||||
String attach) throws WeixinException {
|
||||
return payApi.createFacePayRequest(faceCode, body, outTradeNo,
|
||||
totalFee, createIp, openId, attach);
|
||||
}
|
||||
|
||||
/**
|
||||
* 押金支付请求
|
||||
*
|
||||
* @param code
|
||||
* 授权码/人脸凭证
|
||||
* @param body
|
||||
* 商品或支付单简要描述,格式要求:门店品牌名-城市分店名-实际商品名称
|
||||
* @param outTradeNo
|
||||
* 商户系统内部的订单号,32个字符内、可包含字母;更换授权码必须要换新的商户订单号
|
||||
* @param totalFee
|
||||
* 订单总金额,单位元
|
||||
* @param createIp
|
||||
* 调用微信支付API的机器IP
|
||||
* @param openId
|
||||
* 用户在商户appid 下的唯一标识,人脸支付押金时提供
|
||||
* @param attach
|
||||
* 附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据,非必填
|
||||
* @param store
|
||||
* 门店信息,仅在付款码支付押金时提供,非必填
|
||||
* @param isFacePay
|
||||
* 是否人脸押金支付,否则是付款码押金支付
|
||||
* @return
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public MchPayRequest createDepositPayRequest(String code, String body,
|
||||
String outTradeNo, double totalFee, String createIp, String openId,
|
||||
String attach, SceneInfoStore store, boolean isFacePay) throws WeixinException{
|
||||
|
||||
return payApi.createDepositPayRequest(code, body, outTradeNo, totalFee, createIp, openId, attach, store, isFacePay);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单查询
|
||||
* <p>
|
||||
* 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;</br> 调用支付接口后,返回系统错误或未知交易状态情况;</br>
|
||||
* 调用被扫支付API,返回USERPAYING的状态;</br> 调用关单或撤销接口API之前,需确认支付状态;
|
||||
* </P>
|
||||
*
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id、out_trade_no 二 选一,如果同时存在优先级:
|
||||
* transaction_id> out_trade_no
|
||||
* @since V3
|
||||
* @see Order
|
||||
* @see PayApi
|
||||
* @see <a href=
|
||||
* "http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2">
|
||||
* 订单查询API</a>
|
||||
* @return 订单详情
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public Order queryOrder(IdQuery idQuery) throws WeixinException {
|
||||
return payApi.queryOrder(idQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请退款
|
||||
*
|
||||
* @see PayApi#applyRefund(IdQuery, String, double, double, CurrencyType, String, String, RefundAccountType)
|
||||
*/
|
||||
public RefundResult applyRefund(IdQuery idQuery, String outRefundNo,
|
||||
double totalFee, double refundFee, CurrencyType refundFeeType,
|
||||
String opUserId, String refundDesc,
|
||||
RefundAccountType refundAccountType) throws WeixinException {
|
||||
return payApi.applyRefund(idQuery, outRefundNo, totalFee, refundFee,
|
||||
refundFeeType, opUserId, refundDesc, refundAccountType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请退款
|
||||
*
|
||||
* @see PayApi#applyRefund(IdQuery, String, double)
|
||||
*/
|
||||
public RefundResult applyRefund(IdQuery idQuery, String outRefundNo,
|
||||
double totalFee) throws WeixinException {
|
||||
return payApi.applyRefund(idQuery, outRefundNo, totalFee);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款查询
|
||||
* <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 PayApi
|
||||
* @see 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 queryRefund(IdQuery idQuery) throws WeixinException {
|
||||
return payApi.queryRefund(idQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载对账单<br>
|
||||
* 1.微信侧未成功下单的交易不会出现在对账单中。支付成功后撤销的交易会出现在对账 单中,跟原支付单订单号一致,bill_type 为
|
||||
* REVOKED;<br>
|
||||
* 2.微信在次日 9 点启动生成前一天的对账单,建议商户 9 点半后再获取;<br>
|
||||
* 3.对账单中涉及金额的字段单位为“元”。<br>
|
||||
*
|
||||
* @param billDate
|
||||
* 下载对账单的日期
|
||||
* @param billType
|
||||
* 下载对账单的类型 ALL,返回当日所有订单信息, 默认值 SUCCESS,返回当日成功支付的订单
|
||||
* REFUND,返回当日退款订单
|
||||
* @para outputStream 输出流
|
||||
* @param tarType
|
||||
* 非必传参数,固定值:GZIP,返回格式为.gzip的压缩包账单。不传则默认为数据流形式。
|
||||
* @since V2 & V3
|
||||
* @see PayApi
|
||||
* @see <a href=
|
||||
* "http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_6">
|
||||
* 下载对账单API</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public void downloadBill(Date billDate, BillType billType,
|
||||
OutputStream outputStream, TarType tarType) throws WeixinException {
|
||||
payApi.downloadBill(billDate, billType, outputStream, tarType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 冲正订单(需要证书)</br> 当支付返回失败,或收银系统超时需要取消交易,可以调用该接口</br> 接口逻辑:支
|
||||
* 付失败的关单,支付成功的撤销支付</br> <font color="red">7天以内的单可撤销,其他正常支付的单
|
||||
* 如需实现相同功能请调用退款接口</font></br> <font
|
||||
* color="red">调用扣款接口后请勿立即调用撤销,需要等待5秒以上。先调用查单接口,如果没有确切的返回,再调用撤销</font> </br>
|
||||
*
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
|
||||
* transaction_id> out_trade_no
|
||||
* @return 撤销结果
|
||||
* @see PayApi
|
||||
* @since V3
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public MerchantResult reverseOrder(IdQuery idQuery) throws WeixinException {
|
||||
return payApi.reverseOrder(idQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭订单
|
||||
* <p>
|
||||
* 商户订单支付失败需要生成新单号重新发起支付,要对原订单号调用关单,避免重复支付;系统下单后,用户支付超时,系统退出不再受理,避免用户继续
|
||||
* ,请调用关单接口,如果关单失败,返回已完 成支付请按正常支付处理。如果出现银行掉单,调用关单成功后,微信后台会主动发起退款。
|
||||
* </p>
|
||||
*
|
||||
* @param outTradeNo
|
||||
* 商户系统内部的订单号
|
||||
* @return 执行结果
|
||||
* @see PayApi
|
||||
* @since V3
|
||||
* @throws WeixinException
|
||||
* @see <a href=
|
||||
* "http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_3">
|
||||
* 关闭订单API</a>
|
||||
*/
|
||||
public MerchantResult closeOrder(String outTradeNo) throws WeixinException {
|
||||
return payApi.closeOrder(outTradeNo);
|
||||
}
|
||||
|
||||
/**
|
||||
* native支付URL转短链接:用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX),减小二维码数据量
|
||||
* ,提升扫描速度和精确度。
|
||||
*
|
||||
* @param url
|
||||
* 具有native标识的支付URL
|
||||
* @return 转换后的短链接
|
||||
* @see PayApi
|
||||
* @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 payApi.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 PayApi
|
||||
* @see <a href=
|
||||
* "http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_8">
|
||||
* 接口测试上报API</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public XmlResult reportInterface(String interfaceUrl, int executeTime,
|
||||
String outTradeNo, String ip, Date time, XmlResult returnXml)
|
||||
throws WeixinException {
|
||||
return payApi.reportInterface(interfaceUrl, executeTime, outTradeNo,
|
||||
ip, time, returnXml);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发放代金券(需要证书)
|
||||
*
|
||||
* @param couponStockId
|
||||
* 代金券批次id
|
||||
* @param partnerTradeNo
|
||||
* 商户发放凭据号(格式:商户id+日期+流水号),商户侧需保持唯一性
|
||||
* @param openId
|
||||
* 用户的openid
|
||||
* @param opUserId
|
||||
* 操作员帐号, 默认为商户号 可在商户平台配置操作员对应的api权限 可为空
|
||||
* @return 发放结果
|
||||
* @see CouponApi
|
||||
* @see CouponResult
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/tools/sp_coupon.php?chapter=12_3">
|
||||
* 发放代金券接口</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public CouponResult sendCoupon(String couponStockId, String partnerTradeNo,
|
||||
String openId, String opUserId) throws WeixinException {
|
||||
return couponApi.sendCoupon(couponStockId, partnerTradeNo, openId,
|
||||
opUserId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询代金券批次
|
||||
*
|
||||
* @param couponStockId
|
||||
* 代金券批次ID
|
||||
* @return 代金券批次信息
|
||||
* @see CouponApi
|
||||
* @see CouponStock
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/tools/sp_coupon.php?chapter=12_4">
|
||||
* 查询代金券批次信息接口</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public CouponStock queryCouponStock(String couponStockId)
|
||||
throws WeixinException {
|
||||
return couponApi.queryCouponStock(couponStockId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询代金券详细
|
||||
*
|
||||
* @param openId
|
||||
* 用户ID
|
||||
* @param couponId
|
||||
* 代金券ID
|
||||
* @param stockId
|
||||
* 代金劵对应的批次号
|
||||
* @return 代金券详细信息
|
||||
* @see CouponApi
|
||||
* @see CouponDetail
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/tools/sp_coupon.php?chapter=12_5">
|
||||
* 查询代金券详细信息接口</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public CouponDetail queryCouponDetail(String openId, String couponId,
|
||||
String stockId) throws WeixinException {
|
||||
return couponApi.queryCouponDetail(openId, couponId, stockId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发放红包 企业向微信用户个人发现金红包
|
||||
*
|
||||
* @param redpacket
|
||||
* 红包信息
|
||||
* @return 发放结果
|
||||
* @see CashApi
|
||||
* @see Redpacket
|
||||
* @see RedpacketSendResult
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_5">
|
||||
* 发放现金红包接口</a>
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=16_5">
|
||||
* 发放裂变红包接口</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public RedpacketSendResult sendRedpack(Redpacket redpacket)
|
||||
throws WeixinException {
|
||||
return cashApi.sendRedpack(redpacket);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量发放红包 企业向微信用户个人发现金红包
|
||||
*
|
||||
* @param redpackets
|
||||
* 多个红包信息
|
||||
* @return 发放结果
|
||||
* @see CashApi
|
||||
* @see #sendRedpacks(Redpacket...)
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public List<Future<RedpacketSendResult>> sendRedpacks(
|
||||
Redpacket... redpackets) {
|
||||
return cashApi.sendRedpacks(redpackets);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询红包记录
|
||||
*
|
||||
* @param outTradeNo
|
||||
* 商户发放红包的商户订单号
|
||||
* @return 红包记录
|
||||
* @see CashApi
|
||||
* @see RedpacketRecord
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_7&index=6">
|
||||
* 查询现金红包接口</a>
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=16_6">
|
||||
* 查询裂变红包接口</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public RedpacketRecord queryRedpack(String outTradeNo)
|
||||
throws WeixinException {
|
||||
return cashApi.queryRedpack(outTradeNo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业付款
|
||||
*
|
||||
* @see CashApi#sendCorpPayment(CorpPayment)
|
||||
*/
|
||||
public CorpPaymentResult sendCorpPayment(CorpPayment payment)
|
||||
throws WeixinException {
|
||||
return cashApi.sendCorpPayment(payment);
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业付款查询 用于商户的企业付款操作进行结果查询,返回付款操作详细结果
|
||||
*
|
||||
* @param outTradeNo
|
||||
* 商户调用企业付款API时使用的商户订单号
|
||||
* @return 付款记录
|
||||
* @see CashApi
|
||||
* @see CorpPaymentRecord
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_3">
|
||||
* 企业付款查询接口</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public CorpPaymentRecord queryCorpPayment(String outTradeNo)
|
||||
throws WeixinException {
|
||||
return cashApi.queryCorpPayment(outTradeNo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 授权码查询OPENID
|
||||
*
|
||||
* @param authCode
|
||||
* 扫码支付授权码,设备读取用户微信中的条码或者二维码信息
|
||||
* @return 查询结果
|
||||
* @see CashApi
|
||||
* @see OpenIdResult
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_13&index=9">
|
||||
* 授权码查询OPENID</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public OpenIdResult authCode2openId(String authCode) throws WeixinException {
|
||||
return payApi.authCode2openId(authCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询结算资金
|
||||
*
|
||||
* @param status
|
||||
* 是否结算
|
||||
* @param pageable
|
||||
* 分页数据
|
||||
* @param start
|
||||
* 开始日期 查询未结算记录时,该字段可不传
|
||||
* @param end
|
||||
* 结束日期 查询未结算记录时,该字段可不传
|
||||
* @return 结算金额记录
|
||||
* @throws WeixinException
|
||||
* @see CashApi
|
||||
* @see SettlementRecord
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/external/micropay.php?chapter=9_14&index=7">
|
||||
* 查询结算资金接口</a>
|
||||
*/
|
||||
public SettlementRecord querySettlement(boolean status, Pageable pageable,
|
||||
Date start, Date end) throws WeixinException {
|
||||
return cashApi.querySettlement(status, pageable, start, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询汇率
|
||||
*
|
||||
* @param currencyType
|
||||
* 外币币种
|
||||
* @param date
|
||||
* 日期 不填则默认当天
|
||||
* @return 汇率对象
|
||||
* @throws WeixinException
|
||||
* @see CashApi
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/external/micropay.php?chapter=9_15&index=8">
|
||||
* 查询汇率接口</a>
|
||||
*/
|
||||
public double queryExchageRate(CurrencyType currencyType, Date date)
|
||||
throws WeixinException {
|
||||
return cashApi.queryExchageRate(currencyType, date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单附加信息提交
|
||||
*
|
||||
* @param customsOrder
|
||||
* 附加订单信息
|
||||
* @return 报关结果
|
||||
* @see CustomsApi
|
||||
* @see CustomsOrder
|
||||
* @see CustomsOrderResult
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/external/declarecustom.php?chapter=18_1">
|
||||
* 附加订单信息提交接口</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public CustomsOrderResult declareCustomsOrder(CustomsOrder customsOrder)
|
||||
throws WeixinException {
|
||||
return customsApi.declareCustomsOrder(customsOrder);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单附加信息查询
|
||||
*
|
||||
* @param idQuery
|
||||
* out_trade_no,transaction_id,sub_order_no,sub_order_id四选一
|
||||
* @param customsCity
|
||||
* 海关
|
||||
* @return 报关记录
|
||||
* @see CustomsOrderRecord
|
||||
* @see CustomsApi
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/external/declarecustom.php?chapter=18_1">
|
||||
* 附加订单信息查询接口</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public CustomsOrderRecord queryCustomsOrder(IdQuery idQuery,
|
||||
CustomsCity customsCity) throws WeixinException {
|
||||
return customsApi.queryCustomsOrder(idQuery, customsCity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信刷脸支付,获取调用凭证
|
||||
*
|
||||
* @param storeId
|
||||
* 门店编号, 由商户定义, 各门店唯一。
|
||||
* @param storeName
|
||||
* 门店名称,由商户定义。(可用于展示)
|
||||
* @param deviceId
|
||||
* 终端设备编号,由商户定义。
|
||||
* @param attach
|
||||
* 附加字段。字段格式使用Json, 非必填
|
||||
* @param rawdata
|
||||
* 初始化数据。由微信人脸SDK的接口返回。
|
||||
* @return SDK调用凭证
|
||||
* @throws WeixinException
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/wxfacepay/develop/sdk-android.html#获取数据-getwxpayfacerawdata">
|
||||
* 获取数据-getwxpayfacerawdata</a>
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/wxfacepay/develop/sdk-android.html#获取调用凭证-get-wxpayface-authinfo">
|
||||
* 获取调用凭证-get-wxpayface-authinfo</a>
|
||||
* @see PayfaceAuthinfo
|
||||
*/
|
||||
public PayfaceAuthinfo getWxPayfaceAuthinfo(String storeId, String storeName, String deviceId,
|
||||
String attach, String rawdata) throws WeixinException {
|
||||
PayfaceAuthinfoRequest request = new PayfaceAuthinfoRequest(this.weixinPayAccount, storeId, storeName, deviceId,
|
||||
attach, rawdata);
|
||||
return payApi.getWxPayfaceAuthinfo(request);
|
||||
}
|
||||
|
||||
public final static String VERSION = Consts.VERSION;
|
||||
}
|
||||
@ -0,0 +1,269 @@
|
||||
package com.foxinmy.weixin4j.pay.api;
|
||||
|
||||
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.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.pay.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.model.paging.Pageable;
|
||||
import com.foxinmy.weixin4j.pay.payment.mch.*;
|
||||
import com.foxinmy.weixin4j.pay.type.CurrencyType;
|
||||
import com.foxinmy.weixin4j.util.DateUtil;
|
||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
/**
|
||||
* 现金API
|
||||
*
|
||||
* @className CashApi
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @date 2015年3月28日
|
||||
* @since JDK 1.6
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_1">
|
||||
* 现金红包</a>
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_1">
|
||||
* 企业付款</a>
|
||||
*/
|
||||
public class CashApi extends MchApi {
|
||||
|
||||
public CashApi(WeixinPayAccount weixinAccount) {
|
||||
super(weixinAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发放红包 企业向微信用户个人发现金红包
|
||||
*
|
||||
* @param redpacket
|
||||
* 红包信息
|
||||
* @return 发放结果
|
||||
* @see Redpacket
|
||||
* @see RedpacketSendResult
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_5">
|
||||
* 发放现金红包接口</a>
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=16_5">
|
||||
* 发放裂变红包接口</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public RedpacketSendResult sendRedpack(Redpacket redpacket)
|
||||
throws WeixinException {
|
||||
String appId = redpacket.getAppId();
|
||||
super.declareMerchant(redpacket);
|
||||
final JSONObject obj = (JSONObject) JSON.toJSON(redpacket);
|
||||
if (StringUtil.isNotBlank(appId)) {
|
||||
obj.put("appid", appId);
|
||||
}
|
||||
obj.put("wxappid", obj.remove("appid"));
|
||||
final String redpack_uri = redpacket.getTotalNum() > 1 ? getRequestUri("groupredpack_send_uri")
|
||||
: getRequestUri("redpack_send_uri");
|
||||
obj.put("sign", weixinSignature.sign(obj));
|
||||
String param = XmlStream.map2xml(obj);
|
||||
WeixinResponse response = getWeixinSSLExecutor().post(redpack_uri,
|
||||
param);
|
||||
String text = response.getAsString()
|
||||
.replaceFirst("<wxappid>", "<appid>")
|
||||
.replaceFirst("</wxappid>", "</appid>");
|
||||
return XmlStream.fromXML(text, RedpacketSendResult.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量发放红包 企业向微信用户个人发现金红包
|
||||
*
|
||||
* 多个红包信息
|
||||
* @return 发放结果
|
||||
* @see #sendRedpacks(Redpacket...)
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public List<Future<RedpacketSendResult>> sendRedpacks(
|
||||
Redpacket... redpackets) {
|
||||
ExecutorService sendExecutor = Executors.newFixedThreadPool(Math.max(1,
|
||||
redpackets.length / 10)); // 十分之一?
|
||||
CompletionService<RedpacketSendResult> completion = new ExecutorCompletionService<RedpacketSendResult>(
|
||||
sendExecutor);
|
||||
List<Future<RedpacketSendResult>> callSendList = new ArrayList<Future<RedpacketSendResult>>(
|
||||
redpackets.length);
|
||||
for (final Redpacket redpacket : redpackets) {
|
||||
Future<RedpacketSendResult> futureSend = completion
|
||||
.submit(new Callable<RedpacketSendResult>() {
|
||||
@Override
|
||||
public RedpacketSendResult call() throws Exception {
|
||||
return sendRedpack(redpacket);
|
||||
}
|
||||
});
|
||||
callSendList.add(futureSend);
|
||||
}
|
||||
// 关闭启动线程,不再接受新的任务
|
||||
sendExecutor.shutdown();
|
||||
return callSendList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询红包记录
|
||||
*
|
||||
* @param outTradeNo
|
||||
* 商户发放红包的商户订单号
|
||||
* @return 红包记录
|
||||
* @see RedpacketRecord
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_7&index=6">
|
||||
* 查询现金红包接口</a>
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=16_6">
|
||||
* 查询裂变红包接口</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public RedpacketRecord queryRedpack(String outTradeNo)
|
||||
throws WeixinException {
|
||||
Map<String, String> para = createBaseRequestMap(null);
|
||||
para.put("bill_type", "MCHT");
|
||||
para.put("mch_billno", outTradeNo);
|
||||
para.put("sign", weixinSignature.sign(para));
|
||||
String param = XmlStream.map2xml(para);
|
||||
WeixinResponse response = getWeixinSSLExecutor().post(
|
||||
getRequestUri("redpack_query_uri"), param);
|
||||
return response.getAsObject(new TypeReference<RedpacketRecord>() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业付款为企业提供付款至用户零钱的能力
|
||||
*
|
||||
* @param payment 付款信息
|
||||
* @return 付款结果
|
||||
* @see CorpPayment
|
||||
* @see CorpPaymentResult
|
||||
* @see <a href="https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2">企业付款</a>
|
||||
* @see <a href="https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_1">场景介绍(使用条件、付款资金、付款规则等)</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public CorpPaymentResult sendCorpPayment(CorpPayment payment)
|
||||
throws WeixinException {
|
||||
super.declareMerchant(payment);
|
||||
JSONObject obj = (JSONObject) JSON.toJSON(payment);
|
||||
obj.put("mchid", obj.remove("mch_id"));
|
||||
obj.put("mch_appid", obj.remove("appid"));
|
||||
obj.put("sign", weixinSignature.sign(obj));
|
||||
String param = XmlStream.map2xml(obj);
|
||||
WeixinResponse response = getWeixinSSLExecutor().post(
|
||||
getRequestUri("corppayment_send_uri"), param);
|
||||
String text = response.getAsString()
|
||||
.replaceFirst("<mch_appid>", "<appid>")
|
||||
.replaceFirst("</mch_appid>", "</appid>")
|
||||
.replaceFirst("<mchid>", "<mch_id>")
|
||||
.replaceFirst("</mchid>", "</mch_id>");
|
||||
return XmlStream.fromXML(text, CorpPaymentResult.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业付款查询 用于商户的企业付款操作进行结果查询,返回付款操作详细结果
|
||||
*
|
||||
* @param outTradeNo
|
||||
* 商户调用企业付款API时使用的商户订单号
|
||||
* @return 付款记录
|
||||
* @see CorpPaymentRecord
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_3">
|
||||
* 企业付款查询接口</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public CorpPaymentRecord queryCorpPayment(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);
|
||||
obj.put("sign", weixinSignature.sign(obj));
|
||||
String param = XmlStream.map2xml(obj);
|
||||
WeixinResponse response = getWeixinSSLExecutor().post(
|
||||
getRequestUri("corppayment_query_uri"), param);
|
||||
return response.getAsObject(new TypeReference<CorpPaymentRecord>() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询结算资金
|
||||
*
|
||||
* @param status
|
||||
* 是否结算
|
||||
* @param pageable
|
||||
* 分页数据
|
||||
* @param start
|
||||
* 开始日期 查询未结算记录时,该字段可不传
|
||||
* @param end
|
||||
* 结束日期 查询未结算记录时,该字段可不传
|
||||
* @return 结算金额记录
|
||||
* @throws WeixinException
|
||||
* @see SettlementRecord
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/external/micropay.php?chapter=9_14&index=7">
|
||||
* 查询结算资金接口</a>
|
||||
*/
|
||||
public SettlementRecord querySettlement(boolean status, Pageable pageable,
|
||||
Date start, Date end) 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("usetag", status ? 1 : 2);
|
||||
obj.put("offset", pageable.getOffset());
|
||||
obj.put("limit", pageable.getPageSize());
|
||||
if (start != null) {
|
||||
obj.put("date_start", DateUtil.fortmat2yyyyMMdd(start));
|
||||
}
|
||||
if (end != null) {
|
||||
obj.put("date_end", DateUtil.fortmat2yyyyMMdd(end));
|
||||
}
|
||||
obj.put("sign", weixinSignature.sign(obj));
|
||||
String param = XmlStream.map2xml(obj);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
getRequestUri("settlement_query_uri"), param);
|
||||
return response.getAsObject(new TypeReference<SettlementRecord>() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询汇率
|
||||
*
|
||||
* @param currencyType
|
||||
* 外币币种
|
||||
* @param date
|
||||
* 日期 不填则默认当天
|
||||
* @return 汇率 例如美元兑换人民币的比例为6.5
|
||||
* @throws WeixinException
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/external/micropay.php?chapter=9_15&index=8">
|
||||
* 查询汇率接口</a>
|
||||
*/
|
||||
public double queryExchageRate(CurrencyType currencyType, Date date)
|
||||
throws WeixinException {
|
||||
if (date == null) {
|
||||
date = new Date();
|
||||
}
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("mch_id", weixinAccount.getMchId());
|
||||
obj.put("appid", weixinAccount.getId());
|
||||
obj.put("sub_mch_id", weixinAccount.getSubMchId());
|
||||
obj.put("fee_type", currencyType.name());
|
||||
obj.put("date", DateUtil.fortmat2yyyyMMdd(date));
|
||||
obj.put("sign", weixinSignature.sign(obj));
|
||||
String param = XmlStream.map2xml(obj);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
getRequestUri("exchagerate_query_uri"), param);
|
||||
BigDecimal rate = new BigDecimal(XmlStream.xml2map(
|
||||
response.getAsString()).get("rate"));
|
||||
return rate.divide(new BigDecimal(100000000d)).doubleValue();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,122 @@
|
||||
package com.foxinmy.weixin4j.pay.api;
|
||||
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.pay.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.pay.payment.coupon.CouponDetail;
|
||||
import com.foxinmy.weixin4j.pay.payment.coupon.CouponResult;
|
||||
import com.foxinmy.weixin4j.pay.payment.coupon.CouponStock;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 代金券API
|
||||
*
|
||||
* @className CouponApi
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @date 2015年3月25日
|
||||
* @since JDK 1.6
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/tools/sp_coupon.php?chapter=12_1">代金券</a>
|
||||
*/
|
||||
public class CouponApi extends MchApi {
|
||||
|
||||
public CouponApi(WeixinPayAccount weixinAccount) {
|
||||
super(weixinAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发放代金券(需要证书)
|
||||
*
|
||||
* @param couponStockId
|
||||
* 代金券批次id
|
||||
* @param partnerTradeNo
|
||||
* 商户发放凭据号(格式:商户id+日期+流水号),商户侧需保持唯一性
|
||||
* @param openId
|
||||
* 用户的openid
|
||||
* @param opUserId
|
||||
* 操作员帐号, 默认为商户号 可在商户平台配置操作员对应的api权限 可为空
|
||||
* @return 发放结果
|
||||
* @see CouponResult
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/tools/sp_coupon.php?chapter=12_3">发放代金券接口</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public CouponResult sendCoupon(String couponStockId, String partnerTradeNo,
|
||||
String openId, String opUserId) throws WeixinException {
|
||||
Map<String, String> map = createBaseRequestMap(null);
|
||||
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");
|
||||
map.put("sign", weixinSignature.sign(map));
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = getWeixinSSLExecutor().post(
|
||||
getRequestUri("coupon_send_uri"), param);
|
||||
return response.getAsObject(new TypeReference<CouponResult>() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询代金券批次
|
||||
*
|
||||
* @param couponStockId
|
||||
* 代金券批次ID
|
||||
* @return 代金券批次信息
|
||||
* @see CouponStock
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/tools/sp_coupon.php?chapter=12_4">查询代金券批次信息接口</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public CouponStock queryCouponStock(String couponStockId)
|
||||
throws WeixinException {
|
||||
Map<String, String> map = createBaseRequestMap(null);
|
||||
map.put("coupon_stock_id", couponStockId);
|
||||
map.put("sign", weixinSignature.sign(map));
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
getRequestUri("couponstock_query_uri"), param);
|
||||
return response.getAsObject(new TypeReference<CouponStock>() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询代金券详细
|
||||
*
|
||||
* @param openId
|
||||
* 用户ID
|
||||
* @param couponId
|
||||
* 代金券ID
|
||||
* @param stockId
|
||||
* 代金劵对应的批次号
|
||||
* @return 代金券详细信息
|
||||
* @see CouponDetail
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/tools/sp_coupon.php?chapter=12_5">查询代金券详细信息接口</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public CouponDetail queryCouponDetail(String openId, String couponId,
|
||||
String stockId) throws WeixinException {
|
||||
Map<String, String> map = createBaseRequestMap(null);
|
||||
map.put("openid", openId);
|
||||
map.put("coupon_id", couponId);
|
||||
map.put("stock_id", stockId);
|
||||
map.put("sign", weixinSignature.sign(map));
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
getRequestUri("coupondetail_query_uri"), param);
|
||||
return response.getAsObject(new TypeReference<CouponDetail>() {
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,84 @@
|
||||
package com.foxinmy.weixin4j.pay.api;
|
||||
|
||||
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.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.pay.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.pay.payment.mch.CustomsOrder;
|
||||
import com.foxinmy.weixin4j.pay.payment.mch.CustomsOrderRecord;
|
||||
import com.foxinmy.weixin4j.pay.payment.mch.CustomsOrderResult;
|
||||
import com.foxinmy.weixin4j.pay.type.CustomsCity;
|
||||
import com.foxinmy.weixin4j.pay.type.IdQuery;
|
||||
import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer;
|
||||
import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
|
||||
/**
|
||||
* 报关接口
|
||||
*
|
||||
* @className CustomsApi
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @date 2016年3月67日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
public class CustomsApi extends MchApi {
|
||||
|
||||
public CustomsApi(WeixinPayAccount weixinAccount) {
|
||||
super(weixinAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单附加信息提交
|
||||
*
|
||||
* @param customsOrder
|
||||
* 附加订单信息
|
||||
* @return 报关结果
|
||||
* @see CustomsOrder
|
||||
* @see CustomsOrderResult
|
||||
* @see <a
|
||||
* href="https://pay.weixin.qq.com/wiki/doc/api/external/declarecustom.php?chapter=18_1">附加订单信息提交接口</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public CustomsOrderResult declareCustomsOrder(CustomsOrder customsOrder)
|
||||
throws WeixinException {
|
||||
JSONObject para = (JSONObject) JSON.toJSON(customsOrder);
|
||||
para.put("appid", weixinAccount.getId());
|
||||
para.put("mch_id", weixinAccount.getMchId());
|
||||
para.put("sign", weixinSignature.sign(para));
|
||||
String param = XmlStream.map2xml(para);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
getRequestUri("customsorder_declare_uri"), param);
|
||||
return response.getAsObject(new TypeReference<CustomsOrderResult>() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单附加信息查询
|
||||
*
|
||||
* @param idQuery
|
||||
* out_trade_no,transaction_id,sub_order_no,sub_order_id四选一
|
||||
* @param customsCity
|
||||
* 海关
|
||||
* @return 报关记录
|
||||
* @see CustomsOrderRecord
|
||||
* @see <a
|
||||
* href="https://pay.weixin.qq.com/wiki/doc/api/external/declarecustom.php?chapter=18_1">附加订单信息查询接口</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public CustomsOrderRecord queryCustomsOrder(IdQuery idQuery,
|
||||
CustomsCity customsCity) throws WeixinException {
|
||||
JSONObject para = new JSONObject();
|
||||
para.put("appid", weixinAccount.getId());
|
||||
para.put("mch_id", weixinAccount.getMchId());
|
||||
para.put(idQuery.getType().getName(), idQuery.getId());
|
||||
para.put("customs", customsCity.name());
|
||||
para.put("sign", weixinSignature.sign(para));
|
||||
String param = XmlStream.map2xml(para);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
getRequestUri("customsorder_query_uri"), param);
|
||||
return ListsuffixResultDeserializer.deserialize(response.getAsString(),
|
||||
CustomsOrderRecord.class);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,138 @@
|
||||
package com.foxinmy.weixin4j.pay.api;
|
||||
|
||||
import com.foxinmy.weixin4j.api.BaseApi;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinRequestExecutor;
|
||||
import com.foxinmy.weixin4j.pay.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.pay.payment.mch.MerchantResult;
|
||||
import com.foxinmy.weixin4j.pay.sign.WeixinPaymentSignature;
|
||||
import com.foxinmy.weixin4j.pay.type.IdQuery;
|
||||
import com.foxinmy.weixin4j.pay.sign.WeixinSignature;
|
||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
|
||||
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 java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* 商户支付
|
||||
*
|
||||
* @className MchApi
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @date 2016年3月26日
|
||||
* @since JDK 1.6
|
||||
* @see <a href="https://pay.weixin.qq.com/wiki/doc/api/index.html">商户支付平台</a>
|
||||
*/
|
||||
public class MchApi extends BaseApi {
|
||||
private final static ResourceBundle WEIXIN_BUNDLE;
|
||||
|
||||
private final static String PEM_CERT_PREFIX = "-----BEGIN CERTIFICATE-----";
|
||||
|
||||
static {
|
||||
WEIXIN_BUNDLE = ResourceBundle.getBundle("com/foxinmy/weixin4j/payment/weixin");
|
||||
}
|
||||
|
||||
protected final WeixinPayAccount weixinAccount;
|
||||
protected final WeixinSignature weixinSignature;
|
||||
private volatile WeixinRequestExecutor weixinSSLExecutor;
|
||||
|
||||
public MchApi(WeixinPayAccount weixinAccount) {
|
||||
this.weixinAccount = weixinAccount;
|
||||
this.weixinSignature = new WeixinPaymentSignature(weixinAccount.getPaySignKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceBundle weixinBundle() {
|
||||
return WEIXIN_BUNDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付接口请求基本数据
|
||||
*
|
||||
* @param idQuery
|
||||
* ID信息 可为空
|
||||
* @return 基础map
|
||||
*/
|
||||
protected Map<String, String> createBaseRequestMap(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 (StringUtil.isNotBlank(weixinAccount.getSubId())) {
|
||||
map.put("sub_appid", weixinAccount.getSubId());
|
||||
}
|
||||
if (StringUtil.isNotBlank(weixinAccount.getSubMchId())) {
|
||||
map.put("sub_mch_id", weixinAccount.getSubMchId());
|
||||
}
|
||||
if (idQuery != null) {
|
||||
map.put(idQuery.getType().getName(), idQuery.getId());
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信签名类
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public WeixinSignature getWeixinSignature() {
|
||||
return this.weixinSignature;
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信SSL
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected WeixinRequestExecutor getWeixinSSLExecutor() throws WeixinException {
|
||||
if (weixinSSLExecutor == null) {
|
||||
if(weixinAccount.getCertificateFile().startsWith(PEM_CERT_PREFIX)){
|
||||
// 证书是PEM格式,直接使用PEM内容生成请求执行类
|
||||
this.weixinSSLExecutor = weixinExecutor.createSSLRequestExecutor(weixinAccount.getMchId(),
|
||||
weixinAccount.getCertificateFile(), weixinAccount.getCertificateKey());
|
||||
}else {
|
||||
// 证书是p12格式,读取证书文件并生成请求执行类
|
||||
try {
|
||||
InputStream is = null;
|
||||
File certificate = new File(
|
||||
Weixin4jConfigUtil.replaceClassPathValue(weixinAccount.getCertificateFile()));
|
||||
if (!certificate.exists() || !certificate.isFile()) {
|
||||
is = Weixin4jConfigUtil.CLASSLOADER.getResourceAsStream(certificate.getName());
|
||||
} else {
|
||||
is = new FileInputStream(certificate);
|
||||
}
|
||||
if (is == null) {
|
||||
throw new WeixinException("Invalid certificate file : " + certificate.toString());
|
||||
}
|
||||
this.weixinSSLExecutor = weixinExecutor.createSSLRequestExecutor(weixinAccount.getCertificateKey(), is);
|
||||
} catch (IOException e) {
|
||||
throw new WeixinException("IO Error on createSSLRequestExecutor", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.weixinSSLExecutor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置商户信息
|
||||
*
|
||||
* @param merchant
|
||||
*/
|
||||
protected <T extends MerchantResult> void declareMerchant(T merchant) {
|
||||
merchant.setAppId(weixinAccount.getId());
|
||||
merchant.setMchId(weixinAccount.getMchId());
|
||||
merchant.setDeviceInfo(weixinAccount.getDeviceInfo());
|
||||
merchant.setSubAppId(weixinAccount.getSubId());
|
||||
merchant.setSubMchId(weixinAccount.getSubMchId());
|
||||
merchant.setNonceStr(RandomUtil.generateString(16));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,815 @@
|
||||
package com.foxinmy.weixin4j.pay.api;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.http.weixin.XmlResult;
|
||||
import com.foxinmy.weixin4j.pay.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.pay.payment.face.PayfaceAuthinfo;
|
||||
import com.foxinmy.weixin4j.pay.payment.face.PayfaceAuthinfoRequest;
|
||||
import com.foxinmy.weixin4j.pay.payment.mch.*;
|
||||
import com.foxinmy.weixin4j.pay.type.mch.BillType;
|
||||
import com.foxinmy.weixin4j.pay.type.mch.DepositType;
|
||||
import com.foxinmy.weixin4j.pay.type.mch.RefundAccountType;
|
||||
import com.foxinmy.weixin4j.pay.type.*;
|
||||
import com.foxinmy.weixin4j.util.*;
|
||||
import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer;
|
||||
import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 支付API
|
||||
*
|
||||
* @className PayApi
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @date 2014年10月28日
|
||||
* @since JDK 1.6
|
||||
*/
|
||||
public class PayApi extends MchApi {
|
||||
|
||||
public PayApi(WeixinPayAccount weixinAccount) {
|
||||
super(weixinAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一下单接口</br>
|
||||
* 除被扫支付场景以外,商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易回话标识后再按扫码、JSAPI
|
||||
* 、APP等不同场景生成交易串调起支付。
|
||||
*
|
||||
* @param payPackage
|
||||
* 包含订单信息的对象
|
||||
* @see MchPayPackage
|
||||
* @see PrePay
|
||||
* @see <a href=
|
||||
* "http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1">统一下单接口
|
||||
* </a>
|
||||
* @return 预支付对象
|
||||
*/
|
||||
public PrePay createPrePay(MchPayPackage payPackage) throws WeixinException {
|
||||
super.declareMerchant(payPackage);
|
||||
payPackage.setSign(weixinSignature.sign(payPackage));
|
||||
String payJsRequestXml = XmlStream.toXML(payPackage);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
getRequestUri("order_create_uri"), payJsRequestXml);
|
||||
return response.getAsObject(new TypeReference<PrePay>() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建支付请求对象
|
||||
*
|
||||
* @param payPackage
|
||||
* 支付详情
|
||||
* @return 支付请求对象
|
||||
* @see JSAPIPayRequest JS支付
|
||||
* @see NATIVEPayRequest 扫码支付
|
||||
* @see MICROPayRequest 刷卡支付
|
||||
* @see APPPayRequest APP支付
|
||||
* @see WAPPayRequest WAP支付
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public MchPayRequest createPayRequest(MchPayPackage payPackage)
|
||||
throws WeixinException {
|
||||
if (StringUtil.isBlank(payPackage.getTradeType())) {
|
||||
throw new WeixinException("tradeType not be empty");
|
||||
}
|
||||
String tradeType = payPackage.getTradeType().toUpperCase();
|
||||
if (TradeType.MICROPAY.name().equals(tradeType) || TradeType.FACEPAY.name().equals(tradeType)) {
|
||||
MchPayPackage _payPackage = new MchPayPackage(payPackage.getBody(),
|
||||
payPackage.getDetail(), payPackage.getOutTradeNo(),
|
||||
DateUtil.formatFee2Yuan(payPackage.getTotalFee()), null,
|
||||
null, payPackage.getCreateIp(), null, payPackage.getOpenId(),
|
||||
payPackage.getAuthCode(), null, payPackage.getAttach(),
|
||||
null, null, payPackage.getGoodsTag(),
|
||||
payPackage.getLimitPay(), payPackage.getSubAppId(), payPackage.getFaceCode(),
|
||||
payPackage.getDeposit());
|
||||
// 默认为MD5签名
|
||||
SignType signType= SignType.MD5;
|
||||
super.declareMerchant(_payPackage);
|
||||
// 默认为刷卡支付(付款码支付)的API地址
|
||||
String url = getRequestUri("micropay_uri");
|
||||
if(payPackage.getDeposit()==DepositType.Y){
|
||||
// 押金支付只支持HMAC-SHA256签名
|
||||
signType = SignType.HMAC$SHA256;
|
||||
_payPackage.setSignType("HMAC-SHA256");
|
||||
// 如果是押金支付,改为押金支付的API地址
|
||||
url = TradeType.MICROPAY.name().equals(tradeType) ? getRequestUri("deposit_micropay_uri") :
|
||||
getRequestUri("deposit_facepay_uri");
|
||||
}else if(TradeType.FACEPAY.name().equals(tradeType)){
|
||||
url = getRequestUri("facepay_url");
|
||||
}
|
||||
_payPackage.setSign(weixinSignature.sign(_payPackage, signType));
|
||||
String para = XmlStream.toXML(_payPackage);
|
||||
|
||||
WeixinResponse response = weixinExecutor.post(url, para);
|
||||
MICROPayRequest microPayRequest = response.getAsObject(new TypeReference<MICROPayRequest>() {});
|
||||
microPayRequest.setPaymentAccount(weixinAccount);
|
||||
return microPayRequest;
|
||||
}
|
||||
PrePay prePay = createPrePay(payPackage);
|
||||
if (TradeType.APP.name().equals(tradeType)) {
|
||||
return new APPPayRequest(prePay.getPrepayId(), weixinAccount);
|
||||
} else if (TradeType.JSAPI.name().equals(tradeType)) {
|
||||
return new JSAPIPayRequest(prePay.getPrepayId(), weixinAccount);
|
||||
} else if (TradeType.NATIVE.name().equals(tradeType)) {
|
||||
return new NATIVEPayRequest(prePay.getPrepayId(),
|
||||
prePay.getPayUrl(), weixinAccount);
|
||||
} else if (TradeType.MWEB.name().equals(tradeType)) {
|
||||
return new WAPPayRequest(prePay.getPrepayId(), prePay.getPayUrl(),
|
||||
weixinAccount);
|
||||
} else {
|
||||
throw new WeixinException("unknown tradeType:" + tradeType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建JSAPI支付请求对象
|
||||
*
|
||||
* @param openId
|
||||
* 用户ID
|
||||
* @param body
|
||||
* 订单描述
|
||||
* @param outTradeNo
|
||||
* 订单号
|
||||
* @param totalFee
|
||||
* 订单总额(元)
|
||||
* @param notifyUrl
|
||||
* 支付通知地址
|
||||
* @param createIp
|
||||
* ip地址
|
||||
* @param attach
|
||||
* 附加数据 非必填
|
||||
* @see JSAPIPayRequest
|
||||
* @return JSAPI支付对象
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public MchPayRequest createJSPayRequest(String openId, String body,
|
||||
String outTradeNo, double totalFee, String notifyUrl,
|
||||
String createIp, String attach) throws WeixinException {
|
||||
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
|
||||
totalFee, notifyUrl, createIp, TradeType.JSAPI, openId, null,
|
||||
null, attach);
|
||||
return createPayRequest(payPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Native支付(扫码支付)链接【模式一】
|
||||
*
|
||||
* @param productId
|
||||
* 与订单ID等价
|
||||
* @return 支付链接
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1">扫码支付
|
||||
* </a>
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4">模式一
|
||||
* </a>
|
||||
*/
|
||||
public String createNativePayRequest(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 = weixinSignature.sign(map);
|
||||
return String.format(getRequestUri("native_pay_uri"), sign,
|
||||
weixinAccount.getId(), weixinAccount.getMchId(), productId,
|
||||
timestamp, noncestr);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Native支付(扫码支付)回调对象【模式一】
|
||||
*
|
||||
* @param productId
|
||||
* 商品ID
|
||||
* @param body
|
||||
* 商品描述
|
||||
* @param outTradeNo
|
||||
* 商户内部唯一订单号
|
||||
* @param totalFee
|
||||
* 商品总额 单位元
|
||||
* @param notifyUrl
|
||||
* 支付回调URL
|
||||
* @param createIp
|
||||
* 订单生成的机器 IP
|
||||
* @param attach
|
||||
* 附加数据 非必填
|
||||
* @return Native回调对象
|
||||
* @see NativePayResponse
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1">扫码支付
|
||||
* </a>
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4">模式一
|
||||
* </a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public NativePayResponse createNativePayResponse(String productId,
|
||||
String body, String outTradeNo, double totalFee, String notifyUrl,
|
||||
String createIp, String attach) throws WeixinException {
|
||||
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
|
||||
totalFee, notifyUrl, createIp, TradeType.NATIVE, null, null,
|
||||
productId, attach);
|
||||
PrePay prePay = createPrePay(payPackage);
|
||||
return new NativePayResponse(weixinAccount, prePay.getPrepayId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Native支付(扫码支付)链接【模式二】
|
||||
*
|
||||
* @param productId
|
||||
* 商品ID
|
||||
* @param body
|
||||
* 商品描述
|
||||
* @param outTradeNo
|
||||
* 商户内部唯一订单号
|
||||
* @param totalFee
|
||||
* 商品总额 单位元
|
||||
* @param notifyUrl
|
||||
* 支付回调URL
|
||||
* @param createIp
|
||||
* 订单生成的机器 IP
|
||||
* @param attach
|
||||
* 附加数据 非必填
|
||||
* @return Native支付对象
|
||||
* @see NATIVEPayRequest
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1">扫码支付
|
||||
* </a>
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_5">模式二
|
||||
* </a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public MchPayRequest createNativePayRequest(String productId, String body,
|
||||
String outTradeNo, double totalFee, String notifyUrl,
|
||||
String createIp, String attach) throws WeixinException {
|
||||
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
|
||||
totalFee, notifyUrl, createIp, TradeType.NATIVE, null, null,
|
||||
productId, attach);
|
||||
return createPayRequest(payPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建APP支付请求对象
|
||||
*
|
||||
* @param body
|
||||
* 商品描述
|
||||
* @param outTradeNo
|
||||
* 商户内部唯一订单号
|
||||
* @param totalFee
|
||||
* 商品总额 单位元
|
||||
* @param notifyUrl
|
||||
* 支付回调URL
|
||||
* @param createIp
|
||||
* 订单生成的机器 IP
|
||||
* @param attach
|
||||
* 附加数据 非必填
|
||||
* @param store
|
||||
* 门店信息 非必填
|
||||
* @return APP支付对象
|
||||
* @see SceneInfoStore
|
||||
* @see APPPayRequest
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_1">
|
||||
* APP支付</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public MchPayRequest createAppPayRequest(String body, String outTradeNo,
|
||||
double totalFee, String notifyUrl, String createIp, String attach,
|
||||
SceneInfoStore store) throws WeixinException {
|
||||
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
|
||||
totalFee, notifyUrl, createIp, TradeType.APP, null, null, null,
|
||||
attach);
|
||||
if (store != null) {
|
||||
payPackage.setSceneInfo(String.format(
|
||||
"{\"store_id\": \"%s\", \"store_name\":\"%s\"}",
|
||||
store.getId(), store.getName()));
|
||||
}
|
||||
return createPayRequest(payPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建WAP支付请求对象:正常流程用户支付完成后会返回至发起支付的页面,如需返回至指定页面,
|
||||
* 则可以在MWEB_URL后拼接上redirect_url参数,来指定回调页面
|
||||
*
|
||||
* @param body
|
||||
* 商品描述
|
||||
* @param outTradeNo
|
||||
* 商户内部唯一订单号
|
||||
* @param totalFee
|
||||
* 商品总额 单位元
|
||||
* @param notifyUrl
|
||||
* 支付回调URL
|
||||
* @param createIp
|
||||
* 订单生成的机器 IP
|
||||
* @param attach
|
||||
* 附加数据 非必填
|
||||
* @param app
|
||||
* 应用信息
|
||||
* @return WAP支付对象
|
||||
* @see SceneInfoApp
|
||||
* @see WAPPayRequest
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/wap.php?chapter=15_1">WAP支付
|
||||
* </a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public MchPayRequest createWapPayRequest(String body, String outTradeNo,
|
||||
double totalFee, String notifyUrl, String createIp, String attach,
|
||||
SceneInfoApp app) throws WeixinException {
|
||||
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
|
||||
totalFee, notifyUrl, createIp, TradeType.MWEB, null, null,
|
||||
null, attach);
|
||||
if (app != null) {
|
||||
payPackage.setSceneInfo(String.format("{\"h5_info\":\"%s\"}",
|
||||
app.getSceneInfo()));
|
||||
}
|
||||
return createPayRequest(payPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交被扫支付
|
||||
*
|
||||
* @param authCode
|
||||
* 扫码支付授权码 ,设备读取用户微信中的条码或者二维码信息
|
||||
* @param body
|
||||
* 商品描述
|
||||
* @param outTradeNo
|
||||
* 商户内部唯一订单号
|
||||
* @param totalFee
|
||||
* 商品总额 单位元
|
||||
* @param createIp
|
||||
* 订单生成的机器 IP
|
||||
* @param attach
|
||||
* 附加数据 非必填
|
||||
* @param store
|
||||
* 门店信息 非必填
|
||||
* @return 支付的订单信息
|
||||
* @see MICROPayRequest
|
||||
* @see Order
|
||||
* @see SceneInfoStore
|
||||
* @see <a href=
|
||||
* "http://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_10">
|
||||
* 提交被扫支付API</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public MchPayRequest createMicroPayRequest(String authCode, String body,
|
||||
String outTradeNo, double totalFee, String createIp, String attach,
|
||||
SceneInfoStore store) throws WeixinException {
|
||||
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
|
||||
totalFee, null, createIp, TradeType.MICROPAY, null, authCode,
|
||||
null, attach);
|
||||
if (store != null) {
|
||||
payPackage.setSceneInfo(String.format("{\"store_info\":\"%s\"}",
|
||||
JSON.toJSONString(store)));
|
||||
}
|
||||
return createPayRequest(payPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单查询
|
||||
* <p>
|
||||
* 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;</br> 调用支付接口后,返回系统错误或未知交易状态情况;</br>
|
||||
* 调用被扫支付API,返回USERPAYING的状态;</br> 调用关单或撤销接口API之前,需确认支付状态;
|
||||
* </P>
|
||||
*
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id、out_trade_no 二 选一,如果同时存在优先级:
|
||||
* transaction_id> out_trade_no
|
||||
* @return 订单信息
|
||||
* @see 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 queryOrder(IdQuery idQuery) throws WeixinException {
|
||||
Map<String, String> map = createBaseRequestMap(idQuery);
|
||||
map.put("sign", weixinSignature.sign(map));
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
getRequestUri("order_query_uri"), param);
|
||||
return ListsuffixResultDeserializer.deserialize(response.getAsString(),
|
||||
Order.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请退款(请求需要双向证书)
|
||||
*
|
||||
* <p>
|
||||
* 当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付款退还给买家,微信支付将在收到退款请求并且验证成功之后,
|
||||
* 按照退款规则将支付款按原路退到买家帐号上。
|
||||
* </p>
|
||||
*
|
||||
* <ol>
|
||||
* <li>交易时间超过一年的订单无法提交退款;</li>
|
||||
* <li>
|
||||
* 微信支付退款支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。
|
||||
* 申请退款总金额不能超过订单金额。
|
||||
* <span style="color:red">一笔退款失败后重新提交,请不要更换退款单号,请使用原商户退款单号。</span>
|
||||
* </li>
|
||||
* <li>
|
||||
* 请求频率限制:150qps,即每秒钟正常的申请退款请求次数不超过150次。
|
||||
* 错误或无效请求频率限制:6qps,即每秒钟异常或错误的退款申请请求不超过6次。
|
||||
* </li>
|
||||
* <li>每个支付订单的部分退款次数不能超过50次。</li>
|
||||
* </ol>
|
||||
*
|
||||
* @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
|
||||
* 操作员帐号, 默认为商户号
|
||||
* @param refundDesc
|
||||
* 退款原因,若商户传入,会在下发给用户的退款消息中体现退款原因
|
||||
* @param refundAccountType
|
||||
* 退款资金来源,默认使用未结算资金退款:REFUND_SOURCE_UNSETTLED_FUNDS
|
||||
* @return 退款申请结果
|
||||
* @see RefundResult
|
||||
* @see <a href=
|
||||
* "http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4">
|
||||
* 申请退款API</a>
|
||||
* @since V3
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public RefundResult applyRefund(IdQuery idQuery, String outRefundNo,
|
||||
double totalFee, double refundFee, CurrencyType refundFeeType,
|
||||
String opUserId, String refundDesc,
|
||||
RefundAccountType refundAccountType) throws WeixinException {
|
||||
Map<String, String> map = createBaseRequestMap(idQuery);
|
||||
map.put("out_refund_no", outRefundNo);
|
||||
map.put("total_fee",
|
||||
Integer.toString(DateUtil.formatYuan2Fen(totalFee)));
|
||||
map.put("refund_fee",
|
||||
Integer.toString(DateUtil.formatYuan2Fen(refundFee)));
|
||||
if (StringUtil.isBlank(opUserId)) {
|
||||
opUserId = weixinAccount.getMchId();
|
||||
}
|
||||
map.put("op_user_id", opUserId);
|
||||
if (refundFeeType == null) {
|
||||
refundFeeType = CurrencyType.CNY;
|
||||
}
|
||||
if (refundAccountType == null) {
|
||||
refundAccountType = RefundAccountType.REFUND_SOURCE_UNSETTLED_FUNDS;
|
||||
}
|
||||
if (StringUtil.isNotBlank(refundDesc)) {
|
||||
map.put("refund_desc", refundDesc);
|
||||
}
|
||||
map.put("refund_fee_type", refundFeeType.name());
|
||||
map.put("refund_account", refundAccountType.name());
|
||||
map.put("sign", weixinSignature.sign(map));
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = getWeixinSSLExecutor().post(
|
||||
getRequestUri("refund_apply_uri"), param);
|
||||
return response.getAsObject(new TypeReference<RefundResult>() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款申请(全额退款)
|
||||
*
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
|
||||
* transaction_id> out_trade_no
|
||||
* @param outRefundNo
|
||||
* 商户系统内部的退款单号,商 户系统内部唯一,同一退款单号多次请求只退一笔
|
||||
* @param totalFee
|
||||
* 订单总金额,单位为元
|
||||
* @see #applyRefund(IdQuery, String, double, double, CurrencyType, String, String, RefundAccountType)
|
||||
*/
|
||||
public RefundResult applyRefund(IdQuery idQuery, String outRefundNo,
|
||||
double totalFee) throws WeixinException {
|
||||
return applyRefund(idQuery, outRefundNo, totalFee, totalFee, null,
|
||||
null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 冲正订单(需要证书)</br> 当支付返回失败,或收银系统超时需要取消交易,可以调用该接口</br> 接口逻辑:支
|
||||
* 付失败的关单,支付成功的撤销支付</br> <font color="red">7天以内的单可撤销,其他正常支付的单
|
||||
* 如需实现相同功能请调用退款接口</font></br> <font
|
||||
* color="red">调用扣款接口后请勿立即调用撤销,需要等待5秒以上。先调用查单接口,如果没有确切的返回,再调用撤销</font> </br>
|
||||
*
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
|
||||
* transaction_id> out_trade_no
|
||||
* @return 撤销结果
|
||||
* @since V3
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public MerchantResult reverseOrder(IdQuery idQuery) throws WeixinException {
|
||||
Map<String, String> map = createBaseRequestMap(idQuery);
|
||||
map.put("sign", weixinSignature.sign(map));
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = getWeixinSSLExecutor().post(
|
||||
getRequestUri("order_reverse_uri"), param);
|
||||
return response.getAsObject(new TypeReference<MerchantResult>() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = createBaseRequestMap(null);
|
||||
try {
|
||||
map.put("long_url", URLEncoder.encode(url, Consts.UTF_8.name()));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
;
|
||||
}
|
||||
map.put("sign", weixinSignature.sign(map));
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
getRequestUri("longurl_convert_uri"), 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 MerchantResult closeOrder(String outTradeNo) throws WeixinException {
|
||||
Map<String, String> map = createBaseRequestMap(new IdQuery(outTradeNo,
|
||||
IdType.TRADENO));
|
||||
map.put("sign", weixinSignature.sign(map));
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
getRequestUri("order_close_uri"), param);
|
||||
return response.getAsObject(new TypeReference<MerchantResult>() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载对账单<br>
|
||||
* 1.微信侧未成功下单的交易不会出现在对账单中。支付成功后撤销的交易会出现在对账 单中,跟原支付单订单号一致,bill_type 为
|
||||
* REVOKED;<br>
|
||||
* 2.微信在次日 9 点启动生成前一天的对账单,建议商户 9 点半后再获取;<br>
|
||||
* 3.对账单中涉及金额的字段单位为“元”。<br>
|
||||
*
|
||||
* @param billDate
|
||||
* 下载对账单的日期
|
||||
* @param billType
|
||||
* 下载对账单的类型 ALL,返回当日所有订单信息, 默认值 SUCCESS,返回当日成功支付的订单
|
||||
* REFUND,返回当日退款订单
|
||||
* @param outputStream
|
||||
* 输出流
|
||||
* @param tarType
|
||||
* 非必传参数,固定值:GZIP,返回格式为.gzip的压缩包账单。不传则默认为数据流形式。
|
||||
* @since V3
|
||||
* @see <a href=
|
||||
* "http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_6">
|
||||
* 下载对账单API</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public void downloadBill(Date billDate, BillType billType,
|
||||
OutputStream outputStream, TarType tarType) 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);
|
||||
Map<String, String> map = createBaseRequestMap(null);
|
||||
map.put("bill_date", formatBillDate);
|
||||
map.put("bill_type", billType.name());
|
||||
if (tarType != null) {
|
||||
map.put("tar_type", tarType.name());
|
||||
}
|
||||
map.put("sign", weixinSignature.sign(map));
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
getRequestUri("downloadbill_uri"), param);
|
||||
|
||||
if (TarType.GZIP == tarType) {
|
||||
try {
|
||||
IOUtil.copy(response.getBody(), outputStream);
|
||||
} catch (IOException e) {
|
||||
;
|
||||
}
|
||||
} else {
|
||||
BufferedReader reader = null;
|
||||
BufferedWriter writer = null;
|
||||
try {
|
||||
writer = new BufferedWriter(new OutputStreamWriter(
|
||||
outputStream, Consts.UTF_8));
|
||||
reader = new BufferedReader(new InputStreamReader(
|
||||
response.getBody(), Consts.UTF_8));
|
||||
String line = null;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
writer.write(line);
|
||||
writer.newLine();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new WeixinException(e);
|
||||
} finally {
|
||||
try {
|
||||
if (reader != null) {
|
||||
reader.close();
|
||||
}
|
||||
if (writer != null) {
|
||||
writer.close();
|
||||
}
|
||||
} catch (IOException ignore) {
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款查询
|
||||
*
|
||||
* <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 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 queryRefund(IdQuery idQuery) throws WeixinException {
|
||||
Map<String, String> map = createBaseRequestMap(idQuery);
|
||||
map.put("sign", weixinSignature.sign(map));
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
getRequestUri("refund_query_uri"), 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">
|
||||
* 交易保障</a>
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public XmlResult reportInterface(String interfaceUrl, int executeTime,
|
||||
String outTradeNo, String ip, Date time, XmlResult returnXml)
|
||||
throws WeixinException {
|
||||
Map<String, String> map = createBaseRequestMap(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));
|
||||
map.put("sign", weixinSignature.sign(map));
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
getRequestUri("interface_report_uri"), param);
|
||||
return response.getAsXml();
|
||||
}
|
||||
|
||||
/**
|
||||
* 授权码查询OPENID接口
|
||||
*
|
||||
* @param authCode
|
||||
* 扫码支付授权码,设备读取用户微信中的条码或者二维码信息
|
||||
* @return 查询结果
|
||||
* @see OpenIdResult
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_13&index=9">
|
||||
* 授权码查询OPENID</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public OpenIdResult authCode2openId(String authCode) throws WeixinException {
|
||||
Map<String, String> map = createBaseRequestMap(null);
|
||||
map.put("auth_code", authCode);
|
||||
map.put("sign", weixinSignature.sign(map));
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
getRequestUri("authcode_openid_uri"), param);
|
||||
return response.getAsObject(new TypeReference<OpenIdResult>() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信刷脸支付,获取调用凭证
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/wxfacepay/develop/sdk-android.html#获取调用凭证-get-wxpayface-authinfo">
|
||||
* 获取调用凭证-get-wxpayface-authinfo</a>
|
||||
*/
|
||||
public PayfaceAuthinfo getWxPayfaceAuthinfo(PayfaceAuthinfoRequest request) throws WeixinException {
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
getRequestUri("get_wxpayface_authinfo_uri"), request.toRequestString());
|
||||
return response.getAsObject(new TypeReference<PayfaceAuthinfo>() {});
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信旧版刷脸支付
|
||||
*
|
||||
* @param faceCode
|
||||
* @param body
|
||||
* @param outTradeNo
|
||||
* @param totalFee
|
||||
* @param createIp
|
||||
* @param openId
|
||||
* @param attach
|
||||
* @return
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public MchPayRequest createFacePayRequest(String faceCode, String body,
|
||||
String outTradeNo, double totalFee, String createIp, String openId,
|
||||
String attach) throws WeixinException {
|
||||
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
|
||||
totalFee, null, createIp, TradeType.FACEPAY, openId, null,
|
||||
null, attach);
|
||||
payPackage.setFaceCode(faceCode);
|
||||
return createPayRequest(payPackage);
|
||||
}
|
||||
|
||||
public MchPayRequest createDepositPayRequest(String code, String body, String outTradeNo, double totalFee,
|
||||
String createIp, String openId, String attach, SceneInfoStore store,
|
||||
boolean isFacePay) throws WeixinException {
|
||||
MchPayPackage payPackage;
|
||||
if(isFacePay) {
|
||||
payPackage = new MchPayPackage(body, outTradeNo, totalFee, null, createIp, TradeType.FACEPAY,
|
||||
openId, null, null, attach);
|
||||
payPackage.setFaceCode(code);
|
||||
payPackage.setDeposit(DepositType.Y);
|
||||
return createPayRequest(payPackage);
|
||||
}else{
|
||||
payPackage = new MchPayPackage(body, outTradeNo, totalFee, null, createIp, TradeType.MICROPAY,
|
||||
openId, code, null, attach);
|
||||
payPackage.setDeposit(DepositType.Y);
|
||||
if (store != null) {
|
||||
payPackage.setSceneInfo(String.format("{\"store_info\":\"%s\"}",
|
||||
JSON.toJSONString(store)));
|
||||
}
|
||||
return createPayRequest(payPackage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,190 @@
|
||||
package com.foxinmy.weixin4j.pay.model;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONCreator;
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
|
||||
/**
|
||||
* 微信支付账户
|
||||
*
|
||||
* @className WeixinPayAccount
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @date 2015年6月26日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
public class WeixinPayAccount extends WeixinAccount {
|
||||
|
||||
private static final long serialVersionUID = -2791256176906048632L;
|
||||
/**
|
||||
* 公众号支付请求中用于加密的密钥
|
||||
*/
|
||||
private final String paySignKey;
|
||||
/**
|
||||
* 微信支付分配的商户号
|
||||
*/
|
||||
private final String mchId;
|
||||
/**
|
||||
* 加载支付证书文件的密码(默认为商户号)
|
||||
*/
|
||||
private String certificateKey;
|
||||
/**
|
||||
* 商户证书文件(默认加载classpath:ca.p12)
|
||||
*/
|
||||
private String certificateFile;
|
||||
/**
|
||||
* 微信支付分配的设备号
|
||||
*/
|
||||
private String deviceInfo;
|
||||
/**
|
||||
* 财付通商户身份的标识
|
||||
*/
|
||||
private String partnerId;
|
||||
|
||||
/**
|
||||
* 微信分配的子商户公众账号ID
|
||||
*/
|
||||
private String subId;
|
||||
/**
|
||||
* 微信支付分配的子商户号
|
||||
*/
|
||||
private String subMchId;
|
||||
|
||||
/**
|
||||
* 支付商户信息
|
||||
*
|
||||
* @param id
|
||||
* 公众号唯一的身份ID(必填)
|
||||
* @param paySignKey
|
||||
* 支付密钥字符串(必填)
|
||||
* @param mchId
|
||||
* 微信支付分配的商户号(必填)
|
||||
*/
|
||||
public WeixinPayAccount(String id, String paySignKey, String mchId) {
|
||||
this(id, paySignKey, mchId, mchId, "classpath:ca.p12");
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付商户信息
|
||||
*
|
||||
* @param id
|
||||
* 公众号唯一的身份ID(必填)
|
||||
* @param paySignKey
|
||||
* 支付密钥字符串(必填)
|
||||
* @param mchId
|
||||
* 微信支付分配的商户号(必填)
|
||||
* @param certificateKey
|
||||
* 加载支付证书文件的密码(默认为商户号)
|
||||
* @param certificateFile
|
||||
* 商户证书文件(默认加载classpath:ca.p12)
|
||||
*/
|
||||
public WeixinPayAccount(String id, String paySignKey, String mchId, String certificateKey, String certificateFile) {
|
||||
this(id, null, paySignKey, mchId, certificateKey, certificateFile, null, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付商户信息
|
||||
*
|
||||
* @param id
|
||||
* 公众号唯一的身份ID(必填)
|
||||
* @param secret
|
||||
* 公众号调用接口的凭证(最好填写)
|
||||
* @param paySignKey
|
||||
* 支付密钥字符串(必填)
|
||||
* @param mchId
|
||||
* 微信支付分配的商户号(必填)
|
||||
* @param certificateKey
|
||||
* 加载支付证书文件的密码(默认为商户号)
|
||||
* @param certificateFile
|
||||
* 商户证书文件(默认加载classpath:ca.p12)
|
||||
* @param deviceInfo
|
||||
* 微信支付分配的设备号(非必填)
|
||||
* @param partnerId
|
||||
* 财付通的商户号(非必填)
|
||||
* @param subId
|
||||
* 微信分配的子商户公众账号ID(非必填)
|
||||
* @param subMchId
|
||||
* 微信支付分配的子商户号(非必填)
|
||||
*/
|
||||
@JSONCreator
|
||||
public WeixinPayAccount(@JSONField(name = "id") String id, @JSONField(name = "secret") String secret,
|
||||
@JSONField(name = "paySignKey") String paySignKey, @JSONField(name = "mchId") String mchId,
|
||||
@JSONField(name = "certificateKey") String certificateKey,
|
||||
@JSONField(name = "certificateFile") String certificateFile,
|
||||
@JSONField(name = "deviceInfo") String deviceInfo, @JSONField(name = "partnerId") String partnerId,
|
||||
@JSONField(name = "subId") String subId, @JSONField(name = "subMchId") String subMchId) {
|
||||
super(id, secret);
|
||||
this.paySignKey = paySignKey;
|
||||
this.mchId = mchId;
|
||||
this.certificateKey = certificateKey;
|
||||
this.certificateFile = certificateFile;
|
||||
this.deviceInfo = deviceInfo;
|
||||
this.partnerId = partnerId;
|
||||
this.subId = subId;
|
||||
this.subMchId = subMchId;
|
||||
}
|
||||
|
||||
public String getPaySignKey() {
|
||||
return paySignKey;
|
||||
}
|
||||
|
||||
public String getMchId() {
|
||||
return mchId;
|
||||
}
|
||||
|
||||
public String getDeviceInfo() {
|
||||
return deviceInfo;
|
||||
}
|
||||
|
||||
public String getCertificateKey() {
|
||||
return StringUtil.isBlank(certificateKey) ? mchId : certificateKey;
|
||||
}
|
||||
|
||||
public String getPartnerId() {
|
||||
return partnerId;
|
||||
}
|
||||
|
||||
public String getSubId() {
|
||||
return subId;
|
||||
}
|
||||
|
||||
public String getSubMchId() {
|
||||
return subMchId;
|
||||
}
|
||||
|
||||
public void setCertificateKey(String certificateKey) {
|
||||
this.certificateKey = certificateKey;
|
||||
}
|
||||
|
||||
public String getCertificateFile() {
|
||||
return certificateFile;
|
||||
}
|
||||
|
||||
public void setCertificateFile(String certificateFile) {
|
||||
this.certificateFile = certificateFile;
|
||||
}
|
||||
|
||||
public void setDeviceInfo(String deviceInfo) {
|
||||
this.deviceInfo = deviceInfo;
|
||||
}
|
||||
|
||||
public void setPartnerId(String partnerId) {
|
||||
this.partnerId = partnerId;
|
||||
}
|
||||
|
||||
public void setSubId(String subId) {
|
||||
this.subId = subId;
|
||||
}
|
||||
|
||||
public void setSubMchId(String subMchId) {
|
||||
this.subMchId = subMchId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WeixinPayAccount [" + super.toString() + ", paySignKey=" + paySignKey + ", mchId=" + mchId
|
||||
+ ", certificateKey=" + certificateKey + ",certificateFile =" + certificateFile + ", deviceInfo="
|
||||
+ deviceInfo + ", partnerId=" + partnerId + ", subId=" + subId + ", subMchId=" + subMchId + "]";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
package com.foxinmy.weixin4j.pay.payment;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
/**
|
||||
* JSAPI支付回调时的POST信息
|
||||
*
|
||||
* @className JsPayNotify
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @date 2014年8月19日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class JsPayNotify extends PayBaseInfo {
|
||||
|
||||
private static final long serialVersionUID = -4659030958445259803L;
|
||||
|
||||
/**
|
||||
* 用户的openid
|
||||
*/
|
||||
@JSONField(name = "OpenId")
|
||||
@XmlElement(name = "OpenId")
|
||||
private String openId;
|
||||
/**
|
||||
* 是否关注公众号
|
||||
*/
|
||||
@JSONField(name = "IsSubscribe")
|
||||
@XmlElement(name = "IsSubscribe")
|
||||
private int isSubscribe;
|
||||
|
||||
public JsPayNotify() {
|
||||
|
||||
}
|
||||
|
||||
public String getOpenId() {
|
||||
return openId;
|
||||
}
|
||||
|
||||
public int getIsSubscribe() {
|
||||
return isSubscribe;
|
||||
}
|
||||
|
||||
@JSONField(serialize = false)
|
||||
public boolean getFormatIsSubscribe() {
|
||||
return isSubscribe == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "openId=" + openId + ", isSubscribe=" + getFormatIsSubscribe()
|
||||
+ ", " + super.toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,116 @@
|
||||
package com.foxinmy.weixin4j.pay.payment;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.pay.type.SignType;
|
||||
|
||||
import javax.xml.bind.annotation.*;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 基本信息
|
||||
*
|
||||
* @className PayBaseInfo
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @date 2014年11月5日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class PayBaseInfo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1843024880782466990L;
|
||||
|
||||
/**
|
||||
* 公众号ID
|
||||
*/
|
||||
@JSONField(name = "appId")
|
||||
@XmlElement(name = "AppId")
|
||||
private String appId;
|
||||
/**
|
||||
* 时间戳
|
||||
*/
|
||||
@JSONField(name = "timeStamp")
|
||||
@XmlElement(name = "TimeStamp")
|
||||
private String timeStamp;
|
||||
/**
|
||||
* 随机字符串
|
||||
*/
|
||||
@JSONField(name = "nonceStr")
|
||||
@XmlElement(name = "NonceStr")
|
||||
private String nonceStr;
|
||||
/**
|
||||
* 签名结果
|
||||
*/
|
||||
@JSONField(name = "paySign")
|
||||
@XmlElement(name = "AppSignature")
|
||||
private String paySign;
|
||||
/**
|
||||
* 签名方式
|
||||
*/
|
||||
@JSONField(name = "signType")
|
||||
@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;
|
||||
}
|
||||
|
||||
@XmlTransient
|
||||
@JSONField(serialize = false)
|
||||
public SignType getFormatSignType() {
|
||||
return signType != null ? SignType.valueOf(signType.toUpperCase())
|
||||
: null;
|
||||
}
|
||||
|
||||
public void setSignType(SignType signType) {
|
||||
this.signType = signType != null ? signType.name() : 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,284 @@
|
||||
package com.foxinmy.weixin4j.pay.payment;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.pay.payment.mch.MerchantResult;
|
||||
import com.foxinmy.weixin4j.util.DateUtil;
|
||||
|
||||
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 java.util.Date;
|
||||
|
||||
/**
|
||||
* 订单信息
|
||||
*
|
||||
* @className PayPackage
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @date 2014年12月18日
|
||||
* @since JDK 1.6
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class PayPackage extends MerchantResult {
|
||||
|
||||
private static final long serialVersionUID = 3450161267802545790L;
|
||||
|
||||
/**
|
||||
* 商品描述 必须
|
||||
*/
|
||||
private String body;
|
||||
/**
|
||||
* 商品详情 非必须
|
||||
*/
|
||||
private String detail;
|
||||
/**
|
||||
* 商户系统内部的订单号 ,32 个字符内 、可包含字母 ,确保 在商户系统唯一 必须
|
||||
*/
|
||||
@XmlElement(name = "out_trade_no")
|
||||
@JSONField(name = "out_trade_no")
|
||||
private String outTradeNo;
|
||||
/**
|
||||
* 订单总金额,单位为分,不能带小数点 必须
|
||||
*/
|
||||
@XmlElement(name = "total_fee")
|
||||
@JSONField(name = "total_fee")
|
||||
private int totalFee;
|
||||
/**
|
||||
* 通知地址接收微信支付成功通知 必须
|
||||
*/
|
||||
@XmlElement(name = "notify_url")
|
||||
@JSONField(name = "notify_url")
|
||||
private String notifyUrl;
|
||||
/**
|
||||
* 订单生成的机器 IP 必须
|
||||
*/
|
||||
@XmlElement(name = "spbill_create_ip")
|
||||
@JSONField(name = "spbill_create_ip")
|
||||
private String createIp;
|
||||
/**
|
||||
* 附加数据,原样返回 非必须
|
||||
*/
|
||||
private String attach;
|
||||
/**
|
||||
* 订单生成时间,格式为 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;
|
||||
|
||||
protected PayPackage() {
|
||||
// jaxb required
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单对象
|
||||
*
|
||||
* @param body
|
||||
* 订单描述 必填
|
||||
* @param detail
|
||||
* 订单详情 非必填
|
||||
* @param outTradeNo
|
||||
* 商户内部ID 必填
|
||||
* @param totalFee
|
||||
* 订单总额 必填 <font color="red">单位为元</font>
|
||||
* @param notifyUrl
|
||||
* 回调地址 必填
|
||||
* @param createIp
|
||||
* 生成订单数据的机器IP 必填
|
||||
* @param attach
|
||||
* 附加数据 非必填
|
||||
* @param timeStart
|
||||
* 订单生成时间 非必填
|
||||
* @param timeExpire
|
||||
* 订单失效时间 非必填
|
||||
* @param goodsTag
|
||||
* 订单标记 非必填
|
||||
*/
|
||||
public PayPackage(String body, String detail, String outTradeNo,
|
||||
double totalFee, String notifyUrl, String createIp, String attach,
|
||||
Date timeStart, Date timeExpire, String goodsTag) {
|
||||
this.body = body;
|
||||
this.detail = detail;
|
||||
this.outTradeNo = outTradeNo;
|
||||
this.totalFee = DateUtil.formatYuan2Fen(totalFee);
|
||||
this.notifyUrl = notifyUrl;
|
||||
this.createIp = createIp;
|
||||
this.attach = attach;
|
||||
this.timeStart = timeStart != null ? DateUtil
|
||||
.fortmat2yyyyMMddHHmmss(timeStart) : null;
|
||||
this.timeExpire = timeExpire != null ? DateUtil
|
||||
.fortmat2yyyyMMddHHmmss(timeExpire) : null;
|
||||
this.goodsTag = goodsTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单对象
|
||||
*
|
||||
* @param body
|
||||
* 订单描述 必填
|
||||
* @param detail
|
||||
* 订单详情 非必填
|
||||
* @param outTradeNo
|
||||
* 商户内部ID 必填
|
||||
* @param totalFee
|
||||
* 订单总额 必填 <font color="red">单位为分</font>
|
||||
* @param notifyUrl
|
||||
* 回调地址 必填
|
||||
* @param createIp
|
||||
* 生成订单数据的机器IP 必填
|
||||
* @param attach
|
||||
* 附加数据 非必填
|
||||
* @param timeStart
|
||||
* 订单生成时间 非必填
|
||||
* @param timeExpire
|
||||
* 订单失效时间 非必填
|
||||
* @param goodsTag
|
||||
* 订单标记 非必填
|
||||
*/
|
||||
public PayPackage(String body, String detail, String outTradeNo,
|
||||
long totalFee, String notifyUrl, String createIp, String attach,
|
||||
Date timeStart, Date timeExpire, String goodsTag) {
|
||||
this.body = body;
|
||||
this.detail = detail;
|
||||
this.outTradeNo = outTradeNo;
|
||||
this.totalFee = Long.valueOf(totalFee).intValue();
|
||||
this.notifyUrl = notifyUrl;
|
||||
this.createIp = createIp;
|
||||
this.attach = attach;
|
||||
this.timeStart = timeStart != null ? DateUtil
|
||||
.fortmat2yyyyMMddHHmmss(timeStart) : null;
|
||||
this.timeExpire = timeExpire != null ? DateUtil
|
||||
.fortmat2yyyyMMddHHmmss(timeExpire) : null;
|
||||
this.goodsTag = goodsTag;
|
||||
}
|
||||
|
||||
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 getOutTradeNo() {
|
||||
return outTradeNo;
|
||||
}
|
||||
|
||||
public void setOutTradeNo(String outTradeNo) {
|
||||
this.outTradeNo = outTradeNo;
|
||||
}
|
||||
|
||||
public int getTotalFee() {
|
||||
return totalFee;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
public double getFormatTotalFee() {
|
||||
return totalFee / 100d;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">单位为元,自动格式化为分</font>
|
||||
*
|
||||
* @param totalFee
|
||||
* 订单总额 单位为元
|
||||
*/
|
||||
public void setTotalFee(double totalFee) {
|
||||
this.totalFee = DateUtil.formatYuan2Fen(totalFee);
|
||||
}
|
||||
|
||||
public String getNotifyUrl() {
|
||||
return notifyUrl;
|
||||
}
|
||||
|
||||
public void setNotifyUrl(String notifyUrl) {
|
||||
this.notifyUrl = notifyUrl;
|
||||
}
|
||||
|
||||
public String getCreateIp() {
|
||||
return createIp;
|
||||
}
|
||||
|
||||
public void setCreateIp(String createIp) {
|
||||
this.createIp = createIp;
|
||||
}
|
||||
|
||||
public String getAttach() {
|
||||
return attach;
|
||||
}
|
||||
|
||||
public void setAttach(String attach) {
|
||||
this.attach = attach;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "body=" + body + ", detail=" + detail + ", outTradeNo="
|
||||
+ outTradeNo + ", totalFee=" + totalFee + ", notifyUrl="
|
||||
+ notifyUrl + ", createIp=" + createIp + ", attach=" + attach
|
||||
+ ", timeStart=" + timeStart + ", timeExpire=" + timeExpire
|
||||
+ ", goodsTag=" + goodsTag;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,75 @@
|
||||
package com.foxinmy.weixin4j.pay.payment;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.util.DateUtil;
|
||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||
|
||||
import javax.xml.bind.annotation.*;
|
||||
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class PayRequest extends PayBaseInfo {
|
||||
|
||||
private static final long serialVersionUID = -453746488398523883L;
|
||||
|
||||
/**
|
||||
* 订单详情扩展 订单信息组成该字符串
|
||||
*/
|
||||
@XmlElement(name = "Package")
|
||||
@JSONField(name = "package")
|
||||
private String packageInfo;
|
||||
|
||||
/**
|
||||
* 冗余字段
|
||||
*/
|
||||
@XmlTransient
|
||||
@JSONField(serialize = false)
|
||||
private String prepayId;
|
||||
/**
|
||||
* 冗余字段
|
||||
*/
|
||||
@XmlTransient
|
||||
@JSONField(serialize = false)
|
||||
private String partnerId;
|
||||
|
||||
|
||||
protected PayRequest() {
|
||||
// jaxb required
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public String getPrepayId() {
|
||||
return prepayId;
|
||||
}
|
||||
|
||||
public void setPrepayId(String prepayId) {
|
||||
this.prepayId = prepayId;
|
||||
}
|
||||
|
||||
public String getPartnerId() {
|
||||
return partnerId;
|
||||
}
|
||||
|
||||
public void setPartnerId(String partnerId) {
|
||||
this.partnerId = partnerId;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "package" + packageInfo + ", prepayId=" + prepayId
|
||||
+ super.toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,377 @@
|
||||
package com.foxinmy.weixin4j.pay.payment.coupon;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.pay.payment.mch.MerchantResult;
|
||||
import com.foxinmy.weixin4j.pay.type.mch.CouponStatus;
|
||||
import com.foxinmy.weixin4j.pay.type.mch.CouponStockType;
|
||||
import com.foxinmy.weixin4j.pay.type.mch.CouponType;
|
||||
import com.foxinmy.weixin4j.util.DateUtil;
|
||||
|
||||
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 java.util.Date;
|
||||
|
||||
/**
|
||||
* 代金券详细
|
||||
*
|
||||
* @className CouponDetail
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @date 2015年3月27日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class CouponDetail extends MerchantResult {
|
||||
|
||||
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(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(serialize = false)
|
||||
public double getFormatCouponValue() {
|
||||
return couponValue / 100d;
|
||||
}
|
||||
|
||||
public int getCouponMininum() {
|
||||
return couponMininum;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
public double getFormatCouponMininum() {
|
||||
return couponMininum / 100d;
|
||||
}
|
||||
|
||||
public String getCouponName() {
|
||||
return couponName;
|
||||
}
|
||||
|
||||
public int getCouponStatus() {
|
||||
return couponStatus;
|
||||
}
|
||||
|
||||
@JSONField(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(serialize = false)
|
||||
public double getFormatCouponUseValue() {
|
||||
return couponUseValue / 100d;
|
||||
}
|
||||
|
||||
public int getCouponRemainValue() {
|
||||
return couponRemainValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
public double getFormatCouponRemainValue() {
|
||||
return couponRemainValue / 100d;
|
||||
}
|
||||
|
||||
public String getBeginTime() {
|
||||
return beginTime;
|
||||
}
|
||||
|
||||
@JSONField(serialize = false)
|
||||
public Date getFormatBeginTime() {
|
||||
return beginTime != null ? DateUtil.parse2yyyyMMddHHmmss(beginTime)
|
||||
: null;
|
||||
}
|
||||
|
||||
public String getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
@JSONField(serialize = false)
|
||||
public Date getFormatEndTime() {
|
||||
return endTime != null ? DateUtil.parse2yyyyMMddHHmmss(endTime) : null;
|
||||
}
|
||||
|
||||
public String getSendTime() {
|
||||
return sendTime;
|
||||
}
|
||||
|
||||
@JSONField(serialize = false)
|
||||
public Date getFormatSendTime() {
|
||||
return sendTime != null ? DateUtil.parse2yyyyMMddHHmmss(sendTime)
|
||||
: null;
|
||||
}
|
||||
|
||||
public String getUseTime() {
|
||||
return useTime;
|
||||
}
|
||||
|
||||
@JSONField(serialize = false)
|
||||
public Date getFormatUseTime() {
|
||||
return useTime != null ? 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(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,119 @@
|
||||
package com.foxinmy.weixin4j.pay.payment.coupon;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.pay.payment.mch.MerchantResult;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
/**
|
||||
* 代金券发放结果
|
||||
*
|
||||
* @className CouponResult
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @date 2015年3月25日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class CouponResult extends MerchantResult {
|
||||
|
||||
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,307 @@
|
||||
package com.foxinmy.weixin4j.pay.payment.coupon;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.pay.payment.mch.MerchantResult;
|
||||
import com.foxinmy.weixin4j.pay.type.mch.CouponStockStatus;
|
||||
import com.foxinmy.weixin4j.pay.type.mch.CouponType;
|
||||
import com.foxinmy.weixin4j.util.DateUtil;
|
||||
|
||||
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 java.util.Date;
|
||||
|
||||
/**
|
||||
* 代金券信息
|
||||
*
|
||||
* @className CouponStock
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @date 2015年3月27日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class CouponStock extends MerchantResult {
|
||||
|
||||
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(serialize = false)
|
||||
public double getFormatCouponValue() {
|
||||
return couponValue / 100d;
|
||||
}
|
||||
|
||||
public Integer getCouponMininumn() {
|
||||
return couponMininumn;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
public double getFormatCouponMininumn() {
|
||||
return couponMininumn != null ? couponMininumn.intValue() / 100d : 0d;
|
||||
}
|
||||
|
||||
public int getCouponType() {
|
||||
return couponType;
|
||||
}
|
||||
|
||||
@JSONField(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(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(serialize = false)
|
||||
public double getFormatMaxQuota() {
|
||||
return maxQuota != null ? maxQuota.intValue() / 100d : 0d;
|
||||
}
|
||||
|
||||
public Integer getLockedNum() {
|
||||
return lockedNum;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
public double getFormatLockedNum() {
|
||||
return lockedNum != null ? lockedNum.intValue() / 100d : 0d;
|
||||
}
|
||||
|
||||
public Integer getUsedNum() {
|
||||
return usedNum;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
public double getFormatUsedNum() {
|
||||
return usedNum != null ? usedNum.intValue() / 100d : 0d;
|
||||
}
|
||||
|
||||
public Integer getSendNum() {
|
||||
return sendNum;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
public double getFormatSendNum() {
|
||||
return sendNum != null ? sendNum.intValue() / 100d : 0d;
|
||||
}
|
||||
|
||||
public String getBeginTime() {
|
||||
return beginTime;
|
||||
}
|
||||
|
||||
@JSONField(serialize = false)
|
||||
public Date getFormatBeginTime() {
|
||||
return beginTime != null ? DateUtil.parse2yyyyMMddHHmmss(beginTime)
|
||||
: null;
|
||||
}
|
||||
|
||||
public String getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
@JSONField(serialize = false)
|
||||
public Date getFormatEndTime() {
|
||||
return endTime != null ? DateUtil.parse2yyyyMMddHHmmss(endTime) : null;
|
||||
}
|
||||
|
||||
public String getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
@JSONField(serialize = false)
|
||||
public Date getFormatCreateTime() {
|
||||
return createTime != null ? DateUtil.parse2yyyyMMddHHmmss(createTime)
|
||||
: null;
|
||||
}
|
||||
|
||||
public Integer getCouponBudget() {
|
||||
return couponBudget;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(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,95 @@
|
||||
package com.foxinmy.weixin4j.pay.payment.coupon;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.pay.type.mch.CouponType;
|
||||
|
||||
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 java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 订单代金券信息
|
||||
*
|
||||
* @className OrderCouponInfo
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @date 2015年3月24日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class OrderCouponInfo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -8744999305258786901L;
|
||||
|
||||
/**
|
||||
* 代金券或立减优惠批次ID
|
||||
*/
|
||||
@XmlElement(name = "coupon_batch_id")
|
||||
@JSONField(name = "coupon_batch_id")
|
||||
private String couponBatchId;
|
||||
/**
|
||||
* 代金券类型
|
||||
*
|
||||
* @see CouponType
|
||||
*/
|
||||
@XmlElement(name = "coupon_type")
|
||||
@JSONField(name = "coupon_type")
|
||||
private String couponType;
|
||||
/**
|
||||
* 代金券或立减优惠ID
|
||||
*/
|
||||
@XmlElement(name = "coupon_id")
|
||||
@JSONField(name = "coupon_id")
|
||||
private String couponId;
|
||||
/**
|
||||
* 单个代金券或立减优惠支付金额
|
||||
*/
|
||||
@XmlElement(name = "coupon_fee")
|
||||
@JSONField(name = "coupon_fee")
|
||||
private Integer couponFee;
|
||||
|
||||
protected OrderCouponInfo() {
|
||||
// jaxb requried
|
||||
}
|
||||
|
||||
public String getCouponBatchId() {
|
||||
return couponBatchId;
|
||||
}
|
||||
|
||||
public String getCouponType() {
|
||||
return couponType;
|
||||
}
|
||||
|
||||
@JSONField(serialize = false)
|
||||
public CouponType getFormatCouponType() {
|
||||
return couponType != null ? CouponType
|
||||
.valueOf(couponType.toUpperCase()) : null;
|
||||
}
|
||||
|
||||
public String getCouponId() {
|
||||
return couponId;
|
||||
}
|
||||
|
||||
public Integer getCouponFee() {
|
||||
return couponFee;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
public double getFormatCouponFee() {
|
||||
return couponFee != null ? couponFee.doubleValue() / 100d : 0d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "couponBatchId=" + couponBatchId + ", couponType=" + couponType
|
||||
+ ", couponId=" + couponId + ", couponFee=" + couponFee;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,76 @@
|
||||
package com.foxinmy.weixin4j.pay.payment.coupon;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
|
||||
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 java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 退款代金券信息
|
||||
*
|
||||
* @className RefundCouponInfo
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @date 2015年3月24日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class RefundCouponInfo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -8744999305258786901L;
|
||||
|
||||
/**
|
||||
* 代金券或立减优惠批次ID
|
||||
*/
|
||||
@XmlElement(name = "coupon_refund_batch_id")
|
||||
@JSONField(name = "coupon_refund_batch_id")
|
||||
private String couponBatchId;
|
||||
/**
|
||||
* 退款代金券ID
|
||||
*/
|
||||
@XmlElement(name = "coupon_refund_id")
|
||||
@JSONField(name = "coupon_refund_id")
|
||||
private String couponId;
|
||||
/**
|
||||
* 单个代金券或立减优惠支付金额
|
||||
*/
|
||||
@XmlElement(name = "coupon_refund_fee")
|
||||
@JSONField(name = "coupon_refund_fee")
|
||||
private Integer couponFee;
|
||||
|
||||
protected RefundCouponInfo() {
|
||||
// jaxb requried
|
||||
}
|
||||
|
||||
public String getCouponBatchId() {
|
||||
return couponBatchId;
|
||||
}
|
||||
|
||||
public String getCouponId() {
|
||||
return couponId;
|
||||
}
|
||||
|
||||
public Integer getCouponFee() {
|
||||
return couponFee;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
|
||||
*
|
||||
* @return 元单位
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
public double getFormatCouponFee() {
|
||||
return couponFee != null ? couponFee.doubleValue() / 100d : 0d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "couponBatchId=" + couponBatchId + ", couponId=" + couponId
|
||||
+ ", couponFee=" + couponFee;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user