🆕 #2018 【微信支付】增加营销代金券接口和营销专用图片上传接口

Co-authored-by: 黄星 <huang.xing@aquilaflycloud.com>
This commit is contained in:
thinsstar
2021-02-26 22:10:38 +08:00
committed by GitHub
parent 52c33e207c
commit bac1b679b4
29 changed files with 3079 additions and 1 deletions

View File

@@ -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;
/**
* 设置消息通知地址
* <pre>
* 文档地址https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_12.shtml
* </pre>
*
* @author thinsstar
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class FavorCallbacksSaveRequest implements Serializable {
private static final long serialVersionUID = 1L;
/**
* <pre>
* 字段名:商户号
* 变量名mchid
* 是否必填:是
* 类型string[1,20]
* 描述:
* 微信支付商户号。
* 示例值9856888
* </pre>
*/
@SerializedName(value = "mchid")
private String mchid;
/**
* <pre>
* 字段名通知url地址
* 变量名notify_url
* 是否必填:是
* 类型string[1,256]
* 描述:
* 支付通知商户url地址。
* 示例值https://pay.weixin.qq.com
* </pre>
*/
@SerializedName(value = "notify_url")
private String notifyUrl;
/**
* <pre>
* 字段名:回调开关
* 变量名switch
* 是否必填:否
* 类型bool
* 描述:
* 如果商户不需要再接收营销事件通知,可通过该开关关闭。枚举值:
* true开启推送
* false停止推送
* 示例值true
* </pre>
*/
@SerializedName(value = "switch")
private Boolean switchBool;
}

View File

@@ -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);
}
/**
* 修改时间
* <p>
* 修改时间遵循rfc3339标准格式格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONEYYYY-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;
/**
* 通知地址
* <p>
* 通知地址
* 示例值api.weixin.qq.com
*/
@SerializedName("notify_url")
private String notifyUrl;
}

View File

@@ -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;
/**
* 发放代金券
* <pre>
* 文档地址https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_2.shtml
* </pre>
*
* @author thinsstar
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class FavorCouponsCreateRequest implements Serializable {
private static final long serialVersionUID = 1L;
/**
* <pre>
* 字段名:批次号
* 变量名stock_id
* 是否必填:是
* 类型string[1,20]
* 描述:
* 微信为每个批次分配的唯一id。
* 校验规则:必须为代金券(全场券或单品券)批次号,不支持立减与折扣。
* 示例值9856000
* </pre>
*/
@SerializedName(value = "stock_id")
private String stockId;
/**
* <pre>
* 字段名:商户单据号
* 变量名out_request_no
* 是否必填:是
* 类型string[1,128]
* 描述:
* 商户此次发放凭据号格式商户id+日期+流水号),可包含英文字母,数字,|_*-等内容,不允许出现其他不合法符号,商户侧需保持唯一性。
* 示例值: 89560002019101000121
* </pre>
*/
@SerializedName(value = "out_request_no")
private String outRequestNo;
/**
* <pre>
* 字段名公众账号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
* </pre>
*/
@SerializedName(value = "appid")
private String appid;
/**
* <pre>
* 字段名:创建批次的商户号
* 变量名stock_creator_mchid
* 是否必填:是
* 类型string[1,20]
* 描述:
* 批次创建方商户号。
* 示例值8956000
* </pre>
*/
@SerializedName(value = "stock_creator_mchid")
private String stockCreatorMchid;
/**
* <pre>
* 字段名:指定面额发券,面额
* 变量名coupon_value
* 是否必填:否
* 类型uint64
* 描述:
* 指定面额发券场景,券面额,其他场景不需要填,单位:分。
* 校验规则:仅在发券时指定面额及门槛的场景才生效,常规发券场景请勿传入该信息。
* 示例值100
* </pre>
*/
@SerializedName(value = "coupon_value")
private Integer couponValue;
/**
* <pre>
* 字段名:指定面额发券,券门槛
* 变量名coupon_minimum
* 是否必填:是
* 类型uint64
* 描述:
* 指定面额发券批次门槛,其他场景不需要,单位:分。
* 校验规则:仅在发券时指定面额及门槛的场景才生效,常规发券场景请勿传入该信息。
* 示例值100
* </pre>
*/
@SerializedName(value = "coupon_minimum")
private Integer couponMinimum;
}

View File

@@ -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
* <p>
* 发放给用户的代金券id。
* 示例值9867041
*/
@SerializedName("coupon_id")
private String couponId;
}

View File

@@ -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);
}
/**
* 创建批次的商户号
* <p>
* 批次创建方商户号
* 示例值9800064
*/
@SerializedName("stock_creator_mchid")
private String stockCreatorMchid;
/**
* 批次号
* <p>
* 微信为每个代金券批次分配的唯一id。
* 示例值9865888
*/
@SerializedName("stock_id")
private String stockId;
/**
* 代金券id
* <p>
* 微信为代金券唯一分配的id。
* 示例值98674556
*/
@SerializedName("coupon_id")
private String couponId;
/**
* 单品优惠特定信息
* <p>
* 单品优惠特定信息
*/
@SerializedName("cut_to_message")
private CutToMessage cutToMessage;
/**
* 代金券名称
* <p>
* 代金券名称
* 示例值:微信支付代金券
*/
@SerializedName("coupon_name")
private String couponName;
/**
* 代金券状态
* <p>
* 代金券状态:
* SENDED可用
* USED已实扣
* EXPIRED已过期
* 示例值EXPIRED
*/
@SerializedName("status")
private String status;
/**
* 使用说明
* <p>
* 代金券描述说明字段。
* 示例值:微信支付营销
*/
@SerializedName("description")
private String description;
/**
* 领券时间
* <p>
* 领券时间遵循rfc3339标准格式格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONEYYYY-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;
/**
* 券类型
* <p>
* 券类型:
* NORMAL满减券
* CUT_TO减至券
* 示例值CUT_TO
*/
@SerializedName("coupon_type")
private String couponType;
/**
* 是否无资金流
* <p>
* 枚举值:
* true
* false
* 示例值true
*/
@SerializedName("no_cash")
private Boolean noCash;
/**
* 可用开始时间
* <p>
* 可用开始时间遵循rfc3339标准格式格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONEYYYY-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;
/**
* 可用结束时间
* <p>
* 可用结束时间遵循rfc3339标准格式格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONEYYYY-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;
/**
* 是否单品优惠
* <p>
* 枚举值:
* true
* false
* 示例值true
*/
@SerializedName("singleitem")
private Boolean singleitem;
/**
* 满减券信息
* <p>
* 普通满减券面额、门槛信息。
*/
@SerializedName("normal_coupon_information")
private NormalCouponInformation normalCouponInformation;
@Data
@NoArgsConstructor
public static class CutToMessage implements Serializable {
/**
* 可用优惠的商品最高单价
* <p>
* 可用优惠的商品最高单价,单位:分。
* 示例值100
*/
@SerializedName(value = "single_price_max")
private Integer singlePriceMax;
/**
* 减至后的优惠单价
* <p>
* 减至后的优惠单价,单位:分。
* 示例值100
*/
@SerializedName(value = "cut_to_price")
private Integer cutToPrice;
}
@Data
@NoArgsConstructor
public static class NormalCouponInformation implements Serializable {
/**
* 面额
* <p>
* 面额,单位:分。
* 示例值100
*/
@SerializedName(value = "coupon_amount")
private Integer couponAmount;
/**
* 门槛
* <p>
* 使用券金额门槛,单位:分。
* 示例值100
*/
@SerializedName(value = "transaction_minimum")
private Integer transactionMinimum;
}
}

View File

@@ -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;
/**
* 根据商户号查用户的券
* <pre>
* 文档地址https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_9.shtml
* </pre>
*
* @author thinsstar
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class FavorCouponsQueryRequest implements Serializable {
private static final long serialVersionUID = 1L;
/**
* <pre>
* 字段名:用户标识
* 变量名openid
* 是否必填:是
* 类型string[1,128]
* 描述:
* 用户在商户appid 下的唯一标识。
* 示例值2323dfsdf342342
* </pre>
*/
@SerializedName(value = "openid")
private String openid;
/**
* <pre>
* 字段名公众账号ID
* 变量名appid
* 是否必填:是
* 类型string[1,128]
* 描述:
* 微信为发券方商户分配的公众账号ID接口传入的所有appid应该为公众号的appid在mp.weixin.qq.com申请的不能为APP的appid在open.weixin.qq.com申请的
* 示例值wx233544546545989
* </pre>
*/
@SerializedName(value = "appid")
private String appid;
/**
* <pre>
* 字段名:批次号
* 变量名stock_id
* 是否必填:否
* 类型string[1,20]
* 描述:
* 批次号是否指定批次号查询填写available_mchid该字段不生效。
* 示例值9865000
* </pre>
*/
@SerializedName(value = "stock_id")
private String stockId;
/**
* <pre>
* 字段名:券状态
* 变量名status
* 是否必填:否
* 类型string[1,6]
* 描述:
* 代金券状态:
* SENDED可用
* USED已实扣
* 填写available_mchid该字段不生效。
* 示例值USED
* </pre>
*/
@SerializedName(value = "status")
private String status;
/**
* <pre>
* 字段名:创建批次的商户号
* 变量名creator_mchid
* 是否必填:否
* 类型string[1,20]
* 描述:
* 批次创建方商户号。
* 示例值9865002
* </pre>
*/
@SerializedName(value = "creator_mchid")
private String creatorMchid;
/**
* <pre>
* 字段名:批次发放商户号
* 变量名sender_mchid
* 是否必填:否
* 类型string[1,20]
* 描述:
* 批次创建方商户号。
* 示例值9865002
* </pre>
*/
@SerializedName(value = "sender_mchid")
private String senderMchid;
/**
* <pre>
* 字段名:可用商户号
* 变量名available_mchid
* 是否必填:否
* 类型string[1,20]
* 描述:
* 批次创建方商户号。
* 示例值9865002
* </pre>
*/
@SerializedName(value = "available_mchid")
private String availableMchid;
/**
* <pre>
* 字段名:分页页码
* 变量名offset
* 是否必填:是
* 类型uint32
* 描述:
* 页码从0开始默认第0页。
* 示例值1
* </pre>
*/
@SerializedName(value = "offset")
private Integer offset;
/**
* <pre>
* 字段名:分页大小
* 变量名limit
* 是否必填:是
* 类型uint32
* 描述:
* 分页大小最大10。
* 示例值8
* </pre>
*/
@SerializedName(value = "limit")
private Integer limit;
}

View File

@@ -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);
}
/**
* 查询结果总数
* <p>
* 查询结果总数
* 示例值100
*/
@SerializedName("total_count")
private Integer totalCount;
/**
* 批次详情
* <p>
* 批次详情
*/
@SerializedName("data")
private List<FavorCouponsGetResult> data;
/**
* 分页大小
* <p>
* 分页大小
* 示例值10
*/
@SerializedName("limit")
private Integer limit;
/**
* 分页页码
* <p>
* 分页页码
* 示例值10
*/
@SerializedName("offset")
private Integer offset;
}

View File

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

View File

@@ -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);
}
/**
* 批次号
* <p>
* 微信为每个代金券批次分配的唯一ID。
* 示例值98065001
*/
@SerializedName("stock_id")
private String stockId;
}

View File

@@ -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);
}
/**
* 下载链接
* <p>
* 流水文件下载链接30s内有效。
* 示例值download://example.csv
*/
@SerializedName("url")
private String url;
/**
* 安全校验码
* <p>
* 文件内容的哈希值,防止篡改。
* 示例值8ae0eb442c408d2e90d669d6f4ad6b7e6e049d6f
*/
@SerializedName("hash_value")
private String hashValue;
/**
* 哈希算法类型
* <p>
* 哈希算法类型目前只支持SHA1。
* 示例值SHA1
*/
@SerializedName("hash_type")
private String hashType;
}

View File

@@ -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);
}
/**
* 批次号
* <p>
* 微信为每个代金券批次分配的唯一id。
* 示例值9836588
*/
@SerializedName("stock_id")
private String stockId;
/**
* 创建批次的商户号
* <p>
* 批次创建方商户号。
* 示例值123456
*/
@SerializedName("stock_creator_mchid")
private String stockCreatorMchid;
/**
* 批次名称
* <p>
* 批次名称
* 示例值:微信支付批次
*/
@SerializedName("stock_name")
private String stockName;
/**
* 批次状态
* <p>
* 批次状态
* 枚举值:
* unactivated未激活
* audit审核中
* running运行中
* stoped已停止
* paused暂停发放
* 示例值paused
*/
@SerializedName("status")
private String status;
/**
* 创建时间
* <p>
* 批次创建时间遵循rfc3339标准格式格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONEYYYY-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;
/**
* 使用说明
* <p>
* 批次描述信息
* 示例值:微信支付营销
*/
@SerializedName("description")
private String description;
/**
* 满减券批次使用规则
* <p>
* 普通发券批次特定信息。
* 示例值1900000109
*/
@SerializedName("stock_use_rule")
private StockUseRule stockUseRule;
/**
* 可用开始时间
* <p>
* 可用开始时间遵循rfc3339标准格式格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONEYYYY-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;
/**
* 可用结束时间
* <p>
* 可用结束时间遵循rfc3339标准格式格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONEYYYY-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;
/**
* 已发券数量
* <p>
* 已发券数量
* 示例值100
*/
@SerializedName("distributed_coupons")
private Integer distributedCoupons;
/**
* 是否无资金流
* <p>
* 是否无资金流。
* ture
* false
* 示例值true
*/
@SerializedName("no_cash")
private Boolean noCash;
/**
* 激活批次的时间
* <p>
* 批次激活开启时间遵循rfc3339标准格式格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONEYYYY-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;
/**
* 终止批次的时间
* <p>
* 批次永久停止时间遵循rfc3339标准格式格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONEYYYY-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;
/**
* 单品优惠特定信息
* <p>
* 单品优惠特定信息
*/
@SerializedName("cut_to_message")
private CutToMessage cutToMessage;
/**
* 是否单品优惠
* <p>
* 枚举值:
* true
* false
* 示例值true
*/
@SerializedName("singleitem")
private Boolean singleitem;
/**
* 批次类型
* <p>
* 批次类型, 枚举值:
* NORMAL代金券批次
* DISCOUNT_CUT立减与折扣
* OTHER其他
* 示例值NORMAL
*/
@SerializedName("stock_type")
private String stockType;
@Data
@NoArgsConstructor
public static class CutToMessage implements Serializable {
/**
* 可用优惠的商品最高单价
* <p>
* 可用优惠的商品最高单价,单位:分。
* 示例值100
*/
@SerializedName(value = "single_price_max")
private Integer singlePriceMax;
/**
* 减至后的优惠单价
* <p>
* 减至后的优惠单价,单位:分。
* 示例值100
*/
@SerializedName(value = "cut_to_price")
private Integer cutToPrice;
}
@Data
@NoArgsConstructor
public static class StockUseRule implements Serializable {
/**
* 发放总上限
* <p>
* 最大发券数
* 示例值100
*/
@SerializedName(value = "max_coupons")
private Integer maxCoupons;
/**
* 总预算
* <p>
* 总消耗金额,单位:分。
* 示例值5000
*/
@SerializedName(value = "max_amount")
private Integer maxAmount;
/**
* 单天发放上限金额
* <p>
* 单天最高消耗金额,单位:分。
* 示例值400
*/
@SerializedName(value = "max_amount_by_day")
private Integer maxAmountByDay;
/**
* 固定面额批次特定信息
* <p>
* 固定面额发券批次特定信息。
*/
@SerializedName(value = "fixed_normal_coupon")
private FixedNormalCoupon fixedNormalCoupon;
/**
* 单个用户可领个数
* <p>
* 单个用户可领个数每个用户最多100张券
* 示例值3
*/
@SerializedName(value = "max_coupons_per_user")
private Integer maxCouponsPerUser;
/**
* 券类型
* <p>
* 枚举值:
* NORMAL满减券
* CUT_TO减至券
* 示例值NORMAL
*/
@SerializedName(value = "coupon_type")
private String couponType;
/**
* 订单优惠标记
* <p>
* 订单优惠标记
* 特殊规则单个优惠标记的字符长度为【1128】,条目个数限制为【150】。
* 示例值:{'123456','23456'}
*/
@SerializedName(value = "goods_tag")
private List<String> goodsTag;
/**
* 支付方式
* <p>
* 默认不限制
* 枚举值:
* MICROAPP小程序支付
* APPPAYAPP支付
* PPAY免密支付
* CARD付款码支付
* FACE人脸支付
* OTHER公众号、扫码等
* 示例值MICROAPP
*/
@SerializedName(value = "trade_type")
private List<String> tradeType;
/**
* 是否可叠加其他优惠
* <p>
* 枚举值:
* true
* false
* 示例值true
*/
@SerializedName(value = "combine_use")
private Boolean combineUse;
}
@Data
@NoArgsConstructor
public static class FixedNormalCoupon implements Serializable {
/**
* 面额
* <p>
* 面额,单位:分。
* 示例值100
*/
@SerializedName(value = "coupon_amount")
private Integer couponAmount;
/**
* 门槛
* <p>
* 使用券金额门槛,单位:分。
* 示例值100
*/
@SerializedName(value = "transaction_minimum")
private Integer transactionMinimum;
}
}

View File

@@ -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);
}
/**
* 可用单品编码总数
* <p>
* 可用单品编码总数。
* 示例值: 200
*/
@SerializedName("total_count")
private Integer totalCount;
/**
* 可用单品编码
* <p>
* 可用单品编码
* 特殊规则单个商品编码的字符长度为【1128】,条目个数限制为【150】。
* 示例值:1232001
*/
@SerializedName("data")
private List<String> data;
/**
* 分页大小
* <p>
* 分页大小最大10。
* 示例值8
*/
@SerializedName("limit")
private Integer limit;
/**
* 分页页码
* <p>
* 页码从0开始默认第0页。
* 示例值1
*/
@SerializedName("offset")
private Integer offset;
/**
* 批次号
* <p>
* 批次号
* 示例值: 9865000
*/
@SerializedName("stock_id")
private String stockId;
}

View File

@@ -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);
}
/**
* 可用商户总数量
* <p>
* 可用商户总数量。
* 示例值: 200
*/
@SerializedName("total_count")
private Integer totalCount;
/**
* 可用商户列表
* <p>
* 可用商户列表
* 特殊规则单个商户号的字符长度为【120】,条目个数限制为【150】。
* 示例值:1232001
*/
@SerializedName("data")
private List<String> data;
/**
* 分页大小
* <p>
* 分页大小最大10。
* 示例值8
*/
@SerializedName("limit")
private Integer limit;
/**
* 分页页码
* <p>
* 页码从0开始默认第0页。
* 示例值1
*/
@SerializedName("offset")
private Integer offset;
/**
* 批次号
* <p>
* 批次号
* 示例值: 9865000
*/
@SerializedName("stock_id")
private String stockId;
}

View File

@@ -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;
/**
* 条件查询代金券批次列表
* <pre>
* 文档地址https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_4.shtml
* </pre>
*
* @author thinsstar
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class FavorStocksQueryRequest implements Serializable {
private static final long serialVersionUID = 1L;
/**
* <pre>
* 字段名:分页页码
* 变量名offset
* 是否必填:是
* 类型uint32
* 描述:
* 页码从0开始默认第0页。
* 示例值1
* </pre>
*/
@SerializedName(value = "offset")
private Integer offset;
/**
* <pre>
* 字段名:分页大小
* 变量名limit
* 是否必填:是
* 类型uint32
* 描述:
* 分页大小最大10。
* 示例值8
* </pre>
*/
@SerializedName(value = "limit")
private Integer limit;
/**
* <pre>
* 字段名:创建批次的商户号
* 变量名stock_creator_mchid
* 是否必填:是
* 类型string[1,20]
* 描述:
* 批次创建方商户号。
* 示例值9856888
* </pre>
*/
@SerializedName(value = "stock_creator_mchid")
private String stockCreatorMchid;
/**
* <pre>
* 字段名:起始时间
* 变量名create_start_time
* 是否必填:否
* 类型string[1,64]
* 描述:
* 起始创建时间遵循rfc3339标准格式格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONEYYYY-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
* </pre>
*/
@SerializedName(value = "create_start_time")
private String createStartTime;
/**
* <pre>
* 字段名:终止时间
* 变量名create_end_time
* 是否必填:否
* 类型string[1,64]
* 描述:
* 终止创建时间遵循rfc3339标准格式格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONEYYYY-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
* </pre>
*/
@SerializedName(value = "create_end_time")
private String createEndTime;
/**
* <pre>
* 字段名:批次状态
* 变量名status
* 是否必填:否
* 类型string[1,20]
* 描述:
* 批次状态,枚举值:
* unactivated未激活
* audit审核中
* running运行中
* stoped已停止
* paused暂停发放
* </pre>
*/
@SerializedName(value = "status")
private String status;
}

View File

@@ -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);
}
/**
* 批次总数
* <p>
* 经过条件筛选,查询到的批次总数量。
* 示例值10
*/
@SerializedName("total_count")
private Integer totalCount;
/**
* 批次详情
* <p>
* 批次详情
*/
@SerializedName("data")
private List<FavorStocksGetResult> data;
/**
* 分页大小
* <p>
* 分页大小最大10。
* 示例值8
*/
@SerializedName("limit")
private Integer limit;
/**
* 分页页码
* <p>
* 页码从0开始默认第0页。
* 示例值1
*/
@SerializedName("offset")
private Integer offset;
}

View File

@@ -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;
/**
* 激活代金券批次
* 暂停代金券批次
* 重启代金券批次
* <pre>
* 文档地址:
* 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
* </pre>
*
* @author thinsstar
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class FavorStocksSetRequest implements Serializable {
private static final long serialVersionUID = 1L;
/**
* <pre>
* 字段名:创建批次的商户号
* 变量名stock_creator_mchid
* 是否必填:是
* 类型string[1,20]
* 描述:
* 批次创建方商户号。
* 示例值8956000
* </pre>
*/
@SerializedName(value = "stock_creator_mchid")
private String stockCreatorMchid;
}

View File

@@ -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);
}
/**
* 生效时间
* <p>
* 生效时间遵循rfc3339标准格式格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONEYYYY-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;
/**
* 批次号
* <p>
* 微信为每个代金券批次分配的唯一ID。
* 示例值98065001
*/
@SerializedName("stock_id")
private String stockId;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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"),
/**
* APPPAYAPP支付
*/
APPPAY("APPPAY"),
/**
* PPAY免密支付
*/
PPAY("PPAY"),
/**
* CARD刷卡支付
*/
CARD("CARD"),
/**
* FACE人脸支付
*/
FACE("FACE"),
/**
* OTHER其他支付
*/
OTHER("OTHER"),
;
/**
* 支付方式
*/
private final String value;
}

View File

@@ -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地址
* <p>
* 微信返回的媒体文件标识url。有效期为永久
* 示例值https://qpic.cn/xxx
*/
@SerializedName("media_url")
private String mediaUrl;
}

View File

@@ -0,0 +1,184 @@
package com.github.binarywang.wxpay.service;
import com.github.binarywang.wxpay.bean.marketing.*;
import com.github.binarywang.wxpay.exception.WxPayException;
/**
* <pre>
* 微信支付营销代金券接口
* </pre>
*
* @author thinsstar
*/
public interface MarketingFavorService {
/**
* <pre>
* 代金券接口-创建代金券批次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
* </pre>
*
* @param request 请求对象
* @return FavorStocksResult 微信返回的批次号信息。
* @throws WxPayException the wx pay exception
*/
FavorStocksCreateResult createFavorStocksV3(FavorStocksCreateRequest request) throws WxPayException;
/**
* <pre>
* 代金券接口-发放代金券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
* </pre>
*
* @param openid 用户openid
* @param request 请求对象
* @return FavorStocksResult 微信返回的发放结果信息。
* @throws WxPayException the wx pay exception
*/
FavorCouponsCreateResult createFavorCouponsV3(String openid, FavorCouponsCreateRequest request) throws WxPayException;
/**
* <pre>
* 代金券接口-激活代金券批次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
* </pre>
*
* @param stockId 批次号
* @param request 请求对象
* @return FavorStocksStartResult 微信返回的激活信息。
* @throws WxPayException the wx pay exception
*/
FavorStocksStartResult startFavorStocksV3(String stockId, FavorStocksSetRequest request) throws WxPayException;
/**
* <pre>
* 代金券接口-条件查询代金券批次列表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
* </pre>
*
* @param request 请求对象
* @return FavorStocksQueryResult 微信返回的批次列表信息。
* @throws WxPayException the wx pay exception
*/
FavorStocksQueryResult queryFavorStocksV3(FavorStocksQueryRequest request) throws WxPayException;
/**
* <pre>
* 代金券接口-查询批次详情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}
* </pre>
*
* @param stockId 批次号
* @param stockCreatorMchid 创建批次的商户号
* @return FavorStocksQueryResult 微信返回的批次详情信息。
* @throws WxPayException the wx pay exception
*/
FavorStocksGetResult getFavorStocksV3(String stockId, String stockCreatorMchid) throws WxPayException;
/**
* <pre>
* 代金券接口-查询代金券详情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}
* </pre>
*
* @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;
/**
* <pre>
* 代金券接口-查询代金券可用商户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
* </pre>
*
* @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;
/**
* <pre>
* 代金券接口-查询代金券可用单品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
* </pre>
*
* @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;
/**
* <pre>
* 代金券接口-根据商户号查用户的券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
* </pre>
*
* @param request 请求对象
* @return FavorCouponsQueryResult 微信返回的用户的券信息。
* @throws WxPayException the wx pay exception
*/
FavorCouponsQueryResult queryFavorCouponsV3(FavorCouponsQueryRequest request) throws WxPayException;
/**
* <pre>
* 代金券接口-下载批次核销明细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
* </pre>
*
* @param stockId 批次号
* @return FavorStocksFlowGetResult 微信返回的下载信息。
* @throws WxPayException the wx pay exception
*/
FavorStocksFlowGetResult getFavorStocksUseFlowV3(String stockId) throws WxPayException;
/**
* <pre>
* 代金券接口-下载批次退款明细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
* </pre>
*
* @param stockId 批次号
* @return FavorStocksFlowGetResult 微信返回的下载信息。
* @throws WxPayException the wx pay exception
*/
FavorStocksFlowGetResult getFavorStocksRefundFlowV3(String stockId) throws WxPayException;
/**
* <pre>
* 代金券接口-设置消息通知地址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
* </pre>
*
* @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;
}

View File

@@ -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;
/**
* <pre>
* 微信支付营销专用媒体接口.
* </pre>
*
* @author thinsstar
*/
public interface MarketingMediaService {
/**
* <pre>
* 营销专用接口-图片上传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
* </pre>
*
* @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;
/**
* <pre>
* 营销专用接口-图片上传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
* </pre>
*
* @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;
}

View File

@@ -15,7 +15,6 @@ import org.apache.http.client.methods.HttpRequestBase;
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();
/**
* 设置企业付款服务类,允许开发者自定义实现类.
*

View File

@@ -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 abstract class BaseWxPayServiceImpl implements WxPayService {
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;

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
/**
* <pre>
* 营销工具代金券测试类
* </pre>
*
* @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));
}
}

View File

@@ -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;
/**
* <pre>
* 营销专用媒体文件上传测试类
* </pre>
*
* @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);
}
}