Kaynağa Gözat

Merge remote-tracking branch 'origin/master'

zhuaizhuaidege 4 yıl önce
ebeveyn
işleme
4ead3e9f99
19 değiştirilmiş dosya ile 642 ekleme ve 44 silme
  1. 51 5
      framework-common/src/main/java/com/mrxu/framework/common/xcx/api/PayService.java
  2. 14 0
      framework-common/src/main/java/com/mrxu/framework/common/xcx/bean/CloseorderRequest.java
  3. 32 0
      framework-common/src/main/java/com/mrxu/framework/common/xcx/bean/CloseorderResponse.java
  4. 17 0
      framework-common/src/main/java/com/mrxu/framework/common/xcx/bean/OrderqueryRequest.java
  5. 90 0
      framework-common/src/main/java/com/mrxu/framework/common/xcx/bean/OrderqueryResponse.java
  6. 33 0
      framework-common/src/main/java/com/mrxu/framework/common/xcx/bean/PayBaseRequest.java
  7. 79 0
      framework-common/src/main/java/com/mrxu/framework/common/xcx/bean/PayResultResponse.java
  8. 54 0
      framework-common/src/main/java/com/mrxu/framework/common/xcx/bean/RefundRequest.java
  9. 73 0
      framework-common/src/main/java/com/mrxu/framework/common/xcx/bean/RefundResponse.java
  10. 1 20
      framework-common/src/main/java/com/mrxu/framework/common/xcx/bean/UnifiedorderRequest.java
  11. 63 0
      framework-common/src/main/java/com/mrxu/framework/common/xcx/enums/TradeState.java
  12. 2 4
      framework-starter/mrxu-starter-rocketmq/src/main/java/com/mrxu/framework/starter/rocketmq/README.txt
  13. 17 15
      framework-starter/mrxu-starter-rocketmq/src/main/java/com/mrxu/framework/starter/rocketmq/RocketMQSender.java
  14. 15 0
      framework-starter/mrxu-starter-rocketmq/src/main/java/com/mrxu/framework/starter/rocketmq/anno/EnableRocketmq.java
  15. 10 0
      framework-starter/mrxu-starter-rocketmq/src/main/java/com/mrxu/framework/starter/rocketmq/config/RocketmqAutoConfig.java
  16. 32 0
      framework-starter/mrxu-starter-xxljob/pom.xml
  17. 56 0
      framework-starter/mrxu-starter-xxljob/src/main/java/com/mrxu/framework/stater/xxl/config/XxlJobConfig.java
  18. 2 0
      framework-starter/mrxu-starter-xxljob/src/main/resources/META-INF/spring.factories
  19. 1 0
      framework-starter/pom.xml

+ 51 - 5
framework-common/src/main/java/com/mrxu/framework/common/xcx/api/PayService.java

@@ -7,9 +7,7 @@ import com.mrxu.framework.common.util.IdFunc;
 import com.mrxu.framework.common.util.MrxuAssert;
 import com.mrxu.framework.common.util.StrFunc;
 import com.mrxu.framework.common.xcx.WeixinUtil;
-import com.mrxu.framework.common.xcx.bean.PayBaseResponse;
-import com.mrxu.framework.common.xcx.bean.UnifiedorderRequest;
-import com.mrxu.framework.common.xcx.bean.UnifiedorderResponse;
+import com.mrxu.framework.common.xcx.bean.*;
 
 import java.util.TreeMap;
 
@@ -19,7 +17,9 @@ public class PayService {
     private static String unifiedorder = "https://api.mch.weixin.qq.com/pay/unifiedorder";
     //查询订单状态
     private static String orderquery = "https://api.mch.weixin.qq.com/pay/orderquery";
-
+    // 关闭订单
+    private static String closeorder = "https://api.mch.weixin.qq.com/pay/closeorder";
+    // 申请退款
     private static String refund = "https://api.mch.weixin.qq.com/secapi/pay/refund";
 
     // https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1
@@ -27,6 +27,21 @@ public class PayService {
         return request(UnifiedorderResponse.class,unifiedorder,"POST",request,apiKey,null);
     }
 
+    // https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_2
+    public static OrderqueryResponse orderquery(OrderqueryRequest request, String apiKey) {
+        return request(OrderqueryResponse.class,orderquery,"POST",request,apiKey,null);
+    }
+
+    // https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_3
+    public static CloseorderResponse closeorder(CloseorderRequest request, String apiKey) {
+        return request(CloseorderResponse.class,closeorder,"POST",request,apiKey,null);
+    }
+
+    // https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_4
+    public static RefundResponse refund(RefundRequest request, String apiKey) {
+        return request(RefundResponse.class,refund,"POST",request,apiKey,null);
+    }
+
     private static <T extends PayBaseResponse> T request(Class<T> clazz, String requestUrl, String requestMethod, Object requestBean, String apiKey, String certName) {
         MrxuAssert.validateBean(requestBean);
         String jsonStr = JSONUtil.toJsonStr(requestBean);
@@ -36,6 +51,7 @@ public class PayService {
         parameters.put("sign", sign);
         String requestXML = WeixinUtil.getRequestXml(parameters);
         String resultStr =  HttpUtil.httpsRequest(requestUrl,requestMethod,requestXML,null);
+        MrxuAssert.isNotEmpty(resultStr,"微信未响应");
         System.out.println(resultStr);
         JSONObject resultJson = WeixinUtil.doXMLParse(resultStr);
         T result = JSONUtil.toBean(resultJson.toJSONString(),clazz);
@@ -43,7 +59,16 @@ public class PayService {
         return result;
     }
 
-    public static void main(String[] args) {
+    public static void orderquery(String[] args) {
+        OrderqueryRequest request = new OrderqueryRequest();
+        request.setAppid("wx199e4718946c4e6d");
+        request.setMch_id("1514682921");
+        request.setNonce_str(StrFunc.randomString(32));
+        request.setOut_trade_no(IdFunc.getId("F"));
+        orderquery(request,"7616442b20a95c985ae712d72797c4c7");
+    }
+
+    public static void createOrder(String[] args) {
         UnifiedorderRequest request = new UnifiedorderRequest();
         request.setAppid("wx199e4718946c4e6d");
         request.setMch_id("1514682921");
@@ -59,5 +84,26 @@ public class PayService {
         unifiedorder(request,"7616442b20a95c985ae712d72797c4c7");
     }
 
+    public static void closeorder(String[] args) {
+        CloseorderRequest request = new CloseorderRequest();
+        request.setAppid("wx199e4718946c4e6d");
+        request.setMch_id("1514682921");
+        request.setNonce_str(StrFunc.randomString(32));
+        request.setOut_trade_no(IdFunc.getId("F"));
+        closeorder(request,"7616442b20a95c985ae712d72797c4c7");
+    }
+
+    public static void main(String[] args) {
+        RefundRequest request = new RefundRequest();
+        request.setAppid("wx199e4718946c4e6d");
+        request.setMch_id("1514682921");
+        request.setNonce_str(StrFunc.randomString(32));
+        request.setOut_trade_no(IdFunc.getId("F"));
+        request.setOut_refund_no(IdFunc.getId("F"));
+        request.setTotal_fee(100);
+        request.setRefund_fee(10);
+        refund(request,"7616442b20a95c985ae712d72797c4c7");
+    }
+
 
 }

+ 14 - 0
framework-common/src/main/java/com/mrxu/framework/common/xcx/bean/CloseorderRequest.java

@@ -0,0 +1,14 @@
+package com.mrxu.framework.common.xcx.bean;
+
+import lombok.Data;
+
+import javax.validation.constraints.Size;
+
+@Data
+public class CloseorderRequest extends PayBaseRequest {
+
+    // 商户订单号	out_trade_no	String(32)	20150806125346	商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一。 详见商户订单号
+    @Size(max=32)
+    private String out_trade_no;
+
+}

+ 32 - 0
framework-common/src/main/java/com/mrxu/framework/common/xcx/bean/CloseorderResponse.java

@@ -0,0 +1,32 @@
+package com.mrxu.framework.common.xcx.bean;
+
+import lombok.Data;
+
+@Data
+public class CloseorderResponse extends PayBaseResponse {
+    /***** 以下字段在return_code为SUCCESS的时候有返回 *****/
+    // 小程序ID	appid	是	String(32)	wxd678efh567hg6787	微信分配的小程序ID
+    private String appid;
+    // 商户号	mch_id	是	String(32)	1230000109	微信支付分配的商户号
+    private String mch_id;
+    // 随机字符串	nonce_str	是	String(32)	5K8264ILTKCH16CQ2502SI8ZNMTM67VS	随机字符串,不长于32位。推荐随机数生成算法
+    private String nonce_str;
+    // 签名	sign	是	String(32)	C380BEC2BFD727A4B6845133519F3AD6	签名,详见签名生成算法
+    private String sign;
+    // 业务结果	result_code	是	String(16)	SUCCESS	SUCCESS/FAIL
+    private String result_code;
+    // 业务结果描述	result_msg	是	String(32)	OK	对于业务执行的详细描述
+    private String result_msg;
+    // 错误代码	err_code	否	String(32)	SYSTEMERROR	错误码
+    private String err_code;
+    // 错误代码描述	err_code_des	否	String(128)	系统错误	结果信息描述
+    private String err_code_des;
+
+    public boolean isSuccess() {
+        return super.isSuccess() && "SUCCESS".equals(result_code);
+    }
+
+    public String getErrorMsg() {
+        return super.getErrorMsg()+(("SUCCESS".equals(result_code))?"":err_code_des);
+    }
+}

+ 17 - 0
framework-common/src/main/java/com/mrxu/framework/common/xcx/bean/OrderqueryRequest.java

@@ -0,0 +1,17 @@
+package com.mrxu.framework.common.xcx.bean;
+
+import lombok.Data;
+
+import javax.validation.constraints.Size;
+
+@Data
+public class OrderqueryRequest extends PayBaseRequest {
+
+    // 微信订单号	transaction_id	二选一	String(32)	1009660380201506130728806387	微信的订单号,优先使用
+    @Size(max=32)
+    private String transaction_id;
+    // 商户订单号	out_trade_no	String(32)	20150806125346	商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一。 详见商户订单号
+    @Size(max=32)
+    private String out_trade_no;
+
+}

+ 90 - 0
framework-common/src/main/java/com/mrxu/framework/common/xcx/bean/OrderqueryResponse.java

@@ -0,0 +1,90 @@
+package com.mrxu.framework.common.xcx.bean;
+
+import com.mrxu.framework.common.xcx.enums.TradeState;
+import lombok.Data;
+
+@Data
+public class OrderqueryResponse extends PayBaseResponse {
+    /***** 以下字段在return_code为SUCCESS的时候有返回 *****/
+    // 小程序ID	appid	是	String(32)	wxd678efh567hg6787	微信分配的小程序ID
+    private String appid;
+    // 商户号	mch_id	是	String(32)	1230000109	微信支付分配的商户号
+    private String mch_id;
+    // 随机字符串	nonce_str	是	String(32)	5K8264ILTKCH16CQ2502SI8ZNMTM67VS	随机字符串,不长于32位。推荐随机数生成算法
+    private String nonce_str;
+    // 签名	sign	是	String(32)	C380BEC2BFD727A4B6845133519F3AD6	签名,详见签名生成算法
+    private String sign;
+    // 业务结果	result_code	是	String(16)	SUCCESS	SUCCESS/FAIL
+    private String result_code;
+    // 错误代码	err_code	否	String(32)	SYSTEMERROR	错误码
+    private String err_code;
+    // 错误代码描述	err_code_des	否	String(128)	系统错误	结果信息描述
+    private String err_code_des;
+
+    /***** 以下字段在return_code 和result_code都为SUCCESS的时候有返回 *****/
+    // 设备号	device_info	否	String(32)	013467007045764	微信支付分配的终端设备号,
+    private String device_info;
+    // 用户标识	openid	是	String(128)	oUpF8uMuAJO_M2pxb1Q9zNjWeS6o	用户在商户appid下的唯一标识
+    private String openid;
+    // 是否关注公众账号	is_subscribe	是	String(1)	Y	用户是否关注公众账号,Y-关注,N-未关注
+    private String is_subscribe;
+    // 交易类型	trade_type	是	String(16)	JSAPI	调用接口提交的交易类型,取值如下:JSAPI,NATIVE,APP,MICROPAY,详细说明见参数规定
+    private TradeState trade_type;
+    /* 交易状态	trade_state	是	String(32)	SUCCESS	SUCCESS--支付成功
+    REFUND--转入退款
+    NOTPAY--未支付
+    CLOSED--已关闭
+    REVOKED--已撤销(刷卡支付)
+    USERPAYING--用户支付中
+    PAYERROR--支付失败(其他原因,如银行返回失败)
+    ACCEPT--已接收,等待扣款*/
+    private TradeState trade_state;
+    // 付款银行	bank_type	是	String(16)	CMC	银行类型,采用字符串类型的银行标识
+    private String bank_type;
+    // 标价金额	total_fee	是	int	100	订单总金额,单位为分
+    private Integer total_fee;
+    // 应结订单金额	settlement_total_fee	否	int	100	当订单使用了免充值型优惠券后返回该参数,应结订单金额=订单金额-免充值优惠券金额。
+    private Integer settlement_total_fee;
+    // 标价币种	fee_type	否	String(8)	CNY	货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
+    private String fee_type;
+    // 现金支付金额	cash_fee	是	int	100	现金支付金额订单现金支付金额,详见支付金额
+    private Integer cash_fee;
+    // 现金支付币种	cash_fee_type	否	String(16)	CNY	货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
+    private String cash_fee_type;
+    // 代金券金额	coupon_fee	否	int	100	“代金券”金额<=订单金额,订单金额-“代金券”金额=现金支付金额,详见支付金额
+    private Integer coupon_fee;
+    // 代金券使用数量	coupon_count	否	int	1	代金券使用数量
+    private Integer coupon_count;
+    /* 代金券类型	coupon_type_$n	否	String	CASH
+    CASH--充值代金券
+    NO_CASH---非充值优惠券
+    开通免充值券功能,并且订单使用了优惠券后有返回(取值:CASH、NO_CASH)。$n为下标,从0开始编号,举例:coupon_type_$0*/
+    private String coupon_type_$0;
+    // 代金券ID	coupon_id_$n	否	String(20)	10000 	代金券ID, $n为下标,从0开始编号
+    private String coupon_id_$0;
+    // 单个代金券支付金额	coupon_fee_$n	否	int	100	单个代金券支付金额, $n为下标,从0开始编号
+    private Integer coupon_fee_$0;
+    // 微信支付订单号	transaction_id	是	String(32)	1009660380201506130728806387	微信支付订单号
+    private String transaction_id;
+    // 商户订单号	out_trade_no	是	String(32)	20150806125346	商户系统内部订单号,要求32个字符内(最少6个字符),只能是数字、大小写字母_-|*且在同一个商户号下唯一。详见商户订单号
+    private String out_trade_no;
+    // 附加数据	attach	否	String(128)	深圳分店	附加数据,原样返回
+    private String attach;
+    // 支付完成时间	time_end	是	String(14)	20141030133525	订单支付时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则
+    private String time_end;
+    // 交易状态描述	trade_state_desc	是	String(256)	支付失败,请重新下单支付	对当前查询订单状态的描述和下一步操作的指引
+    private String trade_state_desc;
+
+    public void setTrade_type(String trade_type) {
+        this.trade_state = TradeState.getState(trade_type);
+    }
+
+    public boolean isSuccess() {
+        return super.isSuccess() && "SUCCESS".equals(result_code);
+    }
+
+    public String getErrorMsg() {
+        return super.getErrorMsg()+(("SUCCESS".equals(result_code))?"":err_code_des);
+    }
+
+}

+ 33 - 0
framework-common/src/main/java/com/mrxu/framework/common/xcx/bean/PayBaseRequest.java

@@ -0,0 +1,33 @@
+package com.mrxu.framework.common.xcx.bean;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.Size;
+
+@Data
+public class PayBaseRequest {
+
+    // 小程序ID	appid	是	String(32)	wxd678efh567hg6787	微信分配的小程序ID
+    @Size(max=32)
+    @NotEmpty
+    private String appid;
+    // 商户号	mch_id	是	String(32)	1230000109	微信支付分配的商户号
+    @Size(max=32)
+    @NotEmpty
+    private String mch_id;
+
+    // 随机字符串	nonce_str	是	String(32)	5K8264ILTKCH16CQ2502SI8ZNMTM67VS	随机字符串,长度要求在32位以内。推荐随机数生成算法
+    @Size(max=32)
+    @NotEmpty
+    private String nonce_str;
+    // 签名	sign	是	String(64)	C380BEC2BFD727A4B6845133519F3AD6	通过签名算法计算得出的签名值,详见签名生成算法
+    //@Size(max=64)
+    //@NotEmpty
+    private String sign;
+    // 签名类型	sign_type	否	String(32)	MD5	签名类型,默认为MD5,支持HMAC-SHA256和MD5。
+    @Size(max=32)
+    private String sign_type;
+
+
+}

+ 79 - 0
framework-common/src/main/java/com/mrxu/framework/common/xcx/bean/PayResultResponse.java

@@ -0,0 +1,79 @@
+package com.mrxu.framework.common.xcx.bean;
+
+import lombok.Data;
+
+@Data
+public class PayResultResponse extends PayBaseResponse {
+    /***** 以下字段在return_code为SUCCESS的时候有返回 *****/
+    // 小程序ID	appid	是	String(32)	wx8888888888888888	微信分配的小程序ID
+    private String appid;
+    // 商户号	mch_id	是	String(32)	1900000109	微信支付分配的商户号
+    private String mch_id;
+    // 设备号	device_info	否	String(32)	013467007045764	微信支付分配的终端设备号,
+    private String device_info;
+    // 随机字符串	nonce_str	是	String(32)	5K8264ILTKCH16CQ2502SI8ZNMTM67VS	随机字符串,不长于32位
+    private String nonce_str;
+    // 签名	sign	是	String(32)	C380BEC2BFD727A4B6845133519F3AD6	签名,详见签名算法
+    private String sign;
+    // 签名类型	sign_type	否	String(32)	HMAC-SHA256	签名类型,目前支持HMAC-SHA256和MD5,默认为MD5
+    private String sign_type;
+    // 业务结果	result_code	是	String(16)	SUCCESS	SUCCESS/FAIL
+    private String result_code;
+    // 错误代码	err_code	否	String(32)	SYSTEMERROR	错误返回的信息描述
+    private String err_code;
+    // 错误代码描述	err_code_des	否	String(128)	系统错误	错误返回的信息描述
+    private String err_code_des;
+    // 用户标识	openid	是	String(128)	wxd930ea5d5a258f4f	用户在商户appid下的唯一标识
+    private String openid;
+    // 是否关注公众账号	is_subscribe	是	String(1)	Y	用户是否关注公众账号,Y-关注,N-未关注
+    private String is_subscribe;
+    // 交易类型	trade_type	是	String(16)	JSAPI	JSAPI、NATIVE、APP
+    private String trade_type;
+    // 付款银行	bank_type	是	String(32)	CMC	银行类型,采用字符串类型的银行标识,银行类型见银行列表
+    private String bank_type;
+    // 订单金额	total_fee	是	int	100	订单总金额,单位为分
+    private Integer total_fee;
+    // 应结订单金额	settlement_total_fee	否	int	100	应结订单金额=订单金额-非充值代金券金额,应结订单金额<=订单金额。
+    private Integer settlement_total_fee;
+    // 货币种类	fee_type	否	String(8)	CNY	货币类型,符合ISO4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
+    private String fee_type;
+    // 现金支付金额	cash_fee	是	int	100	现金支付金额订单现金支付金额,详见支付金额
+    private Integer cash_fee;
+    // 现金支付货币类型	cash_fee_type	否	String(16)	CNY	货币类型,符合ISO4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
+    private String cash_fee_type;
+    // 总代金券金额	coupon_fee	否	int	10	代金券金额<=订单金额,订单金额-代金券金额=现金支付金额,详见支付金额
+    private Integer coupon_fee;
+    // 代金券使用数量	coupon_count	否	int	1	代金券使用数量
+    private Integer coupon_count;
+    /*代金券类型	coupon_type_$n	否	String	CASH
+    CASH--充值代金券
+    NO_CASH---非充值代金券
+
+    并且订单使用了免充值券后有返回(取值:CASH、NO_CASH)。$n为下标,从0开始编号,举例:coupon_type_0
+
+    注意:只有下单时订单使用了优惠,回调通知才会返回券信息。
+    下列情况可能导致订单不可以享受优惠:可能情况。*/
+    private String coupon_type_$0;
+    /*代金券ID	coupon_id_$n	否	String(20)	10000	代金券ID,$n为下标,从0开始编号
+    注意:只有下单时订单使用了优惠,回调通知才会返回券信息。
+    下列情况可能导致订单不可以享受优惠:可能情况。*/
+    private String coupon_id_$0;
+    // 单个代金券支付金额	coupon_fee_$n	否	int	100	单个代金券支付金额,$n为下标,从0开始编号
+    private Integer coupon_fee_$0;
+    // 微信支付订单号	transaction_id	是	String(32)	1217752501201407033233368018	微信支付订单号
+    private String transaction_id;
+    // 商户订单号	out_trade_no	是	String(32)	1212321211201407033568112322	商户系统内部订单号,要求32个字符内(最少6个字符),只能是数字、大小写字母_-|*且在同一个商户号下唯一。详见商户订单号
+    private String out_trade_no;
+    // 商家数据包	attach	否	String(128)	123456	商家数据包,原样返回
+    private String attach;
+    // 支付完成时间	time_end	是	String(14)	20141030133525	支付完成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则
+    private String time_end;
+
+    public boolean isSuccess() {
+        return super.isSuccess() && "SUCCESS".equals(result_code);
+    }
+
+    public String getErrorMsg() {
+        return super.getErrorMsg()+(("SUCCESS".equals(result_code))?"":err_code_des);
+    }
+}

+ 54 - 0
framework-common/src/main/java/com/mrxu/framework/common/xcx/bean/RefundRequest.java

@@ -0,0 +1,54 @@
+package com.mrxu.framework.common.xcx.bean;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.Size;
+
+@Data
+public class RefundRequest extends PayBaseRequest {
+
+    // 微信支付订单号	transaction_id	二选一	String(32)	1217752501201407033233368018	微信生成的订单号,在支付通知中有返回
+    @Size(max=32)
+    private String transaction_id;
+    /* 商户订单号	out_trade_no	String(32)	1217752501201407033233368018	商户系统内部订单号,要求32个字符内(最少6个字符),只能是数字、大小写字母_-|*且在同一个商户号下唯一。详见商户订单号
+    transaction_id、out_trade_no二选一,如果同时存在优先级:transaction_id> out_trade_no*/
+    @Size(max=32)
+    private String out_trade_no;
+    // 商户退款单号	out_refund_no	是	String(64)	1217752501201407033233368018	商户系统内部的退款单号,商户系统内部唯一,只能是数字、大小写字母_-|*@ ,同一退款单号多次请求只退一笔。
+    @Size(max=32)
+    @NotEmpty
+    private String out_refund_no;
+    // 订单金额	total_fee	是	int	100	订单总金额,单位为分,只能为整数,详见支付金额
+    private Integer total_fee;
+    // 退款金额	refund_fee	是	int	100	退款总金额,订单总金额,单位为分,只能为整数,详见支付金额
+    private Integer refund_fee;
+    // 货币种类	refund_fee_type	否	String(8)	CNY	货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
+    @Size(max=32)
+    private String refund_fee_type;
+    /* 退款原因	refund_desc	否	String(80)	商品已售完
+    若商户传入,会在下发给用户的退款消息中体现退款原因
+
+    注意:若订单退款金额≤1元,且属于部分退款,则不会在退款消息中体现退款原因*/
+    @Size(max=32)
+    private String refund_desc;
+
+    /* 退款资金来源	refund_account	否	String(30)	REFUND_SOURCE_RECHARGE_FUNDS
+    仅针对老资金流商户使用
+
+    REFUND_SOURCE_UNSETTLED_FUNDS---未结算资金退款(默认使用未结算资金退款)
+
+    REFUND_SOURCE_RECHARGE_FUNDS---可用余额退款*/
+    @Size(max=32)
+    private String refund_account;
+
+    /* 退款结果通知url	notify_url	否	String(256)	https://weixin.qq.com/notify/
+    异步接收微信支付退款结果通知的回调地址,通知URL必须为外网可访问的url,不允许带参数
+
+    公网域名必须为https,如果是走专线接入,使用专线NAT IP或者私有回调域名可使用http。
+
+    如果参数中传了notify_url,则商户平台上配置的回调地址将不会生效。*/
+    @Size(max=32)
+    private String notify_url;
+
+}

+ 73 - 0
framework-common/src/main/java/com/mrxu/framework/common/xcx/bean/RefundResponse.java

@@ -0,0 +1,73 @@
+package com.mrxu.framework.common.xcx.bean;
+
+import lombok.Data;
+
+@Data
+public class RefundResponse extends PayBaseResponse {
+
+    /***** 以下字段在return_code为SUCCESS的时候有返回 *****/
+
+    /*业务结果	result_code	是	String(16)	SUCCESS
+    SUCCESS/FAIL
+    SUCCESS退款申请接收成功,结果通过退款查询接口查询
+    FAIL 提交业务失败*/
+    private String result_code;
+    // 错误代码	err_code	否	String(32)	SYSTEMERROR	列表详见错误码列表
+    private String err_code;
+    // 错误代码描述	err_code_des	否	String(128)	系统超时	结果信息描述
+    private String err_code_des;
+    // 小程序ID	appid	是	String(32)	wx8888888888888888	微信分配的小程序ID
+    private String appid;
+    // 商户号	mch_id	是	String(32)	1900000109	微信支付分配的商户号
+    private String mch_id;
+    // 随机字符串	nonce_str	是	String(32)	5K8264ILTKCH16CQ2502SI8ZNMTM67VS	随机字符串,不长于32位
+    private String nonce_str;
+    // 签名	sign	是	String(32)	5K8264ILTKCH16CQ2502SI8ZNMTM67VS	签名,详见签名算法
+    private String sign;
+    // 微信支付订单号	transaction_id	是	String(32)	4007752501201407033233368018	微信订单号
+    private String transaction_id;
+    // 商户订单号	out_trade_no	是	String(32)	33368018	商户系统内部订单号,要求32个字符内(最少6个字符),只能是数字、大小写字母_-|*且在同一个商户号下唯一。详见商户订单号
+    private String out_trade_no;
+    // 商户退款单号	out_refund_no	是	String(64)	121775250	商户系统内部的退款单号,商户系统内部唯一,只能是数字、大小写字母_-|*@ ,同一退款单号多次请求只退一笔。
+    private String out_refund_no;
+    // 微信退款单号	refund_id	是	String(32)	2007752501201407033233368018	微信退款单号
+    private String refund_id;
+    // 退款金额	refund_fee	是	int	100	退款总金额,单位为分,可以做部分退款
+    private Integer refund_fee;
+    // 应结退款金额	settlement_refund_fee	否	int	100	去掉非充值代金券退款金额后的退款金额,退款金额=申请退款金额-非充值代金券退款金额,退款金额<=申请退款金额
+    private Integer settlement_refund_fee;
+    // 标价金额	total_fee	是	int	100	订单总金额,单位为分,只能为整数,详见支付金额
+    private Integer total_fee;
+    // 应结订单金额	settlement_total_fee	否	int	100	去掉非充值代金券金额后的订单总金额,应结订单金额=订单金额-非充值代金券金额,应结订单金额<=订单金额。
+    private Integer settlement_total_fee;
+    // 标价币种	fee_type	否	String(8)	CNY	订单金额货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
+    private String fee_type;
+    // 现金支付金额	cash_fee	是	int	100	现金支付金额,单位为分,只能为整数,详见支付金额
+    private Integer cash_fee;
+    // 现金支付币种	cash_fee_type	否	String(16)	CNY	货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
+    private String cash_fee_type;
+    // 现金退款金额	cash_refund_fee	否	int	100	现金退款金额,单位为分,只能为整数,详见支付金额
+    private Integer cash_refund_fee;
+    /* 代金券类型	coupon_type_$n	否	String(8)	CASH
+    CASH--充值代金券
+    NO_CASH---非充值代金券
+    订单使用代金券时有返回(取值:CASH、NO_CASH)。$n为下标,从0开始编号,举例:coupon_type_0*/
+    private String coupon_type_0;
+    // 代金券退款总金额	coupon_refund_fee	否	int	100	代金券退款金额<=退款金额,退款金额-代金券或立减优惠退款金额为现金,说明详见代金券或立减优惠
+    private Integer coupon_refund_fee;
+    // 单个代金券退款金额	coupon_refund_fee_$n	否	int	100	代金券退款金额<=退款金额,退款金额-代金券或立减优惠退款金额为现金,说明详见代金券或立减优惠
+    private Integer coupon_refund_fee_$0;
+    // 退款代金券使用数量	coupon_refund_count	否	int	1	退款代金券使用数量
+    private Integer coupon_refund_count;
+    // 退款代金券ID	coupon_refund_id_$n	否	String(20)	10000 	退款代金券ID, $n为下标,从0开始编号
+    private String coupon_refund_id_$0;
+
+    public boolean isSuccess() {
+        return super.isSuccess() && "SUCCESS".equals(result_code);
+    }
+
+    public String getErrorMsg() {
+        return super.getErrorMsg()+(("SUCCESS".equals(result_code))?"":err_code_des);
+    }
+
+}

+ 1 - 20
framework-common/src/main/java/com/mrxu/framework/common/xcx/bean/UnifiedorderRequest.java

@@ -6,29 +6,10 @@ import javax.validation.constraints.NotEmpty;
 import javax.validation.constraints.Size;
 
 @Data
-public class UnifiedorderRequest {
+public class UnifiedorderRequest extends PayBaseRequest {
 
-    //小程序ID	appid  是	String(32)	wxd678efh567hg6787	微信分配的小程序ID
-    @Size(max=32)
-    @NotEmpty
-    private String appid;
-    // 商户号	mch_id	是	String(32)	1230000109	微信支付分配的商户号
-    @Size(max=32)
-    @NotEmpty
-    private String mch_id;
     // 设备号	device_info	否	String(32)	013467007045764	自定义参数,可以为终端设备号(门店号或收银设备ID),PC网页或公众号内支付可以传"WEB"
     private String device_info;
-    // 随机字符串	nonce_str	是	String(32)	5K8264ILTKCH16CQ2502SI8ZNMTM67VS	随机字符串,长度要求在32位以内。推荐随机数生成算法
-    @Size(max=32)
-    @NotEmpty
-    private String nonce_str;
-    // 签名	sign	是	String(64)	C380BEC2BFD727A4B6845133519F3AD6	通过签名算法计算得出的签名值,详见签名生成算法
-    //@Size(max=64)
-    //@NotEmpty
-    private String sign;
-    // 签名类型	sign_type	否	String(32)	MD5	签名类型,默认为MD5,支持HMAC-SHA256和MD5。
-    @Size(max=32)
-    private String sign_type;
     // 商品描述	body	是	String(127)	腾讯充值中心-QQ会员充值 商品简单描述,该字段请按照规范传递,具体请见参数规定
     @Size(max=127)
     @NotEmpty

+ 63 - 0
framework-common/src/main/java/com/mrxu/framework/common/xcx/enums/TradeState.java

@@ -0,0 +1,63 @@
+package com.mrxu.framework.common.xcx.enums;
+
+import lombok.Data;
+
+public enum TradeState {
+
+    SUCCESS("SUCCESS","支付成功"),
+    REFUND("REFUND","转入退款"),
+    NOTPAY("NOTPAY","未支付"),
+    CLOSED("CLOSED","已关闭"),
+    REVOKED("REVOKED","已撤销(刷卡支付)"),
+    USERPAYING("USERPAYING","用户支付中"),
+    PAYERROR("PAYERROR","支付失败(其他原因,如银行返回失败)"),
+    ACCEPT("ACCEPT","已接收,等待扣款");
+
+    private String state;
+
+    /**
+     * 显示值
+     */
+    private String caption;
+
+    TradeState(String state, String caption) {
+        this.state = state;
+        this.caption = caption;
+    }
+
+    public static TradeState getState(String state) {
+        if(SUCCESS.state.equals(state)) {
+            return SUCCESS;
+        }
+        if(REFUND.state.equals(state)) {
+            return REFUND;
+        }
+        if(NOTPAY.state.equals(state)) {
+            return NOTPAY;
+        }
+        if(CLOSED.state.equals(state)) {
+            return CLOSED;
+        }
+        if(REVOKED.state.equals(state)) {
+            return REVOKED;
+        }
+        if(USERPAYING.state.equals(state)) {
+            return USERPAYING;
+        }
+        if(PAYERROR.state.equals(state)) {
+            return PAYERROR;
+        }
+        if(ACCEPT.state.equals(state)) {
+            return ACCEPT;
+        }
+        return null;
+    }
+
+    public String getState() {
+        return state;
+    }
+
+    public String getCaption() {
+        return caption;
+    }
+}

+ 2 - 4
framework-starter/mrxu-starter-rocketmq/src/main/java/com/mrxu/framework/starter/rocketmq/README.txt

@@ -1,8 +1,6 @@
 ## 使用配置rocketmq
 rocketmq:
-    name-server: http://127.0.0.1:9876 #rocketmq服务地址
+    name-server: 127.0.0.1:9876 #rocketmq服务地址
     producer:
-        group: rocketmq_test #自定义的组名称
-        access-key: rocketmq2
-        secret-key: 12345678
+        group: group_test #自定义的组名称
         send-message-timeout: 3000 #消息发送超时时长

+ 17 - 15
framework-starter/mrxu-starter-rocketmq/src/main/java/com/mrxu/framework/starter/rocketmq/RocketMQSender.java

@@ -1,16 +1,14 @@
 package com.mrxu.framework.starter.rocketmq;
 
-import org.apache.rocketmq.client.producer.SendCallback;
 import org.apache.rocketmq.spring.core.RocketMQTemplate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.messaging.Message;
 import org.springframework.messaging.support.MessageBuilder;
 import org.springframework.stereotype.Service;
 
 /**
  * 功能概要:[] <br>
- *
- * @author 上研院 zhuzhoutong
  * @date 2021/11/17
  */
 @Service
@@ -28,49 +26,53 @@ public class RocketMQSender {
     @Value("${rocketmq.producer.send-message-timeout:3000}")
     private Long messageTimeOut;
 
-    /**
+    public void sendMsg(String topic,String tag,Object body) {
+        rocketMQTemplate.syncSend(topic+":"+tag,body,messageTimeOut);
+    }
+
+/*    *//**
      * 发送普通消息
      * @param destination 发送队列
      * @param message 发送内容
-     */
+     *//*
     public void sendMsg(String destination, Object message){
-        this.sendMsg(destination,message);
+        this.sendMsg(destination,message,messageTimeOut);
     }
 
-    /**
+    *//**
      * 发送消息
      * @param destination 队列
      * @param message 消息
      * @param timeOut 超时
-     */
+     *//*
     public void sendMsg(String destination, Object message,Long timeOut){
         rocketMQTemplate.syncSend(destination,MessageBuilder.withPayload(message).build(),timeOut);
     }
 
-    /**
+    *//**
      * 发送异步消息 在SendCallback中可处理相关成功失败时的逻辑
-     */
+     *//*
     public void sendAsyncMsg(String destination, Object message,SendCallback sendCallback){
         this.sendAsyncMsg(destination,message,sendCallback,messageTimeOut);
     }
 
-    /**
+    *//**
      * 异步发送消息
      * @param destination 队列
      * @param message 消息
      * @param sendCallback 回调
      * @param timeOut 超时
-     */
+     *//*
     public void sendAsyncMsg(String destination, Object message,SendCallback sendCallback,Long timeOut){
         rocketMQTemplate.asyncSend(destination,message,sendCallback,timeOut);
     }
 
-    /**
+    *//**
      * 发送延时消息<br/>
      * 在start版本中 延时消息一共分为18个等级分别为:1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h<br/>
-     */
+     *//*
     public void sendDelayMsg(String destination, Object msgBody, Integer delayLevel){
         rocketMQTemplate.syncSend(destination,MessageBuilder.withPayload(msgBody).build(),messageTimeOut,delayLevel);
-    }
+    }*/
 
 }

+ 15 - 0
framework-starter/mrxu-starter-rocketmq/src/main/java/com/mrxu/framework/starter/rocketmq/anno/EnableRocketmq.java

@@ -0,0 +1,15 @@
+package com.mrxu.framework.starter.rocketmq.anno;
+
+
+import com.mrxu.framework.starter.rocketmq.config.RocketmqAutoConfig;
+import org.springframework.context.annotation.Import;
+
+import java.lang.annotation.*;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+@Import(RocketmqAutoConfig.class)
+public @interface EnableRocketmq {
+}

+ 10 - 0
framework-starter/mrxu-starter-rocketmq/src/main/java/com/mrxu/framework/starter/rocketmq/config/RocketmqAutoConfig.java

@@ -0,0 +1,10 @@
+package com.mrxu.framework.starter.rocketmq.config;
+
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+
+@ComponentScan({"com.mrxu.framework.starter.rocketmq"})
+@EnableAspectJAutoProxy
+public class RocketmqAutoConfig {
+
+}

+ 32 - 0
framework-starter/mrxu-starter-xxljob/pom.xml

@@ -0,0 +1,32 @@
+<?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">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.mrxu</groupId>
+        <artifactId>mrxu-upgrader</artifactId>
+        <version>1.0-SNAPSHOT</version>
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+
+    <groupId>com.mrxu</groupId>
+    <artifactId>mrxu-starter-xxljob</artifactId>
+    <version>1.0-SNAPSHOT</version>
+    <packaging>jar</packaging>
+    <name>mrxu-starter-xxljob</name>
+    <description>mrxu starter</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.mrxu</groupId>
+            <artifactId>framework-boot</artifactId>
+        </dependency>
+                <!-- xxl-job-core -->
+        <dependency>
+            <groupId>com.xuxueli</groupId>
+            <artifactId>xxl-job-core</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 56 - 0
framework-starter/mrxu-starter-xxljob/src/main/java/com/mrxu/framework/stater/xxl/config/XxlJobConfig.java

@@ -0,0 +1,56 @@
+package com.mrxu.framework.stater.xxl.config;
+
+import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.cloud.commons.util.InetUtils;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 功能概要:[] <br>
+ *
+ * @author zzt
+ * @date 2021/11/19
+ */
+@Configuration
+@ConditionalOnProperty({"xxl.job.admin.addresses"})
+public class XxlJobConfig {
+    @Value("${xxl.job.admin.addresses}")
+    private String adminAddresses;
+    @Value("${xxl.job.accessToken:#{null}}")
+    private String accessToken;
+    @Value("${xxl.job.executor.appname}")
+    private String appname;
+    @Value("${xxl.job.executor.ip:#{null}}")
+    private String ip;
+    @Value("${xxl.job.executor.port}")
+    private int port;
+    @Value("${xxl.job.executor.logpath:#{null}}")
+    private String logpath;
+    @Value("${xxl.job.executor.logretentiondays:21}")
+    private int logretentiondays;
+
+    public XxlJobConfig() {
+    }
+
+    @Bean
+    public XxlJobSpringExecutor xxlJobExecutor(InetUtils inetUtils) {
+        System.out.println("xxl-job-executor-spring-boot-starter config init.");
+        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
+        xxlJobSpringExecutor.setAdminAddresses(this.adminAddresses);
+        xxlJobSpringExecutor.setAppname(this.appname);
+        xxlJobSpringExecutor.setPort(this.port);
+        xxlJobSpringExecutor.setAccessToken(this.accessToken);
+        xxlJobSpringExecutor.setLogPath(this.logpath);
+        xxlJobSpringExecutor.setLogRetentionDays(this.logretentiondays);
+        if (StringUtils.isBlank(this.ip)) {
+            xxlJobSpringExecutor.setIp(inetUtils.findFirstNonLoopbackAddress().getHostAddress());
+        } else {
+            xxlJobSpringExecutor.setIp(this.ip);
+        }
+
+        return xxlJobSpringExecutor;
+    }
+}

+ 2 - 0
framework-starter/mrxu-starter-xxljob/src/main/resources/META-INF/spring.factories

@@ -0,0 +1,2 @@
+# 指定开启自动配置类
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.mrxu.framework.stater.xxl.config.XxlJobConfig

+ 1 - 0
framework-starter/pom.xml

@@ -20,5 +20,6 @@
     <modules>
         <module>mrxu-starter-redisson</module>
         <module>mrxu-starter-rocketmq</module>
+        <module>mrxu-starter-xxljob</module>
     </modules>
 </project>