From 9c57f921c9da8dc55e52f29edc0dc8ea8c2f9588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=98=9F?= Date: Fri, 26 Feb 2021 15:59:55 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E4=BB=98=E8=90=A5=E9=94=80=E4=BB=A3?= =?UTF-8?q?=E9=87=91=E5=88=B8=E6=8E=A5=E5=8F=A3=E5=92=8C=E5=AA=92=E4=BD=93?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../marketing/FavorCallbacksSaveRequest.java | 70 ++ .../marketing/FavorCallbacksSaveResult.java | 38 + .../marketing/FavorCouponsCreateRequest.java | 116 +++ .../marketing/FavorCouponsCreateResult.java | 29 + .../bean/marketing/FavorCouponsGetResult.java | 199 +++++ .../marketing/FavorCouponsQueryRequest.java | 155 ++++ .../marketing/FavorCouponsQueryResult.java | 57 ++ .../marketing/FavorStocksCreateRequest.java | 736 ++++++++++++++++++ .../marketing/FavorStocksCreateResult.java | 29 + .../marketing/FavorStocksFlowGetResult.java | 47 ++ .../bean/marketing/FavorStocksGetResult.java | 319 ++++++++ .../marketing/FavorStocksItemsGetResult.java | 68 ++ .../FavorStocksMerchantsGetResult.java | 68 ++ .../marketing/FavorStocksQueryRequest.java | 114 +++ .../marketing/FavorStocksQueryResult.java | 57 ++ .../bean/marketing/FavorStocksSetRequest.java | 45 ++ .../marketing/FavorStocksStartResult.java | 38 + .../marketing/enums/BackgroundColorEnum.java | 75 ++ .../bean/marketing/enums/StockTypeEnum.java | 25 + .../bean/marketing/enums/TradeTypeEnum.java | 45 ++ .../media/MarketingImageUploadResult.java | 29 + .../wxpay/service/MarketingFavorService.java | 184 +++++ .../wxpay/service/MarketingMediaService.java | 46 ++ .../wxpay/service/WxPayService.java | 15 +- .../service/impl/BaseWxPayServiceImpl.java | 12 + .../impl/MarketingFavorServiceImpl.java | 164 ++++ .../impl/MarketingMediaServiceImpl.java | 60 ++ .../impl/MarketingFavorServiceImplTest.java | 191 +++++ .../impl/MarketingMediaServiceImplTest.java | 49 ++ 29 files changed, 3079 insertions(+), 1 deletion(-) create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCallbacksSaveRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCallbacksSaveResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCouponsCreateRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCouponsCreateResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCouponsGetResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCouponsQueryRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCouponsQueryResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksCreateRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksCreateResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksFlowGetResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksGetResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksItemsGetResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksMerchantsGetResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksQueryRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksQueryResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksSetRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksStartResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/enums/BackgroundColorEnum.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/enums/StockTypeEnum.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/enums/TradeTypeEnum.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/media/MarketingImageUploadResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/MarketingFavorService.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/MarketingMediaService.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/MarketingFavorServiceImpl.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/MarketingMediaServiceImpl.java create mode 100644 weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/MarketingFavorServiceImplTest.java create mode 100644 weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/MarketingMediaServiceImplTest.java diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCallbacksSaveRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCallbacksSaveRequest.java new file mode 100644 index 0000000000..4a0f10d315 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCallbacksSaveRequest.java @@ -0,0 +1,70 @@ +package com.github.binarywang.wxpay.bean.marketing; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 设置消息通知地址 + *
+ *   文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_12.shtml
+ * 
+ * + * @author thinsstar + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FavorCallbacksSaveRequest implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + *
+   * 字段名:商户号
+   * 变量名:mchid
+   * 是否必填:是
+   * 类型:string[1,20]
+   * 描述:
+   *  微信支付商户号。
+   *  示例值:9856888
+   * 
+ */ + @SerializedName(value = "mchid") + private String mchid; + + /** + *
+   * 字段名:通知url地址
+   * 变量名:notify_url
+   * 是否必填:是
+   * 类型:string[1,256]
+   * 描述:
+   *  支付通知商户url地址。
+   *  示例值:https://pay.weixin.qq.com
+   * 
+ */ + @SerializedName(value = "notify_url") + private String notifyUrl; + + /** + *
+   * 字段名:回调开关
+   * 变量名:switch
+   * 是否必填:否
+   * 类型:bool
+   * 描述:
+   *  如果商户不需要再接收营销事件通知,可通过该开关关闭。枚举值:
+   *  true:开启推送
+   *  false:停止推送
+   *  示例值:true
+   * 
+ */ + @SerializedName(value = "switch") + private Boolean switchBool; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCallbacksSaveResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCallbacksSaveResult.java new file mode 100644 index 0000000000..55015a6ac6 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCallbacksSaveResult.java @@ -0,0 +1,38 @@ +package com.github.binarywang.wxpay.bean.marketing; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +/** + * 设置消息通知地址返回结果对象 + * + * @author thinsstar + */ +@NoArgsConstructor +@Data +public class FavorCallbacksSaveResult { + + public static FavorCallbacksSaveResult fromJson(String json) { + return WxGsonBuilder.create().fromJson(json, FavorCallbacksSaveResult.class); + } + + /** + * 修改时间 + *

+ * 修改时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss.sss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35.120+08:00表示,北京时间2015年5月20日 13点29分35秒。 + * 示例值:2015-05-20T13:29:35.120+08:00 + */ + @SerializedName("update_time") + private String updateTime; + + /** + * 通知地址 + *

+ * 通知地址 + * 示例值:api.weixin.qq.com + */ + @SerializedName("notify_url") + private String notifyUrl; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCouponsCreateRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCouponsCreateRequest.java new file mode 100644 index 0000000000..4c8d19dfe9 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCouponsCreateRequest.java @@ -0,0 +1,116 @@ +package com.github.binarywang.wxpay.bean.marketing; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 发放代金券 + *

+ *   文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_2.shtml
+ * 
+ * + * @author thinsstar + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FavorCouponsCreateRequest implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + *
+   * 字段名:批次号
+   * 变量名:stock_id
+   * 是否必填:是
+   * 类型:string[1,20]
+   * 描述:
+   *  微信为每个批次分配的唯一id。
+   *  校验规则:必须为代金券(全场券或单品券)批次号,不支持立减与折扣。
+   *  示例值:9856000
+   * 
+ */ + @SerializedName(value = "stock_id") + private String stockId; + + /** + *
+   * 字段名:商户单据号
+   * 变量名:out_request_no
+   * 是否必填:是
+   * 类型:string[1,128]
+   * 描述:
+   *  商户此次发放凭据号(格式:商户id+日期+流水号),可包含英文字母,数字,|,_,*,-等内容,不允许出现其他不合法符号,商户侧需保持唯一性。
+   *  示例值: 89560002019101000121
+   * 
+ */ + @SerializedName(value = "out_request_no") + private String outRequestNo; + + /** + *
+   * 字段名:公众账号ID
+   * 变量名:appid
+   * 是否必填:是
+   * 类型:string[1,128]
+   * 描述:
+   *  微信为发券方商户分配的公众账号ID,接口传入的所有appid应该为公众号的appid或者小程序的appid(在mp.weixin.qq.com申请的),不能为APP的appid(在open.weixin.qq.com申请的)。。
+   *  校验规则:
+   *  1、该appid需要与接口传入中的openid有对应关系;
+   *  2、该appid需要与调用接口的商户号(即请求头中的商户号)有绑定关系,若未绑定,可参考该指引完成绑定(商家商户号与AppID账号关联管理)
+   *  示例值:wx233544546545989
+   * 
+ */ + @SerializedName(value = "appid") + private String appid; + + /** + *
+   * 字段名:创建批次的商户号
+   * 变量名:stock_creator_mchid
+   * 是否必填:是
+   * 类型:string[1,20]
+   * 描述:
+   *  批次创建方商户号。
+   *  示例值:8956000
+   * 
+ */ + @SerializedName(value = "stock_creator_mchid") + private String stockCreatorMchid; + + /** + *
+   * 字段名:指定面额发券,面额
+   * 变量名:coupon_value
+   * 是否必填:否
+   * 类型:uint64
+   * 描述:
+   *  指定面额发券场景,券面额,其他场景不需要填,单位:分。
+   *  校验规则:仅在发券时指定面额及门槛的场景才生效,常规发券场景请勿传入该信息。
+   *  示例值:100
+   * 
+ */ + @SerializedName(value = "coupon_value") + private Integer couponValue; + + /** + *
+   * 字段名:指定面额发券,券门槛
+   * 变量名:coupon_minimum
+   * 是否必填:是
+   * 类型:uint64
+   * 描述:
+   *  指定面额发券批次门槛,其他场景不需要,单位:分。
+   *  校验规则:仅在发券时指定面额及门槛的场景才生效,常规发券场景请勿传入该信息。
+   *  示例值:100
+   * 
+ */ + @SerializedName(value = "coupon_minimum") + private Integer couponMinimum; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCouponsCreateResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCouponsCreateResult.java new file mode 100644 index 0000000000..e3530e80e1 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCouponsCreateResult.java @@ -0,0 +1,29 @@ +package com.github.binarywang.wxpay.bean.marketing; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +/** + * 发放代金券返回结果对象 + * + * @author thinsstar + */ +@NoArgsConstructor +@Data +public class FavorCouponsCreateResult { + + public static FavorCouponsCreateResult fromJson(String json) { + return WxGsonBuilder.create().fromJson(json, FavorCouponsCreateResult.class); + } + + /** + * 代金券id + *

+ * 发放给用户的代金券id。 + * 示例值:9867041 + */ + @SerializedName("coupon_id") + private String couponId; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCouponsGetResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCouponsGetResult.java new file mode 100644 index 0000000000..b6f6dd854b --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCouponsGetResult.java @@ -0,0 +1,199 @@ +package com.github.binarywang.wxpay.bean.marketing; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +import java.io.Serializable; + +/** + * 查询代金券详情结果对象 + * + * @author thinsstar + */ +@NoArgsConstructor +@Data +public class FavorCouponsGetResult { + + public static FavorCouponsGetResult fromJson(String json) { + return WxGsonBuilder.create().fromJson(json, FavorCouponsGetResult.class); + } + + /** + * 创建批次的商户号 + *

+ * 批次创建方商户号 + * 示例值:9800064 + */ + @SerializedName("stock_creator_mchid") + private String stockCreatorMchid; + + /** + * 批次号 + *

+ * 微信为每个代金券批次分配的唯一id。 + * 示例值:9865888 + */ + @SerializedName("stock_id") + private String stockId; + + /** + * 代金券id + *

+ * 微信为代金券唯一分配的id。 + * 示例值:98674556 + */ + @SerializedName("coupon_id") + private String couponId; + + /** + * 单品优惠特定信息 + *

+ * 单品优惠特定信息 + */ + @SerializedName("cut_to_message") + private CutToMessage cutToMessage; + + /** + * 代金券名称 + *

+ * 代金券名称 + * 示例值:微信支付代金券 + */ + @SerializedName("coupon_name") + private String couponName; + + /** + * 代金券状态 + *

+ * 代金券状态: + * SENDED:可用 + * USED:已实扣 + * EXPIRED:已过期 + * 示例值:EXPIRED + */ + @SerializedName("status") + private String status; + + /** + * 使用说明 + *

+ * 代金券描述说明字段。 + * 示例值:微信支付营销 + */ + @SerializedName("description") + private String description; + + /** + * 领券时间 + *

+ * 领券时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss.sss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35.120+08:00表示,北京时间2015年5月20日 13点29分35秒。 + * 示例值: 2015-05-20T13:29:35.120+08:00 + */ + @SerializedName("create_time") + private String createTime; + + /** + * 券类型 + *

+ * 券类型: + * NORMAL:满减券 + * CUT_TO:减至券 + * 示例值:CUT_TO + */ + @SerializedName("coupon_type") + private String couponType; + + /** + * 是否无资金流 + *

+ * 枚举值: + * true:是 + * false:否 + * 示例值:true + */ + @SerializedName("no_cash") + private Boolean noCash; + + /** + * 可用开始时间 + *

+ * 可用开始时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss.sss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35.120+08:00表示,北京时间2015年5月20日 13点29分35秒。 + * 示例值: 2015-05-20T13:29:35.120+08:00 + */ + @SerializedName("available_begin_time") + private String availableBeginTime; + + /** + * 可用结束时间 + *

+ * 可用结束时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss.sss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35.120+08:00表示,北京时间2015年5月20日 13点29分35秒。 + * 示例值: 2015-05-20T13:29:35.120+08:00 + */ + @SerializedName("available_end_time") + private String availableEndTime; + + /** + * 是否单品优惠 + *

+ * 枚举值: + * true:是 + * false:否 + * 示例值:true + */ + @SerializedName("singleitem") + private Boolean singleitem; + + /** + * 满减券信息 + *

+ * 普通满减券面额、门槛信息。 + */ + @SerializedName("normal_coupon_information") + private NormalCouponInformation normalCouponInformation; + + @Data + @NoArgsConstructor + public static class CutToMessage implements Serializable { + /** + * 可用优惠的商品最高单价 + *

+ * 可用优惠的商品最高单价,单位:分。 + * 示例值:100 + */ + @SerializedName(value = "single_price_max") + private Integer singlePriceMax; + + /** + * 减至后的优惠单价 + *

+ * 减至后的优惠单价,单位:分。 + * 示例值:100 + */ + @SerializedName(value = "cut_to_price") + private Integer cutToPrice; + } + + @Data + @NoArgsConstructor + public static class NormalCouponInformation implements Serializable { + /** + * 面额 + *

+ * 面额,单位:分。 + * 示例值:100 + */ + @SerializedName(value = "coupon_amount") + private Integer couponAmount; + + /** + * 门槛 + *

+ * 使用券金额门槛,单位:分。 + * 示例值:100 + */ + @SerializedName(value = "transaction_minimum") + private Integer transactionMinimum; + } +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCouponsQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCouponsQueryRequest.java new file mode 100644 index 0000000000..e8d263c66c --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCouponsQueryRequest.java @@ -0,0 +1,155 @@ +package com.github.binarywang.wxpay.bean.marketing; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 根据商户号查用户的券 + *

+ *   文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_9.shtml
+ * 
+ * + * @author thinsstar + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FavorCouponsQueryRequest implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + *
+   * 字段名:用户标识
+   * 变量名:openid
+   * 是否必填:是
+   * 类型:string[1,128]
+   * 描述:
+   *  用户在商户appid 下的唯一标识。
+   *  示例值:2323dfsdf342342
+   * 
+ */ + @SerializedName(value = "openid") + private String openid; + + /** + *
+   * 字段名:公众账号ID
+   * 变量名:appid
+   * 是否必填:是
+   * 类型:string[1,128]
+   * 描述:
+   *  微信为发券方商户分配的公众账号ID,接口传入的所有appid应该为公众号的appid(在mp.weixin.qq.com申请的),不能为APP的appid(在open.weixin.qq.com申请的)。
+   *  示例值:wx233544546545989
+   * 
+ */ + @SerializedName(value = "appid") + private String appid; + + /** + *
+   * 字段名:批次号
+   * 变量名:stock_id
+   * 是否必填:否
+   * 类型:string[1,20]
+   * 描述:
+   *  批次号,是否指定批次号查询,填写available_mchid,该字段不生效。
+   *  示例值:9865000
+   * 
+ */ + @SerializedName(value = "stock_id") + private String stockId; + + /** + *
+   * 字段名:券状态
+   * 变量名:status
+   * 是否必填:否
+   * 类型:string[1,6]
+   * 描述:
+   *  代金券状态:
+   *  SENDED:可用
+   *  USED:已实扣
+   *  填写available_mchid,该字段不生效。
+   *  示例值:USED
+   * 
+ */ + @SerializedName(value = "status") + private String status; + + /** + *
+   * 字段名:创建批次的商户号
+   * 变量名:creator_mchid
+   * 是否必填:否
+   * 类型:string[1,20]
+   * 描述:
+   *  批次创建方商户号。
+   *  示例值:9865002
+   * 
+ */ + @SerializedName(value = "creator_mchid") + private String creatorMchid; + + /** + *
+   * 字段名:批次发放商户号
+   * 变量名:sender_mchid
+   * 是否必填:否
+   * 类型:string[1,20]
+   * 描述:
+   *  批次创建方商户号。
+   *  示例值:9865002
+   * 
+ */ + @SerializedName(value = "sender_mchid") + private String senderMchid; + + /** + *
+   * 字段名:可用商户号
+   * 变量名:available_mchid
+   * 是否必填:否
+   * 类型:string[1,20]
+   * 描述:
+   *  批次创建方商户号。
+   *  示例值:9865002
+   * 
+ */ + @SerializedName(value = "available_mchid") + private String availableMchid; + + /** + *
+   * 字段名:分页页码
+   * 变量名:offset
+   * 是否必填:是
+   * 类型:uint32
+   * 描述:
+   *  页码从0开始,默认第0页。
+   *  示例值:1
+   * 
+ */ + @SerializedName(value = "offset") + private Integer offset; + + /** + *
+   * 字段名:分页大小
+   * 变量名:limit
+   * 是否必填:是
+   * 类型:uint32
+   * 描述:
+   *  分页大小,最大10。
+   *  示例值:8
+   * 
+ */ + @SerializedName(value = "limit") + private Integer limit; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCouponsQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCouponsQueryResult.java new file mode 100644 index 0000000000..2c47a99fd5 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorCouponsQueryResult.java @@ -0,0 +1,57 @@ +package com.github.binarywang.wxpay.bean.marketing; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +import java.util.List; + +/** + * 条件查询代金券批次列表结果对象 + * + * @author thinsstar + */ +@NoArgsConstructor +@Data +public class FavorCouponsQueryResult { + + public static FavorCouponsQueryResult fromJson(String json) { + return WxGsonBuilder.create().fromJson(json, FavorCouponsQueryResult.class); + } + + /** + * 查询结果总数 + *

+ * 查询结果总数 + * 示例值:100 + */ + @SerializedName("total_count") + private Integer totalCount; + + /** + * 批次详情 + *

+ * 批次详情 + */ + @SerializedName("data") + private List data; + + /** + * 分页大小 + *

+ * 分页大小 + * 示例值:10 + */ + @SerializedName("limit") + private Integer limit; + + /** + * 分页页码 + *

+ * 分页页码 + * 示例值:10 + */ + @SerializedName("offset") + private Integer offset; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksCreateRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksCreateRequest.java new file mode 100644 index 0000000000..9b75008208 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksCreateRequest.java @@ -0,0 +1,736 @@ +package com.github.binarywang.wxpay.bean.marketing; + +import com.github.binarywang.wxpay.bean.marketing.enums.BackgroundColorEnum; +import com.github.binarywang.wxpay.bean.marketing.enums.StockTypeEnum; +import com.github.binarywang.wxpay.bean.marketing.enums.TradeTypeEnum; +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + * 创建代金券批次 + *

+ *   文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_1.shtml
+ * 
+ * + * @author thinsstar + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FavorStocksCreateRequest implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + *
+   * 字段名:批次名称
+   * 变量名:stock_name
+   * 是否必填:是
+   * 类型:string[1,20]
+   * 描述:
+   *  批次名称
+   *  校验规则:
+   *  1、批次名称最多9个中文汉字
+   *  2、批次名称最多20个字母
+   *  3、批次名称中不能包含不当内容和特殊字符 _ , ; |
+   *  示例值:微信支付代金券批次
+   * 
+ */ + @SerializedName(value = "stock_name") + private String stockName; + + /** + *
+   * 字段名:批次备注
+   * 变量名:comment
+   * 是否必填:否
+   * 类型:string[1,60]
+   * 描述:
+   *  仅制券商户可见,用于自定义信息。
+   *  校验规则:批次备注最多60个UTF8字符数
+   *  示例值:零售批次
+   * 
+ */ + @SerializedName(value = "comment") + private String comment; + + /** + *
+   * 字段名:归属商户号
+   * 变量名:belong_merchant
+   * 是否必填:是
+   * 类型:string[1,20]
+   * 描述:
+   *  批次归属商户号
+   *  该字段暂未开放
+   *  示例值:98568865
+   * 
+ */ + @SerializedName(value = "belong_merchant") + private String belongMerchant; + + /** + *
+   * 字段名:可用时间-开始时间
+   * 变量名:available_begin_time
+   * 是否必填:是
+   * 类型:string[1,32]
+   * 描述:
+   *  批次开始时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss.sss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35.120+08:00表示,北京时间2015年5月20日 13点29分35秒。
+   *  校验规则:
+   *  1、开始时间不可早于当前时间
+   *  2、不能创建365天后开始的批次
+   *  示例值:2015-05-20T13:29:35.120+08:00
+   * 
+ */ + @SerializedName(value = "available_begin_time") + private String availableBeginTime; + + /** + *
+   * 字段名:可用时间-结束时间
+   * 变量名:available_end_time
+   * 是否必填:是
+   * 类型:string[1,32]
+   * 描述:
+   *  批次结束时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss.sss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35.120+08:00表示,北京时间2015年5月20日 13点29分35秒。
+   *  校验规则:
+   *  1、结束时间需晚于开始时间
+   *  2、可用时间最长为90天
+   *  3、有效时间间隔最短为1s
+   *  示例值:2015-05-20T13:29:35.120+08:00
+   * 
+ */ + @SerializedName(value = "available_end_time") + private String availableEndTime; + + /** + *
+   * 字段名:发放规则
+   * 变量名:stock_use_rule
+   * 是否必填:是
+   * 类型:object
+   * 描述:批次使用规则
+   * 
+ */ + @SerializedName(value = "stock_use_rule") + private StockUseRule stockUseRule; + + /** + *
+   * 字段名:样式设置
+   * 变量名:pattern_info
+   * 是否必填:否
+   * 类型:object
+   * 描述:代金券详情页
+   * 
+ */ + @SerializedName(value = "pattern_info") + private PatternInfo patternInfo; + + /** + *
+   * 字段名:核销规则
+   * 变量名:coupon_use_rule
+   * 是否必填:是
+   * 类型:object
+   * 描述:核销规则
+   * 
+ */ + @SerializedName(value = "coupon_use_rule") + private CouponUseRule couponUseRule; + + /** + *
+   * 字段名:营销经费
+   * 变量名:no_cash
+   * 是否必填:是
+   * 类型:bool
+   * 描述:
+   *  营销经费。枚举值:
+   *  true:免充值
+   *  false:预充值
+   *  1、免充值:制券方无需提前充值资金,用户核销代金券时,直接从订单原价中扣除优惠减价金额,最终只将用户实际支付的金额结算给核销商户,商户实收少于订单原价。
+   *  2、预充值:制券方需将优惠预算提前充值到微信支付商户可用余额中,用户核销代金券时,系统从制券方商户可用余额中扣除优惠减价部分对应的资金,连同用户实际支付的资金,一并结算给核销商户,不影响实收。
+   *  示例值:false
+   * 
+ */ + @SerializedName(value = "no_cash") + private Boolean noCash; + + /** + *
+   * 字段名:批次类型
+   * 变量名:stock_type
+   * 是否必填:是
+   * 类型:string[1,16]
+   * 描述:
+   *  批次类型,仅支持:
+   *  NORMAL:固定面额满减券批次
+   *  示例值:NORMAL
+   * 
+ */ + @SerializedName(value = "stock_type") + private StockTypeEnum stockType; + + /** + *
+   * 字段名:商户单据号
+   * 变量名:out_request_no
+   * 是否必填:是
+   * 类型:string[1,128]
+   * 描述:
+   *  商户创建批次凭据号(格式:商户id+日期+流水号),可包含英文字母,数字,|,_,*,-等内容,不允许出现其他不合法符号,商户侧需保持商户单据号全局唯一。
+   * 
+ */ + @SerializedName(value = "out_request_no") + private String outRequestNo; + + /** + *
+   * 字段名:扩展属性
+   * 变量名:ext_info
+   * 是否必填:否
+   * 类型:string[1,128]
+   * 描述:
+   *  扩展属性字段,按json格式,如无需要则不填写。
+   *  示例值:{'exinfo1':'1234','exinfo2':'3456'}
+   * 
+ */ + @SerializedName(value = "ext_info") + private String extInfo; + + @Data + @NoArgsConstructor + public static class StockUseRule implements Serializable { + /** + *
+     * 字段名:发放总上限
+     * 变量名:max_coupons
+     * 是否必填:是
+     * 类型:uint64
+     * 描述:
+     *  最大发券数
+     *  校验规则:
+     *  1、发放总个数最少5个
+     *  2、发放总个数最多1000万个
+     *  示例值:100
+     * 
+ */ + @SerializedName(value = "max_coupons") + private Integer maxCoupons; + + /** + *
+     * 字段名:总预算
+     * 变量名:max_amount
+     * 是否必填:是
+     * 类型:uint64
+     * 描述:
+     *  最大发券预算,当营销经费no_cash选择预充值false时,激活批次时会从制券商户的余额中扣除预算,请保证账户金额充足,单位:分
+     *  max_amount需要等于coupon_amount(面额) * max_coupons(发放总上限)
+     *  校验规则:批次总预算最多1亿元
+     *  示例值:5000
+     * 
+ */ + @SerializedName(value = "max_amount") + private Integer maxAmount; + + /** + *
+     * 字段名:单天预算发放上限
+     * 变量名:max_amount_by_day
+     * 是否必填:否
+     * 类型:uint64
+     * 描述:
+     *  设置此字段,允许指定单天最大发券预算,单位:分。
+     *  校验规则:不能大于总预算
+     *  示例值:400
+     * 
+ */ + @SerializedName(value = "max_amount_by_day") + private Integer maxAmountByDay; + + /** + *
+     * 字段名:单个用户可领个数
+     * 变量名:max_coupons_per_user
+     * 是否必填:是
+     * 类型:uint32
+     * 描述:
+     *  活动期间每个用户可领个数,当开启了自然人限领时,多个微信号同属于一个身份证时,视为同一用户。
+     *  校验规则:
+     *  1、不能大于发放总个数
+     *  2、最少为1个,最多为60个
+     *  示例值:3
+     * 
+ */ + @SerializedName(value = "max_coupons_per_user") + private Integer maxCouponsPerUser; + + /** + *
+     * 字段名:是否开启自然人限制
+     * 变量名:natural_person_limit
+     * 是否必填:是
+     * 类型:bool
+     * 描述:
+     *  当开启了自然人限领时,多个微信号同属于一个身份证时,视为同一用户,枚举值
+     *  true:是
+     *  false:否
+     *  示例值:false
+     * 
+ */ + @SerializedName(value = "natural_person_limit") + private Boolean naturalPersonLimit; + + /** + *
+     * 字段名:是否开启防刷拦截
+     * 变量名:prevent_api_abuse
+     * 是否必填:是
+     * 类型:bool
+     * 描述:
+     *  若开启防刷拦截,当用户命中恶意、小号、机器、羊毛党、黑产等风险行为时,无法成功发放代金券。
+     *  枚举值
+     *  true:是
+     *  false:否
+     *  示例值:false
+     * 
+ */ + @SerializedName(value = "prevent_api_abuse") + private Boolean preventApiAbuse; + } + + @Data + @NoArgsConstructor + public static class PatternInfo implements Serializable { + /** + *
+     * 字段名:使用说明
+     * 变量名:description
+     * 是否必填:是
+     * 类型:string[1,3000]
+     * 描述:
+     *  用于说明详细的活动规则,会展示在代金券详情页。
+     *  校验规则:最多1000个UTF8字符
+     *  示例值:微信支付营销代金券
+     * 
+ */ + @SerializedName(value = "description") + private String description; + + /** + *
+     * 字段名:商户logo
+     * 变量名:merchant_logo
+     * 是否必填:否
+     * 类型:string[1,128]
+     * 描述:
+     *  商户logo ,仅支持通过《图片上传API》接口获取的图片URL地址。
+     *  1、商户logo大小需为120像素*120像素。
+     *  2、支持JPG/JPEG/PNG格式,且图片小于1M。
+     *  3、最多128个UTF8字符
+     *  示例值:https://qpic.cn/xxx
+     * 
+ */ + @SerializedName(value = "merchant_logo") + private String merchantLogo; + + /** + *
+     * 字段名:品牌名称
+     * 变量名:merchant_name
+     * 是否必填:否
+     * 类型:string[1,128]
+     * 描述:
+     *  品牌名称,展示在用户卡包
+     *  校验规则:
+     *  1、最多12个中文汉字
+     *  2、最多36个英文字符
+     *  示例值:微信支付
+     * 
+ */ + @SerializedName(value = "merchant_name") + private String merchantName; + + /** + *
+     * 字段名:背景颜色
+     * 变量名:background_color
+     * 是否必填:否
+     * 类型:string[1,15]
+     * 描述:
+     *  券的背景颜色,可设置10种颜色,色值请参考卡券背景颜色图。颜色取值为颜色图中的颜色名称。可选枚举字段不用则不传,不可以传空值
+     *  示例值:COLOR020
+     * 
+ */ + @SerializedName(value = "background_color") + private BackgroundColorEnum backgroundColor; + + /** + *
+     * 字段名:券详情图片
+     * 变量名:coupon_image
+     * 是否必填:是
+     * 类型:string[1,128]
+     * 描述:
+     *  券详情图片, 850像素*350像素,且图片大小不超过2M,支持JPG/PNG格式,仅支持通过《图片上传API》接口获取的图片URL地址。。
+     *  示例值:https://qpic.cn/xxx
+     * 
+ */ + @SerializedName(value = "coupon_image") + private Boolean couponImage; + } + + @Data + @NoArgsConstructor + public static class CouponUseRule implements Serializable { + /** + *
+     * 字段名:券生效时间
+     * 变量名:coupon_available_time
+     * 是否必填:否
+     * 类型:object
+     * 描述:
+     *  允许指定券的特殊生效时间规则。
+     *  该字段暂未开放
+     * 
+ */ +// @SerializedName(value = "coupon_available_time") +// private CouponAvailableTime couponAvailableTime; + + /** + *
+     * 字段名:固定面额满减券使用规则
+     * 变量名:fixed_normal_coupon
+     * 是否必填:否
+     * 类型:object
+     * 描述:
+     *  stock_type为NORMAL时必填。
+     * 
+ */ + @SerializedName(value = "fixed_normal_coupon") + private FixedNormalCoupon fixedNormalCoupon; + + /** + *
+     * 字段名:订单优惠标记
+     * 变量名:goods_tag
+     * 是否必填:否
+     * 类型:array
+     * 描述:
+     *  订单优惠标记,按json格式。
+     *  商户下单时需要传入相同的标记(goods_tag),用户同时符合其他规则才能享受优惠
+     *  校验规则:
+     *  1、最多允许录入50个
+     *  2、每个订单优惠标记支持字母/数字/下划线,不超过128个UTF8字符。
+     *  示例值:["123321","456654"]
+     * 
+ */ + @SerializedName(value = "goods_tag") + private List goodsTag; + + /** + *
+     * 字段名:指定付款方式
+     * 变量名:limit_pay
+     * 是否必填:否
+     * 类型:array[1,1]
+     * 描述:
+     *  指定付款方式的交易可核销/使用代金券,可指定零钱付款、指定银行卡付款,需填入支付方式编码, 不在此列表中的银行卡,暂不支持此功能。
+     *  校验规则:条目个数限制为【1,1】。
+     *  示例值:ICBC_CREDIT
+     * 
+ */ + @SerializedName(value = "limit_pay") + private List limitPay; + + /** + *
+     * 字段名:指定银行卡BIN
+     * 变量名:limit_card
+     * 是否必填:否
+     * 类型:object
+     * 描述:
+     *  指定银行卡bin付款的交易可核销/使用代金券,当批次限定了指定银行卡时方可生效
+     * 
+ */ + @SerializedName(value = "limit_card") + private LimitCard limitCard; + + /** + *
+     * 字段名:支付方式
+     * 变量名:trade_type
+     * 是否必填:否
+     * 类型:array
+     * 描述:
+     *  允许指定支付方式的交易才可核销/使用代金券,不填则默认“不限”。
+     *  枚举值:
+     *  MICROAPP:小程序支付
+     *  APPPAY:APP支付
+     *  PPAY:免密支付
+     *  CARD:刷卡支付
+     *  FACE:人脸支付
+     *  OTHER:其他支付
+     *  示例值:["MICROAPP","APPPAY"]
+     * 
+ */ + @SerializedName(value = "trade_type") + private List tradeType; + + /** + *
+     * 字段名:是否可叠加其他优惠
+     * 变量名:combine_use
+     * 是否必填:否
+     * 类型:bool
+     * 描述:
+     *  允许指定本优惠是否可以和本商户号创建的其他券同时使用,不填则默认允许同时使用。枚举值:
+     *  true:是
+     *  false:否
+     *  示例值:false
+     * 
+ */ + @SerializedName(value = "combine_use") + private Boolean combineUse; + + /** + *
+     * 字段名:可核销商品编码
+     * 变量名:available_items
+     * 是否必填:否
+     * 类型:array
+     * 描述:
+     *  包含指定SKU商品编码的交易才可核销/使用代金券:活动商户在交易下单时,需传入用户购买的所有SKU商品编码,当命中代金券中设置的商品编码时可享受优惠。
+     *  校验规则:
+     *  1、单个商品编码的字符长度为【1,128】
+     *  2、条目个数限制为【1,50】
+     *  示例值:['123321','456654']
+     * 
+ */ + @SerializedName(value = "available_items") + private List availableItems; + + /** + *
+     * 字段名:不可核销商品编码
+     * 变量名:unavailable_items
+     * 是否必填:否
+     * 类型:array
+     * 描述:
+     *  该字段暂未开放
+     *  包含指定SKU商品编码的交易不可核销/使用代金券。
+     *  校验规则:
+     *  1、单个商品编码的字符长度为【1,128】
+     *  2、条目个数限制为【1,50】
+     *  示例值:['789987','56765']
+     * 
+ */ +// @SerializedName(value = "unavailable_items") +// private List unavailableItems; + + /** + *
+     * 字段名:可用商户号
+     * 变量名:available_merchants
+     * 是否必填:是
+     * 类型:array
+     * 描述:
+     *  可用商户的交易才可核销/使用代金券。当营销经费no_cash=false时,可用商户允许填入任何类型的特约商户或普通商户
+     *  当营销经费no_cash=ture时,分为以下几种情况:
+     *  1、创建商户是普通商户或服务商特约商户(子商户):可添加本商户号或同品牌商户。
+     *  说明:若可用商户中,有特约商户(子商户),那么特约商户自己发起的交易、以及服务商帮特约商户发起的交易,都可以使用代金券。
+     *  2、创建商户是普通服务商:可添加已授权的子商户,详见《申请免充值代金券产品权限》。
+     *  说明:特约商户如果有多个服务商,那么服务商为他发起的交易,只要完成了免充值授权,都可以使用代金券;特约商户自己发起的交易不可以使用代金券。
+     *  3、创建商户是渠道商、银行服务商或从业机构:可直接添加旗下任意子商户,不需要子商户授权。
+     *  示例值:['9856000','9856111']
+     * 
+ */ + @SerializedName(value = "available_merchants") + private List availableMerchants; + } + +// @Data +// @NoArgsConstructor +// public static class CouponAvailableTime implements Serializable { +// /** +// *
+//     * 字段名:固定时间段可用
+//     * 变量名:fix_available_time
+//     * 是否必填:否
+//     * 类型:object
+//     * 描述:
+//     *  允许指定券在特殊时间段生效。当设置固定时间段可用时不可设置领取后N天有效
+//     *  该字段暂未开放
+//     * 
+// */ +// @SerializedName(value = "fix_available_time") +// private FixAvailableTime fixAvailableTime; +// +// /** +// *
+//     * 字段名:领取后N天有效
+//     * 变量名:second_day_available
+//     * 是否必填:否
+//     * 类型:bool
+//     * 描述:
+//     *  领取后,券的开始时间为领券后第二天,如7月1日领券,那么在7月2日00:00:00开始。
+//     *  当设置领取后N天有效时,不可设置固定时间段可用。
+//     *  枚举值:
+//     *  true:是
+//     *  false:否
+//     *  该字段暂未开放
+//     *  示例值:false
+//     * 
+// */ +// @SerializedName(value = "second_day_available") +// private Boolean secondDayAvailable; +// +// /** +// *
+//     * 字段名:领取后有效时间
+//     * 变量名:available_time_after_receive
+//     * 是否必填:否
+//     * 类型:uint32
+//     * 描述:
+//     *  领取后,券的结束时间为领取N天后,如设置领取后7天有效,那么7月1日领券,在7月7日23:59:59失效(在可用时间内计算失效时间,若券还未到领取后N天,但是已经到了可用结束时间,那么也会过期)
+//     *  领取后有效时间,单位:分钟。
+//     *  该字段暂未开放
+//     *  示例值:1440
+//     * 
+// */ +// @SerializedName(value = "available_time_after_receive") +// private Integer availableTimeAfterReceive; +// } +// +// @Data +// @NoArgsConstructor +// public static class FixAvailableTime implements Serializable { +// /** +// *
+//     * 字段名:可用星期数
+//     * 变量名:available_week_day
+//     * 是否必填:否
+//     * 类型:uint32
+//     * 描述:
+//     *  允许指定每周固定星期数生效,0代表周日生效,1代表周一生效,以此类推;不填则代表在可用时间内周一至周日都生效。
+//     *  该字段暂未开放
+//     *  示例值:1,2
+//     * 
+// */ +// @SerializedName(value = "available_week_day") +// private Integer availableWeekDay; +// +// /** +// *
+//     * 字段名:当天开始时间
+//     * 变量名:begin_time
+//     * 是否必填:否
+//     * 类型:uint32
+//     * 描述:
+//     *  允许指定特殊生效星期数中的具体生效的时间段。
+//     *  当天开始时间,单位:秒。
+//     *  该字段暂未开放
+//     *  示例值:0
+//     * 
+// */ +// @SerializedName(value = "begin_time") +// private Integer beginTime; +// +// /** +// *
+//     * 字段名:当天结束时间
+//     * 变量名:end_time
+//     * 是否必填:否
+//     * 类型:uint32
+//     * 描述:
+//     *  允许指定特殊生效星期数中的具体生效的时间段。
+//     *  当天结束时间,单位:秒,默认为23点59分59秒。
+//     *  该字段暂未开放
+//     *  示例值:3600
+//     * 
+// */ +// @SerializedName(value = "end_time") +// private Integer endTime; +// } + + @Data + @NoArgsConstructor + public static class FixedNormalCoupon implements Serializable { + /** + *
+     * 字段名:面额
+     * 变量名:fixed_normal_coupon
+     * 是否必填:是
+     * 类型:uint64
+     * 描述:
+     *  面额,单位:分。
+     *  校验规则:
+     *  1、必须为整数
+     *  2、必须大于1分且小于等于1000元
+     *  示例值:100
+     * 
+ */ + @SerializedName(value = "coupon_amount") + private Integer couponAmount; + + /** + *
+     * 字段名:门槛
+     * 变量名:transaction_minimum
+     * 是否必填:是
+     * 类型:uint64
+     * 描述:
+     *  使用券金额门槛,单位:分。
+     *  若指定可核销商品编码,门槛则为可核销商品部分的消费金额,而不是订单的消费金额。
+     *  校验规则:使用门槛必须大于优惠金额
+     *  示例值:100
+     * 
+ */ + @SerializedName(value = "transaction_minimum") + private Integer transactionMinimum; + } + + @Data + @NoArgsConstructor + public static class LimitCard implements Serializable { + /** + *
+     * 字段名:银行卡名称
+     * 变量名:name
+     * 是否必填:否
+     * 类型:string[1,4]
+     * 描述:
+     *  将在微信支付收银台向用户展示,最多4个中文汉字
+     *  示例值:精粹白金
+     * 
+ */ + @SerializedName(value = "name") + private String name; + + /** + *
+     * 字段名:指定卡BIN
+     * 变量名:bin
+     * 是否必填:否
+     * 类型:array
+     * 描述:
+     *  使用指定卡BIN的银行卡支付方可享受优惠,按json格式
+     *  特殊规则:单个卡BIN的字符长度为【6,9】,条目个数限制为【1,10】。
+     *  示例值:['62123456','62123457']
+     * 
+ */ + @SerializedName(value = "bin") + private List bin; + } + +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksCreateResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksCreateResult.java new file mode 100644 index 0000000000..26ea1796b4 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksCreateResult.java @@ -0,0 +1,29 @@ +package com.github.binarywang.wxpay.bean.marketing; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +/** + * 创建代金券批次返回结果对象 + * + * @author thinsstar + */ +@NoArgsConstructor +@Data +public class FavorStocksCreateResult { + + public static FavorStocksCreateResult fromJson(String json) { + return WxGsonBuilder.create().fromJson(json, FavorStocksCreateResult.class); + } + + /** + * 批次号 + *

+ * 微信为每个代金券批次分配的唯一ID。 + * 示例值:98065001 + */ + @SerializedName("stock_id") + private String stockId; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksFlowGetResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksFlowGetResult.java new file mode 100644 index 0000000000..1c7259da8f --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksFlowGetResult.java @@ -0,0 +1,47 @@ +package com.github.binarywang.wxpay.bean.marketing; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +/** + * 获取下载结果对象 + * + * @author thinsstar + */ +@NoArgsConstructor +@Data +public class FavorStocksFlowGetResult { + + public static FavorStocksFlowGetResult fromJson(String json) { + return WxGsonBuilder.create().fromJson(json, FavorStocksFlowGetResult.class); + } + + /** + * 下载链接 + *

+ * 流水文件下载链接,30s内有效。 + * 示例值:download://example.csv + */ + @SerializedName("url") + private String url; + + /** + * 安全校验码 + *

+ * 文件内容的哈希值,防止篡改。 + * 示例值:8ae0eb442c408d2e90d669d6f4ad6b7e6e049d6f + */ + @SerializedName("hash_value") + private String hashValue; + + /** + * 哈希算法类型 + *

+ * 哈希算法类型,目前只支持SHA1。 + * 示例值:SHA1 + */ + @SerializedName("hash_type") + private String hashType; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksGetResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksGetResult.java new file mode 100644 index 0000000000..cdde077bc7 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksGetResult.java @@ -0,0 +1,319 @@ +package com.github.binarywang.wxpay.bean.marketing; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +import java.io.Serializable; +import java.util.List; + +/** + * 查询批次详情结果对象 + * + * @author thinsstar + */ +@NoArgsConstructor +@Data +public class FavorStocksGetResult { + + public static FavorStocksGetResult fromJson(String json) { + return WxGsonBuilder.create().fromJson(json, FavorStocksGetResult.class); + } + + /** + * 批次号 + *

+ * 微信为每个代金券批次分配的唯一id。 + * 示例值:9836588 + */ + @SerializedName("stock_id") + private String stockId; + + /** + * 创建批次的商户号 + *

+ * 批次创建方商户号。 + * 示例值:123456 + */ + @SerializedName("stock_creator_mchid") + private String stockCreatorMchid; + + /** + * 批次名称 + *

+ * 批次名称 + * 示例值:微信支付批次 + */ + @SerializedName("stock_name") + private String stockName; + + /** + * 批次状态 + *

+ * 批次状态 + * 枚举值: + * unactivated:未激活 + * audit:审核中 + * running:运行中 + * stoped:已停止 + * paused:暂停发放 + * 示例值:paused + */ + @SerializedName("status") + private String status; + + /** + * 创建时间 + *

+ * 批次创建时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss.sss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35.120+08:00表示,北京时间2015年5月20日 13点29分35秒。 + * 示例值:2015-05-20T13:29:35.120+08:00 + */ + @SerializedName("create_time") + private String create_time; + + /** + * 使用说明 + *

+ * 批次描述信息 + * 示例值:微信支付营销 + */ + @SerializedName("description") + private String description; + + /** + * 满减券批次使用规则 + *

+ * 普通发券批次特定信息。 + * 示例值:1900000109 + */ + @SerializedName("stock_use_rule") + private StockUseRule stockUseRule; + + /** + * 可用开始时间 + *

+ * 可用开始时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss.sss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35.120+08:00表示,北京时间2015年5月20日 13点29分35秒。 + * 示例值:2015-05-20T13:29:35.120+08:00 + */ + @SerializedName("available_begin_time") + private String availableBeginTime; + + /** + * 可用结束时间 + *

+ * 可用结束时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss.sss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35.120+08:00表示,北京时间2015年5月20日 13点29分35秒。 + * 示例值:2015-05-20T13:29:35.120+08:00 + */ + @SerializedName("available_end_time") + private String availableEndTime; + + /** + * 已发券数量 + *

+ * 已发券数量 + * 示例值:100 + */ + @SerializedName("distributed_coupons") + private Integer distributedCoupons; + + /** + * 是否无资金流 + *

+ * 是否无资金流。 + * ture:是 + * false:否 + * 示例值:true + */ + @SerializedName("no_cash") + private Boolean noCash; + + /** + * 激活批次的时间 + *

+ * 批次激活开启时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss.sss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35.120+08:00表示,北京时间2015年5月20日 13点29分35秒。 + * 示例值:2015-05-20T13:29:35.120+08:00 + */ + @SerializedName("start_time") + private String startTime; + + /** + * 终止批次的时间 + *

+ * 批次永久停止时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss.sss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35.120+08:00表示,北京时间2015年5月20日 13点29分35秒。 + * 示例值:2015-05-20T13:29:35.120+08:00 + */ + @SerializedName("stop_time") + private String stopTime; + + /** + * 单品优惠特定信息 + *

+ * 单品优惠特定信息 + */ + @SerializedName("cut_to_message") + private CutToMessage cutToMessage; + + /** + * 是否单品优惠 + *

+ * 枚举值: + * true:是 + * false:否 + * 示例值:true + */ + @SerializedName("singleitem") + private Boolean singleitem; + + /** + * 批次类型 + *

+ * 批次类型, 枚举值: + * NORMAL:代金券批次 + * DISCOUNT_CUT:立减与折扣 + * OTHER:其他 + * 示例值:NORMAL + */ + @SerializedName("stock_type") + private String stockType; + + @Data + @NoArgsConstructor + public static class CutToMessage implements Serializable { + /** + * 可用优惠的商品最高单价 + *

+ * 可用优惠的商品最高单价,单位:分。 + * 示例值:100 + */ + @SerializedName(value = "single_price_max") + private Integer singlePriceMax; + + /** + * 减至后的优惠单价 + *

+ * 减至后的优惠单价,单位:分。 + * 示例值:100 + */ + @SerializedName(value = "cut_to_price") + private Integer cutToPrice; + } + + @Data + @NoArgsConstructor + public static class StockUseRule implements Serializable { + /** + * 发放总上限 + *

+ * 最大发券数 + * 示例值:100 + */ + @SerializedName(value = "max_coupons") + private Integer maxCoupons; + + /** + * 总预算 + *

+ * 总消耗金额,单位:分。 + * 示例值:5000 + */ + @SerializedName(value = "max_amount") + private Integer maxAmount; + + /** + * 单天发放上限金额 + *

+ * 单天最高消耗金额,单位:分。 + * 示例值:400 + */ + @SerializedName(value = "max_amount_by_day") + private Integer maxAmountByDay; + + /** + * 固定面额批次特定信息 + *

+ * 固定面额发券批次特定信息。 + */ + @SerializedName(value = "fixed_normal_coupon") + private FixedNormalCoupon fixedNormalCoupon; + + /** + * 单个用户可领个数 + *

+ * 单个用户可领个数,每个用户最多100张券 + * 示例值:3 + */ + @SerializedName(value = "max_coupons_per_user") + private Integer maxCouponsPerUser; + + /** + * 券类型 + *

+ * 枚举值: + * NORMAL:满减券 + * CUT_TO:减至券 + * 示例值:NORMAL + */ + @SerializedName(value = "coupon_type") + private String couponType; + + /** + * 订单优惠标记 + *

+ * 订单优惠标记 + * 特殊规则:单个优惠标记的字符长度为【1,128】,条目个数限制为【1,50】。 + * 示例值:{'123456','23456'} + */ + @SerializedName(value = "goods_tag") + private List goodsTag; + + /** + * 支付方式 + *

+ * 默认不限制 + * 枚举值: + * MICROAPP:小程序支付 + * APPPAY:APP支付 + * PPAY:免密支付 + * CARD:付款码支付 + * FACE:人脸支付 + * OTHER:(公众号、扫码等) + * 示例值:MICROAPP + */ + @SerializedName(value = "trade_type") + private List tradeType; + + /** + * 是否可叠加其他优惠 + *

+ * 枚举值: + * true:是 + * false:否 + * 示例值:true + */ + @SerializedName(value = "combine_use") + private Boolean combineUse; + } + + @Data + @NoArgsConstructor + public static class FixedNormalCoupon implements Serializable { + /** + * 面额 + *

+ * 面额,单位:分。 + * 示例值:100 + */ + @SerializedName(value = "coupon_amount") + private Integer couponAmount; + + /** + * 门槛 + *

+ * 使用券金额门槛,单位:分。 + * 示例值:100 + */ + @SerializedName(value = "transaction_minimum") + private Integer transactionMinimum; + } +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksItemsGetResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksItemsGetResult.java new file mode 100644 index 0000000000..6b3153eb48 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksItemsGetResult.java @@ -0,0 +1,68 @@ +package com.github.binarywang.wxpay.bean.marketing; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +import java.util.List; + +/** + * 查询批次可以单品结果对象 + * + * @author thinsstar + */ +@NoArgsConstructor +@Data +public class FavorStocksItemsGetResult { + + public static FavorStocksItemsGetResult fromJson(String json) { + return WxGsonBuilder.create().fromJson(json, FavorStocksItemsGetResult.class); + } + + /** + * 可用单品编码总数 + *

+ * 可用单品编码总数。 + * 示例值: 200 + */ + @SerializedName("total_count") + private Integer totalCount; + + /** + * 可用单品编码 + *

+ * 可用单品编码 + * 特殊规则:单个商品编码的字符长度为【1,128】,条目个数限制为【1,50】。 + * 示例值:1232001 + */ + @SerializedName("data") + private List data; + + /** + * 分页大小 + *

+ * 分页大小,最大10。 + * 示例值:8 + */ + @SerializedName("limit") + private Integer limit; + + /** + * 分页页码 + *

+ * 页码从0开始,默认第0页。 + * 示例值:1 + */ + @SerializedName("offset") + private Integer offset; + + /** + * 批次号 + *

+ * 批次号 + * 示例值: 9865000 + */ + @SerializedName("stock_id") + private String stockId; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksMerchantsGetResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksMerchantsGetResult.java new file mode 100644 index 0000000000..0e0284b8a2 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksMerchantsGetResult.java @@ -0,0 +1,68 @@ +package com.github.binarywang.wxpay.bean.marketing; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +import java.util.List; + +/** + * 查询批次可以商户结果对象 + * + * @author thinsstar + */ +@NoArgsConstructor +@Data +public class FavorStocksMerchantsGetResult { + + public static FavorStocksMerchantsGetResult fromJson(String json) { + return WxGsonBuilder.create().fromJson(json, FavorStocksMerchantsGetResult.class); + } + + /** + * 可用商户总数量 + *

+ * 可用商户总数量。 + * 示例值: 200 + */ + @SerializedName("total_count") + private Integer totalCount; + + /** + * 可用商户列表 + *

+ * 可用商户列表 + * 特殊规则:单个商户号的字符长度为【1,20】,条目个数限制为【1,50】。 + * 示例值:1232001 + */ + @SerializedName("data") + private List data; + + /** + * 分页大小 + *

+ * 分页大小,最大10。 + * 示例值:8 + */ + @SerializedName("limit") + private Integer limit; + + /** + * 分页页码 + *

+ * 页码从0开始,默认第0页。 + * 示例值:1 + */ + @SerializedName("offset") + private Integer offset; + + /** + * 批次号 + *

+ * 批次号 + * 示例值: 9865000 + */ + @SerializedName("stock_id") + private String stockId; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksQueryRequest.java new file mode 100644 index 0000000000..8e37d2f74c --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksQueryRequest.java @@ -0,0 +1,114 @@ +package com.github.binarywang.wxpay.bean.marketing; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 条件查询代金券批次列表 + *

+ *   文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_4.shtml
+ * 
+ * + * @author thinsstar + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FavorStocksQueryRequest implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + *
+   * 字段名:分页页码
+   * 变量名:offset
+   * 是否必填:是
+   * 类型:uint32
+   * 描述:
+   *  页码从0开始,默认第0页。
+   *  示例值:1
+   * 
+ */ + @SerializedName(value = "offset") + private Integer offset; + + /** + *
+   * 字段名:分页大小
+   * 变量名:limit
+   * 是否必填:是
+   * 类型:uint32
+   * 描述:
+   *  分页大小,最大10。
+   *  示例值:8
+   * 
+ */ + @SerializedName(value = "limit") + private Integer limit; + + /** + *
+   * 字段名:创建批次的商户号
+   * 变量名:stock_creator_mchid
+   * 是否必填:是
+   * 类型:string[1,20]
+   * 描述:
+   *  批次创建方商户号。
+   *  示例值:9856888
+   * 
+ */ + @SerializedName(value = "stock_creator_mchid") + private String stockCreatorMchid; + + /** + *
+   * 字段名:起始时间
+   * 变量名:create_start_time
+   * 是否必填:否
+   * 类型:string[1,64]
+   * 描述:
+   *  起始创建时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss.sss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35.120+08:00表示,北京时间2015年5月20日 13点29分35秒。
+   *  示例值:2015-05-20T13:29:35.120+08:00
+   * 
+ */ + @SerializedName(value = "create_start_time") + private String createStartTime; + + /** + *
+   * 字段名:终止时间
+   * 变量名:create_end_time
+   * 是否必填:否
+   * 类型:string[1,64]
+   * 描述:
+   *  终止创建时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss.sss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35.120+08:00表示,北京时间2015年5月20日 13点29分35秒。
+   *  示例值:2015-05-20T13:29:35.120+08:00
+   * 
+ */ + @SerializedName(value = "create_end_time") + private String createEndTime; + + /** + *
+   * 字段名:批次状态
+   * 变量名:status
+   * 是否必填:否
+   * 类型:string[1,20]
+   * 描述:
+   *  批次状态,枚举值:
+   *  unactivated:未激活
+   *  audit:审核中
+   *  running:运行中
+   *  stoped:已停止
+   *  paused:暂停发放
+   * 
+ */ + @SerializedName(value = "status") + private String status; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksQueryResult.java new file mode 100644 index 0000000000..79259206b0 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksQueryResult.java @@ -0,0 +1,57 @@ +package com.github.binarywang.wxpay.bean.marketing; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +import java.util.List; + +/** + * 条件查询代金券批次列表结果对象 + * + * @author thinsstar + */ +@NoArgsConstructor +@Data +public class FavorStocksQueryResult { + + public static FavorStocksQueryResult fromJson(String json) { + return WxGsonBuilder.create().fromJson(json, FavorStocksQueryResult.class); + } + + /** + * 批次总数 + *

+ * 经过条件筛选,查询到的批次总数量。 + * 示例值:10 + */ + @SerializedName("total_count") + private Integer totalCount; + + /** + * 批次详情 + *

+ * 批次详情 + */ + @SerializedName("data") + private List data; + + /** + * 分页大小 + *

+ * 分页大小,最大10。 + * 示例值:8 + */ + @SerializedName("limit") + private Integer limit; + + /** + * 分页页码 + *

+ * 页码从0开始,默认第0页。 + * 示例值:1 + */ + @SerializedName("offset") + private Integer offset; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksSetRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksSetRequest.java new file mode 100644 index 0000000000..8de99e6529 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksSetRequest.java @@ -0,0 +1,45 @@ +package com.github.binarywang.wxpay.bean.marketing; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 激活代金券批次 + * 暂停代金券批次 + * 重启代金券批次 + *

+ *   文档地址:
+ *   https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_3.shtml
+ *   https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_13.shtml
+ *   https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_14.shtml
+ * 
+ * + * @author thinsstar + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FavorStocksSetRequest implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + *
+   * 字段名:创建批次的商户号
+   * 变量名:stock_creator_mchid
+   * 是否必填:是
+   * 类型:string[1,20]
+   * 描述:
+   *  批次创建方商户号。
+   *  示例值:8956000
+   * 
+ */ + @SerializedName(value = "stock_creator_mchid") + private String stockCreatorMchid; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksStartResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksStartResult.java new file mode 100644 index 0000000000..a66a1740b4 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/FavorStocksStartResult.java @@ -0,0 +1,38 @@ +package com.github.binarywang.wxpay.bean.marketing; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +/** + * 激活代金券批次返回结果对象 + * + * @author thinsstar + */ +@NoArgsConstructor +@Data +public class FavorStocksStartResult { + + public static FavorStocksStartResult fromJson(String json) { + return WxGsonBuilder.create().fromJson(json, FavorStocksStartResult.class); + } + + /** + * 生效时间 + *

+ * 生效时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss.sss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35.120+08:00表示,北京时间2015年5月20日 13点29分35秒。 + * 示例值:2015-05-20T13:29:35.120+08:00 + */ + @SerializedName("start_time") + private String startTime; + + /** + * 批次号 + *

+ * 微信为每个代金券批次分配的唯一ID。 + * 示例值:98065001 + */ + @SerializedName("stock_id") + private String stockId; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/enums/BackgroundColorEnum.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/enums/BackgroundColorEnum.java new file mode 100644 index 0000000000..d9ba753346 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/enums/BackgroundColorEnum.java @@ -0,0 +1,75 @@ +package com.github.binarywang.wxpay.bean.marketing.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 券的背景颜色 + * + * @author thinsstar + */ +@Getter +@AllArgsConstructor +public enum BackgroundColorEnum { + + /** + * 颜色 #63B359 + */ + COLOR010("COLOR010", "#63B359"), + + /** + * 颜色 #2C9F67 + */ + COLOR020("COLOR020", "#2C9F67"), + + /** + * 颜色 #509FC9 + */ + COLOR030("COLOR030", "#509FC9"), + + /** + * 颜色 #5885CF + */ + COLOR040("COLOR040", "#5885CF"), + + /** + * 颜色 #9062C0 + */ + COLOR050("COLOR050", "#9062C0"), + + /** + * 颜色 #D09A45 + */ + COLOR060("COLOR060", "#D09A45"), + + /** + * 颜色 #E4B138 + */ + COLOR070("COLOR070", "#E4B138"), + + /** + * 颜色 #EE903C + */ + COLOR080("COLOR080", "#EE903C"), + + /** + * 颜色 #DD6549 + */ + COLOR090("COLOR090", "#DD6549"), + + /** + * 颜色 #CC463D + */ + COLOR100("COLOR100", "#CC463D"), + ; + + /** + * 色值 + */ + private final String value; + + /** + * 十六进制颜色码 + */ + private final String code; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/enums/StockTypeEnum.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/enums/StockTypeEnum.java new file mode 100644 index 0000000000..a53c5c982b --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/enums/StockTypeEnum.java @@ -0,0 +1,25 @@ +package com.github.binarywang.wxpay.bean.marketing.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 批次类型 + * + * @author thinsstar + */ +@Getter +@AllArgsConstructor +public enum StockTypeEnum { + + /** + * NORMAL:固定面额满减券批次 + */ + NORMAL("NORMAL"), + ; + + /** + * 批次类型 + */ + private final String value; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/enums/TradeTypeEnum.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/enums/TradeTypeEnum.java new file mode 100644 index 0000000000..5e8c96148a --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/enums/TradeTypeEnum.java @@ -0,0 +1,45 @@ +package com.github.binarywang.wxpay.bean.marketing.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 支付方式 + * + * @author thinsstar + */ +@Getter +@AllArgsConstructor +public enum TradeTypeEnum { + + /** + * MICROAPP:小程序支付 + */ + MICROAPP("MICROAPP"), + /** + * APPPAY:APP支付 + */ + APPPAY("APPPAY"), + /** + * PPAY:免密支付 + */ + PPAY("PPAY"), + /** + * CARD:刷卡支付 + */ + CARD("CARD"), + /** + * FACE:人脸支付 + */ + FACE("FACE"), + /** + * OTHER:其他支付 + */ + OTHER("OTHER"), + ; + + /** + * 支付方式 + */ + private final String value; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/media/MarketingImageUploadResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/media/MarketingImageUploadResult.java new file mode 100644 index 0000000000..c0ee3e8a61 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/media/MarketingImageUploadResult.java @@ -0,0 +1,29 @@ +package com.github.binarywang.wxpay.bean.media; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +/** + * 媒体文件上传返回结果对象 + * + * @author thinsstar + */ +@NoArgsConstructor +@Data +public class MarketingImageUploadResult { + + public static MarketingImageUploadResult fromJson(String json) { + return WxGsonBuilder.create().fromJson(json, MarketingImageUploadResult.class); + } + + /** + * 媒体文件URL地址 + *

+ * 微信返回的媒体文件标识url。有效期为永久 + * 示例值:https://qpic.cn/xxx + */ + @SerializedName("media_url") + private String mediaUrl; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/MarketingFavorService.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/MarketingFavorService.java new file mode 100644 index 0000000000..94efa81c4c --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/MarketingFavorService.java @@ -0,0 +1,184 @@ +package com.github.binarywang.wxpay.service; + +import com.github.binarywang.wxpay.bean.marketing.*; +import com.github.binarywang.wxpay.exception.WxPayException; + +/** + *

+ * 微信支付营销代金券接口
+ * 
+ * + * @author thinsstar + */ +public interface MarketingFavorService { + /** + *
+   * 代金券接口-创建代金券批次API
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_1.shtml
+   * 接口链接:https://api.mch.weixin.qq.com/v3/marketing/favor/coupon-stocks
+   * 
+ * + * @param request 请求对象 + * @return FavorStocksResult 微信返回的批次号信息。 + * @throws WxPayException the wx pay exception + */ + FavorStocksCreateResult createFavorStocksV3(FavorStocksCreateRequest request) throws WxPayException; + + /** + *
+   * 代金券接口-发放代金券API
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_2.shtml
+   * 接口链接:https://api.mch.weixin.qq.com/v3/marketing/favor/users/{openid}/coupons
+   * 
+ * + * @param openid 用户openid + * @param request 请求对象 + * @return FavorStocksResult 微信返回的发放结果信息。 + * @throws WxPayException the wx pay exception + */ + FavorCouponsCreateResult createFavorCouponsV3(String openid, FavorCouponsCreateRequest request) throws WxPayException; + + /** + *
+   * 代金券接口-激活代金券批次API
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_3.shtml
+   * 接口链接:https://api.mch.weixin.qq.com/v3/marketing/favor/stocks/{stock_id}/start
+   * 
+ * + * @param stockId 批次号 + * @param request 请求对象 + * @return FavorStocksStartResult 微信返回的激活信息。 + * @throws WxPayException the wx pay exception + */ + FavorStocksStartResult startFavorStocksV3(String stockId, FavorStocksSetRequest request) throws WxPayException; + + /** + *
+   * 代金券接口-条件查询代金券批次列表API
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_4.shtml
+   * 接口链接:https://api.mch.weixin.qq.com/v3/marketing/favor/stocks
+   * 
+ * + * @param request 请求对象 + * @return FavorStocksQueryResult 微信返回的批次列表信息。 + * @throws WxPayException the wx pay exception + */ + FavorStocksQueryResult queryFavorStocksV3(FavorStocksQueryRequest request) throws WxPayException; + + /** + *
+   * 代金券接口-查询批次详情API
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_5.shtml
+   * 接口链接:https://api.mch.weixin.qq.com/v3/marketing/favor/stocks/{stock_id}
+   * 
+ * + * @param stockId 批次号 + * @param stockCreatorMchid 创建批次的商户号 + * @return FavorStocksQueryResult 微信返回的批次详情信息。 + * @throws WxPayException the wx pay exception + */ + FavorStocksGetResult getFavorStocksV3(String stockId, String stockCreatorMchid) throws WxPayException; + + /** + *
+   * 代金券接口-查询代金券详情API
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_6.shtml
+   * 接口链接:https://api.mch.weixin.qq.com/v3/marketing/favor/users/{openid}/coupons/{coupon_id}
+   * 
+ * + * @param couponId 代金券id + * @param appid 公众账号ID + * @param openid 用户openid + * @return FavorCouponsGetResult 微信返回的代金券详情信息。 + * @throws WxPayException the wx pay exception + */ + FavorCouponsGetResult getFavorCouponsV3(String couponId, String appid, String openid) throws WxPayException; + + /** + *
+   * 代金券接口-查询代金券可用商户API
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_7.shtml
+   * 接口链接:https://api.mch.weixin.qq.com/v3/marketing/favor/stocks/{stock_id}/merchants
+   * 
+ * + * @param stockId 批次号 + * @param stockCreatorMchid 创建批次的商户号 + * @param offset 分页大小 + * @param limit 创建批次的商户号 + * @return FavorStocksMerchantsGetResult 微信返回的代金券可用商户信息。 + * @throws WxPayException the wx pay exception + */ + FavorStocksMerchantsGetResult getFavorStocksMerchantsV3(String stockId, String stockCreatorMchid, Integer offset, Integer limit) throws WxPayException; + + /** + *
+   * 代金券接口-查询代金券可用单品API
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_8.shtml
+   * 接口链接:https://api.mch.weixin.qq.com/v3/marketing/favor/stocks/{stock_id}/items
+   * 
+ * + * @param stockId 批次号 + * @param stockCreatorMchid 创建批次的商户号 + * @param offset 分页大小 + * @param limit 创建批次的商户号 + * @return FavorStocksItemsGetResult 微信返回的代金券可用单品信息。 + * @throws WxPayException the wx pay exception + */ + FavorStocksItemsGetResult getFavorStocksItemsV3(String stockId, String stockCreatorMchid, Integer offset, Integer limit) throws WxPayException; + + /** + *
+   * 代金券接口-根据商户号查用户的券API
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_9.shtml
+   * 接口链接:https://api.mch.weixin.qq.com/v3/marketing/favor/users/{openid}/coupons
+   * 
+ * + * @param request 请求对象 + * @return FavorCouponsQueryResult 微信返回的用户的券信息。 + * @throws WxPayException the wx pay exception + */ + FavorCouponsQueryResult queryFavorCouponsV3(FavorCouponsQueryRequest request) throws WxPayException; + + /** + *
+   * 代金券接口-下载批次核销明细API
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_10.shtml
+   * 接口链接:https://api.mch.weixin.qq.com/v3/marketing/favor/stocks/{stock_id}/use-flow
+   * 
+ * + * @param stockId 批次号 + * @return FavorStocksFlowGetResult 微信返回的下载信息。 + * @throws WxPayException the wx pay exception + */ + FavorStocksFlowGetResult getFavorStocksUseFlowV3(String stockId) throws WxPayException; + + /** + *
+   * 代金券接口-下载批次退款明细API
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_11.shtml
+   * 接口链接:https://api.mch.weixin.qq.com/v3/marketing/favor/stocks/{stock_id}/refund-flow
+   * 
+ * + * @param stockId 批次号 + * @return FavorStocksFlowGetResult 微信返回的下载信息。 + * @throws WxPayException the wx pay exception + */ + FavorStocksFlowGetResult getFavorStocksRefundFlowV3(String stockId) throws WxPayException; + + /** + *
+   * 代金券接口-设置消息通知地址API
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_12.shtml
+   * 接口链接:https://api.mch.weixin.qq.com/v3/marketing/favor/callbacks
+   * 
+ * + * @param request 批次号 + * @return FavorCallbacksSaveResult 微信返回的结果信息。 + * @throws WxPayException the wx pay exception + */ + FavorCallbacksSaveResult saveFavorCallbacksV3(FavorCallbacksSaveRequest request) throws WxPayException; + + FavorStocksStartResult pauseFavorStocksV3(String stockId, FavorStocksSetRequest request) throws WxPayException; + + FavorStocksStartResult restartFavorStocksV3(String stockId, FavorStocksSetRequest request) throws WxPayException; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/MarketingMediaService.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/MarketingMediaService.java new file mode 100644 index 0000000000..895cdeff8c --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/MarketingMediaService.java @@ -0,0 +1,46 @@ +package com.github.binarywang.wxpay.service; + +import com.github.binarywang.wxpay.bean.media.MarketingImageUploadResult; +import com.github.binarywang.wxpay.exception.WxPayException; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +/** + *
+ * 微信支付营销专用媒体接口.
+ * 
+ * + * @author thinsstar + */ +public interface MarketingMediaService { + /** + *
+   * 营销专用接口-图片上传API
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter9_0_1.shtml
+   * 接口链接:https://api.mch.weixin.qq.com/v3/marketing/favor/media/image-upload
+   * 
+ * + * @param imageFile 需要上传的图片文件 + * @return ImageUploadResult 微信返回的媒体文件标识Id。示例值:6uqyGjGrCf2GtyXP8bxrbuH9-aAoTjH-rKeSl3Lf4_So6kdkQu4w8BYVP3bzLtvR38lxt4PjtCDXsQpzqge_hQEovHzOhsLleGFQVRF-U_0 + * @throws WxPayException the wx pay exception + */ + MarketingImageUploadResult imageUploadV3(File imageFile) throws WxPayException, IOException; + + /** + *
+   * 营销专用接口-图片上传API
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter9_0_1.shtml
+   * 接口链接:https://api.mch.weixin.qq.com/v3/marketing/favor/media/image-upload
+   * 
+ * + * @param inputStream 需要上传的图片文件流 + * @param fileName 需要上传的图片文件名 + * @return ImageUploadResult 微信返回的媒体文件标识Id。示例值:6uqyGjGrCf2GtyXP8bxrbuH9-aAoTjH-rKeSl3Lf4_So6kdkQu4w8BYVP3bzLtvR38lxt4PjtCDXsQpzqge_hQEovHzOhsLleGFQVRF-U_0 + * @throws WxPayException the wx pay exception + */ + MarketingImageUploadResult imageUploadV3(InputStream inputStream, String fileName) throws WxPayException, IOException; + + +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java index 50ee046fee..366b2907ee 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java @@ -15,7 +15,6 @@ import java.io.File; import java.io.InputStream; -import java.net.URI; import java.util.Date; import java.util.Map; @@ -161,6 +160,20 @@ public interface WxPayService { */ MerchantMediaService getMerchantMediaService(); + /** + * 获取微信支付营销媒体服务类 + * + * @return the marketing media service + */ + MarketingMediaService getMarketingMediaService(); + + /** + * 获取微信支付营销代金券服务类 + * + * @return the marketing favor service + */ + MarketingFavorService getMarketingFavorService(); + /** * 设置企业付款服务类,允许开发者自定义实现类. * diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java index 4c14cda096..23d06c4b46 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java @@ -61,6 +61,8 @@ public abstract class BaseWxPayServiceImpl implements WxPayService { private final PayScoreService payScoreService = new PayScoreServiceImpl(this); private final EcommerceService ecommerceService = new EcommerceServiceImpl(this); private final MerchantMediaService merchantMediaService = new MerchantMediaServiceImpl(this); + private final MarketingMediaService marketingMediaService = new MarketingMediaServiceImpl(this); + private final MarketingFavorService marketingFavorService = new MarketingFavorServiceImpl(this); protected WxPayConfig config; @@ -94,6 +96,16 @@ public MerchantMediaService getMerchantMediaService() { return this.merchantMediaService; } + @Override + public MarketingMediaService getMarketingMediaService() { + return this.marketingMediaService; + } + + @Override + public MarketingFavorService getMarketingFavorService() { + return this.marketingFavorService; + } + @Override public void setEntPayService(EntPayService entPayService) { this.entPayService = entPayService; diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/MarketingFavorServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/MarketingFavorServiceImpl.java new file mode 100644 index 0000000000..c8efc20500 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/MarketingFavorServiceImpl.java @@ -0,0 +1,164 @@ +package com.github.binarywang.wxpay.service.impl; + +import com.github.binarywang.wxpay.bean.marketing.*; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.github.binarywang.wxpay.service.MarketingFavorService; +import com.github.binarywang.wxpay.service.WxPayService; +import com.github.binarywang.wxpay.v3.util.RsaCryptoUtil; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +/** + * 微信支付-营销代金券接口 + * + * @author thinsstar + */ +@Slf4j +@RequiredArgsConstructor +public class MarketingFavorServiceImpl implements MarketingFavorService { + private static final Gson GSON = new GsonBuilder().create(); + private final WxPayService payService; + + @Override + public FavorStocksCreateResult createFavorStocksV3(FavorStocksCreateRequest request) throws WxPayException { + String url = String.format("%s/v3/marketing/favor/coupon-stocks", this.payService.getPayBaseUrl()); + RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate()); + String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request)); + return GSON.fromJson(result, FavorStocksCreateResult.class); + } + + @Override + public FavorCouponsCreateResult createFavorCouponsV3(String openid, FavorCouponsCreateRequest request) throws WxPayException { + String url = String.format("%s/v3/marketing/favor/users/%s/coupons", this.payService.getPayBaseUrl(), openid); + RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate()); + String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request)); + return GSON.fromJson(result, FavorCouponsCreateResult.class); + } + + @Override + public FavorStocksStartResult startFavorStocksV3(String stockId, FavorStocksSetRequest request) throws WxPayException { + String url = String.format("%s/v3/marketing/favor/stocks/%s/start", this.payService.getPayBaseUrl(), stockId); + RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate()); + String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request)); + return GSON.fromJson(result, FavorStocksStartResult.class); + } + + @Override + public FavorStocksQueryResult queryFavorStocksV3(FavorStocksQueryRequest request) throws WxPayException { + String url = String.format("%s/v3/marketing/favor/stocks", this.payService.getPayBaseUrl()); + String query = String.format("?offset=%s&limit=%s&stock_creator_mchid=%s", request.getOffset(), request.getLimit(), request.getStockCreatorMchid()); + if (StringUtils.isNotBlank(request.getCreateStartTime())) { + query += "&create_start_time=" + request.getCreateStartTime(); + } + if (StringUtils.isNotBlank(request.getCreateEndTime())) { + query += "&create_end_time=" + request.getCreateEndTime(); + } + if (StringUtils.isNotBlank(request.getStatus())) { + query += "&status=" + request.getStatus(); + } + String result = this.payService.getV3(url + query); + return GSON.fromJson(result, FavorStocksQueryResult.class); + } + + @Override + public FavorStocksGetResult getFavorStocksV3(String stockId, String stockCreatorMchid) throws WxPayException { + String url = String.format("%s/v3/marketing/favor/stocks/%s", this.payService.getPayBaseUrl(), stockId); + String query = String.format("?stock_creator_mchid=%s", stockCreatorMchid); + String result = this.payService.getV3(url + query); + return GSON.fromJson(result, FavorStocksGetResult.class); + } + + @Override + public FavorCouponsGetResult getFavorCouponsV3(String couponId, String appid, String openid) throws WxPayException { + String url = String.format("%s/v3/marketing/favor/users/%s/coupons/%s", this.payService.getPayBaseUrl(), openid, couponId); + String query = String.format("?appid=%s", appid); + String result = this.payService.getV3(url + query); + return GSON.fromJson(result, FavorCouponsGetResult.class); + } + + @Override + public FavorStocksMerchantsGetResult getFavorStocksMerchantsV3(String stockId, String stockCreatorMchid, Integer offset, Integer limit) throws WxPayException { + String url = String.format("%s/v3/marketing/favor/stocks/%s/merchants", this.payService.getPayBaseUrl(), stockId); + String query = String.format("?stock_creator_mchid=%s&offset=%s&limit=%s", stockCreatorMchid, offset, limit); + String result = this.payService.getV3(url + query); + return GSON.fromJson(result, FavorStocksMerchantsGetResult.class); + } + + @Override + public FavorStocksItemsGetResult getFavorStocksItemsV3(String stockId, String stockCreatorMchid, Integer offset, Integer limit) throws WxPayException { + String url = String.format("%s/v3/marketing/favor/stocks/%s/items", this.payService.getPayBaseUrl(), stockId); + String query = String.format("?stock_creator_mchid=%s&offset=%s&limit=%s", stockCreatorMchid, offset, limit); + String result = this.payService.getV3(url + query); + return GSON.fromJson(result, FavorStocksItemsGetResult.class); + } + + @Override + public FavorCouponsQueryResult queryFavorCouponsV3(FavorCouponsQueryRequest request) throws WxPayException { + String url = String.format("%s/v3/marketing/favor/users/%s/coupons", this.payService.getPayBaseUrl(), request.getOpenid()); + String query = String.format("?appid=%s", request.getAppid()); + if (StringUtils.isNotBlank(request.getStockId())) { + query += "&stock_id=" + request.getStockId(); + } + if (StringUtils.isNotBlank(request.getStatus())) { + query += "&status=" + request.getStatus(); + } + if (StringUtils.isNotBlank(request.getCreatorMchid())) { + query += "&creator_mchid=" + request.getCreatorMchid(); + } + if (StringUtils.isNotBlank(request.getSenderMchid())) { + query += "&sender_mchid=" + request.getSenderMchid(); + } + if (StringUtils.isNotBlank(request.getAvailableMchid())) { + query += "&available_mchid=" + request.getAvailableMchid(); + } + if (request.getOffset() != null) { + query += "&offset=" + request.getOffset(); + } + if (request.getLimit() != null) { + query += "&limit=" + request.getLimit(); + } + String result = this.payService.getV3(url + query); + return GSON.fromJson(result, FavorCouponsQueryResult.class); + } + + @Override + public FavorStocksFlowGetResult getFavorStocksUseFlowV3(String stockId) throws WxPayException { + String url = String.format("%s/v3/marketing/favor/stocks/%s/use-flow", this.payService.getPayBaseUrl(), stockId); + String result = this.payService.getV3(url); + return GSON.fromJson(result, FavorStocksFlowGetResult.class); + } + + @Override + public FavorStocksFlowGetResult getFavorStocksRefundFlowV3(String stockId) throws WxPayException { + String url = String.format("%s/v3/marketing/favor/stocks/%s/refund-flow", this.payService.getPayBaseUrl(), stockId); + String result = this.payService.getV3(url); + return GSON.fromJson(result, FavorStocksFlowGetResult.class); + } + + @Override + public FavorCallbacksSaveResult saveFavorCallbacksV3(FavorCallbacksSaveRequest request) throws WxPayException { + String url = String.format("%s/v3/marketing/favor/callbacks", this.payService.getPayBaseUrl()); + RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate()); + String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request)); + return GSON.fromJson(result, FavorCallbacksSaveResult.class); + } + + @Override + public FavorStocksStartResult pauseFavorStocksV3(String stockId, FavorStocksSetRequest request) throws WxPayException { + String url = String.format("%s/v3/marketing/favor/stocks/%s/start", this.payService.getPayBaseUrl(), stockId); + RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate()); + String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request)); + return GSON.fromJson(result, FavorStocksStartResult.class); + } + + @Override + public FavorStocksStartResult restartFavorStocksV3(String stockId, FavorStocksSetRequest request) throws WxPayException { + String url = String.format("%s/v3/marketing/favor/stocks/%s/start", this.payService.getPayBaseUrl(), stockId); + RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate()); + String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request)); + return GSON.fromJson(result, FavorStocksStartResult.class); + } +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/MarketingMediaServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/MarketingMediaServiceImpl.java new file mode 100644 index 0000000000..805af6180e --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/MarketingMediaServiceImpl.java @@ -0,0 +1,60 @@ +package com.github.binarywang.wxpay.service.impl; + +import com.github.binarywang.wxpay.bean.media.MarketingImageUploadResult; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.github.binarywang.wxpay.service.MarketingMediaService; +import com.github.binarywang.wxpay.service.WxPayService; +import com.github.binarywang.wxpay.v3.WechatPayUploadHttpPost; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.digest.DigestUtils; + +import java.io.*; +import java.net.URI; + +/** + * 微信支付-营销专用媒体文件上传service + * + * @author thinsstar + */ +@Slf4j +@RequiredArgsConstructor +public class MarketingMediaServiceImpl implements MarketingMediaService { + private final WxPayService payService; + + @Override + public MarketingImageUploadResult imageUploadV3(File imageFile) throws WxPayException, IOException { + String url = String.format("%s/v3/marketing/favor/media/image-upload", this.payService.getPayBaseUrl()); + try (FileInputStream s1 = new FileInputStream(imageFile)) { + String sha256 = DigestUtils.sha256Hex(s1); + try (InputStream s2 = new FileInputStream(imageFile)) { + WechatPayUploadHttpPost request = new WechatPayUploadHttpPost.Builder(URI.create(url)) + .withImage(imageFile.getName(), sha256, s2) + .build(); + String result = this.payService.postV3(url, request); + return MarketingImageUploadResult.fromJson(result); + } + } + } + + @Override + public MarketingImageUploadResult imageUploadV3(InputStream inputStream, String fileName) throws WxPayException, IOException { + String url = String.format("%s/v3/marketing/favor/media/image-upload", this.payService.getPayBaseUrl()); + try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) { + byte[] buffer = new byte[2048]; + int len; + while ((len = inputStream.read(buffer)) > -1) { + bos.write(buffer, 0, len); + } + bos.flush(); + byte[] data = bos.toByteArray(); + String sha256 = DigestUtils.sha256Hex(data); + WechatPayUploadHttpPost request = new WechatPayUploadHttpPost.Builder(URI.create(url)) + .withImage(fileName, sha256, new ByteArrayInputStream(data)) + .build(); + String result = this.payService.postV3(url, request); + return MarketingImageUploadResult.fromJson(result); + } + } + +} diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/MarketingFavorServiceImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/MarketingFavorServiceImplTest.java new file mode 100644 index 0000000000..48fdf8c8e5 --- /dev/null +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/MarketingFavorServiceImplTest.java @@ -0,0 +1,191 @@ +package com.github.binarywang.wxpay.service.impl; + +import com.github.binarywang.wxpay.bean.marketing.*; +import com.github.binarywang.wxpay.bean.marketing.enums.StockTypeEnum; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.github.binarywang.wxpay.service.MarketingFavorService; +import com.github.binarywang.wxpay.service.WxPayService; +import com.github.binarywang.wxpay.testbase.ApiTestModule; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import java.util.Collections; + +/** + *
+ *  营销工具代金券测试类
+ * 
+ * + * @author thinsstar + */ +@Slf4j +@Test +@Guice(modules = ApiTestModule.class) +public class MarketingFavorServiceImplTest { + + @Inject + private WxPayService wxPayService; + + private static final Gson GSON = new GsonBuilder().create(); + + private final String stockId = "批次id"; + + private final String appId = "公众号id"; + private final String openId = "微信openid"; + + @Test + public void testCreateFavorStocksV3() throws WxPayException { + FavorStocksCreateRequest request = new FavorStocksCreateRequest(); + request.setStockName("测试代金券"); + request.setComment("测试代金券备注"); + request.setBelongMerchant(wxPayService.getConfig().getMchId()); + request.setAvailableBeginTime("2021-02-05T00:00:00.000+08:00"); + request.setAvailableEndTime("2021-03-31T00:00:00.000+08:00"); + request.setNoCash(false); + request.setStockType(StockTypeEnum.NORMAL); + request.setOutRequestNo(wxPayService.getConfig().getMchId() + "20210204" + "1234567890"); + //发放规则 + FavorStocksCreateRequest.StockUseRule stockUseRule = new FavorStocksCreateRequest.StockUseRule(); + stockUseRule.setMaxCoupons(5); + stockUseRule.setMaxCouponsPerUser(5); + stockUseRule.setNaturalPersonLimit(true); + stockUseRule.setPreventApiAbuse(false); + stockUseRule.setMaxAmount(50); + request.setStockUseRule(stockUseRule); + //样式设置 +// FavorStocksCreateRequest.PatternInfo patternInfo = new FavorStocksCreateRequest.PatternInfo(); +// request.setPatternInfo(patternInfo); + //核销规则 + FavorStocksCreateRequest.CouponUseRule couponUseRule = new FavorStocksCreateRequest.CouponUseRule(); + FavorStocksCreateRequest.FixedNormalCoupon fixedNormalCoupon = new FavorStocksCreateRequest.FixedNormalCoupon(); + fixedNormalCoupon.setCouponAmount(10); + fixedNormalCoupon.setTransactionMinimum(11); + couponUseRule.setFixedNormalCoupon(fixedNormalCoupon); + couponUseRule.setCombineUse(true); + couponUseRule.setAvailableMerchants(Collections.singletonList(wxPayService.getConfig().getMchId())); + request.setCouponUseRule(couponUseRule); + FavorStocksCreateResult result = wxPayService.getMarketingFavorService().createFavorStocksV3(request); + String stockId = result.getStockId(); + + log.info("stockId: [{}]", stockId); + } + + @Test + public void testCreateFavorCouponsV3() throws WxPayException { + MarketingFavorService marketingFavorService = new MarketingFavorServiceImpl(wxPayService); + FavorCouponsCreateRequest request = new FavorCouponsCreateRequest(); + request.setStockCreatorMchid(wxPayService.getConfig().getMchId()); + request.setStockId(stockId); + request.setAppid(appId); + request.setOutRequestNo(wxPayService.getConfig().getMchId() + "20210204" + "1234567890"); + FavorCouponsCreateResult result = wxPayService.getMarketingFavorService().createFavorCouponsV3(openId, request); + + log.info("result: {}", GSON.toJson(result)); + } + + @Test + public void testStartFavorStocksV3() throws WxPayException { + FavorStocksSetRequest request = new FavorStocksSetRequest(); + request.setStockCreatorMchid(wxPayService.getConfig().getMchId()); + FavorStocksStartResult result = wxPayService.getMarketingFavorService().startFavorStocksV3(stockId, request); + + log.info("result: {}", GSON.toJson(result)); + } + + @Test + public void testQueryFavorStocksV3() throws WxPayException { + FavorStocksQueryRequest request = new FavorStocksQueryRequest(); + request.setOffset(0); + request.setLimit(10); + request.setStockCreatorMchid(wxPayService.getConfig().getMchId()); + FavorStocksQueryResult result = wxPayService.getMarketingFavorService().queryFavorStocksV3(request); + + log.info("result: {}", GSON.toJson(result)); + } + + @Test + public void testGetFavorStocksV3() throws WxPayException { + FavorStocksGetResult result = wxPayService.getMarketingFavorService().getFavorStocksV3(stockId, wxPayService.getConfig().getMchId()); + + log.info("result: {}", GSON.toJson(result)); + } + + @Test + public void testGetFavorCouponsV3() throws WxPayException { + FavorCouponsGetResult result = wxPayService.getMarketingFavorService().getFavorCouponsV3("20387541242", appId, openId); + + log.info("result: {}", GSON.toJson(result)); + } + + @Test + public void testGetFavorStocksMerchantsV3() throws WxPayException { + FavorStocksMerchantsGetResult result = wxPayService.getMarketingFavorService().getFavorStocksMerchantsV3(stockId, wxPayService.getConfig().getMchId(), 0, 50); + + log.info("result: {}", GSON.toJson(result)); + } + + @Test + public void testGetFavorStocksItemsV3() throws WxPayException { + FavorStocksItemsGetResult result = wxPayService.getMarketingFavorService().getFavorStocksItemsV3(stockId, wxPayService.getConfig().getMchId(), 0, 100); + + log.info("result: {}", GSON.toJson(result)); + } + + @Test + public void testQueryFavorCouponsV3() throws WxPayException { + FavorCouponsQueryRequest request = new FavorCouponsQueryRequest(); + request.setAppid(appId); + request.setOpenid(openId); + request.setAvailableMchid(wxPayService.getConfig().getMchId()); + FavorCouponsQueryResult result = wxPayService.getMarketingFavorService().queryFavorCouponsV3(request); + + log.info("result: {}", GSON.toJson(result)); + } + + @Test + public void testGetFavorStocksUseFlowV3() throws WxPayException { + FavorStocksFlowGetResult result = wxPayService.getMarketingFavorService().getFavorStocksUseFlowV3(stockId); + + log.info("result: {}", GSON.toJson(result)); + } + + @Test + public void testGetFavorStocksRefundFlowV3() throws WxPayException { + FavorStocksFlowGetResult result = wxPayService.getMarketingFavorService().getFavorStocksRefundFlowV3(stockId); + + log.info("result: {}", GSON.toJson(result)); + } + + @Test + public void testSaveFavorCallbacksV3() throws WxPayException { + FavorCallbacksSaveRequest request = new FavorCallbacksSaveRequest(); + request.setMchid(wxPayService.getConfig().getMchId()); + request.setNotifyUrl("你的回调地址"); + request.setSwitchBool(false); + FavorCallbacksSaveResult result = wxPayService.getMarketingFavorService().saveFavorCallbacksV3(request); + + log.info("result: {}", GSON.toJson(result)); + } + + @Test + public void testPauseFavorStocksV3() throws WxPayException { + FavorStocksSetRequest request = new FavorStocksSetRequest(); + request.setStockCreatorMchid(wxPayService.getConfig().getMchId()); + FavorStocksStartResult result = wxPayService.getMarketingFavorService().pauseFavorStocksV3(stockId, request); + + log.info("result: {}", GSON.toJson(result)); + } + + @Test + public void testRestartFavorStocksV3() throws WxPayException { + FavorStocksSetRequest request = new FavorStocksSetRequest(); + request.setStockCreatorMchid(wxPayService.getConfig().getMchId()); + FavorStocksStartResult result = wxPayService.getMarketingFavorService().restartFavorStocksV3(stockId, request); + + log.info("result: {}", GSON.toJson(result)); + } +} diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/MarketingMediaServiceImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/MarketingMediaServiceImplTest.java new file mode 100644 index 0000000000..c03ed0d31c --- /dev/null +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/MarketingMediaServiceImplTest.java @@ -0,0 +1,49 @@ +package com.github.binarywang.wxpay.service.impl; + +import com.github.binarywang.wxpay.bean.media.MarketingImageUploadResult; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.github.binarywang.wxpay.service.WxPayService; +import com.github.binarywang.wxpay.testbase.ApiTestModule; +import com.google.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.IOException; + +/** + *
+ *  营销专用媒体文件上传测试类
+ * 
+ * + * @author thinsstar + */ +@Slf4j +@Test +@Guice(modules = ApiTestModule.class) +public class MarketingMediaServiceImplTest { + + @Inject + private WxPayService wxPayService; + + @Test + public void testMarketingImageUploadV3() throws WxPayException, IOException { + String filePath = "你的图片文件的路径地址"; + + File file = new File(filePath); + + MarketingImageUploadResult imageUploadResult = wxPayService.getMarketingMediaService().imageUploadV3(file); + String mediaUrl = imageUploadResult.getMediaUrl(); + + log.info("mediaUrl:[{}]", mediaUrl); + + File file2 = new File(filePath); + + MarketingImageUploadResult imageUploadResult2 = wxPayService.getMarketingMediaService().imageUploadV3(file2); + String mediaUrl2 = imageUploadResult2.getMediaUrl(); + + log.info("mediaUrl2:[{}]", mediaUrl2); + + } +}