context, final WxSessionManager sessionManager);
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/BaseWxChannelService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/BaseWxChannelService.java
new file mode 100644
index 0000000000..f745ff3e41
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/BaseWxChannelService.java
@@ -0,0 +1,136 @@
+package me.chanjar.weixin.channel.api;
+
+import me.chanjar.weixin.channel.config.WxChannelConfig;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.service.WxService;
+import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor;
+import me.chanjar.weixin.common.util.http.RequestExecutor;
+import me.chanjar.weixin.common.util.http.RequestHttp;
+
+/**
+ * The interface Wx Channel service
+ *
+ * @author Zeyes
+ */
+public interface BaseWxChannelService extends WxService {
+
+ /**
+ *
+ * 验证消息的确来自微信服务器.
+ * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421135319&token=&lang=zh_CN
+ *
+ *
+ * @param timestamp the timestamp
+ * @param nonce the nonce
+ * @param signature the signature
+ * @return the boolean
+ */
+ boolean checkSignature(String timestamp, String nonce, String signature);
+
+ /**
+ * 获取access_token, 不强制刷新access_token.
+ *
+ * @return the access token
+ *
+ * @throws WxErrorException the wx error exception
+ * @see #getAccessToken(boolean) #getAccessToken(boolean)
+ */
+ String getAccessToken() throws WxErrorException;
+
+ /**
+ *
+ * 获取access_token,本方法线程安全.
+ * 且在多线程同时刷新时只刷新一次,避免超出2000次/日的调用次数上限
+ *
+ * 另:本service的所有方法都会在access_token过期是调用此方法
+ *
+ * 程序员在非必要情况下尽量不要主动调用此方法
+ *
+ * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183&token=&lang=zh_CN
+ *
+ *
+ * @param forceRefresh 强制刷新
+ * @return the access token
+ *
+ * @throws WxErrorException the wx error exception
+ */
+ String getAccessToken(boolean forceRefresh) throws WxErrorException;
+
+ /**
+ *
+ * Service没有实现某个API的时候,可以用这个,
+ * 比{@link #get}和{@link #post}方法更灵活,可以自己构造RequestExecutor用来处理不同的参数和不同的返回类型。
+ * 可以参考,{@link MediaUploadRequestExecutor}的实现方法
+ *
+ *
+ * @param .
+ * @param .
+ * @param executor 执行器
+ * @param uri 接口请求地址
+ * @param data 参数或请求数据
+ * @return . t
+ *
+ * @throws WxErrorException the wx error exception
+ */
+ T execute(RequestExecutor executor, String uri, E data) throws WxErrorException;
+
+ /**
+ * 执行器
+ *
+ * @param .
+ * @param .
+ * @param executor 执行器
+ * @param uri 接口请求地址
+ * @param data 参数或请求数据
+ * @return T
+ *
+ * @throws WxErrorException the wx error exception
+ */
+ T executeWithoutLog(RequestExecutor executor, String uri, E data) throws WxErrorException;
+
+ /**
+ *
+ * 设置当微信系统响应系统繁忙时,要等待多少 retrySleepMillis(ms) * 2^(重试次数 - 1) 再发起重试.
+ * 默认:1000ms
+ *
+ *
+ * @param retrySleepMillis 重试等待毫秒数
+ */
+ void setRetrySleepMillis(int retrySleepMillis);
+
+ /**
+ *
+ * 设置当微信系统响应系统繁忙时,最大重试次数.
+ * 默认:5次
+ *
+ *
+ * @param maxRetryTimes 最大重试次数
+ */
+ void setMaxRetryTimes(int maxRetryTimes);
+
+ /**
+ * WxChannelConfig对象
+ *
+ * @return WxMaConfig wx channel config
+ */
+ WxChannelConfig getConfig();
+
+ /**
+ * 注入 {@link WxChannelConfig} 的实现.
+ *
+ * @param config config
+ */
+ void setConfig(WxChannelConfig config);
+
+ /**
+ * 初始化http请求对象.
+ */
+ void initHttp();
+
+ /**
+ * 请求http请求相关信息.
+ *
+ * @return . request http
+ */
+ RequestHttp getRequestHttp();
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelAddressService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelAddressService.java
new file mode 100644
index 0000000000..063dd53948
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelAddressService.java
@@ -0,0 +1,68 @@
+package me.chanjar.weixin.channel.api;
+
+
+import me.chanjar.weixin.channel.bean.address.AddressDetail;
+import me.chanjar.weixin.channel.bean.address.AddressIdResponse;
+import me.chanjar.weixin.channel.bean.address.AddressInfoResponse;
+import me.chanjar.weixin.channel.bean.address.AddressListResponse;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号小店 地址管理服务
+ *
+ * @author Zeyes
+ */
+public interface WxChannelAddressService {
+
+ /**
+ * 获取地址列表
+ *
+ * @param offset 起始位置
+ * @param limit 拉取个数
+ * @return 列表
+ *
+ * @throws WxErrorException 异常
+ */
+ AddressListResponse listAddress(Integer offset, Integer limit) throws WxErrorException;
+
+ /**
+ * 获取地址详情
+ *
+ * @param addressId 地址id
+ * @return 地址详情
+ *
+ * @throws WxErrorException 异常
+ */
+ AddressInfoResponse getAddress(String addressId) throws WxErrorException;
+
+ /**
+ * 添加地址
+ *
+ * @param addressDetail 地址
+ * @return AddressIdResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ AddressIdResponse addAddress(AddressDetail addressDetail) throws WxErrorException;
+
+ /**
+ * 更新地址
+ *
+ * @param addressDetail 地址
+ * @return BaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse updateAddress(AddressDetail addressDetail) throws WxErrorException;
+
+ /**
+ * 删除地址
+ *
+ * @param addressId 地址id
+ * @return BaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse deleteAddress(String addressId) throws WxErrorException;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelAfterSaleService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelAfterSaleService.java
new file mode 100644
index 0000000000..ac1e61729b
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelAfterSaleService.java
@@ -0,0 +1,111 @@
+package me.chanjar.weixin.channel.api;
+
+
+import java.util.List;
+import me.chanjar.weixin.channel.bean.after.AfterSaleInfoResponse;
+import me.chanjar.weixin.channel.bean.after.AfterSaleListResponse;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.complaint.ComplaintOrderResponse;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号小店 售后服务接口
+ *
+ * @author Zeyes
+ */
+public interface WxChannelAfterSaleService {
+
+ /**
+ * 获取售后单列表
+ *
+ * @param beginCreateTime 订单创建启始时间 unix时间戳
+ * @param endCreateTime 订单创建结束时间,end_create_time减去begin_create_time不得大于24小时
+ * @param nextKey 翻页参数,从第二页开始传,来源于上一页的返回值
+ * @return 售后单列表
+ *
+ * @throws WxErrorException 异常
+ */
+ AfterSaleListResponse listIds(Long beginCreateTime, Long endCreateTime, String nextKey)
+ throws WxErrorException;
+
+ /**
+ * 获取售后单详情
+ *
+ * @param afterSaleOrderId 售后单号
+ * @return 售后单信息
+ *
+ * @throws WxErrorException 异常
+ */
+ AfterSaleInfoResponse get(String afterSaleOrderId) throws WxErrorException;
+
+ /**
+ * 同意退款
+ *
+ * @param afterSaleOrderId 售后单号
+ * @param addressId 同意退货时传入地址id
+ * @return BaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse accept(String afterSaleOrderId, String addressId) throws WxErrorException;
+
+ /**
+ * 拒绝售后
+ *
+ * @param afterSaleOrderId 售后单号
+ * @param rejectReason 拒绝原因
+ * @return BaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse reject(String afterSaleOrderId, String rejectReason) throws WxErrorException;
+
+ /**
+ * 上传退款凭证
+ *
+ * @param afterSaleOrderId 售后单号
+ * @param desc 退款凭证描述
+ * @param certificates 退款凭证图片列表
+ * @return BaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse uploadRefundEvidence(String afterSaleOrderId, String desc, List certificates)
+ throws WxErrorException;
+
+ /**
+ * 商家补充纠纷单留言
+ *
+ * @param complaintId 纠纷单号
+ * @param content 留言内容,最多500字
+ * @param mediaIds 图片media_id列表,所有留言总图片数量最多20张
+ * @return BaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse addComplaintMaterial(String complaintId, String content, List mediaIds)
+ throws WxErrorException;
+
+ /**
+ * 商家举证
+ *
+ * @param complaintId 纠纷单号
+ * @param content 举证内容,最多500字
+ * @param mediaIds 图片media_id列表,所有留言总图片数量最多20张
+ * @return BaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse addComplaintEvidence(String complaintId, String content, List mediaIds)
+ throws WxErrorException;
+
+ /**
+ * 获取纠纷单
+ *
+ * @param complaintId 纠纷单号
+ * @return BaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ ComplaintOrderResponse getComplaint(String complaintId) throws WxErrorException;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelBasicService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelBasicService.java
new file mode 100644
index 0000000000..a687aaeb5c
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelBasicService.java
@@ -0,0 +1,73 @@
+package me.chanjar.weixin.channel.api;
+
+import java.io.File;
+import me.chanjar.weixin.channel.bean.address.AddressCodeResponse;
+import me.chanjar.weixin.channel.bean.image.ChannelImageInfo;
+import me.chanjar.weixin.channel.bean.image.ChannelImageResponse;
+import me.chanjar.weixin.channel.bean.image.QualificationFileResponse;
+import me.chanjar.weixin.channel.bean.shop.ShopInfoResponse;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 基础接口
+ *
+ * @author Zeyes
+ */
+public interface WxChannelBasicService {
+
+ /**
+ * 获取店铺基本信息
+ *
+ * @return 店铺基本信息
+ */
+ ShopInfoResponse getShopInfo() throws WxErrorException;
+
+ /**
+ * 上传图片
+ *
+ * @param respType 0:media_id和pay_media_id;1:图片链接(商品信息相关图片请务必使用此参数得到链接)
+ * @param imgUrl 图片url
+ * @return 图片信息
+ *
+ * @throws WxErrorException 异常
+ */
+ ChannelImageInfo uploadImg(int respType, String imgUrl) throws WxErrorException;
+
+ /**
+ * 上传图片
+ *
+ * @param respType 0:media_id和pay_media_id;1:图片链接(商品信息相关图片请务必使用此参数得到链接)
+ * @param file 图片文件
+ * @param height 图片的高,单位:像素
+ * @param width 图片的宽,单位:像素
+ * @return 图片信息
+ *
+ * @throws WxErrorException 异常
+ */
+ ChannelImageInfo uploadImg(int respType, File file, int height, int width) throws WxErrorException;
+
+ /**
+ * 上传资质图片
+ *
+ * @param file 资质图片
+ * @return 结果
+ *
+ * @throws WxErrorException 异常
+ */
+ QualificationFileResponse uploadQualificationFile(File file) throws WxErrorException;
+
+ /**
+ * 根据media_id获取图片
+ *
+ * @param mediaId media_id
+ */
+ ChannelImageResponse getImg(String mediaId) throws WxErrorException;
+
+ /**
+ * 获取地址编码(最多获取4级)
+ *
+ * @param code 地址行政编码,不填或者填0时,拉取全国的省级行政编码
+ * @return AddressCodeResponse
+ */
+ AddressCodeResponse getAddressCode(Integer code) throws WxErrorException;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelBrandService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelBrandService.java
new file mode 100644
index 0000000000..905d354955
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelBrandService.java
@@ -0,0 +1,103 @@
+package me.chanjar.weixin.channel.api;
+
+
+import me.chanjar.weixin.channel.bean.audit.AuditApplyResponse;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.brand.Brand;
+import me.chanjar.weixin.channel.bean.brand.BrandApplyListResponse;
+import me.chanjar.weixin.channel.bean.brand.BrandInfoResponse;
+import me.chanjar.weixin.channel.bean.brand.BrandListResponse;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号小店 品牌服务接口
+ *
+ * @author Zeyes
+ */
+public interface WxChannelBrandService {
+
+ /**
+ * 获取品牌库列表
+ *
+ * @param pageSize 每页数量(默认10, 不超过50)
+ * @param nextKey 由上次请求返回, 记录翻页的上下文, 传入时会从上次返回的结果往后翻一页, 不传默认拉取第一页数据
+ * @return 品牌库列表
+ *
+ * @throws WxErrorException 异常
+ */
+ BrandListResponse listAllBrand(Integer pageSize, String nextKey) throws WxErrorException;
+
+ /**
+ * 新增品牌资质
+ *
+ * @param brand 品牌参数
+ * @return 审核id
+ *
+ * @throws WxErrorException 异常
+ */
+ AuditApplyResponse addBrandApply(Brand brand) throws WxErrorException;
+
+ /**
+ * 修改品牌资质
+ *
+ * @param brand 品牌参数
+ * @return 审核id
+ *
+ * @throws WxErrorException 异常
+ */
+ AuditApplyResponse updateBrandApply(Brand brand) throws WxErrorException;
+
+ /**
+ * 撤回品牌资质审核
+ *
+ * @param brandId 品牌id
+ * @param auditId 审核id
+ * @return 审核id
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse cancelBrandApply(String brandId, String auditId) throws WxErrorException;
+
+ /**
+ * 删除品牌资质
+ *
+ * @param brandId 品牌id
+ * @return 结果
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse deleteBrandApply(String brandId) throws WxErrorException;
+
+ /**
+ * 获取品牌资质申请详情
+ *
+ * @param brandId 品牌id
+ * @return 品牌信息
+ *
+ * @throws WxErrorException 异常
+ */
+ BrandInfoResponse getBrandApply(String brandId) throws WxErrorException;
+
+ /**
+ * 获取品牌资质申请列表
+ *
+ * @param pageSize 每页数量(默认10, 不超过50)
+ * @param nextKey 由上次请求返回, 记录翻页的上下文, 传入时会从上次返回的结果往后翻一页, 不传默认拉取第一页数据
+ * @param status 审核单状态, 不填默认拉全部商品
+ * @return 品牌列表
+ *
+ * @throws WxErrorException 异常
+ */
+ BrandApplyListResponse listBrandApply(Integer pageSize, String nextKey, Integer status) throws WxErrorException;
+
+ /**
+ * 获取生效中的品牌资质列表
+ *
+ * @param pageSize 每页数量(默认10, 不超过50)
+ * @param nextKey 由上次请求返回, 记录翻页的上下文, 传入时会从上次返回的结果往后翻一页, 不传默认拉取第一页数据
+ * @return 品牌列表
+ *
+ * @throws WxErrorException 异常
+ */
+ BrandApplyListResponse listValidBrandApply(Integer pageSize, String nextKey) throws WxErrorException;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelCategoryService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelCategoryService.java
new file mode 100644
index 0000000000..ddbc99e5d4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelCategoryService.java
@@ -0,0 +1,93 @@
+package me.chanjar.weixin.channel.api;
+
+import java.io.File;
+import java.util.List;
+import me.chanjar.weixin.channel.bean.audit.AuditApplyResponse;
+import me.chanjar.weixin.channel.bean.audit.AuditResponse;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.category.CategoryDetailResult;
+import me.chanjar.weixin.channel.bean.category.CategoryQualificationResponse;
+import me.chanjar.weixin.channel.bean.category.PassCategoryResponse;
+import me.chanjar.weixin.channel.bean.category.ShopCategory;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号小店 商品类目相关接口
+ *
+ * @author Zeyes
+ */
+public interface WxChannelCategoryService {
+
+ /**
+ * 获取所有的类目
+ *
+ * @return 所有类目以及资质信息
+ *
+ * @throws WxErrorException 异常
+ */
+ CategoryQualificationResponse listAllCategory() throws WxErrorException;
+
+ /**
+ * 获取商品类目列表(全量) 有频率限制
+ *
+ * @param parentId 类目父id
+ * @return 类目列表
+ *
+ * @throws WxErrorException 异常
+ */
+ List listAvailableCategory(String parentId) throws WxErrorException;
+
+ /**
+ * 获取类目信息
+ *
+ * @param id 三级类目id
+ * @return 类目信息
+ *
+ * @throws WxErrorException 异常
+ */
+ CategoryDetailResult getCategoryDetail(String id) throws WxErrorException;
+
+ /**
+ * 上传类目资质
+ *
+ * @param level1 一级类目ID
+ * @param level2 二级类目ID
+ * @param level3 三级类目ID
+ * @param certificate 资质材料,图片mediaid,图片类型,最多不超过10张
+ * @return 审核id
+ *
+ * @throws WxErrorException 异常
+ * @see WxChannelBasicService#uploadQualificationFile(File)
+ */
+ AuditApplyResponse addCategory(String level1, String level2, String level3, List certificate)
+ throws WxErrorException;
+
+ /**
+ * 取消类目提审
+ *
+ * @param auditId 提交审核时返回的id
+ * @return BaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse cancelCategoryAudit(String auditId) throws WxErrorException;
+
+ /**
+ * 查询类目审核结果
+ *
+ * @param auditId 审核id
+ * @return 审核结果
+ *
+ * @throws WxErrorException 异常
+ */
+ AuditResponse getAudit(String auditId) throws WxErrorException;
+
+ /**
+ * 获取账号申请通过的类目和资质信息
+ *
+ * @return 类目和资质信息
+ *
+ * @throws WxErrorException 异常
+ */
+ PassCategoryResponse listPassCategory() throws WxErrorException;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelCouponService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelCouponService.java
new file mode 100644
index 0000000000..df59fdc8b9
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelCouponService.java
@@ -0,0 +1,92 @@
+package me.chanjar.weixin.channel.api;
+
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.coupon.CouponIdResponse;
+import me.chanjar.weixin.channel.bean.coupon.CouponInfoResponse;
+import me.chanjar.weixin.channel.bean.coupon.CouponListParam;
+import me.chanjar.weixin.channel.bean.coupon.CouponListResponse;
+import me.chanjar.weixin.channel.bean.coupon.CouponParam;
+import me.chanjar.weixin.channel.bean.coupon.UserCouponListParam;
+import me.chanjar.weixin.channel.bean.coupon.UserCouponListResponse;
+import me.chanjar.weixin.channel.bean.coupon.UserCouponResponse;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号小店 优惠券服务
+ *
+ * @author Zeyes
+ */
+public interface WxChannelCouponService {
+
+ /**
+ * 创建优惠券
+ *
+ * @param coupon 优惠券
+ * @return 优惠券ID
+ *
+ * @throws WxErrorException 异常
+ */
+ CouponIdResponse createCoupon(CouponParam coupon) throws WxErrorException;
+
+ /**
+ * 更新优惠券
+ *
+ * @param coupon 优惠券
+ * @return 优惠券ID
+ *
+ * @throws WxErrorException 异常
+ */
+ CouponIdResponse updateCoupon(CouponParam coupon) throws WxErrorException;
+
+ /**
+ * 更新优惠券状态
+ *
+ * @param couponId 优惠券ID
+ * @param status 状态 2生效 4已作废 5删除 {@link me.chanjar.weixin.channel.enums.WxCouponStatus}
+ * @return BaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse updateCouponStatus(String couponId, Integer status) throws WxErrorException;
+
+ /**
+ * 获取优惠券详情
+ *
+ * @param couponId 优惠券ID
+ * @return CouponInfoResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ CouponInfoResponse getCoupon(String couponId) throws WxErrorException;
+
+ /**
+ * 获取优惠券ID列表
+ *
+ * @param param 条件参数
+ * @return 优惠券ID列表
+ *
+ * @throws WxErrorException 异常
+ */
+ CouponListResponse getCouponList(CouponListParam param) throws WxErrorException;
+
+ /**
+ * 获取用户优惠券
+ *
+ * @param openId 用户openid
+ * @param userCouponId 用户优惠券ID
+ * @return UserCouponResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ UserCouponResponse getUserCoupon(String openId, String userCouponId) throws WxErrorException;
+
+ /**
+ * 获取用户优惠券ID列表
+ *
+ * @param param 条件参数
+ * @return UserCouponListResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ UserCouponListResponse getUserCouponList(UserCouponListParam param) throws WxErrorException;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelFreightTemplateService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelFreightTemplateService.java
new file mode 100644
index 0000000000..188b33464b
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelFreightTemplateService.java
@@ -0,0 +1,57 @@
+package me.chanjar.weixin.channel.api;
+
+
+import me.chanjar.weixin.channel.bean.freight.FreightTemplate;
+import me.chanjar.weixin.channel.bean.freight.TemplateIdResponse;
+import me.chanjar.weixin.channel.bean.freight.TemplateInfoResponse;
+import me.chanjar.weixin.channel.bean.freight.TemplateListResponse;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号小店 运费模板服务接口
+ *
+ * @author Zeyes
+ */
+public interface WxChannelFreightTemplateService {
+
+ /**
+ * 获取运费模板列表
+ *
+ * @param offset 起始位置
+ * @param limit 拉取个数
+ * @return 列表
+ *
+ * @throws WxErrorException 异常
+ */
+ TemplateListResponse listTemplate(Integer offset, Integer limit) throws WxErrorException;
+
+ /**
+ * 获取运费模板
+ *
+ * @param templateId 模板id
+ * @return 运费模板
+ *
+ * @throws WxErrorException 异常
+ */
+ TemplateInfoResponse getTemplate(String templateId) throws WxErrorException;
+
+ /**
+ * 添加运费模板
+ *
+ * @param template 运费模板
+ * @return TemplateIdResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ TemplateIdResponse addTemplate(FreightTemplate template) throws WxErrorException;
+
+ /**
+ * 更新运费模板
+ *
+ * @param template 运费模板
+ * @return TemplateIdResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ TemplateIdResponse updateTemplate(FreightTemplate template) throws WxErrorException;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelFundService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelFundService.java
new file mode 100644
index 0000000000..cb0f5aab79
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelFundService.java
@@ -0,0 +1,189 @@
+package me.chanjar.weixin.channel.api;
+
+
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.fund.AccountInfo;
+import me.chanjar.weixin.channel.bean.fund.AccountInfoResponse;
+import me.chanjar.weixin.channel.bean.fund.BalanceInfoResponse;
+import me.chanjar.weixin.channel.bean.fund.FlowListResponse;
+import me.chanjar.weixin.channel.bean.fund.FundsFlowResponse;
+import me.chanjar.weixin.channel.bean.fund.FundsListParam;
+import me.chanjar.weixin.channel.bean.fund.WithdrawDetailResponse;
+import me.chanjar.weixin.channel.bean.fund.WithdrawListResponse;
+import me.chanjar.weixin.channel.bean.fund.WithdrawSubmitResponse;
+import me.chanjar.weixin.channel.bean.fund.bank.BankCityResponse;
+import me.chanjar.weixin.channel.bean.fund.bank.BankInfoResponse;
+import me.chanjar.weixin.channel.bean.fund.bank.BankListResponse;
+import me.chanjar.weixin.channel.bean.fund.bank.BankProvinceResponse;
+import me.chanjar.weixin.channel.bean.fund.bank.BranchInfoResponse;
+import me.chanjar.weixin.channel.bean.fund.qrcode.QrCheckResponse;
+import me.chanjar.weixin.channel.bean.fund.qrcode.QrCodeResponse;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 资金相关服务
+ *
+ * @author Zeyes
+ */
+public interface WxChannelFundService {
+
+ /**
+ * 获取账户余额
+ *
+ * @return 账户余额
+ *
+ * @throws WxErrorException 异常
+ */
+ BalanceInfoResponse getBalance() throws WxErrorException;
+
+ /**
+ * 获取结算账户
+ *
+ * @return 结算账户
+ *
+ * @throws WxErrorException 异常
+ */
+ AccountInfoResponse getBankAccount() throws WxErrorException;
+
+ /**
+ * 获取资金流水详情
+ *
+ * @param flowId 资金流水号
+ * @return 资金流水详情
+ *
+ * @throws WxErrorException 异常
+ */
+ FundsFlowResponse getFundsFlowDetail(String flowId) throws WxErrorException;
+
+ /**
+ * 获取资金流水列表
+ *
+ * @param param 资金流水列表参数
+ * @return 资金流水列表
+ *
+ * @throws WxErrorException 异常
+ */
+ FlowListResponse listFundsFlow(FundsListParam param) throws WxErrorException;
+
+ /**
+ * 获取提现记录
+ *
+ * @param withdrawId 提现单号
+ * @return 提现记录
+ *
+ * @throws WxErrorException 异常
+ */
+ WithdrawDetailResponse getWithdrawDetail(String withdrawId) throws WxErrorException;
+
+ /**
+ * 获取提现记录列表
+ *
+ * @param pageNum 页码
+ * @param pageSize 每页大小
+ * @param startTime 开始时间
+ * @param endTime 结束时间
+ * @return 提现记录列表
+ *
+ * @throws WxErrorException 异常
+ */
+ WithdrawListResponse listWithdraw(Integer pageNum, Integer pageSize, Long startTime, Long endTime)
+ throws WxErrorException;
+
+ /**
+ * 修改结算账户
+ *
+ * @param accountInfo 结算账户信息
+ * @return 修改结果
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse setBankAccount(AccountInfo accountInfo) throws WxErrorException;
+
+ /***
+ * 商户提现
+ *
+ * @param amount 提现金额(单位:分)
+ * @param remark 提现备注
+ * @param bankMemo 银行附言
+ * @return 提现结果
+ * @throws WxErrorException 异常
+ */
+ WithdrawSubmitResponse submitWithdraw(Integer amount, String remark, String bankMemo) throws WxErrorException;
+
+ /**
+ * 根据卡号查银行信息
+ *
+ * @param accountNumber 卡号
+ * @return 银行信息
+ *
+ * @throws WxErrorException 异常
+ */
+ BankInfoResponse getBankInfoByCardNo(String accountNumber) throws WxErrorException;
+
+ /**
+ * 搜索银行列表
+ *
+ * @param offset 偏移量
+ * @param limit 每页数据大小
+ * @param keywords 银行关键字
+ * @param bankType 银行类型(1:对私银行,2:对公银行; 默认对公)
+ * @return 银行列表
+ *
+ * @throws WxErrorException 异常
+ */
+ BankListResponse searchBankList(Integer offset, Integer limit, String keywords, Integer bankType)
+ throws WxErrorException;
+
+ /**
+ * 查询城市列表
+ *
+ * @param provinceCode 省份编码
+ * @return 城市列表
+ *
+ * @throws WxErrorException 异常
+ */
+ BankCityResponse searchCityList(String provinceCode) throws WxErrorException;
+
+ /**
+ * 查询大陆银行省份列表
+ *
+ * @return 省份列表
+ *
+ * @throws WxErrorException 异常
+ */
+ BankProvinceResponse getProvinceList() throws WxErrorException;
+
+ /**
+ * 查询支行列表
+ *
+ * @param bankCode 银行编码
+ * @param cityCode 城市编码
+ * @param offset 偏移量
+ * @param limit 每页数据大小
+ * @return 支行列表
+ *
+ * @throws WxErrorException 异常
+ */
+ BranchInfoResponse searchBranchList(String bankCode, String cityCode, Integer offset, Integer limit)
+ throws WxErrorException;
+
+ /**
+ * 获取二维码
+ *
+ * @param qrcodeTicket 二维码ticket
+ * @return 二维码响应
+ *
+ * @throws WxErrorException 异常
+ */
+ QrCodeResponse getQrCode(String qrcodeTicket) throws WxErrorException;
+
+ /**
+ * 查询扫码状态
+ *
+ * @param qrcodeTicket 二维码ticket
+ * @return 扫码状态
+ *
+ * @throws WxErrorException 异常
+ */
+ QrCheckResponse checkQrStatus(String qrcodeTicket) throws WxErrorException;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelOrderService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelOrderService.java
new file mode 100644
index 0000000000..e280ace2fc
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelOrderService.java
@@ -0,0 +1,126 @@
+package me.chanjar.weixin.channel.api;
+
+import java.util.List;
+import me.chanjar.weixin.channel.bean.base.AddressInfo;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.delivery.DeliveryCompanyResponse;
+import me.chanjar.weixin.channel.bean.delivery.DeliveryInfo;
+import me.chanjar.weixin.channel.bean.order.ChangeOrderInfo;
+import me.chanjar.weixin.channel.bean.order.DeliveryUpdateParam;
+import me.chanjar.weixin.channel.bean.order.OrderInfoResponse;
+import me.chanjar.weixin.channel.bean.order.OrderListParam;
+import me.chanjar.weixin.channel.bean.order.OrderListResponse;
+import me.chanjar.weixin.channel.bean.order.OrderSearchParam;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号小店 订单服务接口
+ *
+ * @author Zeyes
+ * @link 订单接口文档
+ */
+public interface WxChannelOrderService {
+
+ /**
+ * 获取订单
+ *
+ * @param orderId 订单id
+ * @return 订单详情
+ *
+ * @throws WxErrorException 异常
+ */
+ OrderInfoResponse getOrder(String orderId) throws WxErrorException;
+
+ /**
+ * 获取订单列表
+ *
+ * @param param 搜索条件
+ * @return 订单列表
+ *
+ * @throws WxErrorException 异常
+ */
+ OrderListResponse getOrders(OrderListParam param) throws WxErrorException;
+
+ /**
+ * 订单搜索
+ *
+ * @param param 搜索条件
+ * @return 订单列表
+ *
+ * @throws WxErrorException 异常
+ */
+ OrderListResponse searchOrder(OrderSearchParam param) throws WxErrorException;
+
+ /**
+ * 更改订单价格
+ *
+ * @param orderId 订单id
+ * @param expressFee 运费价格(以分为单位)(不填不改)
+ * @param changeOrderInfos 改价列表
+ * @return 结果
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse updatePrice(String orderId, Integer expressFee, List changeOrderInfos)
+ throws WxErrorException;
+
+ /**
+ * 更改订单备注
+ *
+ * @param orderId 订单id
+ * @param merchantNotes 备注
+ * @return BaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse updateRemark(String orderId, String merchantNotes) throws WxErrorException;
+
+ /**
+ * 更新订单地址
+ *
+ * @param orderId 订单id
+ * @param userAddress 用户地址
+ * @return BaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse updateAddress(String orderId, AddressInfo userAddress) throws WxErrorException;
+
+ /**
+ * 修改物流信息
发货完成的订单可以修改,最多修改1次 拆包发货的订单暂不允许修改物流 虚拟商品订单暂不允许修改物流
+ *
+ * @param param 物流信息
+ * @return BaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse updateDelivery(DeliveryUpdateParam param) throws WxErrorException;
+
+ /**
+ * 关闭订单 (需要订单状态为未付款状态)
+ *
+ * @param orderId 订单id
+ * @return BaseResponse
+ */
+ WxChannelBaseResponse closeOrder(String orderId);
+
+ /**
+ * 获取快递公司列表
+ *
+ * @return 快递公司列表
+ *
+ * @throws WxErrorException 异常
+ */
+ DeliveryCompanyResponse listDeliveryCompany() throws WxErrorException;
+
+ /**
+ * 订单发货
+ *
+ * @param orderId 订单id
+ * @param deliveryList 物流信息
+ * @return BaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse deliveryOrder(String orderId, List deliveryList) throws WxErrorException;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelProductService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelProductService.java
new file mode 100644
index 0000000000..b962b9ec85
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelProductService.java
@@ -0,0 +1,171 @@
+package me.chanjar.weixin.channel.api;
+
+
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.limit.LimitTaskAddResponse;
+import me.chanjar.weixin.channel.bean.limit.LimitTaskListResponse;
+import me.chanjar.weixin.channel.bean.limit.LimitTaskParam;
+import me.chanjar.weixin.channel.bean.product.SkuStockResponse;
+import me.chanjar.weixin.channel.bean.product.SpuGetResponse;
+import me.chanjar.weixin.channel.bean.product.SpuInfo;
+import me.chanjar.weixin.channel.bean.product.SpuListResponse;
+import me.chanjar.weixin.channel.bean.product.SpuUpdateResponse;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号小店 商品服务接口
+ *
+ * @author Zeyes
+ */
+public interface WxChannelProductService {
+
+ /**
+ * 添加商品
+ *
+ * @param info 商品信息
+ * @return 返回商品的状态和id
+ *
+ * @throws WxErrorException 异常
+ */
+ SpuUpdateResponse addProduct(SpuInfo info) throws WxErrorException;
+
+ /**
+ * 更新商品
+ *
+ * @param info 商品信息
+ * @return 返回商品的状态和id
+ *
+ * @throws WxErrorException 异常
+ */
+ SpuUpdateResponse updateProduct(SpuInfo info) throws WxErrorException;
+
+ /**
+ * 更新商品库存 (仅对edit_status != 2 的商品适用,其他状态的商品无法通过该接口修改库存)
+ *
+ * @param productId 内部商品ID
+ * @param skuId 内部sku_id
+ * @param diffType 修改类型 1增加 2减少 3设置
+ * @param num 增加、减少或者设置的库存值
+ * @return WxChannelBaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse updateStock(String productId, String skuId, Integer diffType, Integer num)
+ throws WxErrorException;
+
+ /**
+ * 删除商品
+ *
+ * @param productId 商品ID
+ * @return 是否成功
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse deleteProduct(String productId) throws WxErrorException;
+
+ /**
+ * 撤回商品审核
+ *
+ * @param productId 商品ID
+ * @return 是否成功
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse cancelProductAudit(String productId) throws WxErrorException;
+
+ /**
+ * 获取商品
+ *
+ * @param productId 商品ID
+ * @param dataType 默认取1 1:获取线上数据 2:获取草稿数据 3:同时获取线上和草稿数据(注意:需成功上架后才有线上数据)
+ * @return 商品信息
+ *
+ * @throws WxErrorException 异常
+ */
+ SpuGetResponse getProduct(String productId, Integer dataType) throws WxErrorException;
+
+ /**
+ * 获取商品列表
+ *
+ * @param pageSize 每页数量(默认10,不超过30)
+ * @param nextKey 由上次请求返回,记录翻页的上下文。传入时会从上次返回的结果往后翻一页,不传默认拉取第一页数据。
+ * @param status 商品状态,不填默认拉全部商品(不包含回收站) {@link me.chanjar.weixin.channel.enums.SpuStatus}
+ * @return List
+ *
+ * @throws WxErrorException 异常
+ */
+ SpuListResponse listProduct(Integer pageSize, String nextKey, Integer status) throws WxErrorException;
+
+ /**
+ * 上架商品
+ *
+ * @param productId 商品ID
+ * @return 是否成功
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse upProduct(String productId) throws WxErrorException;
+
+ /**
+ * 下架商品
+ *
+ * @param productId 商品ID
+ * @return 是否成功
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse downProduct(String productId) throws WxErrorException;
+
+ /**
+ * 获取商品实时库存
+ *
+ * @param productId 商品ID
+ * @param skuId skuId
+ * @return SkuStockResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ SkuStockResponse getSkuStock(String productId, String skuId) throws WxErrorException;
+
+ /**
+ * 添加限时抢购任务
+ *
+ * @param param 限时抢购任务
+ * @return LimitTaskAddResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ LimitTaskAddResponse addLimitTask(LimitTaskParam param) throws WxErrorException;
+
+ /**
+ * 拉取限时抢购任务列表
+ *
+ * @param pageSize 每页数量(默认10,不超过50)
+ * @param nextKey 由上次请求返回,记录翻页的上下文。传入时会从上次返回的结果往后翻一页,不传默认拉取第一页数据
+ * @param status 抢购活动状态
+ * @return LimitTaskListResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ LimitTaskListResponse listLimitTask(Integer pageSize, String nextKey, Integer status) throws WxErrorException;
+
+ /**
+ * 停止限时抢购任务
+ *
+ * @param taskId 限时抢购任务ID
+ * @return BaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse stopLimitTask(String taskId) throws WxErrorException;
+
+ /**
+ * 停止限时抢购任务
+ *
+ * @param taskId 限时抢购任务ID
+ * @return BaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse deleteLimitTask(String taskId) throws WxErrorException;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelService.java
new file mode 100644
index 0000000000..8f960f4795
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelService.java
@@ -0,0 +1,122 @@
+package me.chanjar.weixin.channel.api;
+
+/**
+ * The interface Wx Channel service
+ *
+ * @author Zeyes
+ */
+public interface WxChannelService extends BaseWxChannelService {
+
+ /**
+ * 基础接口服务
+ *
+ * @return 基础接口服务
+ */
+ WxChannelBasicService getBasicService();
+
+ /**
+ * 商品类目服务
+ *
+ * @return 商品类目服务
+ */
+ WxChannelCategoryService getCategoryService();
+
+ /**
+ * 品牌服务
+ *
+ * @return 品牌服务
+ */
+ WxChannelBrandService getBrandService();
+
+ /**
+ * 商品服务
+ *
+ * @return 商品服务
+ */
+ WxChannelProductService getProductService();
+
+ /**
+ * 仓库服务
+ *
+ * @return 仓库服务
+ */
+ WxChannelWarehouseService getWarehouseService();
+
+ /**
+ * 订单服务
+ *
+ * @return 订单服务
+ */
+ WxChannelOrderService getOrderService();
+
+ /**
+ * 售后服务
+ *
+ * @return 售后服务
+ */
+ WxChannelAfterSaleService getAfterSaleService();
+
+ /**
+ * 运费模板服务
+ *
+ * @return 运费模板服务
+ */
+ WxChannelFreightTemplateService getFreightTemplateService();
+
+ /**
+ * 地址服务
+ *
+ * @return 地址服务
+ */
+ WxChannelAddressService getAddressService();
+
+ /**
+ * 优惠券服务
+ *
+ * @return 优惠券服务
+ */
+ WxChannelCouponService getCouponService();
+
+ /**
+ * 分享员服务
+ *
+ * @return 分享员服务
+ */
+ WxChannelSharerService getSharerService();
+
+ /**
+ * 资金服务
+ *
+ * @return 资金服务
+ */
+ WxChannelFundService getFundService();
+
+ /**
+ * 优选联盟-团长合作达人管理服务
+ *
+ * @return 团长合作达人管理服务
+ */
+ WxLeagueWindowService getLeagueWindowService();
+
+ /**
+ * 优选联盟-团长服务
+ *
+ * @return 团长服务
+ */
+ WxLeagueSupplierService getLeagueSupplierService();
+
+ /**
+ * 优选联盟-达人服务
+ *
+ * @return 达人服务
+ */
+ WxLeaguePromoterService getLeaguePromoterService();
+
+ /**
+ * 优选联盟-商品服务
+ *
+ * @return 商品服务
+ */
+ WxLeagueProductService getLeagueProductService();
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelSharerService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelSharerService.java
new file mode 100644
index 0000000000..300493158b
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelSharerService.java
@@ -0,0 +1,71 @@
+package me.chanjar.weixin.channel.api;
+
+import java.util.List;
+import me.chanjar.weixin.channel.bean.sharer.SharerBindResponse;
+import me.chanjar.weixin.channel.bean.sharer.SharerInfoResponse;
+import me.chanjar.weixin.channel.bean.sharer.SharerOrderParam;
+import me.chanjar.weixin.channel.bean.sharer.SharerOrderResponse;
+import me.chanjar.weixin.channel.bean.sharer.SharerSearchResponse;
+import me.chanjar.weixin.channel.bean.sharer.SharerUnbindResponse;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号小店 分享员服务接口
+ *
+ * @author Zeyes
+ */
+public interface WxChannelSharerService {
+
+ /**
+ * 邀请分享员
+ *
+ * @param username 邀请的用户微信号
+ * @return SharerBindResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ SharerBindResponse bindSharer(String username) throws WxErrorException;
+
+ /**
+ * 获取绑定的分享员
+ *
+ * @param openid 分享员openid
+ * @param username 分享员微信号(二选一)
+ * @return SharerSearchResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ SharerSearchResponse searchSharer(String openid, String username) throws WxErrorException;
+
+ /**
+ * 获取绑定的分享员列表
+ *
+ * @param page 分页参数,页数
+ * @param pageSize 分页参数,每页分享员数(不超过100
+ * @param sharerType 分享员类型
+ * @return 分享员列表
+ *
+ * @throws WxErrorException 异常
+ */
+ SharerInfoResponse listSharer(Integer page, Integer pageSize, Integer sharerType) throws WxErrorException;
+
+ /**
+ * 获取分享员订单列表
+ *
+ * @param param 参数
+ * @return 列表
+ *
+ * @throws WxErrorException 异常
+ */
+ SharerOrderResponse listSharerOrder(SharerOrderParam param) throws WxErrorException;
+
+ /**
+ * 解绑分享员
+ *
+ * @param openIds openid列表
+ * @return 状态
+ *
+ * @throws WxErrorException 异常
+ */
+ SharerUnbindResponse unbindSharer(List openIds) throws WxErrorException;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelWarehouseService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelWarehouseService.java
new file mode 100644
index 0000000000..1bb00885f5
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelWarehouseService.java
@@ -0,0 +1,137 @@
+package me.chanjar.weixin.channel.api;
+
+
+import java.util.List;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.warehouse.LocationPriorityResponse;
+import me.chanjar.weixin.channel.bean.warehouse.PriorityLocationParam;
+import me.chanjar.weixin.channel.bean.warehouse.WarehouseIdsResponse;
+import me.chanjar.weixin.channel.bean.warehouse.WarehouseLocation;
+import me.chanjar.weixin.channel.bean.warehouse.WarehouseParam;
+import me.chanjar.weixin.channel.bean.warehouse.WarehouseResponse;
+import me.chanjar.weixin.channel.bean.warehouse.WarehouseStockParam;
+import me.chanjar.weixin.channel.bean.warehouse.WarehouseStockResponse;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+
+/**
+ * 视频号小店 区域仓库服务
+ *
+ * @author Zeyes
+ */
+public interface WxChannelWarehouseService {
+
+ /**
+ * 创建仓库
+ *
+ * @param param 仓库信息
+ * @return 响应
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse createWarehouse(WarehouseParam param) throws WxErrorException;
+
+ /**
+ * 查询仓库列表
+ *
+ * @param pageSize 每页数量(最大不超过10)
+ * @param nextKey 由上次请求返回,记录翻页的上下文。传入时会从上次返回的结果往后翻一页,不传默认拉取第一页数据
+ * @return 响应
+ *
+ * @throws WxErrorException 异常
+ */
+ WarehouseIdsResponse listWarehouse(Integer pageSize, String nextKey) throws WxErrorException;
+
+ /**
+ * 获取仓库详情
+ *
+ * @param outWarehouseId 外部仓库ID
+ * @return 响应
+ *
+ * @throws WxErrorException 异常
+ */
+ WarehouseResponse getWarehouse(String outWarehouseId) throws WxErrorException;
+
+ /**
+ * 修改仓库详情
+ *
+ * @param outWarehouseId 外部仓库ID
+ * @param name 仓库名称
+ * @param intro 仓库介绍
+ * @return 响应
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse updateWarehouse(String outWarehouseId, String name, String intro) throws WxErrorException;
+
+ /**
+ * 批量增加覆盖区域
+ *
+ * @param outWarehouseId 外部仓库ID
+ * @param coverLocations 覆盖区域
+ * @return 响应
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse addWarehouseArea(String outWarehouseId, List coverLocations)
+ throws WxErrorException;
+
+ /**
+ * 批量删除覆盖区域
+ *
+ * @param outWarehouseId 外部仓库ID
+ * @param coverLocations 覆盖区域
+ * @return 响应
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse deleteWarehouseArea(String outWarehouseId, List coverLocations)
+ throws WxErrorException;
+
+ /**
+ * 设置指定地址下的仓的优先级
+ *
+ * @param param 参数
+ * @return 响应
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse setWarehousePriority(PriorityLocationParam param) throws WxErrorException;
+
+ /**
+ * 获取指定地址下的仓的优先级
+ *
+ * @param addressId1 省份地址编码
+ * @param addressId2 市地址编码
+ * @param addressId3 区地址编码
+ * @param addressId4 街道地址编码
+ * @return 仓的优先级
+ *
+ * @throws WxErrorException 异常
+ */
+ LocationPriorityResponse getWarehousePriority(Integer addressId1, Integer addressId2, Integer addressId3,
+ Integer addressId4) throws WxErrorException;
+
+ /**
+ * 更新区域仓库存数量
+ *
+ * @param param 参数
+ * @return 响应
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse updateWarehouseStock(WarehouseStockParam param) throws WxErrorException;
+
+ /**
+ * 获取区域仓库存数量
+ *
+ * @param productId 商品ID
+ * @param outWarehouseId 外部仓库ID
+ * @param skuId 商品skuId
+ * @return 响应
+ *
+ * @throws WxErrorException 异常
+ */
+ WarehouseStockResponse getWarehouseStock(String productId, String skuId, String outWarehouseId)
+ throws WxErrorException;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxLeagueProductService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxLeagueProductService.java
new file mode 100644
index 0000000000..d8d6781505
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxLeagueProductService.java
@@ -0,0 +1,62 @@
+package me.chanjar.weixin.channel.api;
+
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.league.product.BatchAddParam;
+import me.chanjar.weixin.channel.bean.league.product.BatchAddResponse;
+import me.chanjar.weixin.channel.bean.league.product.ProductDetailParam;
+import me.chanjar.weixin.channel.bean.league.product.ProductDetailResponse;
+import me.chanjar.weixin.channel.bean.league.product.ProductListParam;
+import me.chanjar.weixin.channel.bean.league.product.ProductListResponse;
+import me.chanjar.weixin.channel.bean.league.product.ProductUpdateParam;
+import me.chanjar.weixin.channel.bean.league.product.ProductUpdateResponse;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 优选联盟 商品操作服务
+ *
+ * @author Zeyes
+ */
+public interface WxLeagueProductService {
+
+ /**
+ * 批量新增联盟商品
+ *
+ * @param param 参数
+ * @return 结果
+ */
+ BatchAddResponse batchAddProduct(BatchAddParam param) throws WxErrorException;
+
+ /**
+ * 更新联盟商品信息
+ *
+ * @param param 参数
+ * @return 结果
+ */
+ ProductUpdateResponse updateProduct(ProductUpdateParam param) throws WxErrorException;
+
+ /**
+ * 删除联盟商品
+ *
+ * @param type 1普通推广商品 2定向推广商品 3专属推广商品
+ * @param productId 商品id type为普通推广商品时必填
+ * @param infoId 特殊推广商品计划id type为特殊推广商品时必填
+ * @return
+ */
+ WxChannelBaseResponse deleteProduct(Integer type, String productId, String infoId) throws WxErrorException;
+
+ /**
+ * 拉取联盟商品详情
+ *
+ * @param param 参数
+ * @return 结果
+ */
+ ProductDetailResponse getProductDetail(ProductDetailParam param) throws WxErrorException;
+
+ /**
+ * 拉取联盟商品推广列表
+ *
+ * @param param 参数
+ * @return 结果
+ */
+ ProductListResponse listProduct(ProductListParam param) throws WxErrorException;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxLeaguePromoterService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxLeaguePromoterService.java
new file mode 100644
index 0000000000..8a8ffb9acf
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxLeaguePromoterService.java
@@ -0,0 +1,57 @@
+package me.chanjar.weixin.channel.api;
+
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.league.promoter.PromoterInfoResponse;
+import me.chanjar.weixin.channel.bean.league.promoter.PromoterListResponse;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 优选联盟 达人服务
+ *
+ * @author Zeyes
+ */
+public interface WxLeaguePromoterService {
+
+ /**
+ * 新增达人
+ *
+ * @param finderId 视频号finder_id
+ * @return 结果
+ */
+ WxChannelBaseResponse addPromoter(String finderId) throws WxErrorException;
+
+ /**
+ * 编辑达人
+ *
+ * @param finderId 视频号finder_id
+ * @param type 操作 1取消邀请 2结束合作
+ * @return 结果
+ */
+ WxChannelBaseResponse updatePromoter(String finderId, int type) throws WxErrorException;
+
+ /**
+ * 删除达人
+ *
+ * @param finderId 视频号finder_id
+ * @return 结果
+ */
+ WxChannelBaseResponse deletePromoter(String finderId) throws WxErrorException;
+
+ /**
+ * 获取达人详情信息
+ *
+ * @param finderId 视频号finder_id
+ * @return 结果
+ */
+ PromoterInfoResponse getPromoterInfo(String finderId) throws WxErrorException;
+
+ /**
+ * 获取达人列表
+ *
+ * @param pageIndex 页面下标,下标从1开始,默认为1
+ * @param pageSize 单页达人数(不超过200)
+ * @param status 拉取该状态下的达人列表
+ * @return 结果
+ */
+ PromoterListResponse listPromoter(Integer pageIndex, Integer pageSize, Integer status) throws WxErrorException;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxLeagueSupplierService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxLeagueSupplierService.java
new file mode 100644
index 0000000000..cde96843f1
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxLeagueSupplierService.java
@@ -0,0 +1,98 @@
+package me.chanjar.weixin.channel.api;
+
+import me.chanjar.weixin.channel.bean.league.supplier.CommissionOrderListParam;
+import me.chanjar.weixin.channel.bean.league.supplier.CommissionOrderListResponse;
+import me.chanjar.weixin.channel.bean.league.supplier.CommissionOrderResponse;
+import me.chanjar.weixin.channel.bean.league.supplier.CoopProductListResponse;
+import me.chanjar.weixin.channel.bean.league.supplier.CoopProductResponse;
+import me.chanjar.weixin.channel.bean.league.supplier.FlowListParam;
+import me.chanjar.weixin.channel.bean.league.supplier.ShopDetailResponse;
+import me.chanjar.weixin.channel.bean.league.supplier.ShopListResponse;
+import me.chanjar.weixin.channel.bean.league.supplier.SupplierBalanceResponse;
+import me.chanjar.weixin.channel.bean.league.supplier.SupplierFlowDetailResponse;
+import me.chanjar.weixin.channel.bean.league.supplier.SupplierFlowListResponse;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 优选联盟 团长数据服务
+ *
+ * @author Zeyes
+ */
+public interface WxLeagueSupplierService {
+
+ /**
+ * 获取团长账户余额
+ *
+ * @return 余额
+ */
+ SupplierBalanceResponse getBalanceInfo() throws WxErrorException;
+
+ /**
+ * 获取资金流水详情
+ *
+ * @param flowId 流水ID
+ * @return 流水详情
+ */
+ SupplierFlowDetailResponse getFlowDetail(String flowId) throws WxErrorException;
+
+ /**
+ * 获取团长资金流水列表
+ *
+ * @param param 查询参数
+ * @return 流水列表
+ */
+ SupplierFlowListResponse getFlowList(FlowListParam param) throws WxErrorException;
+
+ /**
+ * 获取合作商品详情
+ *
+ * @param productId 商品ID
+ * @param appId 团长商品 所属小店appid
+ * @return 商品详情
+ */
+ CoopProductResponse getProductDetail(String productId, String appId) throws WxErrorException;
+
+ /**
+ * 获取合作商品列表
+ *
+ * @param appid 团长商品 所属小店appid
+ * @param pageSize 单页商品数(不超过30)
+ * @param nextKey 由上次请求返回,顺序翻页时需要传入, 会从上次返回的结果往后翻一页
+ * @return 商品列表
+ */
+ CoopProductListResponse getProductList(String appid, Integer pageSize, String nextKey) throws WxErrorException;
+
+ /**
+ * 获取佣金单详情
+ *
+ * @param orderId 订单号,可从获取佣金单列表中获得
+ * @param skuId 商品skuId
+ * @return 订单详情
+ */
+ CommissionOrderResponse getCommissionOrder(String orderId, String skuId) throws WxErrorException;
+
+ /**
+ * 获取佣金单列表
+ *
+ * @param param 查询参数
+ * @return 佣金单列表
+ */
+ CommissionOrderListResponse getCommissionOrderList(CommissionOrderListParam param) throws WxErrorException;
+
+ /**
+ * 获取合作小店详情
+ *
+ * @param appid 小店appid
+ * @return 小店详情
+ */
+ ShopDetailResponse getShopDetail(String appid) throws WxErrorException;
+
+ /**
+ * 获取合作小店列表
+ *
+ * @param pageSize 单页小店数(不超过30)
+ * @param nextKey 由上次请求返回,顺序翻页时需要传入, 会从上次返回的结果往后翻一页
+ * @return 小店列表
+ */
+ ShopListResponse getShopList(Integer pageSize, String nextKey) throws WxErrorException;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxLeagueWindowService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxLeagueWindowService.java
new file mode 100644
index 0000000000..c4af1571d0
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxLeagueWindowService.java
@@ -0,0 +1,72 @@
+package me.chanjar.weixin.channel.api;
+
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.league.window.AuthInfoResponse;
+import me.chanjar.weixin.channel.bean.league.window.AuthStatusResponse;
+import me.chanjar.weixin.channel.bean.league.window.ProductSearchParam;
+import me.chanjar.weixin.channel.bean.league.window.WindowProductListResponse;
+import me.chanjar.weixin.channel.bean.league.window.WindowProductResponse;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 优选联盟 团长合作达人管理服务
+ *
+ * @author Zeyes
+ */
+public interface WxLeagueWindowService {
+
+ /**
+ * 添加团长商品到橱窗
+ *
+ * @param appid 团长appid
+ * @param openfinderid 视频号openfinderid
+ * @param productId 团长商品ID
+ * @return 结果
+ */
+ WxChannelBaseResponse addProduct(String appid, String openfinderid, String productId) throws WxErrorException;
+
+ /**
+ * 查询橱窗上团长商品列表
+ *
+ * @param param 查询参数
+ * @return 团长商品列表
+ */
+ WindowProductListResponse listProduct(ProductSearchParam param) throws WxErrorException;
+
+ /**
+ * 从橱窗移除团长商品
+ *
+ * @param appid 团长appid
+ * @param openfinderid 视频号openfinderid
+ * @param productId 团长商品ID
+ * @return 结果
+ */
+ WxChannelBaseResponse removeProduct(String appid, String openfinderid, String productId) throws WxErrorException;
+
+ /**
+ * 查询橱窗上团长商品详情
+ *
+ * @param appid 团长appid
+ * @param openfinderid 视频号openfinderid
+ * @param productId 团长商品ID
+ * @return 结果
+ */
+ WindowProductResponse getProductDetail(String appid, String openfinderid, String productId)
+ throws WxErrorException;
+
+ /**
+ * 获取达人橱窗授权链接
+ *
+ * @param finderId 视频号finder_id
+ * @return 授权链接
+ */
+ AuthInfoResponse getWindowAuthInfo(String finderId) throws WxErrorException;
+
+ /**
+ * 获取达人橱窗授权状态
+ *
+ * @param finderId 视频号finder_id
+ * @return 授权链接
+ */
+ AuthStatusResponse getWindowAuthStatus(String finderId) throws WxErrorException;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/BaseWxChannelMessageServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/BaseWxChannelMessageServiceImpl.java
new file mode 100644
index 0000000000..008da958a9
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/BaseWxChannelMessageServiceImpl.java
@@ -0,0 +1,343 @@
+package me.chanjar.weixin.channel.api.impl;
+
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.ACCOUNT_NOTIFY;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.AFTER_SALE_UPDATE;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.BRAND;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.COMPLAINT_NOTIFY;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.CREATE_COUPON;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.DELETE_COUPON;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.EXPIRE_COUPON;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.INVALID_COUPON;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.ORDER_CANCEL;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.ORDER_CONFIRM;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.ORDER_DELIVER;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.ORDER_EXT_INFO_UPDATE;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.ORDER_NEW;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.ORDER_PAY;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.ORDER_SETTLE;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.ORDER_STATUS_UPDATE;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.PRODUCT_CATEGORY_AUDIT;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.PRODUCT_SPU_AUDIT;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.PRODUCT_SPU_STATUS_UPDATE;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.PRODUCT_SPU_UPDATE;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.QRCODE_STATUS;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.RECEIVE_COUPON;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.SUPPLIER_ITEM_UPDATE;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.UPDATE_COUPON_INFO;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.USER_COUPON_EXPIRE;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.USER_COUPON_UNUSE;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.USER_COUPON_USE;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.WITHDRAW_NOTIFY;
+
+import java.util.Map;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.BaseWxChannelMessageService;
+import me.chanjar.weixin.channel.api.WxChannelService;
+import me.chanjar.weixin.channel.bean.message.after.AfterSaleMessage;
+import me.chanjar.weixin.channel.bean.message.after.ComplaintMessage;
+import me.chanjar.weixin.channel.bean.message.coupon.CouponActionMessage;
+import me.chanjar.weixin.channel.bean.message.coupon.CouponReceiveMessage;
+import me.chanjar.weixin.channel.bean.message.coupon.UserCouponExpireMessage;
+import me.chanjar.weixin.channel.bean.message.fund.AccountNotifyMessage;
+import me.chanjar.weixin.channel.bean.message.fund.QrNotifyMessage;
+import me.chanjar.weixin.channel.bean.message.fund.WithdrawNotifyMessage;
+import me.chanjar.weixin.channel.bean.message.order.OrderCancelMessage;
+import me.chanjar.weixin.channel.bean.message.order.OrderConfirmMessage;
+import me.chanjar.weixin.channel.bean.message.order.OrderDeliveryMessage;
+import me.chanjar.weixin.channel.bean.message.order.OrderExtMessage;
+import me.chanjar.weixin.channel.bean.message.order.OrderIdMessage;
+import me.chanjar.weixin.channel.bean.message.order.OrderPayMessage;
+import me.chanjar.weixin.channel.bean.message.order.OrderSettleMessage;
+import me.chanjar.weixin.channel.bean.message.order.OrderStatusMessage;
+import me.chanjar.weixin.channel.bean.message.product.BrandMessage;
+import me.chanjar.weixin.channel.bean.message.product.CategoryAuditMessage;
+import me.chanjar.weixin.channel.bean.message.product.SpuAuditMessage;
+import me.chanjar.weixin.channel.bean.message.supplier.SupplierItemMessage;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+import me.chanjar.weixin.channel.message.WxChannelMessageRouter;
+import me.chanjar.weixin.channel.message.WxChannelMessageRouterRule;
+import me.chanjar.weixin.channel.message.rule.HandlerConsumer;
+import me.chanjar.weixin.channel.util.JsonUtils;
+import me.chanjar.weixin.common.session.WxSessionManager;
+
+/**
+ * @author Zeyes
+ */
+@Slf4j
+public class BaseWxChannelMessageServiceImpl implements BaseWxChannelMessageService {
+
+ /** 消息路由器 */
+ protected WxChannelMessageRouter router;
+
+ public BaseWxChannelMessageServiceImpl(WxChannelMessageRouter router) {
+ this.router = router;
+ this.addDefaultRule();
+ }
+
+ /**
+ * 添加默认的回调规则
+ */
+ protected void addDefaultRule() {
+ /* 品牌资质事件回调 */
+ this.addRule(BrandMessage.class, BRAND, this::brandUpdate);
+ /* 商品审核结果 */
+ this.addRule(SpuAuditMessage.class, PRODUCT_SPU_AUDIT, this::spuAudit);
+ /* 商品上下架 */
+ this.addRule(SpuAuditMessage.class, PRODUCT_SPU_STATUS_UPDATE, this::spuStatusUpdate);
+ /* 商品更新 */
+ this.addRule(SpuAuditMessage.class, PRODUCT_SPU_UPDATE, this::spuUpdate);
+ /* 类目审核结果 */
+ this.addRule(CategoryAuditMessage.class, PRODUCT_CATEGORY_AUDIT, this::categoryAudit);
+ /* 订单下单 */
+ this.addRule(OrderIdMessage.class, ORDER_NEW, this::orderNew);
+ /* 订单取消 */
+ this.addRule(OrderCancelMessage.class, ORDER_CANCEL, this::orderCancel);
+ /* 订单支付成功 */
+ this.addRule(OrderPayMessage.class, ORDER_PAY, this::orderPay);
+ /* 订单发货 */
+ this.addRule(OrderDeliveryMessage.class, ORDER_DELIVER, this::orderDelivery);
+ /* 订单确认收货 */
+ this.addRule(OrderConfirmMessage.class, ORDER_CONFIRM, this::orderConfirm);
+ /* 订单结算成功 */
+ this.addRule(OrderSettleMessage.class, ORDER_SETTLE, this::orderSettle);
+ /* 订单其他信息更新 */
+ this.addRule(OrderExtMessage.class, ORDER_EXT_INFO_UPDATE, this::orderExtInfoUpdate);
+ /* 订单状态更新 */
+ this.addRule(OrderStatusMessage.class, ORDER_STATUS_UPDATE, this::orderStatusUpdate);
+ /* 售后单更新通知 */
+ this.addRule(AfterSaleMessage.class, AFTER_SALE_UPDATE, this::afterSaleStatusUpdate);
+ /* 纠纷更新通知 */
+ this.addRule(ComplaintMessage.class, COMPLAINT_NOTIFY, this::complaintNotify);
+ /* 优惠券领取通知 */
+ this.addRule(CouponReceiveMessage.class, RECEIVE_COUPON, this::couponReceive);
+ /* 优惠券使用通知 */
+ this.addRule(CouponActionMessage.class, CREATE_COUPON, this::couponCreate);
+ /* 优惠券删除通知 */
+ this.addRule(CouponActionMessage.class, DELETE_COUPON, this::couponDelete);
+ /* 优惠券过期通知 */
+ this.addRule(CouponActionMessage.class, EXPIRE_COUPON, this::couponExpire);
+ /* 更新优惠券信息通知 */
+ this.addRule(CouponActionMessage.class, UPDATE_COUPON_INFO, this::couponUpdate);
+ /* 更新优惠券信息通知 */
+ this.addRule(CouponActionMessage.class, INVALID_COUPON, this::couponInvalid);
+ /* 用户优惠券过期通知 */
+ this.addRule(UserCouponExpireMessage.class, USER_COUPON_EXPIRE, this::userCouponExpire);
+ /* 用户优惠券过期通知 */
+ this.addRule(UserCouponExpireMessage.class, USER_COUPON_UNUSE, this::userCouponUnuse);
+ /* 优惠券返还通知 */
+ this.addRule(UserCouponExpireMessage.class, USER_COUPON_USE, this::userCouponUse);
+ /* 结算账户变更回调 */
+ this.addRule(AccountNotifyMessage.class, ACCOUNT_NOTIFY, this::accountNotify);
+ /* 提现回调 */
+ this.addRule(WithdrawNotifyMessage.class, WITHDRAW_NOTIFY, this::withdrawNotify);
+ /* 提现二维码回调 */
+ this.addRule(QrNotifyMessage.class, QRCODE_STATUS, this::qrNotify);
+ /* 团长 */
+ this.addRule(SupplierItemMessage.class, SUPPLIER_ITEM_UPDATE, this::supplierItemUpdate);
+ }
+
+ /**
+ * 添加一条规则进入路由器
+ *
+ * @param clazz 消息类型
+ * @param event 事件类型
+ * @param consumer 处理器
+ * @param 消息类型
+ */
+ protected void addRule(Class clazz, String event,
+ HandlerConsumer, WxSessionManager> consumer) {
+ WxChannelMessageRouterRule rule = new WxChannelMessageRouterRule<>();
+ rule.setMessageClass(clazz).setEvent(event).setAsync(true);
+ rule.getHandlers().add((message, content, appId, context, sessionManager) -> {
+ consumer.accept(message, content, appId, context, sessionManager);
+ return "success";
+ });
+ this.addRule(rule);
+ }
+
+ @Override
+ public void addRule(WxChannelMessageRouterRule extends WxChannelMessage> rule) {
+ router.getRules().add(rule);
+ }
+
+ @Override
+ public Object route(WxChannelMessage message, String content, String appId, final WxChannelService service) {
+ return router.route(message, content, appId, service);
+ }
+
+
+ @Override
+ public void orderNew(OrderIdMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("订单下单:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void orderCancel(OrderCancelMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("订单取消:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void orderPay(OrderPayMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("订单支付成功:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void orderDelivery(OrderDeliveryMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("订单发货:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void orderConfirm(OrderConfirmMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("订单确认收货:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void orderSettle(OrderSettleMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("订单结算:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void orderExtInfoUpdate(OrderExtMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("订单其他信息更新:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void orderStatusUpdate(OrderStatusMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("订单状态更新:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void spuAudit(SpuAuditMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("商品审核:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void spuStatusUpdate(SpuAuditMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("商品状态更新:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void spuUpdate(SpuAuditMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("商品更新:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void categoryAudit(CategoryAuditMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("分类审核:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void brandUpdate(BrandMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("品牌更新:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void afterSaleStatusUpdate(AfterSaleMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("售后状态更新:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void complaintNotify(ComplaintMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("投诉通知:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void couponReceive(CouponReceiveMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("优惠券领取:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void couponCreate(CouponActionMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("优惠券创建:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void couponDelete(CouponActionMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("优惠券删除:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void couponExpire(CouponActionMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("优惠券过期:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void couponUpdate(CouponActionMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("优惠券更新:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void couponInvalid(CouponActionMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("优惠券失效:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void userCouponExpire(UserCouponExpireMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("用户优惠券过期:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void userCouponUse(UserCouponExpireMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("用户优惠券使用:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void userCouponUnuse(UserCouponExpireMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("用户优惠券取消使用:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void accountNotify(AccountNotifyMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("账户通知:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void withdrawNotify(WithdrawNotifyMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("提现通知:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void qrNotify(QrNotifyMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("二维码通知:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void supplierItemUpdate(SupplierItemMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("供应商商品更新:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public Object defaultMessageHandler(WxChannelMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("默认消息处理:{}", JsonUtils.encode(message));
+ return null;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/BaseWxChannelServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/BaseWxChannelServiceImpl.java
new file mode 100644
index 0000000000..6dd12a5b51
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/BaseWxChannelServiceImpl.java
@@ -0,0 +1,389 @@
+package me.chanjar.weixin.channel.api.impl;
+
+
+import com.google.gson.JsonObject;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.WxChannelAddressService;
+import me.chanjar.weixin.channel.api.WxChannelAfterSaleService;
+import me.chanjar.weixin.channel.api.WxChannelBasicService;
+import me.chanjar.weixin.channel.api.WxChannelBrandService;
+import me.chanjar.weixin.channel.api.WxChannelCategoryService;
+import me.chanjar.weixin.channel.api.WxChannelCouponService;
+import me.chanjar.weixin.channel.api.WxChannelFreightTemplateService;
+import me.chanjar.weixin.channel.api.WxChannelFundService;
+import me.chanjar.weixin.channel.api.WxChannelOrderService;
+import me.chanjar.weixin.channel.api.WxChannelProductService;
+import me.chanjar.weixin.channel.api.WxChannelService;
+import me.chanjar.weixin.channel.api.WxChannelSharerService;
+import me.chanjar.weixin.channel.api.WxChannelWarehouseService;
+import me.chanjar.weixin.channel.api.WxLeagueProductService;
+import me.chanjar.weixin.channel.api.WxLeaguePromoterService;
+import me.chanjar.weixin.channel.api.WxLeagueSupplierService;
+import me.chanjar.weixin.channel.api.WxLeagueWindowService;
+import me.chanjar.weixin.channel.config.WxChannelConfig;
+import me.chanjar.weixin.channel.util.JsonUtils;
+import me.chanjar.weixin.common.api.WxConsts;
+import me.chanjar.weixin.common.bean.ToJson;
+import me.chanjar.weixin.common.bean.WxAccessToken;
+import me.chanjar.weixin.common.enums.WxType;
+import me.chanjar.weixin.common.error.WxError;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.error.WxRuntimeException;
+import me.chanjar.weixin.common.util.DataUtils;
+import me.chanjar.weixin.common.util.crypto.SHA1;
+import me.chanjar.weixin.common.util.http.RequestExecutor;
+import me.chanjar.weixin.common.util.http.RequestHttp;
+import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
+import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * @author Zeyes
+ * @see #doGetAccessTokenRequest
+ */
+@Slf4j
+public abstract class BaseWxChannelServiceImpl implements WxChannelService, RequestHttp {
+
+ private final WxChannelBasicService basicService = new WxChannelBasicServiceImpl(this);
+ private final WxChannelCategoryService categoryService = new WxChannelCategoryServiceImpl(this);
+ private final WxChannelBrandService brandService = new WxChannelBrandServiceImpl(this);
+ private final WxChannelProductService productService = new WxChannelProductServiceImpl(this);
+ private final WxChannelWarehouseService warehouseService = new WxChannelWarehouseServiceImpl(this);
+ private final WxChannelOrderService orderService = new WxChannelOrderServiceImpl(this);
+ private final WxChannelAfterSaleService afterSaleService = new WxChannelAfterSaleServiceImpl(this);
+ private final WxChannelFreightTemplateService freightTemplateService =
+ new WxChannelFreightTemplateServiceImpl(this);
+ private final WxChannelAddressService addressService = new WxChannelAddressServiceImpl(this);
+ private final WxChannelCouponService couponService = new WxChannelCouponServiceImpl(this);
+ private final WxChannelSharerService sharerService = new WxChannelSharerServiceImpl(this);
+ private final WxChannelFundService fundService = new WxChannelFundServiceImpl(this);
+ private WxLeagueWindowService leagueWindowService = null;
+ private WxLeagueSupplierService leagueSupplierService = null;
+ private WxLeaguePromoterService leaguePromoterService = null;
+ private WxLeagueProductService leagueProductService = null;
+
+ protected WxChannelConfig config;
+ private int retrySleepMillis = 1000;
+ private int maxRetryTimes = 5;
+
+ @Override
+ public RequestHttp getRequestHttp() {
+ return this;
+ }
+
+ @Override
+ public boolean checkSignature(String timestamp, String nonce, String signature) {
+ try {
+ return SHA1.gen(this.getConfig().getToken(), timestamp, nonce).equals(signature);
+ } catch (Exception e) {
+ log.error("Checking signature failed, and the reason is :" + e.getMessage());
+ return false;
+ }
+ }
+
+ @Override
+ public String getAccessToken() throws WxErrorException {
+ return getAccessToken(false);
+ }
+
+ @Override
+ public String getAccessToken(boolean forceRefresh) throws WxErrorException {
+ if (!forceRefresh && !this.getConfig().isAccessTokenExpired()) {
+ return this.getConfig().getAccessToken();
+ }
+
+ Lock lock = this.getConfig().getAccessTokenLock();
+ boolean locked = false;
+ try {
+ do {
+ locked = lock.tryLock(100, TimeUnit.MILLISECONDS);
+ if (!forceRefresh && !this.getConfig().isAccessTokenExpired()) {
+ return this.getConfig().getAccessToken();
+ }
+ } while (!locked);
+ String response = doGetAccessTokenRequest();
+ return extractAccessToken(response);
+ } catch (IOException | InterruptedException e) {
+ throw new WxRuntimeException(e);
+ } finally {
+ if (locked) {
+ lock.unlock();
+ }
+ }
+ }
+
+ /**
+ * 通过网络请求获取AccessToken
+ *
+ * @return .
+ *
+ * @throws IOException .
+ */
+ protected abstract String doGetAccessTokenRequest() throws IOException;
+
+ @Override
+ public String get(String url, String queryParam) throws WxErrorException {
+ return execute(SimpleGetRequestExecutor.create(this), url, queryParam);
+ }
+
+ @Override
+ public String post(String url, String postData) throws WxErrorException {
+ return execute(SimplePostRequestExecutor.create(this), url, postData);
+ }
+
+ @Override
+ public String post(String url, Object obj) throws WxErrorException {
+ // 此处用JsonUtils.encode, 不用Gson
+ return this.execute(SimplePostRequestExecutor.create(this), url, JsonUtils.encode(obj));
+ }
+
+ @Override
+ public String post(String url, ToJson obj) throws WxErrorException {
+ return this.post(url, obj.toJson());
+ }
+
+ @Override
+ public String post(String url, JsonObject jsonObject) throws WxErrorException {
+ return this.post(url, jsonObject.toString());
+ }
+
+ /**
+ * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求
+ */
+ @Override
+ public T execute(RequestExecutor executor, String uri, E data) throws WxErrorException {
+ return execute0(executor, uri, data, true);
+ }
+
+ @Override
+ public T executeWithoutLog(RequestExecutor executor, String uri, E data) throws WxErrorException {
+ return execute0(executor, uri, data, false);
+ }
+
+ protected T execute0(RequestExecutor executor, String uri, E data, boolean printResult)
+ throws WxErrorException {
+ int retryTimes = 0;
+ do {
+ try {
+ return this.executeInternal(executor, uri, data, false, printResult);
+ } catch (WxErrorException e) {
+ if (retryTimes + 1 > this.maxRetryTimes) {
+ log.warn("重试达到最大次数【{}】", maxRetryTimes);
+ //最后一次重试失败后,直接抛出异常,不再等待
+ throw new WxErrorException(WxError.builder()
+ .errorCode(e.getError().getErrorCode())
+ .errorMsg("微信服务端异常,超出重试次数!")
+ .build());
+ }
+
+ WxError error = e.getError();
+ // -1 系统繁忙, 1000ms后重试
+ if (error.getErrorCode() == -1) {
+ int sleepMillis = this.retrySleepMillis * (1 << retryTimes);
+ try {
+ log.warn("微信系统繁忙,{} ms 后重试(第{}次)", sleepMillis, retryTimes + 1);
+ Thread.sleep(sleepMillis);
+ } catch (InterruptedException e1) {
+ Thread.currentThread().interrupt();
+ }
+ } else {
+ throw e;
+ }
+ }
+ } while (retryTimes++ < this.maxRetryTimes);
+
+ log.warn("重试达到最大次数【{}】", this.maxRetryTimes);
+ throw new WxRuntimeException("微信服务端异常,超出重试次数");
+ }
+
+ protected T executeInternal(RequestExecutor executor, String uri, E data, boolean doNotAutoRefreshToken,
+ boolean printResult) throws WxErrorException {
+ E dataForLog = DataUtils.handleDataWithSecret(data);
+
+ if (uri.contains("access_token=")) {
+ throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri);
+ }
+ String accessToken = getAccessToken(false);
+
+ WxChannelConfig config = this.getConfig();
+ if (StringUtils.isNotEmpty(config.getApiHostUrl())) {
+ uri = uri.replace("https://api.weixin.qq.com", config.getApiHostUrl());
+ }
+
+ String uriWithAccessToken = uri + (uri.contains("?") ? "&" : "?") + "access_token=" + accessToken;
+
+ try {
+ T result = executor.execute(uriWithAccessToken, data, WxType.Channel);
+ log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog,
+ printResult ? result : "...");
+ return result;
+ } catch (WxErrorException e) {
+ WxError error = e.getError();
+ if (WxConsts.ACCESS_TOKEN_ERROR_CODES.contains(error.getErrorCode())) {
+ // 强制设置WxMaConfig的access token过期了,这样在下一次请求里就会刷新access token
+ Lock lock = config.getAccessTokenLock();
+ lock.lock();
+ try {
+ if (StringUtils.equals(config.getAccessToken(), accessToken)) {
+ config.expireAccessToken();
+ }
+ } catch (Exception ex) {
+ config.expireAccessToken();
+ } finally {
+ lock.unlock();
+ }
+ if (config.autoRefreshToken() && !doNotAutoRefreshToken) {
+ log.warn("即将重新获取新的access_token,错误代码:{},错误信息:{}", error.getErrorCode(), error.getErrorMsg());
+ //下一次不再自动重试
+ //当小程序误调用第三方平台专属接口时,第三方无法使用小程序的access token,如果可以继续自动获取token会导致无限循环重试,直到栈溢出
+ return this.executeInternal(executor, uri, data, true, printResult);
+ }
+ }
+
+ if (error.getErrorCode() != 0) {
+ log.warn("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, dataForLog, error);
+ throw new WxErrorException(error, e);
+ }
+ return null;
+ } catch (IOException e) {
+ log.warn("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, dataForLog, e.getMessage());
+ throw new WxRuntimeException(e);
+ }
+ }
+
+ /**
+ * 设置当前的AccessToken
+ *
+ * @param resultContent 响应内容
+ * @return access token
+ *
+ * @throws WxErrorException 异常
+ */
+ protected String extractAccessToken(String resultContent) throws WxErrorException {
+ log.info("resultContent: " + resultContent);
+ WxChannelConfig config = this.getConfig();
+ WxError error = WxError.fromJson(resultContent, WxType.MiniApp);
+ if (error.getErrorCode() != 0) {
+ throw new WxErrorException(error);
+ }
+ WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
+ config.updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
+ return accessToken.getAccessToken();
+ }
+
+ @Override
+ public WxChannelConfig getConfig() {
+ return config;
+ }
+
+ @Override
+ public void setConfig(WxChannelConfig config) {
+ this.config = config;
+ initHttp();
+ }
+
+ @Override
+ public void setRetrySleepMillis(int retrySleepMillis) {
+ this.retrySleepMillis = retrySleepMillis;
+ }
+
+ @Override
+ public void setMaxRetryTimes(int maxRetryTimes) {
+ this.maxRetryTimes = maxRetryTimes;
+ }
+
+ @Override
+ public WxChannelBasicService getBasicService() {
+ return basicService;
+ }
+
+ @Override
+ public WxChannelCategoryService getCategoryService() {
+ return categoryService;
+ }
+
+ @Override
+ public WxChannelBrandService getBrandService() {
+ return brandService;
+ }
+
+ @Override
+ public WxChannelProductService getProductService() {
+ return productService;
+ }
+
+ @Override
+ public WxChannelWarehouseService getWarehouseService() {
+ return warehouseService;
+ }
+
+ @Override
+ public WxChannelOrderService getOrderService() {
+ return orderService;
+ }
+
+ @Override
+ public WxChannelAfterSaleService getAfterSaleService() {
+ return afterSaleService;
+ }
+
+ @Override
+ public WxChannelFreightTemplateService getFreightTemplateService() {
+ return freightTemplateService;
+ }
+
+ @Override
+ public WxChannelAddressService getAddressService() {
+ return addressService;
+ }
+
+ @Override
+ public WxChannelCouponService getCouponService() {
+ return couponService;
+ }
+
+ @Override
+ public WxChannelSharerService getSharerService() {
+ return sharerService;
+ }
+
+ @Override
+ public WxChannelFundService getFundService() {
+ return fundService;
+ }
+
+ @Override
+ public synchronized WxLeagueWindowService getLeagueWindowService() {
+ if (leagueWindowService == null) {
+ leagueWindowService = new WxLeagueWindowServiceImpl(this);
+ }
+ return leagueWindowService;
+ }
+
+ @Override
+ public synchronized WxLeagueSupplierService getLeagueSupplierService() {
+ if (leagueSupplierService == null) {
+ leagueSupplierService = new WxLeagueSupplierServiceImpl(this);
+ }
+ return leagueSupplierService;
+ }
+
+ @Override
+ public synchronized WxLeaguePromoterService getLeaguePromoterService() {
+ if (leaguePromoterService == null) {
+ leaguePromoterService = new WxLeaguePromoterServiceImpl(this);
+ }
+ return leaguePromoterService;
+ }
+
+ @Override
+ public synchronized WxLeagueProductService getLeagueProductService() {
+ if (leagueProductService == null) {
+ leagueProductService = new WxLeagueProductServiceImpl(this);
+ }
+ return leagueProductService;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelAddressServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelAddressServiceImpl.java
new file mode 100644
index 0000000000..53b9eb4d7a
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelAddressServiceImpl.java
@@ -0,0 +1,72 @@
+package me.chanjar.weixin.channel.api.impl;
+
+
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Address.ADD_ADDRESS_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Address.DELETE_ADDRESS_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Address.GET_ADDRESS_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Address.LIST_ADDRESS_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Address.UPDATE_ADDRESS_URL;
+
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.WxChannelAddressService;
+import me.chanjar.weixin.channel.bean.address.AddressAddParam;
+import me.chanjar.weixin.channel.bean.address.AddressDetail;
+import me.chanjar.weixin.channel.bean.address.AddressIdParam;
+import me.chanjar.weixin.channel.bean.address.AddressIdResponse;
+import me.chanjar.weixin.channel.bean.address.AddressInfoResponse;
+import me.chanjar.weixin.channel.bean.address.AddressListParam;
+import me.chanjar.weixin.channel.bean.address.AddressListResponse;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.util.ResponseUtils;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号小店 地址管理服务实现
+ *
+ * @author Zeyes
+ */
+@Slf4j
+public class WxChannelAddressServiceImpl implements WxChannelAddressService {
+
+ /** 微信商店服务 */
+ private final BaseWxChannelServiceImpl shopService;
+
+ public WxChannelAddressServiceImpl(BaseWxChannelServiceImpl shopService) {
+ this.shopService = shopService;
+ }
+
+ @Override
+ public AddressListResponse listAddress(Integer offset, Integer limit) throws WxErrorException {
+ AddressListParam param = new AddressListParam(offset, limit);
+ String resJson = shopService.post(LIST_ADDRESS_URL, param);
+ return ResponseUtils.decode(resJson, AddressListResponse.class);
+ }
+
+ @Override
+ public AddressInfoResponse getAddress(String addressId) throws WxErrorException {
+ AddressIdParam param = new AddressIdParam(addressId);
+ String resJson = shopService.post(GET_ADDRESS_URL, param);
+ return ResponseUtils.decode(resJson, AddressInfoResponse.class);
+ }
+
+ @Override
+ public AddressIdResponse addAddress(AddressDetail addressDetail) throws WxErrorException {
+ AddressAddParam param = new AddressAddParam(addressDetail);
+ String resJson = shopService.post(ADD_ADDRESS_URL, param);
+ return ResponseUtils.decode(resJson, AddressIdResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse updateAddress(AddressDetail addressDetail) throws WxErrorException {
+ AddressAddParam param = new AddressAddParam(addressDetail);
+ String resJson = shopService.post(UPDATE_ADDRESS_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse deleteAddress(String addressId) throws WxErrorException {
+ AddressIdParam param = new AddressIdParam(addressId);
+ String resJson = shopService.post(DELETE_ADDRESS_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelAfterSaleServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelAfterSaleServiceImpl.java
new file mode 100644
index 0000000000..c29ea49b34
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelAfterSaleServiceImpl.java
@@ -0,0 +1,103 @@
+package me.chanjar.weixin.channel.api.impl;
+
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.AfterSale.AFTER_SALE_ACCEPT_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.AfterSale.AFTER_SALE_GET_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.AfterSale.AFTER_SALE_LIST_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.AfterSale.AFTER_SALE_REJECT_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.AfterSale.AFTER_SALE_UPLOAD_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Complaint.ADD_COMPLAINT_MATERIAL_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Complaint.ADD_COMPLAINT_PROOF_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Complaint.GET_COMPLAINT_ORDER_URL;
+
+import java.util.List;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.WxChannelAfterSaleService;
+import me.chanjar.weixin.channel.bean.after.AfterSaleAcceptParam;
+import me.chanjar.weixin.channel.bean.after.AfterSaleIdParam;
+import me.chanjar.weixin.channel.bean.after.AfterSaleInfoResponse;
+import me.chanjar.weixin.channel.bean.after.AfterSaleListParam;
+import me.chanjar.weixin.channel.bean.after.AfterSaleListResponse;
+import me.chanjar.weixin.channel.bean.after.AfterSaleRejectParam;
+import me.chanjar.weixin.channel.bean.after.RefundEvidenceParam;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.complaint.ComplaintOrderResponse;
+import me.chanjar.weixin.channel.bean.complaint.ComplaintParam;
+import me.chanjar.weixin.channel.util.ResponseUtils;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号小店 售后服务实现
+ *
+ * @author Zeyes
+ */
+@Slf4j
+public class WxChannelAfterSaleServiceImpl implements WxChannelAfterSaleService {
+
+ /** 微信商店服务 */
+ private final BaseWxChannelServiceImpl shopService;
+
+ public WxChannelAfterSaleServiceImpl(BaseWxChannelServiceImpl shopService) {
+ this.shopService = shopService;
+ }
+
+ @Override
+ public AfterSaleListResponse listIds(Long beginCreateTime, Long endCreateTime, String nextKey)
+ throws WxErrorException {
+ AfterSaleListParam param = new AfterSaleListParam(beginCreateTime, endCreateTime, nextKey);
+ String resJson = shopService.post(AFTER_SALE_LIST_URL, param);
+ return ResponseUtils.decode(resJson, AfterSaleListResponse.class);
+ }
+
+ @Override
+ public AfterSaleInfoResponse get(String afterSaleOrderId) throws WxErrorException {
+ AfterSaleIdParam param = new AfterSaleIdParam(afterSaleOrderId);
+ String resJson = shopService.post(AFTER_SALE_GET_URL, param);
+ return ResponseUtils.decode(resJson, AfterSaleInfoResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse accept(String afterSaleOrderId, String addressId) throws WxErrorException {
+ AfterSaleAcceptParam param = new AfterSaleAcceptParam(afterSaleOrderId, addressId);
+ String resJson = shopService.post(AFTER_SALE_ACCEPT_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse reject(String afterSaleOrderId, String rejectReason) throws WxErrorException {
+ AfterSaleRejectParam param = new AfterSaleRejectParam(afterSaleOrderId, rejectReason);
+ String resJson = shopService.post(AFTER_SALE_REJECT_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse uploadRefundEvidence(String afterSaleOrderId, String desc, List certificates)
+ throws WxErrorException {
+ RefundEvidenceParam param = new RefundEvidenceParam(afterSaleOrderId, desc, certificates);
+ String resJson = shopService.post(AFTER_SALE_UPLOAD_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse addComplaintMaterial(String complaintId, String content, List mediaIds)
+ throws WxErrorException {
+ ComplaintParam param = new ComplaintParam(complaintId, content, mediaIds);
+ String resJson = shopService.post(ADD_COMPLAINT_MATERIAL_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+
+ }
+
+ @Override
+ public WxChannelBaseResponse addComplaintEvidence(String complaintId, String content, List mediaIds)
+ throws WxErrorException {
+ ComplaintParam param = new ComplaintParam(complaintId, content, mediaIds);
+ String resJson = shopService.post(ADD_COMPLAINT_PROOF_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public ComplaintOrderResponse getComplaint(String complaintId) throws WxErrorException {
+ String reqJson = "{\"complaint_id\":\"" + complaintId + "\"}";
+ String resJson = shopService.post(GET_COMPLAINT_ORDER_URL, reqJson);
+ return ResponseUtils.decode(resJson, ComplaintOrderResponse.class);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelBasicServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelBasicServiceImpl.java
new file mode 100644
index 0000000000..cac5e9e513
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelBasicServiceImpl.java
@@ -0,0 +1,96 @@
+package me.chanjar.weixin.channel.api.impl;
+
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Basics.GET_ADDRESS_CODE;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Basics.GET_IMG_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Basics.GET_SHOP_INFO;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Basics.IMG_UPLOAD_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Basics.UPLOAD_QUALIFICATION_FILE;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.WxChannelBasicService;
+import me.chanjar.weixin.channel.bean.address.AddressCodeResponse;
+import me.chanjar.weixin.channel.bean.image.ChannelImageInfo;
+import me.chanjar.weixin.channel.bean.image.ChannelImageResponse;
+import me.chanjar.weixin.channel.bean.image.QualificationFileResponse;
+import me.chanjar.weixin.channel.bean.image.UploadImageResponse;
+import me.chanjar.weixin.channel.bean.shop.ShopInfoResponse;
+import me.chanjar.weixin.channel.executor.ChannelFileUploadRequestExecutor;
+import me.chanjar.weixin.channel.executor.ChannelMediaDownloadRequestExecutor;
+import me.chanjar.weixin.channel.util.ResponseUtils;
+import me.chanjar.weixin.common.error.WxError;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.util.http.RequestExecutor;
+
+/**
+ * @author Zeyes
+ */
+@Slf4j
+public class WxChannelBasicServiceImpl implements WxChannelBasicService {
+
+ /** 微信商店服务 */
+ private final BaseWxChannelServiceImpl shopService;
+
+ public WxChannelBasicServiceImpl(BaseWxChannelServiceImpl shopService) {
+ this.shopService = shopService;
+ }
+
+ @Override
+ public ShopInfoResponse getShopInfo() throws WxErrorException {
+ String resJson = shopService.get(GET_SHOP_INFO, null);
+ return ResponseUtils.decode(resJson, ShopInfoResponse.class);
+ }
+
+ @Override
+ public ChannelImageInfo uploadImg(int respType, String imgUrl) throws WxErrorException {
+ String url = IMG_UPLOAD_URL + "?upload_type=1&resp_type=" + respType;
+ String reqJson = "{\"img_url\":\"" + imgUrl + "\"}";
+ String resJson = shopService.post(url, reqJson);
+ UploadImageResponse response = ResponseUtils.decode(resJson, UploadImageResponse.class);
+ return response.getImgInfo();
+ }
+
+ @Override
+ public ChannelImageInfo uploadImg(int respType, File file, int height, int width) throws WxErrorException {
+ String url = IMG_UPLOAD_URL + "?upload_type=0&resp_type=" + respType + "&height=" + height + "&width=" + width;
+ RequestExecutor executor = ChannelFileUploadRequestExecutor.create(shopService);
+ String resJson = (String) shopService.execute(executor, url, file);
+ UploadImageResponse response = ResponseUtils.decode(resJson, UploadImageResponse.class);
+ return response.getImgInfo();
+ }
+
+ @Override
+ public QualificationFileResponse uploadQualificationFile(File file) throws WxErrorException {
+ RequestExecutor executor = ChannelFileUploadRequestExecutor.create(shopService);
+ String resJson = (String) shopService.execute(executor, UPLOAD_QUALIFICATION_FILE, file);
+ return ResponseUtils.decode(resJson, QualificationFileResponse.class);
+ }
+
+ @Override
+ public ChannelImageResponse getImg(String mediaId) throws WxErrorException {
+ String appId = shopService.getConfig().getAppid();
+ ChannelImageResponse rs = null;
+ try {
+ String url = GET_IMG_URL + "?media_id=" + mediaId;
+ RequestExecutor executor = ChannelMediaDownloadRequestExecutor.create(shopService,
+ Files.createTempDirectory("wxjava-channel-" + appId).toFile());
+ rs = (ChannelImageResponse) shopService.execute(executor, url, null);
+ } catch (IOException e) {
+ throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).build(), e);
+ }
+ if (rs == null) {
+ rs = ResponseUtils.internalError(ChannelImageResponse.class);
+ }
+ return rs;
+ }
+
+ @Override
+ public AddressCodeResponse getAddressCode(Integer code) throws WxErrorException {
+ String reqJson = "{\"addr_code\": " + code + "}";
+ String resJson = shopService.post(GET_ADDRESS_CODE, reqJson);
+ return ResponseUtils.decode(resJson, AddressCodeResponse.class);
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelBrandServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelBrandServiceImpl.java
new file mode 100644
index 0000000000..19aadcc06e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelBrandServiceImpl.java
@@ -0,0 +1,98 @@
+package me.chanjar.weixin.channel.api.impl;
+
+
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Brand.ADD_BRAND_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Brand.ALL_BRAND_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Brand.CANCEL_BRAND_AUDIT_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Brand.DELETE_BRAND_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Brand.GET_BRAND_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Brand.LIST_BRAND_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Brand.LIST_BRAND_VALID_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Brand.UPDATE_BRAND_URL;
+
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.WxChannelBrandService;
+import me.chanjar.weixin.channel.bean.audit.AuditApplyResponse;
+import me.chanjar.weixin.channel.bean.base.StreamPageParam;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.brand.Brand;
+import me.chanjar.weixin.channel.bean.brand.BrandApplyListResponse;
+import me.chanjar.weixin.channel.bean.brand.BrandInfoResponse;
+import me.chanjar.weixin.channel.bean.brand.BrandListResponse;
+import me.chanjar.weixin.channel.bean.brand.BrandParam;
+import me.chanjar.weixin.channel.bean.brand.BrandSearchParam;
+import me.chanjar.weixin.channel.util.ResponseUtils;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号小店 品牌服务实现
+ *
+ * @author Zeyes
+ */
+@Slf4j
+public class WxChannelBrandServiceImpl implements WxChannelBrandService {
+
+ /** 微信商店服务 */
+ private final BaseWxChannelServiceImpl shopService;
+
+ public WxChannelBrandServiceImpl(BaseWxChannelServiceImpl shopService) {
+ this.shopService = shopService;
+ }
+
+ @Override
+ public BrandListResponse listAllBrand(Integer pageSize, String nextKey) throws WxErrorException {
+ StreamPageParam param = new StreamPageParam(pageSize, nextKey);
+ String resJson = shopService.post(ALL_BRAND_URL, param);
+ return ResponseUtils.decode(resJson, BrandListResponse.class);
+ }
+
+ @Override
+ public AuditApplyResponse addBrandApply(Brand brand) throws WxErrorException {
+ BrandParam param = new BrandParam(brand);
+ String resJson = shopService.post(ADD_BRAND_URL, param);
+ return ResponseUtils.decode(resJson, AuditApplyResponse.class);
+ }
+
+ @Override
+ public AuditApplyResponse updateBrandApply(Brand brand) throws WxErrorException {
+ BrandParam param = new BrandParam(brand);
+ String resJson = shopService.post(UPDATE_BRAND_URL, param);
+ return ResponseUtils.decode(resJson, AuditApplyResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse cancelBrandApply(String brandId, String auditId) throws WxErrorException {
+ String reqJson = "{\"brand_id\":\"" + brandId + "\",\"audit_id\":\"" + auditId + "\"}";
+ String resJson = shopService.post(CANCEL_BRAND_AUDIT_URL, reqJson);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse deleteBrandApply(String brandId) throws WxErrorException {
+ String reqJson = "{\"brand_id\":\"" + brandId + "\"}";
+ String resJson = shopService.post(DELETE_BRAND_URL, reqJson);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public BrandInfoResponse getBrandApply(String brandId) throws WxErrorException {
+ String reqJson = "{\"brand_id\":\"" + brandId + "\"}";
+ String resJson = shopService.post(GET_BRAND_URL, reqJson);
+ return ResponseUtils.decode(resJson, BrandInfoResponse.class);
+ }
+
+ @Override
+ public BrandApplyListResponse listBrandApply(Integer pageSize, String nextKey, Integer status)
+ throws WxErrorException {
+ BrandSearchParam param = new BrandSearchParam(pageSize, nextKey, status);
+ String resJson = shopService.post(LIST_BRAND_URL, param);
+ return ResponseUtils.decode(resJson, BrandApplyListResponse.class);
+ }
+
+ @Override
+ public BrandApplyListResponse listValidBrandApply(Integer pageSize, String nextKey) throws WxErrorException {
+ StreamPageParam param = new StreamPageParam(pageSize, nextKey);
+ String resJson = shopService.post(LIST_BRAND_VALID_URL, param);
+ return ResponseUtils.decode(resJson, BrandApplyListResponse.class);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelCategoryServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelCategoryServiceImpl.java
new file mode 100644
index 0000000000..52fdf3cdf8
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelCategoryServiceImpl.java
@@ -0,0 +1,119 @@
+package me.chanjar.weixin.channel.api.impl;
+
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Category.ADD_CATEGORY_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Category.AVAILABLE_CATEGORY_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Category.CANCEL_CATEGORY_AUDIT_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Category.GET_CATEGORY_AUDIT_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Category.GET_CATEGORY_DETAIL_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Category.LIST_ALL_CATEGORY_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Category.LIST_PASS_CATEGORY_URL;
+
+import java.util.Collections;
+import java.util.List;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.WxChannelCategoryService;
+import me.chanjar.weixin.channel.bean.audit.AuditApplyResponse;
+import me.chanjar.weixin.channel.bean.audit.AuditResponse;
+import me.chanjar.weixin.channel.bean.audit.CategoryAuditInfo;
+import me.chanjar.weixin.channel.bean.audit.CategoryAuditRequest;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.category.CategoryDetailResult;
+import me.chanjar.weixin.channel.bean.category.CategoryQualificationResponse;
+import me.chanjar.weixin.channel.bean.category.PassCategoryResponse;
+import me.chanjar.weixin.channel.bean.category.ShopCategory;
+import me.chanjar.weixin.channel.bean.category.ShopCategoryResponse;
+import me.chanjar.weixin.channel.util.JsonUtils;
+import me.chanjar.weixin.channel.util.ResponseUtils;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
+import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor;
+
+/**
+ * 视频号小店 商品类目相关接口
+ *
+ * @author Zeyes
+ */
+@Slf4j
+public class WxChannelCategoryServiceImpl implements WxChannelCategoryService {
+
+ /** 微信商店服务 */
+ private final BaseWxChannelServiceImpl shopService;
+
+ public WxChannelCategoryServiceImpl(BaseWxChannelServiceImpl shopService) {
+ this.shopService = shopService;
+ }
+
+ @Override
+ public CategoryQualificationResponse listAllCategory() throws WxErrorException {
+ // 数据量太大了,不记录日志
+ String resJson = (String) shopService.executeWithoutLog(SimpleGetRequestExecutor.create(shopService),
+ LIST_ALL_CATEGORY_URL, null);
+ return ResponseUtils.decode(resJson, CategoryQualificationResponse.class);
+ }
+
+ public List listAvailableCategory(String parentId) throws WxErrorException {
+ Long pid = null;
+ try {
+ pid = Long.parseLong(parentId);
+ } catch (Throwable e) {
+ log.error("parentId必须为数字, " + parentId, e);
+ return Collections.emptyList();
+ }
+ String reqJson = "{\"f_cat_id\": " + pid + "}";
+ String resJson = (String) shopService.executeWithoutLog(SimplePostRequestExecutor.create(shopService),
+ AVAILABLE_CATEGORY_URL, reqJson);
+ ShopCategoryResponse response = ResponseUtils.decode(resJson, ShopCategoryResponse.class);
+ return response.getCategories();
+ }
+
+ @Override
+ public CategoryDetailResult getCategoryDetail(String id) throws WxErrorException {
+ Long catId = null;
+ try {
+ catId = Long.parseLong(id);
+ } catch (Throwable e) {
+ log.error("id必须为数字, " + id, e);
+ return ResponseUtils.internalError(CategoryDetailResult.class);
+ }
+ String reqJson = "{\"cat_id\": " + catId + "}";
+ String resJson = (String) shopService.executeWithoutLog(SimplePostRequestExecutor.create(shopService),
+ GET_CATEGORY_DETAIL_URL, reqJson);
+ return ResponseUtils.decode(resJson, CategoryDetailResult.class);
+ }
+
+ @Override
+ public AuditApplyResponse addCategory(String level1, String level2, String level3, List certificate)
+ throws WxErrorException {
+ String reqJson = null;
+ try {
+ Long l1 = Long.parseLong(level1);
+ Long l2 = Long.parseLong(level2);
+ Long l3 = Long.parseLong(level3);
+ CategoryAuditInfo categoryInfo = new CategoryAuditInfo(l1, l2, l3, certificate);
+ reqJson = JsonUtils.encode(new CategoryAuditRequest(categoryInfo));
+ } catch (Throwable e) {
+ log.error("微信请求异常", e);
+ }
+ String resJson = shopService.post(ADD_CATEGORY_URL, reqJson);
+ return ResponseUtils.decode(resJson, AuditApplyResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse cancelCategoryAudit(String auditId) throws WxErrorException {
+ String resJson = shopService.post(CANCEL_CATEGORY_AUDIT_URL, "{\"audit_id\": \"" + auditId + "\"}");
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public AuditResponse getAudit(String auditId) throws WxErrorException {
+ String resJson = shopService.post(GET_CATEGORY_AUDIT_URL, "{\"audit_id\": \"" + auditId + "\"}");
+ return ResponseUtils.decode(resJson, AuditResponse.class);
+ }
+
+ @Override
+ public PassCategoryResponse listPassCategory() throws WxErrorException {
+ String resJson = shopService.get(LIST_PASS_CATEGORY_URL, null);
+ return ResponseUtils.decode(resJson, PassCategoryResponse.class);
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelCouponServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelCouponServiceImpl.java
new file mode 100644
index 0000000000..174626f4a9
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelCouponServiceImpl.java
@@ -0,0 +1,88 @@
+package me.chanjar.weixin.channel.api.impl;
+
+
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Coupon.CREATE_COUPON_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Coupon.GET_COUPON_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Coupon.GET_USER_COUPON_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Coupon.LIST_COUPON_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Coupon.LIST_USER_COUPON_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Coupon.UPDATE_COUPON_STATUS_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Coupon.UPDATE_COUPON_URL;
+
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.WxChannelCouponService;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.coupon.CouponIdInfo;
+import me.chanjar.weixin.channel.bean.coupon.CouponIdResponse;
+import me.chanjar.weixin.channel.bean.coupon.CouponInfoResponse;
+import me.chanjar.weixin.channel.bean.coupon.CouponListParam;
+import me.chanjar.weixin.channel.bean.coupon.CouponListResponse;
+import me.chanjar.weixin.channel.bean.coupon.CouponParam;
+import me.chanjar.weixin.channel.bean.coupon.CouponStatusParam;
+import me.chanjar.weixin.channel.bean.coupon.UserCouponIdParam;
+import me.chanjar.weixin.channel.bean.coupon.UserCouponListParam;
+import me.chanjar.weixin.channel.bean.coupon.UserCouponListResponse;
+import me.chanjar.weixin.channel.bean.coupon.UserCouponResponse;
+import me.chanjar.weixin.channel.util.ResponseUtils;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号小店 优惠券服务实现
+ *
+ * @author Zeyes
+ */
+@Slf4j
+public class WxChannelCouponServiceImpl implements WxChannelCouponService {
+
+ /** 微信商店服务 */
+ private final BaseWxChannelServiceImpl shopService;
+
+ public WxChannelCouponServiceImpl(BaseWxChannelServiceImpl shopService) {
+ this.shopService = shopService;
+ }
+
+ @Override
+ public CouponIdResponse createCoupon(CouponParam coupon) throws WxErrorException {
+ String resJson = shopService.post(CREATE_COUPON_URL, coupon);
+ return ResponseUtils.decode(resJson, CouponIdResponse.class);
+ }
+
+ @Override
+ public CouponIdResponse updateCoupon(CouponParam coupon) throws WxErrorException {
+ String resJson = shopService.post(UPDATE_COUPON_URL, coupon);
+ return ResponseUtils.decode(resJson, CouponIdResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse updateCouponStatus(String couponId, Integer status) throws WxErrorException {
+ CouponStatusParam param = new CouponStatusParam(couponId, status);
+ String resJson = shopService.post(UPDATE_COUPON_STATUS_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public CouponInfoResponse getCoupon(String couponId) throws WxErrorException {
+ CouponIdInfo param = new CouponIdInfo(couponId);
+ String resJson = shopService.post(GET_COUPON_URL, param);
+ return ResponseUtils.decode(resJson, CouponInfoResponse.class);
+ }
+
+ @Override
+ public CouponListResponse getCouponList(CouponListParam param) throws WxErrorException {
+ String resJson = shopService.post(LIST_COUPON_URL, param);
+ return ResponseUtils.decode(resJson, CouponListResponse.class);
+ }
+
+ @Override
+ public UserCouponResponse getUserCoupon(String openId, String userCouponId) throws WxErrorException {
+ UserCouponIdParam param = new UserCouponIdParam(openId, userCouponId);
+ String resJson = shopService.post(GET_USER_COUPON_URL, param);
+ return ResponseUtils.decode(resJson, UserCouponResponse.class);
+ }
+
+ @Override
+ public UserCouponListResponse getUserCouponList(UserCouponListParam param) throws WxErrorException {
+ String resJson = shopService.post(LIST_USER_COUPON_URL, param);
+ return ResponseUtils.decode(resJson, UserCouponListResponse.class);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelFreightTemplateServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelFreightTemplateServiceImpl.java
new file mode 100644
index 0000000000..8fbfbd09c3
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelFreightTemplateServiceImpl.java
@@ -0,0 +1,61 @@
+package me.chanjar.weixin.channel.api.impl;
+
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.FreightTemplate.ADD_TEMPLATE_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.FreightTemplate.GET_TEMPLATE_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.FreightTemplate.LIST_TEMPLATE_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.FreightTemplate.UPDATE_TEMPLATE_URL;
+
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.WxChannelFreightTemplateService;
+import me.chanjar.weixin.channel.bean.freight.FreightTemplate;
+import me.chanjar.weixin.channel.bean.freight.TemplateAddParam;
+import me.chanjar.weixin.channel.bean.freight.TemplateIdResponse;
+import me.chanjar.weixin.channel.bean.freight.TemplateInfoResponse;
+import me.chanjar.weixin.channel.bean.freight.TemplateListParam;
+import me.chanjar.weixin.channel.bean.freight.TemplateListResponse;
+import me.chanjar.weixin.channel.util.ResponseUtils;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号小店 运费模板服务实现
+ *
+ * @author Zeyes
+ */
+@Slf4j
+public class WxChannelFreightTemplateServiceImpl implements WxChannelFreightTemplateService {
+ /** 微信商店服务 */
+ private final BaseWxChannelServiceImpl shopService;
+
+ public WxChannelFreightTemplateServiceImpl(BaseWxChannelServiceImpl shopService) {
+ this.shopService = shopService;
+ }
+
+ @Override
+ public TemplateListResponse listTemplate(Integer offset, Integer limit) throws WxErrorException {
+ TemplateListParam param = new TemplateListParam(offset, limit);
+ String resJson = shopService.post(LIST_TEMPLATE_URL, param);
+ return ResponseUtils.decode(resJson, TemplateListResponse.class);
+
+ }
+
+ @Override
+ public TemplateInfoResponse getTemplate(String templateId) throws WxErrorException {
+ String reqJson = "{\"template_id\": \"" + templateId + "\"}";
+ String resJson = shopService.post(GET_TEMPLATE_URL, reqJson);
+ return ResponseUtils.decode(resJson, TemplateInfoResponse.class);
+ }
+
+ @Override
+ public TemplateIdResponse addTemplate(FreightTemplate template) throws WxErrorException {
+ TemplateAddParam param = new TemplateAddParam(template);
+ String resJson = shopService.post(ADD_TEMPLATE_URL, param);
+ return ResponseUtils.decode(resJson, TemplateIdResponse.class);
+ }
+
+ @Override
+ public TemplateIdResponse updateTemplate(FreightTemplate template) throws WxErrorException {
+ TemplateAddParam param = new TemplateAddParam(template);
+ String resJson = shopService.post(UPDATE_TEMPLATE_URL, param);
+ return ResponseUtils.decode(resJson, TemplateIdResponse.class);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelFundServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelFundServiceImpl.java
new file mode 100644
index 0000000000..050a19f44d
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelFundServiceImpl.java
@@ -0,0 +1,167 @@
+package me.chanjar.weixin.channel.api.impl;
+
+
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Fund.CHECK_QRCODE_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Fund.GET_BALANCE_FLOW_DETAIL_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Fund.GET_BALANCE_FLOW_LIST_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Fund.GET_BALANCE_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Fund.GET_BANK_ACCOUNT_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Fund.GET_BANK_BY_NUM_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Fund.GET_BANK_LIST_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Fund.GET_CITY_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Fund.GET_PROVINCE_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Fund.GET_QRCODE_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Fund.GET_SUB_BANK_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Fund.GET_WITHDRAW_DETAIL_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Fund.GET_WITHDRAW_LIST_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Fund.SET_BANK_ACCOUNT_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Fund.WITHDRAW_URL;
+
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.WxChannelFundService;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.fund.AccountInfo;
+import me.chanjar.weixin.channel.bean.fund.AccountInfoParam;
+import me.chanjar.weixin.channel.bean.fund.AccountInfoResponse;
+import me.chanjar.weixin.channel.bean.fund.BalanceInfoResponse;
+import me.chanjar.weixin.channel.bean.fund.FlowListResponse;
+import me.chanjar.weixin.channel.bean.fund.FundsFlowResponse;
+import me.chanjar.weixin.channel.bean.fund.FundsListParam;
+import me.chanjar.weixin.channel.bean.fund.WithdrawDetailResponse;
+import me.chanjar.weixin.channel.bean.fund.WithdrawListParam;
+import me.chanjar.weixin.channel.bean.fund.WithdrawListResponse;
+import me.chanjar.weixin.channel.bean.fund.WithdrawSubmitParam;
+import me.chanjar.weixin.channel.bean.fund.WithdrawSubmitResponse;
+import me.chanjar.weixin.channel.bean.fund.bank.BankCityResponse;
+import me.chanjar.weixin.channel.bean.fund.bank.BankInfoResponse;
+import me.chanjar.weixin.channel.bean.fund.bank.BankListResponse;
+import me.chanjar.weixin.channel.bean.fund.bank.BankProvinceResponse;
+import me.chanjar.weixin.channel.bean.fund.bank.BankSearchParam;
+import me.chanjar.weixin.channel.bean.fund.bank.BranchInfoResponse;
+import me.chanjar.weixin.channel.bean.fund.bank.BranchSearchParam;
+import me.chanjar.weixin.channel.bean.fund.qrcode.QrCheckResponse;
+import me.chanjar.weixin.channel.bean.fund.qrcode.QrCodeResponse;
+import me.chanjar.weixin.channel.util.ResponseUtils;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号小店 资金服务实现
+ *
+ * @author Zeyes
+ */
+@Slf4j
+public class WxChannelFundServiceImpl implements WxChannelFundService {
+
+
+ /** 微信商店服务 */
+ private final BaseWxChannelServiceImpl shopService;
+
+ public WxChannelFundServiceImpl(BaseWxChannelServiceImpl shopService) {
+ this.shopService = shopService;
+ }
+
+ @Override
+ public BalanceInfoResponse getBalance() throws WxErrorException {
+ String resJson = shopService.post(GET_BALANCE_URL, "{}");
+ return ResponseUtils.decode(resJson, BalanceInfoResponse.class);
+ }
+
+ @Override
+ public AccountInfoResponse getBankAccount() throws WxErrorException {
+ String resJson = shopService.post(GET_BANK_ACCOUNT_URL, "{}");
+ return ResponseUtils.decode(resJson, AccountInfoResponse.class);
+ }
+
+ @Override
+ public FundsFlowResponse getFundsFlowDetail(String flowId) throws WxErrorException {
+ String reqJson = "{\"flow_id\":\"" + flowId + "\"}";
+ String resJson = shopService.post(GET_BALANCE_FLOW_DETAIL_URL, reqJson);
+ return ResponseUtils.decode(resJson, FundsFlowResponse.class);
+ }
+
+ @Override
+ public FlowListResponse listFundsFlow(FundsListParam param) throws WxErrorException {
+ String resJson = shopService.post(GET_BALANCE_FLOW_LIST_URL, param);
+ return ResponseUtils.decode(resJson, FlowListResponse.class);
+ }
+
+ @Override
+ public WithdrawDetailResponse getWithdrawDetail(String withdrawId) throws WxErrorException {
+ String reqJson = "{\"withdraw_id\":\"" + withdrawId + "\"}";
+ String resJson = shopService.post(GET_WITHDRAW_DETAIL_URL, reqJson);
+ return ResponseUtils.decode(resJson, WithdrawDetailResponse.class);
+ }
+
+ @Override
+ public WithdrawListResponse listWithdraw(Integer pageNum, Integer pageSize, Long startTime, Long endTime)
+ throws WxErrorException {
+ WithdrawListParam param = new WithdrawListParam(pageNum, pageSize, startTime, endTime);
+ String resJson = shopService.post(GET_WITHDRAW_LIST_URL, param);
+ return ResponseUtils.decode(resJson, WithdrawListResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse setBankAccount(AccountInfo accountInfo) throws WxErrorException {
+ AccountInfoParam param = new AccountInfoParam(accountInfo);
+ String resJson = shopService.post(SET_BANK_ACCOUNT_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WithdrawSubmitResponse submitWithdraw(Integer amount, String remark, String bankMemo)
+ throws WxErrorException {
+ WithdrawSubmitParam param = new WithdrawSubmitParam(amount, remark, bankMemo);
+ String resJson = shopService.post(WITHDRAW_URL, param);
+ return ResponseUtils.decode(resJson, WithdrawSubmitResponse.class);
+ }
+
+ @Override
+ public BankInfoResponse getBankInfoByCardNo(String accountNumber) throws WxErrorException {
+ String reqJson = "{\"account_number\":\"" + accountNumber + "\"}";
+ String resJson = shopService.post(GET_BANK_BY_NUM_URL, reqJson);
+ return ResponseUtils.decode(resJson, BankInfoResponse.class);
+ }
+
+ @Override
+ public BankListResponse searchBankList(Integer offset, Integer limit, String keywords, Integer bankType)
+ throws WxErrorException {
+ BankSearchParam param = new BankSearchParam(offset, limit, keywords, bankType);
+ String resJson = shopService.post(GET_BANK_LIST_URL, param);
+ return ResponseUtils.decode(resJson, BankListResponse.class);
+ }
+
+ @Override
+ public BankCityResponse searchCityList(String provinceCode) throws WxErrorException {
+ String reqJson = "{\"province_code\":\"" + provinceCode + "\"}";
+ String resJson = shopService.post(GET_CITY_URL, reqJson);
+ return ResponseUtils.decode(resJson, BankCityResponse.class);
+ }
+
+ @Override
+ public BankProvinceResponse getProvinceList() throws WxErrorException {
+ String resJson = shopService.post(GET_PROVINCE_URL, "{}");
+ return ResponseUtils.decode(resJson, BankProvinceResponse.class);
+ }
+
+ @Override
+ public BranchInfoResponse searchBranchList(String bankCode, String cityCode, Integer offset, Integer limit)
+ throws WxErrorException {
+ BranchSearchParam param = new BranchSearchParam(bankCode, cityCode, offset, limit);
+ String resJson = shopService.post(GET_SUB_BANK_URL, param);
+ return ResponseUtils.decode(resJson, BranchInfoResponse.class);
+ }
+
+ @Override
+ public QrCodeResponse getQrCode(String qrcodeTicket) throws WxErrorException {
+ String reqJson = "{\"qrcode_ticket\":\"" + qrcodeTicket + "\"}";
+ String resJson = shopService.post(GET_QRCODE_URL, reqJson);
+ return ResponseUtils.decode(resJson, QrCodeResponse.class);
+ }
+
+ @Override
+ public QrCheckResponse checkQrStatus(String qrcodeTicket) throws WxErrorException {
+ String reqJson = "{\"qrcode_ticket\":\"" + qrcodeTicket + "\"}";
+ String resJson = shopService.post(CHECK_QRCODE_URL, reqJson);
+ return ResponseUtils.decode(resJson, QrCheckResponse.class);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelOrderServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelOrderServiceImpl.java
new file mode 100644
index 0000000000..acd14a2876
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelOrderServiceImpl.java
@@ -0,0 +1,117 @@
+package me.chanjar.weixin.channel.api.impl;
+
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Delivery.DELIVERY_SEND_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Delivery.GET_DELIVERY_COMPANY_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Order.ORDER_GET_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Order.ORDER_LIST_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Order.ORDER_SEARCH_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Order.UPDATE_ADDRESS_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Order.UPDATE_EXPRESS_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Order.UPDATE_PRICE_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Order.UPDATE_REMARK_URL;
+
+import java.util.List;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.WxChannelOrderService;
+import me.chanjar.weixin.channel.bean.base.AddressInfo;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.delivery.DeliveryCompanyResponse;
+import me.chanjar.weixin.channel.bean.delivery.DeliveryInfo;
+import me.chanjar.weixin.channel.bean.delivery.DeliverySendParam;
+import me.chanjar.weixin.channel.bean.order.ChangeOrderInfo;
+import me.chanjar.weixin.channel.bean.order.DeliveryUpdateParam;
+import me.chanjar.weixin.channel.bean.order.OrderAddressParam;
+import me.chanjar.weixin.channel.bean.order.OrderIdParam;
+import me.chanjar.weixin.channel.bean.order.OrderInfoResponse;
+import me.chanjar.weixin.channel.bean.order.OrderListParam;
+import me.chanjar.weixin.channel.bean.order.OrderListResponse;
+import me.chanjar.weixin.channel.bean.order.OrderPriceParam;
+import me.chanjar.weixin.channel.bean.order.OrderRemarkParam;
+import me.chanjar.weixin.channel.bean.order.OrderSearchParam;
+import me.chanjar.weixin.channel.util.ResponseUtils;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+
+/**
+ * 视频号小店订单服务
+ *
+ * @author Zeyes
+ */
+@Slf4j
+public class WxChannelOrderServiceImpl implements WxChannelOrderService {
+
+ /** 微信商店服务 */
+ private final BaseWxChannelServiceImpl shopService;
+
+ public WxChannelOrderServiceImpl(BaseWxChannelServiceImpl shopService) {
+ this.shopService = shopService;
+ }
+
+ @Override
+ public OrderInfoResponse getOrder(String orderId) throws WxErrorException {
+ OrderIdParam param = new OrderIdParam(orderId);
+ String resJson = shopService.post(ORDER_GET_URL, param);
+ return ResponseUtils.decode(resJson, OrderInfoResponse.class);
+ }
+
+ @Override
+ public OrderListResponse getOrders(OrderListParam param) throws WxErrorException {
+ String resJson = shopService.post(ORDER_LIST_URL, param);
+ return ResponseUtils.decode(resJson, OrderListResponse.class);
+ }
+
+ @Override
+ public OrderListResponse searchOrder(OrderSearchParam param) throws WxErrorException {
+ String resJson = shopService.post(ORDER_SEARCH_URL, param);
+ return ResponseUtils.decode(resJson, OrderListResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse updatePrice(String orderId, Integer expressFee, List changeOrderInfos)
+ throws WxErrorException {
+ OrderPriceParam param = new OrderPriceParam(orderId, expressFee, changeOrderInfos);
+ String resJson = shopService.post(UPDATE_PRICE_URL, param);
+ ;
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse updateRemark(String orderId, String merchantNotes) throws WxErrorException {
+ OrderRemarkParam param = new OrderRemarkParam(orderId, merchantNotes);
+ String resJson = shopService.post(UPDATE_REMARK_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse updateAddress(String orderId, AddressInfo userAddress) throws WxErrorException {
+ OrderAddressParam param = new OrderAddressParam(orderId, userAddress);
+ String resJson = shopService.post(UPDATE_ADDRESS_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse updateDelivery(DeliveryUpdateParam param) throws WxErrorException {
+ String resJson = shopService.post(UPDATE_EXPRESS_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse closeOrder(String orderId) {
+ // 暂不支持
+ return ResponseUtils.internalError(WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public DeliveryCompanyResponse listDeliveryCompany() throws WxErrorException {
+ String resJson = shopService.post(GET_DELIVERY_COMPANY_URL, "{}");
+ return ResponseUtils.decode(resJson, DeliveryCompanyResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse deliveryOrder(String orderId, List deliveryList)
+ throws WxErrorException {
+ DeliverySendParam param = new DeliverySendParam(orderId, deliveryList);
+ String resJson = shopService.post(DELIVERY_SEND_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelProductServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelProductServiceImpl.java
new file mode 100644
index 0000000000..eb168a09e3
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelProductServiceImpl.java
@@ -0,0 +1,180 @@
+package me.chanjar.weixin.channel.api.impl;
+
+
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.ADD_LIMIT_TASK_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.CANCEL_AUDIT_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.DELETE_LIMIT_TASK_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.LIST_LIMIT_TASK_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.SPU_ADD_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.SPU_DELISTING_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.SPU_DEL_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.SPU_GET_STOCK_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.SPU_GET_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.SPU_LISTING_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.SPU_LIST_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.SPU_UPDATE_STOCK_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.SPU_UPDATE_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.STOP_LIMIT_TASK_URL;
+
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.WxChannelProductService;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.limit.LimitTaskAddResponse;
+import me.chanjar.weixin.channel.bean.limit.LimitTaskListParam;
+import me.chanjar.weixin.channel.bean.limit.LimitTaskListResponse;
+import me.chanjar.weixin.channel.bean.limit.LimitTaskParam;
+import me.chanjar.weixin.channel.bean.product.SkuStockParam;
+import me.chanjar.weixin.channel.bean.product.SkuStockResponse;
+import me.chanjar.weixin.channel.bean.product.SpuGetResponse;
+import me.chanjar.weixin.channel.bean.product.SpuInfo;
+import me.chanjar.weixin.channel.bean.product.SpuListParam;
+import me.chanjar.weixin.channel.bean.product.SpuListResponse;
+import me.chanjar.weixin.channel.bean.product.SpuUpdateResponse;
+import me.chanjar.weixin.channel.util.JsonUtils;
+import me.chanjar.weixin.channel.util.ResponseUtils;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号小店商品服务
+ *
+ * @author Zeyes
+ */
+@Slf4j
+public class WxChannelProductServiceImpl implements WxChannelProductService {
+
+ /** 微信商店服务 */
+ private final BaseWxChannelServiceImpl shopService;
+
+ public WxChannelProductServiceImpl(BaseWxChannelServiceImpl shopService) {
+ this.shopService = shopService;
+ }
+
+ @Override
+ public SpuUpdateResponse addProduct(SpuInfo info) throws WxErrorException {
+ String reqJson = JsonUtils.encode(info);
+ String resJson = shopService.post(SPU_ADD_URL, reqJson);
+ return ResponseUtils.decode(resJson, SpuUpdateResponse.class);
+ }
+
+ @Override
+ public SpuUpdateResponse updateProduct(SpuInfo info) throws WxErrorException {
+ String reqJson = JsonUtils.encode(info);
+ String resJson = shopService.post(SPU_UPDATE_URL, reqJson);
+ return ResponseUtils.decode(resJson, SpuUpdateResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse updateStock(String productId, String skuId, Integer diffType, Integer num)
+ throws WxErrorException {
+ SkuStockParam param = new SkuStockParam(productId, skuId, diffType, num);
+ String reqJson = JsonUtils.encode(param);
+ String resJson = shopService.post(SPU_UPDATE_STOCK_URL, reqJson);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ /**
+ * 生成商品id Json
+ *
+ * @param productId 商品ID
+ * @param dataType 默认取1。1:获取线上数据, 2:获取草稿数据, 3:同时获取线上和草稿数据(注意:需成功上架后才有线上数据)
+ * @return json
+ */
+ protected String generateProductIdJson(String productId, Integer dataType) {
+ StringBuilder sb = new StringBuilder();
+ sb.append('{');
+ if (productId != null) {
+ sb.append("\"product_id\":").append(productId);
+ }
+
+ if (dataType != null) {
+ sb.append(",").append("\"data_type\":").append(dataType);
+ }
+ sb.append('}');
+ return sb.toString();
+ }
+
+ /**
+ * 简单的商品请求 参数是商品id 只返回基本结果
+ *
+ * @param url 资源路径
+ * @param productId 商品ID
+ * @return 是否成功
+ */
+ protected WxChannelBaseResponse simpleProductRequest(String url, String productId) throws WxErrorException {
+ String reqJson = this.generateProductIdJson(productId, null);
+ String resJson = shopService.post(url, reqJson);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse deleteProduct(String productId) throws WxErrorException {
+ return simpleProductRequest(SPU_DEL_URL, productId);
+ }
+
+ @Override
+ public WxChannelBaseResponse cancelProductAudit(String productId) throws WxErrorException {
+ return simpleProductRequest(CANCEL_AUDIT_URL, productId);
+ }
+
+ @Override
+ public SpuGetResponse getProduct(String productId, Integer dataType) throws WxErrorException {
+ String reqJson = this.generateProductIdJson(productId, dataType);
+ String resJson = shopService.post(SPU_GET_URL, reqJson);
+ return ResponseUtils.decode(resJson, SpuGetResponse.class);
+ }
+
+ @Override
+ public SpuListResponse listProduct(Integer pageSize, String nextKey, Integer status) throws WxErrorException {
+ SpuListParam param = new SpuListParam(pageSize, nextKey, status);
+ String reqJson = JsonUtils.encode(param);
+ String resJson = shopService.post(SPU_LIST_URL, reqJson);
+ return ResponseUtils.decode(resJson, SpuListResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse upProduct(String productId) throws WxErrorException {
+ return simpleProductRequest(SPU_LISTING_URL, productId);
+ }
+
+ @Override
+ public WxChannelBaseResponse downProduct(String productId) throws WxErrorException {
+ return simpleProductRequest(SPU_DELISTING_URL, productId);
+ }
+
+ @Override
+ public SkuStockResponse getSkuStock(String productId, String skuId) throws WxErrorException {
+ String reqJson = "{\"product_id\":\"" + productId + "\",\"sku_id\":\"" + skuId + "\"}";
+ String resJson = shopService.post(SPU_GET_STOCK_URL, reqJson);
+ return ResponseUtils.decode(resJson, SkuStockResponse.class);
+ }
+
+ @Override
+ public LimitTaskAddResponse addLimitTask(LimitTaskParam param) throws WxErrorException {
+ String reqJson = JsonUtils.encode(param);
+ String resJson = shopService.post(ADD_LIMIT_TASK_URL, reqJson);
+ return ResponseUtils.decode(resJson, LimitTaskAddResponse.class);
+ }
+
+ @Override
+ public LimitTaskListResponse listLimitTask(Integer pageSize, String nextKey, Integer status)
+ throws WxErrorException {
+ LimitTaskListParam param = new LimitTaskListParam(pageSize, nextKey, status);
+ String reqJson = JsonUtils.encode(param);
+ String resJson = shopService.post(LIST_LIMIT_TASK_URL, reqJson);
+ return ResponseUtils.decode(resJson, LimitTaskListResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse stopLimitTask(String taskId) throws WxErrorException {
+ String reqJson = "{\"task_id\": \"" + taskId + "\"}";
+ String resJson = shopService.post(STOP_LIMIT_TASK_URL, reqJson);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse deleteLimitTask(String taskId) throws WxErrorException {
+ String reqJson = "{\"task_id\": \"" + taskId + "\"}";
+ String resJson = shopService.post(DELETE_LIMIT_TASK_URL, reqJson);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceHttpClientImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceHttpClientImpl.java
new file mode 100644
index 0000000000..bbe8865269
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceHttpClientImpl.java
@@ -0,0 +1,100 @@
+package me.chanjar.weixin.channel.api.impl;
+
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.GET_ACCESS_TOKEN_URL;
+
+import java.io.IOException;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.config.WxChannelConfig;
+import me.chanjar.weixin.common.util.http.HttpType;
+import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
+import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.HttpHost;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.BasicResponseHandler;
+import org.apache.http.impl.client.CloseableHttpClient;
+
+/**
+ * @author Zeyes
+ */
+@Slf4j
+public class WxChannelServiceHttpClientImpl extends BaseWxChannelServiceImpl {
+
+ private CloseableHttpClient httpClient;
+ private HttpHost httpProxy;
+
+ public WxChannelServiceHttpClientImpl() {
+
+ }
+
+ @Override
+ public void initHttp() {
+ WxChannelConfig config = this.getConfig();
+ ApacheHttpClientBuilder apacheHttpClientBuilder = config.getApacheHttpClientBuilder();
+ if (null == apacheHttpClientBuilder) {
+ apacheHttpClientBuilder = DefaultApacheHttpClientBuilder.get();
+ }
+
+ apacheHttpClientBuilder.httpProxyHost(config.getHttpProxyHost())
+ .httpProxyPort(config.getHttpProxyPort())
+ .httpProxyUsername(config.getHttpProxyUsername())
+ .httpProxyPassword(config.getHttpProxyPassword());
+
+ if (config.getHttpProxyHost() != null && config.getHttpProxyPort() > 0) {
+ this.httpProxy = new HttpHost(config.getHttpProxyHost(), config.getHttpProxyPort());
+ }
+
+ this.httpClient = apacheHttpClientBuilder.build();
+ }
+
+ @Override
+ public CloseableHttpClient getRequestHttpClient() {
+ return httpClient;
+ }
+
+ @Override
+ public HttpHost getRequestHttpProxy() {
+ return httpProxy;
+ }
+
+ @Override
+ public HttpType getRequestType() {
+ return HttpType.APACHE_HTTP;
+ }
+
+ @Override
+ protected String doGetAccessTokenRequest() throws IOException {
+ WxChannelConfig config = this.getConfig();
+ String url = StringUtils.isNotEmpty(config.getAccessTokenUrl()) ? config.getAccessTokenUrl() :
+ StringUtils.isNotEmpty(config.getApiHostUrl()) ?
+ GET_ACCESS_TOKEN_URL.replace("https://api.weixin.qq.com", config.getApiHostUrl()) : GET_ACCESS_TOKEN_URL;
+
+ url = String.format(url, config.getAppid(), config.getSecret());
+
+ HttpGet httpGet = null;
+ CloseableHttpResponse response = null;
+ try {
+ httpGet = new HttpGet(url);
+ if (this.getRequestHttpProxy() != null) {
+ RequestConfig requestConfig = RequestConfig.custom().setProxy(this.getRequestHttpProxy()).build();
+ httpGet.setConfig(requestConfig);
+ }
+ response = getRequestHttpClient().execute(httpGet);
+ return new BasicResponseHandler().handleResponse(response);
+ } finally {
+ if (httpGet != null) {
+ httpGet.releaseConnection();
+ }
+ if (response != null) {
+ try {
+ response.close();
+ } catch (IOException ignored) {
+ }
+ }
+ }
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceImpl.java
new file mode 100644
index 0000000000..e3e749dca5
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceImpl.java
@@ -0,0 +1,13 @@
+package me.chanjar.weixin.channel.api.impl;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 视频号小店服务实现
+ *
+ * @author Zeyes
+ */
+@Slf4j
+public class WxChannelServiceImpl extends WxChannelServiceHttpClientImpl {
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelSharerServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelSharerServiceImpl.java
new file mode 100644
index 0000000000..96438ae00f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelSharerServiceImpl.java
@@ -0,0 +1,73 @@
+package me.chanjar.weixin.channel.api.impl;
+
+
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Share.BIND_SHARER_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Share.LIST_SHARER_ORDER_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Share.LIST_SHARER_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Share.SEARCH_SHARER_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Share.UNBIND_SHARER_URL;
+
+import java.util.List;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.WxChannelSharerService;
+import me.chanjar.weixin.channel.bean.sharer.SharerBindResponse;
+import me.chanjar.weixin.channel.bean.sharer.SharerInfoResponse;
+import me.chanjar.weixin.channel.bean.sharer.SharerListParam;
+import me.chanjar.weixin.channel.bean.sharer.SharerOrderParam;
+import me.chanjar.weixin.channel.bean.sharer.SharerOrderResponse;
+import me.chanjar.weixin.channel.bean.sharer.SharerSearchParam;
+import me.chanjar.weixin.channel.bean.sharer.SharerSearchResponse;
+import me.chanjar.weixin.channel.bean.sharer.SharerUnbindParam;
+import me.chanjar.weixin.channel.bean.sharer.SharerUnbindResponse;
+import me.chanjar.weixin.channel.util.ResponseUtils;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号小店 分享员服务实现
+ *
+ * @author Zeyes
+ */
+@Slf4j
+public class WxChannelSharerServiceImpl implements WxChannelSharerService {
+
+ /** 微信商店服务 */
+ private final BaseWxChannelServiceImpl shopService;
+
+ public WxChannelSharerServiceImpl(BaseWxChannelServiceImpl shopService) {
+ this.shopService = shopService;
+ }
+
+ @Override
+ public SharerBindResponse bindSharer(String username) throws WxErrorException {
+ String reqJson = "{\"username\": " + username + "}";
+ String resJson = shopService.post(BIND_SHARER_URL, reqJson);
+ return ResponseUtils.decode(resJson, SharerBindResponse.class);
+ }
+
+ @Override
+ public SharerSearchResponse searchSharer(String openid, String username) throws WxErrorException {
+ SharerSearchParam param = new SharerSearchParam(openid, username);
+ String resJson = shopService.post(SEARCH_SHARER_URL, param);
+ return ResponseUtils.decode(resJson, SharerSearchResponse.class);
+ }
+
+ @Override
+ public SharerInfoResponse listSharer(Integer page, Integer pageSize, Integer sharerType) throws WxErrorException {
+ SharerListParam param = new SharerListParam(page, pageSize, sharerType);
+ String resJson = shopService.post(LIST_SHARER_URL, param);
+ return ResponseUtils.decode(resJson, SharerInfoResponse.class);
+ }
+
+ @Override
+ public SharerOrderResponse listSharerOrder(SharerOrderParam param) throws WxErrorException {
+ String resJson = shopService.post(LIST_SHARER_ORDER_URL, param);
+ return ResponseUtils.decode(resJson, SharerOrderResponse.class);
+ }
+
+ @Override
+ public SharerUnbindResponse unbindSharer(List openIds) throws WxErrorException {
+ SharerUnbindParam param = new SharerUnbindParam(openIds);
+ String resJson = shopService.post(UNBIND_SHARER_URL, param);
+ return ResponseUtils.decode(resJson, SharerUnbindResponse.class);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelWarehouseServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelWarehouseServiceImpl.java
new file mode 100644
index 0000000000..b9609e5c6b
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelWarehouseServiceImpl.java
@@ -0,0 +1,123 @@
+package me.chanjar.weixin.channel.api.impl;
+
+
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Warehouse.ADD_COVER_AREA_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Warehouse.ADD_WAREHOUSE_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Warehouse.DELETE_COVER_AREA_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Warehouse.GET_WAREHOUSE_PRIORITY_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Warehouse.GET_WAREHOUSE_STOCK_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Warehouse.GET_WAREHOUSE_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Warehouse.LIST_WAREHOUSE_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Warehouse.SET_WAREHOUSE_PRIORITY_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Warehouse.UPDATE_WAREHOUSE_STOCK_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Warehouse.UPDATE_WAREHOUSE_URL;
+
+import java.util.List;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.WxChannelWarehouseService;
+import me.chanjar.weixin.channel.bean.base.StreamPageParam;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.warehouse.LocationPriorityResponse;
+import me.chanjar.weixin.channel.bean.warehouse.PriorityLocationParam;
+import me.chanjar.weixin.channel.bean.warehouse.StockGetParam;
+import me.chanjar.weixin.channel.bean.warehouse.UpdateLocationParam;
+import me.chanjar.weixin.channel.bean.warehouse.WarehouseIdsResponse;
+import me.chanjar.weixin.channel.bean.warehouse.WarehouseLocation;
+import me.chanjar.weixin.channel.bean.warehouse.WarehouseLocationParam;
+import me.chanjar.weixin.channel.bean.warehouse.WarehouseParam;
+import me.chanjar.weixin.channel.bean.warehouse.WarehouseResponse;
+import me.chanjar.weixin.channel.bean.warehouse.WarehouseStockParam;
+import me.chanjar.weixin.channel.bean.warehouse.WarehouseStockResponse;
+import me.chanjar.weixin.channel.util.ResponseUtils;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号小店 区域仓库服务实现
+ *
+ * @author Zeyes
+ */
+@Slf4j
+public class WxChannelWarehouseServiceImpl implements WxChannelWarehouseService {
+
+ /** 微信商店服务 */
+ private final BaseWxChannelServiceImpl shopService;
+
+ public WxChannelWarehouseServiceImpl(BaseWxChannelServiceImpl shopService) {
+ this.shopService = shopService;
+ }
+
+ @Override
+ public WxChannelBaseResponse createWarehouse(WarehouseParam param) throws WxErrorException {
+ String resJson = shopService.post(ADD_WAREHOUSE_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WarehouseIdsResponse listWarehouse(Integer pageSize, String nextKey) throws WxErrorException {
+ StreamPageParam param = new StreamPageParam(pageSize, nextKey);
+ String resJson = shopService.post(LIST_WAREHOUSE_URL, param);
+ return ResponseUtils.decode(resJson, WarehouseIdsResponse.class);
+ }
+
+ @Override
+ public WarehouseResponse getWarehouse(String outWarehouseId) throws WxErrorException {
+ String reqJson = "{\"out_warehouse_id\":\"" + outWarehouseId + "\"}";
+ String resJson = shopService.post(GET_WAREHOUSE_URL, reqJson);
+ return ResponseUtils.decode(resJson, WarehouseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse updateWarehouse(String outWarehouseId, String name, String intro)
+ throws WxErrorException {
+ String reqJson = "{\"out_warehouse_id\":\"" + outWarehouseId +
+ "\",\"name\":\"" + name + "\",\"intro\":\"" + intro + "\"}";
+ String resJson = shopService.post(UPDATE_WAREHOUSE_URL, reqJson);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse addWarehouseArea(String outWarehouseId, List coverLocations)
+ throws WxErrorException {
+ UpdateLocationParam param = new UpdateLocationParam(outWarehouseId, coverLocations);
+ String resJson = shopService.post(ADD_COVER_AREA_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse deleteWarehouseArea(String outWarehouseId, List coverLocations)
+ throws WxErrorException {
+ UpdateLocationParam param = new UpdateLocationParam(outWarehouseId, coverLocations);
+ String resJson = shopService.post(DELETE_COVER_AREA_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+
+ }
+
+ @Override
+ public WxChannelBaseResponse setWarehousePriority(PriorityLocationParam param) throws WxErrorException {
+ String resJson = shopService.post(SET_WAREHOUSE_PRIORITY_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+
+ }
+
+ @Override
+ public LocationPriorityResponse getWarehousePriority(Integer addressId1, Integer addressId2, Integer addressId3,
+ Integer addressId4) throws WxErrorException {
+ WarehouseLocationParam param = new WarehouseLocationParam(addressId1, addressId2, addressId3, addressId4);
+ String resJson = shopService.post(GET_WAREHOUSE_PRIORITY_URL, param);
+ return ResponseUtils.decode(resJson, LocationPriorityResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse updateWarehouseStock(WarehouseStockParam param) throws WxErrorException {
+ String resJson = shopService.post(UPDATE_WAREHOUSE_STOCK_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WarehouseStockResponse getWarehouseStock(String productId, String skuId, String outWarehouseId)
+ throws WxErrorException {
+ StockGetParam param = new StockGetParam(productId, skuId, outWarehouseId);
+ String resJson = shopService.post(GET_WAREHOUSE_STOCK_URL, param);
+ return ResponseUtils.decode(resJson, WarehouseStockResponse.class);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeagueProductServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeagueProductServiceImpl.java
new file mode 100644
index 0000000000..29620874e2
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeagueProductServiceImpl.java
@@ -0,0 +1,71 @@
+package me.chanjar.weixin.channel.api.impl;
+
+
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.League.BATCH_ADD_LEAGUE_ITEM_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.League.DELETE_LEAGUE_ITEM_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.League.GET_LEAGUE_ITEM_LIST_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.League.GET_LEAGUE_ITEM_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.League.UPDATE_LEAGUE_ITEM_URL;
+
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.WxLeagueProductService;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.league.product.BatchAddParam;
+import me.chanjar.weixin.channel.bean.league.product.BatchAddResponse;
+import me.chanjar.weixin.channel.bean.league.product.ProductDeleteParam;
+import me.chanjar.weixin.channel.bean.league.product.ProductDetailParam;
+import me.chanjar.weixin.channel.bean.league.product.ProductDetailResponse;
+import me.chanjar.weixin.channel.bean.league.product.ProductListParam;
+import me.chanjar.weixin.channel.bean.league.product.ProductListResponse;
+import me.chanjar.weixin.channel.bean.league.product.ProductUpdateParam;
+import me.chanjar.weixin.channel.bean.league.product.ProductUpdateResponse;
+import me.chanjar.weixin.channel.util.ResponseUtils;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+
+/**
+ * 视频号小店 商品服务
+ *
+ * @author Zeyes
+ */
+@Slf4j
+public class WxLeagueProductServiceImpl implements WxLeagueProductService {
+
+ /** 微信商店服务 */
+ private final BaseWxChannelServiceImpl shopService;
+
+ public WxLeagueProductServiceImpl(BaseWxChannelServiceImpl shopService) {
+ this.shopService = shopService;
+ }
+
+ @Override
+ public BatchAddResponse batchAddProduct(BatchAddParam param) throws WxErrorException {
+ String resJson = shopService.post(BATCH_ADD_LEAGUE_ITEM_URL, param);
+ return ResponseUtils.decode(resJson, BatchAddResponse.class);
+ }
+
+ @Override
+ public ProductUpdateResponse updateProduct(ProductUpdateParam param) throws WxErrorException {
+ String resJson = shopService.post(UPDATE_LEAGUE_ITEM_URL, param);
+ return ResponseUtils.decode(resJson, ProductUpdateResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse deleteProduct(Integer type, String productId, String infoId) throws WxErrorException {
+ ProductDeleteParam param = new ProductDeleteParam(type, productId, infoId);
+ String resJson = shopService.post(DELETE_LEAGUE_ITEM_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public ProductDetailResponse getProductDetail(ProductDetailParam param) throws WxErrorException {
+ String resJson = shopService.post(GET_LEAGUE_ITEM_URL, param);
+ return ResponseUtils.decode(resJson, ProductDetailResponse.class);
+ }
+
+ @Override
+ public ProductListResponse listProduct(ProductListParam param) throws WxErrorException {
+ String resJson = shopService.post(GET_LEAGUE_ITEM_LIST_URL, param);
+ return ResponseUtils.decode(resJson, ProductListResponse.class);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeaguePromoterServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeaguePromoterServiceImpl.java
new file mode 100644
index 0000000000..a6bfddfbef
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeaguePromoterServiceImpl.java
@@ -0,0 +1,69 @@
+package me.chanjar.weixin.channel.api.impl;
+
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.League.ADD_PROMOTER_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.League.DELETE_PROMOTER_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.League.EDIT_PROMOTER_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.League.GET_PROMOTER_LIST_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.League.GET_PROMOTER_URL;
+
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.WxLeaguePromoterService;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.league.promoter.PromoterInfoResponse;
+import me.chanjar.weixin.channel.bean.league.promoter.PromoterListParam;
+import me.chanjar.weixin.channel.bean.league.promoter.PromoterListResponse;
+import me.chanjar.weixin.channel.util.ResponseUtils;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号小店 达人服务
+ *
+ * @author Zeyes
+ */
+@Slf4j
+public class WxLeaguePromoterServiceImpl implements WxLeaguePromoterService {
+
+ /** 微信商店服务 */
+ private final BaseWxChannelServiceImpl shopService;
+
+ public WxLeaguePromoterServiceImpl(BaseWxChannelServiceImpl shopService) {
+ this.shopService = shopService;
+ }
+
+ @Override
+ public WxChannelBaseResponse addPromoter(String finderId) throws WxErrorException {
+ String reqJson = "{\"finder_id\":\"" + finderId + "\"}";
+ String resJson = shopService.post(ADD_PROMOTER_URL, reqJson);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse updatePromoter(String finderId, int type) throws WxErrorException {
+ String reqJson = "{\"finder_id\":\"" + finderId + "\",\"type\":" + type + "}";
+ String resJson = shopService.post(EDIT_PROMOTER_URL, reqJson);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse deletePromoter(String finderId) throws WxErrorException {
+ String reqJson = "{\"finder_id\":\"" + finderId + "\"}";
+ String resJson = shopService.post(DELETE_PROMOTER_URL, reqJson);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public PromoterInfoResponse getPromoterInfo(String finderId) throws WxErrorException {
+ String reqJson = "{\"finder_id\":\"" + finderId + "\"}";
+ String resJson = shopService.post(GET_PROMOTER_URL, reqJson);
+ return ResponseUtils.decode(resJson, PromoterInfoResponse.class);
+ }
+
+ @Override
+ public PromoterListResponse listPromoter(Integer pageIndex, Integer pageSize, Integer status)
+ throws WxErrorException {
+ PromoterListParam param = new PromoterListParam(pageIndex, pageSize, status);
+ String resJson = shopService.post(GET_PROMOTER_LIST_URL, param);
+ return ResponseUtils.decode(resJson, PromoterListResponse.class);
+
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeagueSupplierServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeagueSupplierServiceImpl.java
new file mode 100644
index 0000000000..d69296bd0f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeagueSupplierServiceImpl.java
@@ -0,0 +1,107 @@
+package me.chanjar.weixin.channel.api.impl;
+
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.League.GET_SUPPLIER_BALANCE_FLOW_DETAIL_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.League.GET_SUPPLIER_BALANCE_FLOW_LIST_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.League.GET_SUPPLIER_BALANCE_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.League.GET_SUPPLIER_ITEM_LIST_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.League.GET_SUPPLIER_ITEM_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.League.GET_SUPPLIER_ORDER_LIST_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.League.GET_SUPPLIER_ORDER_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.League.GET_SUPPLIER_SHOP_LIST_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.League.GET_SUPPLIER_SHOP_URL;
+
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.WxLeagueSupplierService;
+import me.chanjar.weixin.channel.bean.base.StreamPageParam;
+import me.chanjar.weixin.channel.bean.league.supplier.CommissionOrderListParam;
+import me.chanjar.weixin.channel.bean.league.supplier.CommissionOrderListResponse;
+import me.chanjar.weixin.channel.bean.league.supplier.CommissionOrderResponse;
+import me.chanjar.weixin.channel.bean.league.supplier.CoopProductDetailParam;
+import me.chanjar.weixin.channel.bean.league.supplier.CoopProductListParam;
+import me.chanjar.weixin.channel.bean.league.supplier.CoopProductListResponse;
+import me.chanjar.weixin.channel.bean.league.supplier.CoopProductResponse;
+import me.chanjar.weixin.channel.bean.league.supplier.FlowListParam;
+import me.chanjar.weixin.channel.bean.league.supplier.ShopDetailResponse;
+import me.chanjar.weixin.channel.bean.league.supplier.ShopListResponse;
+import me.chanjar.weixin.channel.bean.league.supplier.SupplierBalanceResponse;
+import me.chanjar.weixin.channel.bean.league.supplier.SupplierFlowDetailResponse;
+import me.chanjar.weixin.channel.bean.league.supplier.SupplierFlowListResponse;
+import me.chanjar.weixin.channel.util.ResponseUtils;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号小店 优选联盟 团长数据服务
+ *
+ * @author Zeyes
+ */
+@Slf4j
+public class WxLeagueSupplierServiceImpl implements WxLeagueSupplierService {
+
+ /** 微信商店服务 */
+ private final BaseWxChannelServiceImpl shopService;
+
+ public WxLeagueSupplierServiceImpl(BaseWxChannelServiceImpl shopService) {
+ this.shopService = shopService;
+ }
+
+ @Override
+ public SupplierBalanceResponse getBalanceInfo() throws WxErrorException {
+ String resJson = shopService.post(GET_SUPPLIER_BALANCE_URL, "{}");
+ return ResponseUtils.decode(resJson, SupplierBalanceResponse.class);
+ }
+
+ @Override
+ public SupplierFlowDetailResponse getFlowDetail(String flowId) throws WxErrorException {
+ String reqJson = "{\"flow_id\":\"" + flowId + "\"}";
+ String resJson = shopService.post(GET_SUPPLIER_BALANCE_FLOW_DETAIL_URL, reqJson);
+ return ResponseUtils.decode(resJson, SupplierFlowDetailResponse.class);
+ }
+
+ @Override
+ public SupplierFlowListResponse getFlowList(FlowListParam param) throws WxErrorException {
+ String resJson = shopService.post(GET_SUPPLIER_BALANCE_FLOW_LIST_URL, param);
+ return ResponseUtils.decode(resJson, SupplierFlowListResponse.class);
+ }
+
+ @Override
+ public CoopProductResponse getProductDetail(String productId, String appId) throws WxErrorException {
+ CoopProductDetailParam param = new CoopProductDetailParam(productId, appId);
+ String resJson = shopService.post(GET_SUPPLIER_ITEM_URL, param);
+ return ResponseUtils.decode(resJson, CoopProductResponse.class);
+ }
+
+ @Override
+ public CoopProductListResponse getProductList(String appid, Integer pageSize, String nextKey)
+ throws WxErrorException {
+ CoopProductListParam param = new CoopProductListParam(appid, pageSize, nextKey);
+ String resJson = shopService.post(GET_SUPPLIER_ITEM_LIST_URL, param);
+ return ResponseUtils.decode(resJson, CoopProductListResponse.class);
+ }
+
+ @Override
+ public CommissionOrderResponse getCommissionOrder(String orderId, String skuId) throws WxErrorException {
+ String reqJson = "{\"order_id\":\"" + orderId + "\",\"sku_id\":\"" + skuId + "\"}";
+ String resJson = shopService.post(GET_SUPPLIER_ORDER_URL, reqJson);
+ return ResponseUtils.decode(resJson, CommissionOrderResponse.class);
+ }
+
+ @Override
+ public CommissionOrderListResponse getCommissionOrderList(CommissionOrderListParam param) throws WxErrorException {
+ String resJson = shopService.post(GET_SUPPLIER_ORDER_LIST_URL, param);
+ return ResponseUtils.decode(resJson, CommissionOrderListResponse.class);
+ }
+
+ @Override
+ public ShopDetailResponse getShopDetail(String appid) throws WxErrorException {
+ String reqJson = "{\"appid\":\"" + appid + "\"}";
+ String resJson = shopService.post(GET_SUPPLIER_SHOP_URL, reqJson);
+ return ResponseUtils.decode(resJson, ShopDetailResponse.class);
+ }
+
+ @Override
+ public ShopListResponse getShopList(Integer pageSize, String nextKey) throws WxErrorException {
+ StreamPageParam param = new StreamPageParam(pageSize, nextKey);
+ String resJson = shopService.post(GET_SUPPLIER_SHOP_LIST_URL, param);
+ return ResponseUtils.decode(resJson, ShopListResponse.class);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeagueWindowServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeagueWindowServiceImpl.java
new file mode 100644
index 0000000000..a59fc6efa5
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeagueWindowServiceImpl.java
@@ -0,0 +1,81 @@
+package me.chanjar.weixin.channel.api.impl;
+
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.League.ADD_SUPPLIER_GOODS_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.League.GET_SUPPLIER_AUTH_STATUS_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.League.GET_SUPPLIER_AUTH_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.League.GET_SUPPLIER_GOODS_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.League.LIST_SUPPLIER_GOODS_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.League.REMOVE_SUPPLIER_GOODS_URL;
+
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.WxLeagueWindowService;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.league.window.AuthInfoResponse;
+import me.chanjar.weixin.channel.bean.league.window.AuthStatusResponse;
+import me.chanjar.weixin.channel.bean.league.window.ProductSearchParam;
+import me.chanjar.weixin.channel.bean.league.window.WindowProductListResponse;
+import me.chanjar.weixin.channel.bean.league.window.WindowProductParam;
+import me.chanjar.weixin.channel.bean.league.window.WindowProductResponse;
+import me.chanjar.weixin.channel.util.ResponseUtils;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+
+/**
+ * 视频号小店 优选联盟 团长合作达人管理服务
+ *
+ * @author Zeyes
+ */
+@Slf4j
+public class WxLeagueWindowServiceImpl implements WxLeagueWindowService {
+
+ /** 微信商店服务 */
+ private final BaseWxChannelServiceImpl shopService;
+
+ public WxLeagueWindowServiceImpl(BaseWxChannelServiceImpl shopService) {
+ this.shopService = shopService;
+ }
+
+ @Override
+ public WxChannelBaseResponse addProduct(String appid, String openfinderid, String productId)
+ throws WxErrorException {
+ WindowProductParam param = new WindowProductParam(appid, openfinderid, productId);
+ String resJson = shopService.post(ADD_SUPPLIER_GOODS_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WindowProductListResponse listProduct(ProductSearchParam param) throws WxErrorException {
+ String resJson = shopService.post(LIST_SUPPLIER_GOODS_URL, param);
+ return ResponseUtils.decode(resJson, WindowProductListResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse removeProduct(String appid, String openfinderid, String productId)
+ throws WxErrorException {
+ WindowProductParam param = new WindowProductParam(appid, openfinderid, productId);
+ String resJson = shopService.post(REMOVE_SUPPLIER_GOODS_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WindowProductResponse getProductDetail(String appid, String openfinderid, String productId)
+ throws WxErrorException {
+ WindowProductParam param = new WindowProductParam(appid, openfinderid, productId);
+ String resJson = shopService.post(GET_SUPPLIER_GOODS_URL, param);
+ return ResponseUtils.decode(resJson, WindowProductResponse.class);
+ }
+
+ @Override
+ public AuthInfoResponse getWindowAuthInfo(String finderId) throws WxErrorException {
+ String reqJson = "{\"finder_id\":\"" + finderId + "\"}";
+ String resJson = shopService.post(GET_SUPPLIER_AUTH_URL, reqJson);
+ return ResponseUtils.decode(resJson, AuthInfoResponse.class);
+ }
+
+ @Override
+ public AuthStatusResponse getWindowAuthStatus(String finderId) throws WxErrorException {
+ String reqJson = "{\"finder_id\":\"" + finderId + "\"}";
+ String resJson = shopService.post(GET_SUPPLIER_AUTH_STATUS_URL, reqJson);
+ return ResponseUtils.decode(resJson, AuthStatusResponse.class);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressAddParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressAddParam.java
new file mode 100644
index 0000000000..a831de6655
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressAddParam.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.address;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 地址 请求参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(Include.NON_NULL)
+public class AddressAddParam implements Serializable {
+
+ private static final long serialVersionUID = 6778585213498438738L;
+
+ /** 地址id */
+ @JsonProperty("address_detail")
+ private AddressDetail addressDetail;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressCode.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressCode.java
new file mode 100644
index 0000000000..c7c885f0ab
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressCode.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.address;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 地址编码
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class AddressCode implements Serializable {
+
+ private static final long serialVersionUID = -6782328785056142627L;
+
+ /** 地址名称 */
+ @JsonProperty("name")
+ private String name;
+
+ /** 地址行政编码 */
+ @JsonProperty("code")
+ private Integer code;
+
+ /** 地址级别 1-省级 2-市级 3-区县级 4-街道 */
+ @JsonProperty("level")
+ private Integer level;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressCodeResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressCodeResponse.java
new file mode 100644
index 0000000000..09ede50c38
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressCodeResponse.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.address;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 地址编码 响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class AddressCodeResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -8994407971295563982L;
+
+ /** 本行政编码地址信息 */
+ @JsonProperty("addrs_msg")
+ private AddressCode current;
+
+ /** 下一级所有地址信息 */
+ @JsonProperty("next_level_addrs")
+ private List list;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressDetail.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressDetail.java
new file mode 100644
index 0000000000..88f4945e20
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressDetail.java
@@ -0,0 +1,66 @@
+package me.chanjar.weixin.channel.bean.address;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.AddressInfo;
+
+/**
+ * 用户地址
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class AddressDetail implements Serializable {
+
+ private static final long serialVersionUID = -7839578838482198641L;
+
+ /** 地址id */
+ @JsonProperty("address_id")
+ private String addressId;
+
+ /** 联系人姓名 */
+ @JsonProperty("name")
+ private String name;
+
+ /** 地区信息 */
+ @JsonProperty("address_info")
+ private AddressInfo addressInfo;
+
+ /** 座机 */
+ @JsonProperty("landline")
+ private String landline;
+
+ /** 是否为发货地址 */
+ @JsonProperty("send_addr")
+ private Boolean sendAddr;
+
+ /** 是否为收货地址 */
+ @JsonProperty("recv_addr")
+ private Boolean recvAddr;
+
+ /** 是否为默认发货地址 */
+ @JsonProperty("default_send")
+ private Boolean defaultSend;
+
+ /** 是否为默认收货地址 */
+ @JsonProperty("default_recv")
+ private Boolean defaultRecv;
+
+ /** 创建时间戳(秒) */
+ @JsonProperty("create_time")
+ private Long createTime;
+
+ /** 更新时间戳(秒) */
+ @JsonProperty("update_time")
+ private Long updateTime;
+
+ /** 线下配送地址类型 */
+ @JsonProperty("address_type")
+ private OfflineAddressType addressType;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressIdParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressIdParam.java
new file mode 100644
index 0000000000..d1eb7e0b46
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressIdParam.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.address;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 地址id 请求参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(Include.NON_NULL)
+public class AddressIdParam implements Serializable {
+
+ private static final long serialVersionUID = -7001183932180608746L;
+
+ /** 地址id */
+ @JsonProperty("address_id")
+ private String addressId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressIdResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressIdResponse.java
new file mode 100644
index 0000000000..f6505efa15
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressIdResponse.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.channel.bean.address;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 地址id 响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class AddressIdResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -9218327846685744008L;
+
+ /** 地址id */
+ @JsonProperty("address_id")
+ private String addressId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressInfoResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressInfoResponse.java
new file mode 100644
index 0000000000..957d0162a8
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressInfoResponse.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.address;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 地址id 响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class AddressInfoResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 8203853673226715673L;
+
+ /** 地址详情 */
+ @JsonProperty("address_detail")
+ private AddressDetail addressDetail;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressListParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressListParam.java
new file mode 100644
index 0000000000..c62cf39fb8
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressListParam.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.channel.bean.address;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.OffsetParam;
+
+/**
+ * 用户地址 列表 请求参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JsonInclude(Include.NON_NULL)
+public class AddressListParam extends OffsetParam {
+
+ private static final long serialVersionUID = -4434287264623932176L;
+
+ public AddressListParam(Integer offset, Integer limit) {
+ super(offset, limit);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressListResponse.java
new file mode 100644
index 0000000000..b8846f9aa3
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/AddressListResponse.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.channel.bean.address;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 地址列表 响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class AddressListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -3997164605170764105L;
+
+ /** 地址详情 */
+ @JsonProperty("address_id_list")
+ private List ids;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/OfflineAddressType.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/OfflineAddressType.java
new file mode 100644
index 0000000000..81dd169399
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/address/OfflineAddressType.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.address;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 线下配送地址类型
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class OfflineAddressType implements Serializable {
+
+ private static final long serialVersionUID = 636850757572901377L;
+
+ /** 1表示同城配送 */
+ @JsonProperty("same_city")
+ private Integer sameCity;
+
+ /** 1表示用户自提 */
+ @JsonProperty("pickup")
+ private Integer pickup;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleAcceptParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleAcceptParam.java
new file mode 100644
index 0000000000..ebc63a2190
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleAcceptParam.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+/**
+ * 售后单同意信息
+ *
+ * @author Zeyes
+ */
+@Data
+@JsonInclude(Include.NON_NULL)
+public class AfterSaleAcceptParam extends AfterSaleIdParam {
+
+ private static final long serialVersionUID = -4352801757159074950L;
+ /** 同意退货时传入地址id */
+ @JsonProperty("address_id")
+ private String addressId;
+
+ public AfterSaleAcceptParam() {
+ }
+
+ public AfterSaleAcceptParam(String afterSaleOrderId, String addressId) {
+ super(afterSaleOrderId);
+ this.addressId = addressId;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleDetail.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleDetail.java
new file mode 100644
index 0000000000..65a8775858
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleDetail.java
@@ -0,0 +1,38 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 售后详情
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class AfterSaleDetail implements Serializable {
+
+ private static final long serialVersionUID = -8130659179770831047L;
+ /** 售后描述 */
+ @JsonProperty("desc")
+ private String desc;
+
+ /** 是否已经收到货 */
+ @JsonProperty("receive_product")
+ private Boolean receiveProduct;
+
+ /** 是否已经收到货 */
+ @JsonProperty("cancel_time")
+ private Long cancelTime;
+
+ /** 举证图片media_id列表,根据mediaid获取文件内容接口 */
+ @JsonProperty("prove_imgs")
+ private List proveImgs;
+
+ /** 联系电话 */
+ @JsonProperty("tel_number")
+ private String telNumber;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleIdParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleIdParam.java
new file mode 100644
index 0000000000..1e16a72395
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleIdParam.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 售后单id信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(Include.NON_NULL)
+public class AfterSaleIdParam implements Serializable {
+
+ private static final long serialVersionUID = 4974332291476116540L;
+ /** 售后单号 */
+ @JsonProperty("after_sale_order_id")
+ private String afterSaleOrderId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleInfo.java
new file mode 100644
index 0000000000..25d005c01f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleInfo.java
@@ -0,0 +1,81 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 售后单信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class AfterSaleInfo implements Serializable {
+
+ private static final long serialVersionUID = 6595670817781635247L;
+ /** 售后单号 */
+ @JsonProperty("after_sale_order_id")
+ private String afterSaleOrderId;
+
+ /** 售后状态 {@link me.chanjar.weixin.channel.enums.AfterSaleStatus} */
+ @JsonProperty("status")
+ private String status;
+
+ /** 订单id */
+ @JsonProperty("order_id")
+ private String orderId;
+
+ /** 买家身份标识 */
+ @JsonProperty("openid")
+ private String openid;
+
+ /** 买家在开放平台的唯一标识符,若当前视频号小店已绑定到微信开放平台帐号下会返回 */
+ @JsonProperty("unionid")
+ private String unionid;
+
+ /** 售后相关商品信息 */
+ @JsonProperty("product_info")
+ private AfterSaleProductInfo productInfo;
+
+ /** 售后详情 */
+ @JsonProperty("details")
+ private AfterSaleDetail details;
+
+ /** 退款详情 */
+ @JsonProperty("refund_info")
+ private RefundInfo refundInfo;
+
+ /** 用户退货信息 */
+ @JsonProperty("return_info")
+ private ReturnInfo returnInfo;
+
+ /** 商家上传的信息 */
+ @JsonProperty("merchant_upload_info")
+ private MerchantUploadInfo merchantUploadInfo;
+
+ /** 创建时间 时间戳 秒 */
+ @JsonProperty("create_time")
+ private String createTime;
+
+ /** 更新时间 时间戳 秒 */
+ @JsonProperty("update_time")
+ private String updateTime;
+
+ /** 退款原因 */
+ @JsonProperty("reason")
+ private String reason;
+
+ /** 退款结果 */
+ @JsonProperty("refund_resp")
+ private RefundResp refundResp;
+
+ /** 售后类型。REFUND:退款;RETURN:退货退款 */
+ @JsonProperty("type")
+ private String type;
+
+ /** 纠纷id,该字段可用于获取纠纷信息 */
+ @JsonProperty("complaint_id")
+ private String complaintId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleInfoResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleInfoResponse.java
new file mode 100644
index 0000000000..adedf72f03
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleInfoResponse.java
@@ -0,0 +1,23 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 售后单 响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class AfterSaleInfoResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -752661975153491902L;
+ /** 售后单 */
+ @JsonProperty("after_sale_order")
+ private AfterSaleInfo info;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleListParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleListParam.java
new file mode 100644
index 0000000000..78cc394085
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleListParam.java
@@ -0,0 +1,34 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 售后单列表 请求参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(Include.NON_NULL)
+public class AfterSaleListParam implements Serializable {
+
+ private static final long serialVersionUID = -103549981452112069L;
+ /** 订单创建启始时间 unix时间戳 */
+ @JsonProperty("begin_create_time")
+ private Long beginCreateTime;
+
+ /** 订单创建结束时间,end_create_time减去begin_create_time不得大于24小时 unix时间戳 */
+ @JsonProperty("end_create_time")
+ private Long endCreateTime;
+
+ /** 翻页参数,从第二页开始传,来源于上一页的返回值 */
+ @JsonProperty("next_key")
+ private String nextKey;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleListResponse.java
new file mode 100644
index 0000000000..3ad67cffcf
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleListResponse.java
@@ -0,0 +1,31 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 售后单列表 响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode
+public class AfterSaleListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 5033313416948732123L;
+ /** 售后单号列表 */
+ @JsonProperty("after_sale_order_id_list")
+ private List ids;
+
+ /** 翻页参数 */
+ private String nextKey;
+
+ /** 是否还有数据 */
+ @JsonProperty("has_more")
+ private Boolean hasMore;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleProductInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleProductInfo.java
new file mode 100644
index 0000000000..ffcaf320ca
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleProductInfo.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 售后相关商品信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class AfterSaleProductInfo implements Serializable {
+
+ private static final long serialVersionUID = 4205179093262757775L;
+ /** 商品spu id */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** 商品sku id */
+ @JsonProperty("sku_id")
+ private String skuId;
+
+ /** 售后数量 */
+ @JsonProperty("count")
+ private Integer count;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleRejectParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleRejectParam.java
new file mode 100644
index 0000000000..080665ac00
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleRejectParam.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+/**
+ * 售后单拒绝信息
+ *
+ * @author Zeyes
+ */
+@Data
+@JsonInclude(Include.NON_NULL)
+public class AfterSaleRejectParam extends AfterSaleIdParam {
+
+ private static final long serialVersionUID = -7507483859864253314L;
+ /** 拒绝原因 */
+ @JsonProperty("reject_reason")
+ private String rejectReason;
+
+ public AfterSaleRejectParam() {
+ }
+
+ public AfterSaleRejectParam(String afterSaleOrderId, String rejectReason) {
+ super(afterSaleOrderId);
+ this.rejectReason = rejectReason;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleReturnParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleReturnParam.java
new file mode 100644
index 0000000000..47e815c8dd
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleReturnParam.java
@@ -0,0 +1,36 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import me.chanjar.weixin.channel.bean.base.AddressInfo;
+
+/**
+ * 退货信息
+ *
+ * @author Zeyes
+ */
+@Data
+public class AfterSaleReturnParam implements Serializable {
+
+ private static final long serialVersionUID = -1101993925465293521L;
+ /** 微信侧售后单号 */
+ @JsonProperty("aftersale_id")
+ private Long afterSaleId;
+
+ /** 外部售后单号,和aftersale_id二选一 */
+ @JsonProperty("out_aftersale_id")
+ private String outAfterSaleId;
+
+ /** 商家收货地址 */
+ @JsonProperty("address_info")
+ private AddressInfo addressInfo;
+
+ public AfterSaleReturnParam() {
+ }
+
+ public AfterSaleReturnParam(Long afterSaleId, String outAfterSaleId) {
+ this.outAfterSaleId = outAfterSaleId;
+ this.afterSaleId = afterSaleId;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/MerchantUploadInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/MerchantUploadInfo.java
new file mode 100644
index 0000000000..805c3a3f6e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/MerchantUploadInfo.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商家上传的信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class MerchantUploadInfo implements Serializable {
+
+ private static final long serialVersionUID = 373513419356603563L;
+ /** 拒绝原因 */
+ @JsonProperty("reject_reason")
+ private String rejectReason;
+
+ /** 退款凭证 */
+ @JsonProperty("refund_certificates")
+ private List refundCertificates;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/RefundEvidenceParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/RefundEvidenceParam.java
new file mode 100644
index 0000000000..c81ae042d4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/RefundEvidenceParam.java
@@ -0,0 +1,35 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 退款凭证信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class RefundEvidenceParam implements Serializable {
+
+ private static final long serialVersionUID = 2117305897849528009L;
+ /** 售后单号 */
+ @JsonProperty("after_sale_order_id")
+ private String afterSaleOrderId;
+
+ /** 描述 */
+ @JsonProperty("desc")
+ private String desc;
+
+ /** 凭证图片列表 */
+ @JsonProperty("refund_certificates")
+ private List certificates;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/RefundInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/RefundInfo.java
new file mode 100644
index 0000000000..9837b72b28
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/RefundInfo.java
@@ -0,0 +1,21 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 退款信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class RefundInfo implements Serializable {
+
+ private static final long serialVersionUID = -6994243947898889309L;
+ /** 退款金额(分) */
+ @JsonProperty("amount")
+ private Integer amount;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/RefundResp.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/RefundResp.java
new file mode 100644
index 0000000000..83b7039a77
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/RefundResp.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 退款结果
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class RefundResp implements Serializable {
+
+ private static final long serialVersionUID = 6549707043779644156L;
+ /** code */
+ @JsonProperty("code")
+ private String code;
+
+ /** ret */
+ @JsonProperty("ret")
+ private Integer ret;
+
+ /** message */
+ @JsonProperty("message")
+ private String message;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/ReturnInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/ReturnInfo.java
new file mode 100644
index 0000000000..08238d5484
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/ReturnInfo.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 用户退货信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class ReturnInfo implements Serializable {
+
+ private static final long serialVersionUID = 1643844664701376892L;
+ /** 快递单号 */
+ @JsonProperty("waybill_id")
+ private String waybillId;
+
+ /** 物流公司id */
+ @JsonProperty("delivery_id")
+ private String deliveryId;
+
+ /** 物流公司名称 */
+ @JsonProperty("delivery_name")
+ private String deliveryName;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/AuditApplyResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/AuditApplyResponse.java
new file mode 100644
index 0000000000..547207c82b
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/AuditApplyResponse.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.audit;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 审核提交结果响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class AuditApplyResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -3950614749162384497L;
+
+ /** 类目列表 */
+ @JsonProperty("audit_id")
+ private String auditId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/AuditResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/AuditResponse.java
new file mode 100644
index 0000000000..3ef07387d1
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/AuditResponse.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.audit;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 审核结果响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class AuditResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 9218713381520774914L;
+
+ /** 审核结果 1:审核中,3:审核成功,2:审核拒绝,12:主动取消申请单 */
+ @JsonProperty("data")
+ private AuditResult data;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/AuditResult.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/AuditResult.java
new file mode 100644
index 0000000000..89aaa8a267
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/AuditResult.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.channel.bean.audit;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 审核结果
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class AuditResult implements Serializable {
+
+ private static final long serialVersionUID = 1846416634865665240L;
+
+ /** 审核状态, 0:审核中,1:审核成功,9:审核拒绝, 12:主动取消 */
+ @JsonProperty("status")
+ private Integer status;
+
+ /** 如果审核拒绝,返回拒绝原因 */
+ @JsonProperty("reject_reason")
+ private String rejectReason;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/CategoryAuditInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/CategoryAuditInfo.java
new file mode 100644
index 0000000000..72a84bc922
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/CategoryAuditInfo.java
@@ -0,0 +1,37 @@
+package me.chanjar.weixin.channel.bean.audit;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 类目审核信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class CategoryAuditInfo implements Serializable {
+
+ private static final long serialVersionUID = -8792967130645424788L;
+
+ /** 一级类目,字符类型,最长不超过10 */
+ @JsonProperty("level1")
+ private Long level1;
+
+ /** 二级类目,字符类型,最长不超过10 */
+ @JsonProperty("level2")
+ private Long level2;
+
+ /** 三级类目,字符类型,最长不超过10 */
+ @JsonProperty("level3")
+ private Long level3;
+
+ /** 资质材料,图片url,图片类型,最多不超过10张 */
+ @JsonProperty("certificate")
+ private List certificates;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/CategoryAuditRequest.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/CategoryAuditRequest.java
new file mode 100644
index 0000000000..a311bf0d2f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/CategoryAuditRequest.java
@@ -0,0 +1,23 @@
+package me.chanjar.weixin.channel.bean.audit;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 类目审核信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class CategoryAuditRequest implements Serializable {
+
+ private static final long serialVersionUID = -1151634735247657643L;
+
+ @JsonProperty("category_info")
+ private CategoryAuditInfo categoryInfo;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/ProductAuditInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/ProductAuditInfo.java
new file mode 100644
index 0000000000..7693f23ed3
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/ProductAuditInfo.java
@@ -0,0 +1,37 @@
+package me.chanjar.weixin.channel.bean.audit;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商品审核信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class ProductAuditInfo implements Serializable {
+
+ private static final long serialVersionUID = -5264206679057480206L;
+
+ /** 审核单id */
+ @JsonProperty("audit_id")
+ private String auditId;
+
+ /** 上一次提交时间, yyyy-MM-dd HH:mm:ss */
+ @JsonProperty("submit_time")
+ private String submitTime;
+
+ /** 上一次审核时间, yyyy-MM-dd HH:mm:ss */
+ @JsonProperty("audit_time")
+ private String auditTime;
+
+ /** 拒绝理由,只有edit_status为3时出现 */
+ @JsonProperty("reject_reason")
+ private String rejectReason;
+
+ @JsonProperty("func_type")
+ private Integer funcType;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/base/AddressInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/base/AddressInfo.java
new file mode 100644
index 0000000000..3c713840a4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/base/AddressInfo.java
@@ -0,0 +1,70 @@
+package me.chanjar.weixin.channel.bean.base;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+/**
+ * 地址信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+public class AddressInfo implements Serializable {
+
+ private static final long serialVersionUID = 6928300709804576100L;
+
+ /** 收件人姓名 */
+ @JsonProperty("user_name")
+ private String userName;
+
+ /** 收件人手机号码 */
+ @JsonProperty("tel_number")
+ private String telNumber;
+
+ /** 邮编 */
+ @JsonProperty("postal_code")
+ private String postalCode;
+
+ /** 省份 */
+ @JsonProperty("province_name")
+ private String provinceName;
+
+ /** 城市 */
+ @JsonProperty("city_name")
+ private String cityName;
+
+ /** 区 */
+ @JsonProperty("county_name")
+ private String countyName;
+
+ /** 详细地址 */
+ @JsonProperty("detail_info")
+ private String detailInfo;
+
+ /** 国家码 */
+ @JsonProperty("national_code")
+ private String nationalCode;
+
+ /** 门牌号码 */
+ @JsonProperty("house_number")
+ private String houseNumber;
+
+ /** 纬度 */
+ @JsonProperty("lat")
+ private Double lat;
+
+ /** 经度 */
+ @JsonProperty("lng")
+ private Double lng;
+
+ public AddressInfo(String provinceName, String cityName, String countyName) {
+ this.provinceName = provinceName;
+ this.cityName = cityName;
+ this.countyName = countyName;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/base/AttrInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/base/AttrInfo.java
new file mode 100644
index 0000000000..ca6ce7a750
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/base/AttrInfo.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.base;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 属性
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class AttrInfo implements Serializable {
+
+ private static final long serialVersionUID = -790859309885311785L;
+
+ /** 销售属性key(自定义),字符类型,最长不超过40 */
+ @JsonProperty("attr_key")
+ private String key;
+
+ /** 销售属性value(自定义),字符类型,最长不超过40,相同key下不能超过100个不同value */
+ @JsonProperty("attr_value")
+ private String value;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/base/OffsetParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/base/OffsetParam.java
new file mode 100644
index 0000000000..ebfad1bf21
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/base/OffsetParam.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.base;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 偏移参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(Include.NON_NULL)
+public class OffsetParam implements Serializable {
+
+ private static final long serialVersionUID = -1268796871980541662L;
+
+ /** 起始位置 */
+ @JsonProperty("offset")
+ private Integer offset;
+ /** 拉取个数 */
+ @JsonProperty("limit")
+ private Integer limit;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/base/PageParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/base/PageParam.java
new file mode 100644
index 0000000000..d76e48d3b6
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/base/PageParam.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.base;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 分页参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class PageParam implements Serializable {
+
+ private static final long serialVersionUID = -2606033044242617845L;
+
+ /** 页码 */
+ @JsonProperty("page")
+ protected Integer page;
+
+ /** 每页订单数,上限100 */
+ @JsonProperty("page_size")
+ protected Integer pageSize;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/base/StreamPageParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/base/StreamPageParam.java
new file mode 100644
index 0000000000..6f3fb76d71
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/base/StreamPageParam.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.base;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 流式分页参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class StreamPageParam implements Serializable {
+
+ private static final long serialVersionUID = -4098060161712929196L;
+
+ /** 每页订单数,上限100 */
+ @JsonProperty("page_size")
+ protected Integer pageSize;
+
+ /** 分页参数,上一页请求返回 */
+ @JsonProperty("next_key")
+ protected String nextKey;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/base/TimeRange.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/base/TimeRange.java
new file mode 100644
index 0000000000..f681794835
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/base/TimeRange.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.channel.bean.base;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 时间范围
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class TimeRange implements Serializable {
+
+ private static final long serialVersionUID = -8149679871789511479L;
+
+ /** 开始时间 秒级时间戳 */
+ @JsonProperty("start_time")
+ private Long startTime;
+
+ /** 结束时间 秒级时间戳 */
+ @JsonProperty("end_time")
+ private Long endTime;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/base/WxChannelBaseResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/base/WxChannelBaseResponse.java
new file mode 100644
index 0000000000..b20d7f4b33
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/base/WxChannelBaseResponse.java
@@ -0,0 +1,68 @@
+package me.chanjar.weixin.channel.bean.base;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.StringJoiner;
+
+/**
+ * 视频号小店 基础响应
+ *
+ * @author Zeyes
+ */
+public class WxChannelBaseResponse implements Serializable {
+
+ private static final long serialVersionUID = 3141420881984171781L;
+
+ /** 请求成功状态码 */
+ public static final int SUCCESS_CODE = 0;
+ public static final int INTERNAL_ERROR_CODE = -99;
+
+ /**
+ * 错误码
+ */
+ @JsonProperty("errcode")
+ protected int errCode;
+
+ /**
+ * 错误消息
+ */
+ @JsonProperty("errmsg")
+ protected String errMsg;
+
+ /**
+ * 错误代码 + 错误消息
+ *
+ * @return String
+ */
+ public String errorMessage() {
+ return "errcode: " + errCode + ", errmsg: " + errMsg;
+ }
+
+ public boolean isSuccess() {
+ return errCode == SUCCESS_CODE;
+ }
+
+ public int getErrCode() {
+ return errCode;
+ }
+
+ public void setErrCode(int errCode) {
+ this.errCode = errCode;
+ }
+
+ public String getErrMsg() {
+ return errMsg;
+ }
+
+ public void setErrMsg(String errMsg) {
+ this.errMsg = errMsg;
+ }
+
+ @Override
+ public String toString() {
+ return new StringJoiner(", ", WxChannelBaseResponse.class.getSimpleName() + "[", "]")
+ .add("errCode=" + errCode)
+ .add("errMsg='" + errMsg + "'")
+ .toString();
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BasicBrand.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BasicBrand.java
new file mode 100644
index 0000000000..714740f843
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BasicBrand.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.brand;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 基础品牌信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class BasicBrand implements Serializable {
+
+ private static final long serialVersionUID = -1991771439710177859L;
+
+ /** 品牌库中的品牌编号(Long) */
+ @JsonProperty("brand_id")
+ private String brandId;
+
+ /** 品牌商标中文名 */
+ @JsonProperty("ch_name")
+ private String chName;
+
+ /** 品牌商标英文名 */
+ @JsonProperty("en_name")
+ private String enName;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/Brand.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/Brand.java
new file mode 100644
index 0000000000..92f4f41acc
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/Brand.java
@@ -0,0 +1,45 @@
+package me.chanjar.weixin.channel.bean.brand;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 品牌信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class Brand extends BasicBrand {
+
+ private static final long serialVersionUID = 4648597514861057019L;
+
+ /** 商标分类号, 取值范围1-45 */
+ @JsonProperty("classification_no")
+ private String classificationNo;
+
+ /** 商标类型, 取值1:R标; 2: TM标 */
+ @JsonProperty("trade_mark_symbol")
+ private Integer tradeMarkSymbol;
+
+ /** 商标注册信息 */
+ @JsonProperty("register_details")
+ private BrandRegisterDetail registerDetail;
+
+ /** 商标申请信息 */
+ @JsonProperty("application_details")
+ private BrandApplicationDetail applicationDetail;
+
+ /** 商标授权信息, 取值1:自有品牌; 2: 授权品牌 */
+ @JsonProperty("grant_type")
+ private Integer grantType;
+
+ /** 授权品牌信息 */
+ @JsonProperty("grant_details")
+ private BrandGrantDetail grantDetail;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandApplicationDetail.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandApplicationDetail.java
new file mode 100644
index 0000000000..48575f27cd
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandApplicationDetail.java
@@ -0,0 +1,31 @@
+package me.chanjar.weixin.channel.bean.brand;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商标申请信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class BrandApplicationDetail implements Serializable {
+
+ private static final long serialVersionUID = 2145344855482129473L;
+
+ /** 商标申请受理时间, TM标时必填 */
+ @JsonProperty("acceptance_time")
+ private Long acceptanceTime;
+
+ /** 商标注册申请受理书file_id, TM标时必填, 限制最多传1张, 需要先调用“资质上传”接口上传资质图片 */
+ @JsonProperty("acceptance_certification")
+ private List acceptanceCertification;
+
+ /** 商标申请号, TM标时必填 */
+ @JsonProperty("acceptance_no")
+ private String acceptanceNo;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandApplyListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandApplyListResponse.java
new file mode 100644
index 0000000000..16e7f3ae82
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandApplyListResponse.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.channel.bean.brand;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 品牌申请列表响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class BrandApplyListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 243021267020609148L;
+
+ /** 品牌资质申请信息 */
+ @JsonProperty("brands")
+ private List brands;
+
+ /** 本次翻页的上下文,用于请求下一页 */
+ @JsonProperty("next_key")
+ private String nextKey;
+
+ /** 品牌资质总数 */
+ @JsonProperty("total_num")
+ private Integer totalNum;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandGrantDetail.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandGrantDetail.java
new file mode 100644
index 0000000000..6b4826fcd4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandGrantDetail.java
@@ -0,0 +1,44 @@
+package me.chanjar.weixin.channel.bean.brand;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商标授权信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class BrandGrantDetail implements Serializable {
+
+ private static final long serialVersionUID = 3537812707384823606L;
+
+ /** 品牌销售授权书的file_id, 授权品牌必填, 限制最多传9张, 需要先调用“资质上传”接口上传资质图片 */
+ @JsonProperty("grant_certifications")
+ private List grantCertifications;
+
+ /** 授权级数, 授权品牌必填, 取值1-3 */
+ @JsonProperty("grant_level")
+ private Integer grantLevel;
+
+ /** 授权有效期, 开始时间, 长期有效可不填 */
+ @JsonProperty("start_time")
+ private Long startTime;
+
+ /** 授权有效期, 结束时间, 长期有效可不填 */
+ @JsonProperty("end_time")
+ private Long endTime;
+
+ /** 是否长期有效 */
+ @JsonProperty("is_permanent")
+ private boolean permanent;
+
+ /** 品牌权利人证件照的file_id, 限制最多传2张, 需要先调用“资质上传”接口上传资质图片 */
+ @JsonProperty("brand_owner_id_photos")
+ private List brandOwnerIdPhotos;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandInfo.java
new file mode 100644
index 0000000000..799002369d
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandInfo.java
@@ -0,0 +1,52 @@
+package me.chanjar.weixin.channel.bean.brand;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 品牌信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class BrandInfo extends Brand {
+
+ private static final long serialVersionUID = 5464505958132626159L;
+
+ /** 申请单状态 1审核中 2审核失败 3已生效 4已撤回 5即将过期(不影响商品售卖) 6已过期 */
+ @JsonProperty("status")
+ private Integer status;
+
+ /** 创建时间 */
+ @JsonProperty("create_time")
+ private Long createTime;
+
+ /** 更新时间 */
+ @JsonProperty("update_time")
+ private Long updateTime;
+
+ /** 审核结果 */
+ @JsonProperty("audit_result")
+ private AuditResult auditResult;
+
+ /** 审核结果 */
+ @Data
+ @NoArgsConstructor
+ public static class AuditResult implements Serializable {
+
+ private static final long serialVersionUID = 3936802571381636820L;
+ /** 提审的审核单ID */
+ @JsonProperty("audit_id")
+ private String auditId;
+
+ /** 审核不通过的原因, 审核成功不返回 */
+ @JsonProperty("reject_reason")
+ private String rejectReason;
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandInfoResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandInfoResponse.java
new file mode 100644
index 0000000000..20536b5a07
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandInfoResponse.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.brand;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 品牌响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class BrandInfoResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 2105745692451683517L;
+
+ /** 品牌信息 */
+ @JsonProperty("brand")
+ private BrandInfo brand;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandListResponse.java
new file mode 100644
index 0000000000..c6cff6f317
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandListResponse.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.channel.bean.brand;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 品牌列表响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class BrandListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -5335449078706304920L;
+
+ /** 品牌库中的品牌信息 */
+ @JsonProperty("brands")
+ private List brands;
+
+ /** 本次翻页的上下文,用于请求下一页 */
+ @JsonProperty("next_key")
+ private String nextKey;
+
+ /** 是否还有下一页内容 */
+ @JsonProperty("continue_flag")
+ private boolean continueFlag;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandParam.java
new file mode 100644
index 0000000000..05f8d89b42
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandParam.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.channel.bean.brand;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 品牌参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class BrandParam implements Serializable {
+
+ private static final long serialVersionUID = -4894709391464428613L;
+
+ /** 品牌信息 */
+ @JsonProperty("brand")
+ private Brand brand;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandRegisterDetail.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandRegisterDetail.java
new file mode 100644
index 0000000000..28b417f38c
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandRegisterDetail.java
@@ -0,0 +1,48 @@
+package me.chanjar.weixin.channel.bean.brand;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 品牌注册信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class BrandRegisterDetail implements Serializable {
+
+ private static final long serialVersionUID = 1169957179510362405L;
+
+ /** 商标注册人, R标时必填 */
+ @JsonProperty("registrant")
+ private String registrant;
+
+ /** 商标注册号, R标时必填 */
+ @JsonProperty("register_no")
+ private String registerNo;
+
+ /** 商标注册有效期(时间戳秒), 开始时间, 长期有效可不填 */
+ @JsonProperty("start_time")
+ private Long startTime;
+
+ /** 商标注册有效期(时间戳秒), 结束时间, 长期有效可不填 */
+ @JsonProperty("end_time")
+ private Long endTime;
+
+ /** 是否长期有效 */
+ @JsonProperty("is_permanent")
+ private boolean permanent;
+
+ /** 商标注册证的file_id, R标时必填, 限制最多传1张, 需要先调用“资质上传”接口上传资质图片 */
+ @JsonProperty("register_certifications")
+ private List registerCertifications;
+
+ /** 变更/续展证明的file_id, 限制最多传5张, 需要先调用“资质上传”接口上传资质图片 */
+ @JsonProperty("renew_certifications")
+ private List renewCertifications;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandSearchParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandSearchParam.java
new file mode 100644
index 0000000000..e73ed4f54e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/brand/BrandSearchParam.java
@@ -0,0 +1,31 @@
+package me.chanjar.weixin.channel.bean.brand;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import me.chanjar.weixin.channel.bean.base.StreamPageParam;
+
+/**
+ * 品牌搜索参数
+ *
+ * @author Zeyes
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class BrandSearchParam extends StreamPageParam {
+
+ private static final long serialVersionUID = 5961201403338269712L;
+ /** 审核单状态, 不填默认拉全部商品 */
+ @JsonProperty("status")
+ private Integer status;
+
+ public BrandSearchParam() {
+ }
+
+ public BrandSearchParam(Integer pageSize, String nextKey, Integer status) {
+ super(pageSize, nextKey);
+ this.status = status;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/AccountCategoryResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/AccountCategoryResponse.java
new file mode 100644
index 0000000000..3db7c74cec
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/AccountCategoryResponse.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.bean.category;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 分类响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class AccountCategoryResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 3486089711447908477L;
+
+ /** 类目列表 */
+ @JsonProperty("data")
+ private List categories;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryAndQualificationList.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryAndQualificationList.java
new file mode 100644
index 0000000000..c9e973c8b8
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryAndQualificationList.java
@@ -0,0 +1,23 @@
+package me.chanjar.weixin.channel.bean.category;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 分类资质响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class CategoryAndQualificationList implements Serializable {
+
+ private static final long serialVersionUID = 4245906598437404655L;
+
+ /** 分类列表 */
+ @JsonProperty("cat_and_qua")
+ private List list;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryDetailResult.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryDetailResult.java
new file mode 100644
index 0000000000..8819e94312
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryDetailResult.java
@@ -0,0 +1,132 @@
+package me.chanjar.weixin.channel.bean.category;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class CategoryDetailResult extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 4657778764371047619L;
+
+ @JsonProperty("info")
+ private Info info;
+
+ @JsonProperty("attr")
+ private Attr attr;
+
+
+ @Data
+ @NoArgsConstructor
+ public static class Info implements Serializable {
+
+ /** 类目ID */
+ @JsonProperty("cat_id")
+ private String id;
+ /** 类目名称 */
+ @JsonProperty("name")
+ private String name;
+ }
+
+ @Data
+ @NoArgsConstructor
+ public static class Attr implements Serializable {
+
+ /** 是否支持虚拟发货 */
+ @JsonProperty("shop_no_shipment")
+ private Boolean shopNoShipment;
+
+ /** 是否定向准入 */
+ @JsonProperty("access_permit_required")
+ private Boolean accessPermitRequired;
+
+ /** 是否支持预售 */
+ @JsonProperty("pre_sale")
+ private Boolean preSale;
+
+ /** 是否必须支持7天无理由退货 */
+ @JsonProperty("seven_day_return")
+ private Boolean sevenDayReturn;
+
+ /** 定准类目的品牌ID */
+ @JsonProperty("brand_list")
+ private List brands;
+
+ /** 类目关联的保证金,单位分 */
+ @JsonProperty("deposit")
+ private Long deposit;
+
+ /** 产品属性 */
+ @JsonProperty("product_attr_list")
+ private List productAttrs;
+
+ /** 销售属性 */
+ @JsonProperty("sale_attr_list")
+ private List saleAttrs;
+
+ /** 佣金信息 */
+ @JsonProperty("transactionfee_info")
+ private FeeInfo feeInfo;
+ }
+
+ @Data
+ @NoArgsConstructor
+ public static class BrandInfo implements Serializable {
+
+ /** 定准类目的品牌ID */
+ @JsonProperty("brand_id")
+ private String id;
+ }
+
+ @Data
+ @NoArgsConstructor
+ public static class ProductAttr implements Serializable {
+
+ /** 类目必填项名称 */
+ @JsonProperty("name")
+ private String name;
+
+ /** 类目必填项类型,string为自定义,select_one为多选一 */
+ @JsonProperty("type")
+ private String type;
+
+ /** 类目必填项值 */
+ @JsonProperty("value")
+ private String value;
+
+ /** 是否类目必填项 */
+ @JsonProperty("is_required")
+ private Boolean required;
+
+
+ }
+
+ @Data
+ @NoArgsConstructor
+ public static class FeeInfo implements Serializable {
+
+ /** 类目实收的交易佣金比例,单位万分比 */
+ @JsonProperty("basis_point")
+ private Integer basisPoint;
+
+ /** 类目原始佣金比例,单位万分比 */
+ @JsonProperty("original_basis_point")
+ private Integer originalBasisPoint;
+
+ /** 佣金激励类型,0:无激励措施,1:新店佣金减免 */
+ @JsonProperty("incentive_type")
+ private Integer incentiveType;
+
+ }
+}
+
+
+
+
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryQualification.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryQualification.java
new file mode 100644
index 0000000000..f384eaae45
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryQualification.java
@@ -0,0 +1,31 @@
+package me.chanjar.weixin.channel.bean.category;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 分类资质信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class CategoryQualification implements Serializable {
+
+ private static final long serialVersionUID = 6495550078851408381L;
+
+ /** 类目 */
+ @JsonProperty("cat")
+ private ShopCategory category;
+
+ /** 资质信息 */
+ @JsonProperty("qua")
+ private QualificationInfo info;
+
+ /** 商品资质信息 */
+ @JsonProperty("product_qua")
+ private QualificationInfo productInfo;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryQualificationResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryQualificationResponse.java
new file mode 100644
index 0000000000..984a3ad79b
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryQualificationResponse.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.bean.category;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 分类资质响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class CategoryQualificationResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -7869091908852685830L;
+
+ @JsonProperty("cats")
+ private List list;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/PassCategoryInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/PassCategoryInfo.java
new file mode 100644
index 0000000000..82b16c0188
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/PassCategoryInfo.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.channel.bean.category;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 审核通过的分类和资质信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class PassCategoryInfo implements Serializable {
+
+ private static final long serialVersionUID = 1152077957498898216L;
+
+ /** 类目ID */
+ @JsonProperty("cat_id")
+ private String catId;
+
+ /** 资质ID */
+ @JsonProperty("qua_id")
+ private String quaId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/PassCategoryResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/PassCategoryResponse.java
new file mode 100644
index 0000000000..af6f484254
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/PassCategoryResponse.java
@@ -0,0 +1,23 @@
+package me.chanjar.weixin.channel.bean.category;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 审核通过的分类和资质信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class PassCategoryResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -3674591447273025743L;
+
+ /** 类目和资质信息列表 */
+ @JsonProperty("list")
+ private List list;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/QualificationInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/QualificationInfo.java
new file mode 100644
index 0000000000..197ac46528
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/QualificationInfo.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.channel.bean.category;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 资质信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class QualificationInfo implements Serializable {
+
+ /** 资质ID */
+ @JsonProperty("qua_id")
+ private String id;
+
+ /** 是否需要申请 */
+ @JsonProperty("need_to_apply")
+ private Boolean needToApply;
+
+ /** 资质信息 */
+ @JsonProperty("tips")
+ private String tips;
+
+ /** 该类目申请的时候是否一定要提交资质 */
+ @JsonProperty("mandatory")
+ private Boolean mandatory;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/ShopCategory.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/ShopCategory.java
new file mode 100644
index 0000000000..b36edfa9e2
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/ShopCategory.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.channel.bean.category;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商品类目
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class ShopCategory implements Serializable {
+
+ /** 类目ID */
+ @JsonProperty("cat_id")
+ private String id;
+
+ /** 类目父ID */
+ @JsonProperty("f_cat_id")
+ private String parentId;
+
+ /** 类目名称 */
+ @JsonProperty("name")
+ private String name;
+
+ /** 层级 */
+ @JsonProperty("level")
+ private Integer level;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/ShopCategoryResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/ShopCategoryResponse.java
new file mode 100644
index 0000000000..2af64ad1c3
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/ShopCategoryResponse.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.category;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 分类响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class ShopCategoryResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 3871098948660947422L;
+
+ /** 类目列表 */
+ @JsonProperty("cat_list")
+ private List categories;
+
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/complaint/ComplaintHistory.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/complaint/ComplaintHistory.java
new file mode 100644
index 0000000000..4570fdc615
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/complaint/ComplaintHistory.java
@@ -0,0 +1,46 @@
+package me.chanjar.weixin.channel.bean.complaint;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 纠纷历史
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class ComplaintHistory implements Serializable {
+
+ private static final long serialVersionUID = -4706637116597650133L;
+ /** 历史操作类型,见 {@link me.chanjar.weixin.channel.enums.ComplaintItemType } */
+ @JsonProperty("item_type")
+ private Integer itemType;
+
+ /** 操作时间,Unix时间戳 */
+ @JsonProperty("time")
+ private Long time;
+
+ /** 用户联系电话 */
+ @JsonProperty("phone_number")
+ private Integer phoneNumber;
+
+ /** 相关文本内容 */
+ @JsonProperty("content")
+ private String content;
+
+ /** 相关图片media_id列表 */
+ @JsonProperty("media_id_list")
+ private List mediaIds;
+
+ /** 售后类型, 1-仅退款 2-退货退款 */
+ @JsonProperty("after_sale_type")
+ private Integer afterSaleType;
+
+ /** 售后原因,见 {@link me.chanjar.weixin.channel.enums.AfterSalesReason} */
+ @JsonProperty("after_sale_reason")
+ private Integer afterSaleReason;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/complaint/ComplaintOrderResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/complaint/ComplaintOrderResponse.java
new file mode 100644
index 0000000000..a0a8ec1e18
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/complaint/ComplaintOrderResponse.java
@@ -0,0 +1,35 @@
+package me.chanjar.weixin.channel.bean.complaint;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 纠纷单响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class ComplaintOrderResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 1968530826349555367L;
+ /** 售后单号 */
+ @JsonProperty("after_sale_order_id")
+ private String afterSaleOrderId;
+
+ /** 订单号 */
+ @JsonProperty("order_id")
+ private String orderId;
+
+ /** 纠纷历史 */
+ @JsonProperty("history")
+ private List history;
+
+ /** 纠纷单状态, 见 {@link me.chanjar.weixin.channel.enums.ComplaintStatus} */
+ @JsonProperty("status")
+ private Integer status;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/complaint/ComplaintParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/complaint/ComplaintParam.java
new file mode 100644
index 0000000000..0090348efe
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/complaint/ComplaintParam.java
@@ -0,0 +1,34 @@
+package me.chanjar.weixin.channel.bean.complaint;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 纠纷单留言
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ComplaintParam implements Serializable {
+
+ private static final long serialVersionUID = 6146118590005718327L;
+ /** 纠纷单号 */
+ @JsonProperty("complaint_id")
+ private String complaintId;
+
+ /** 留言内容,最多500字 */
+ @JsonProperty("content")
+ private String content;
+
+ /** 图片media_id列表,所有留言总图片数量最多20张 */
+ @JsonProperty("media_id_list")
+ private List mediaIds;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/AutoValidInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/AutoValidInfo.java
new file mode 100644
index 0000000000..73c09def1e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/AutoValidInfo.java
@@ -0,0 +1,21 @@
+package me.chanjar.weixin.channel.bean.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 自动生效信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class AutoValidInfo implements Serializable {
+
+ private static final long serialVersionUID = 1702505613539861103L;
+ /** 优惠券开启自动生效类型 0不启用自动生效 1启用自动生效,按领券开始时间(自动生效时间为 receive_info.start_time) */
+ @JsonProperty("auto_valid_type")
+ private Integer autoValidType;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponDetailInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponDetailInfo.java
new file mode 100644
index 0000000000..34f76716f9
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponDetailInfo.java
@@ -0,0 +1,43 @@
+package me.chanjar.weixin.channel.bean.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 优惠券信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+
+public class CouponDetailInfo implements Serializable {
+
+ private static final long serialVersionUID = 5994815232349181577L;
+ /** 优惠券名称 **/
+ @JsonProperty("name")
+ private String name;
+
+ /** 优惠券有效信息 **/
+ @JsonProperty("valid_info")
+ private ValidInfo validInfo;
+
+ /** 推广信息 **/
+ @JsonProperty("promote_info")
+ private PromoteInfo promoteInfo;
+
+ /** 优惠信息 **/
+ @JsonProperty("discount_info")
+ private DiscountInfo discountInfo;
+
+ /** 额外信息 **/
+ @JsonProperty("ext_info")
+ private ExtInfo extInfo;
+
+ /** 领取信息 **/
+ @JsonProperty("receive_info")
+ private ReceiveInfo receiveInfo;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponIdInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponIdInfo.java
new file mode 100644
index 0000000000..b787016a09
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponIdInfo.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 优惠券id
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class CouponIdInfo implements Serializable {
+
+ private static final long serialVersionUID = 6284609705855608275L;
+ /** 优惠券ID */
+ @JsonProperty("coupon_id")
+ private String couponId;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponIdResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponIdResponse.java
new file mode 100644
index 0000000000..7556fa6f11
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponIdResponse.java
@@ -0,0 +1,21 @@
+package me.chanjar.weixin.channel.bean.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+
+/**
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class CouponIdResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -3263189706802013651L;
+ @JsonProperty("data")
+ private CouponIdInfo data;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponInfo.java
new file mode 100644
index 0000000000..cd247f9d71
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponInfo.java
@@ -0,0 +1,38 @@
+package me.chanjar.weixin.channel.bean.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class CouponInfo extends CouponIdInfo {
+
+ private static final long serialVersionUID = -5862063828870424262L;
+ /** 优惠券类型 **/
+ @JsonProperty("type")
+ private Integer type;
+
+ /** 优惠券状态 **/
+ @JsonProperty("status")
+ private Integer status;
+
+ /** 优惠券创建时间 */
+ @JsonProperty("create_time")
+ private Long createTime;
+
+ /** 优惠券更新时间 */
+ @JsonProperty("update_time")
+ private Long updateTime;
+
+ /** 优惠券信息 */
+ @JsonProperty("coupon_info")
+ private CouponDetailInfo detail;
+
+ /** 库存信息 */
+ @JsonProperty("stock_info")
+ private StockInfo stockInfo;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponInfoResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponInfoResponse.java
new file mode 100644
index 0000000000..801843025e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponInfoResponse.java
@@ -0,0 +1,20 @@
+package me.chanjar.weixin.channel.bean.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class CouponInfoResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 5261320058699488529L;
+ @JsonProperty("coupon")
+ private CouponInfo coupon;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponListParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponListParam.java
new file mode 100644
index 0000000000..35e980098f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponListParam.java
@@ -0,0 +1,34 @@
+package me.chanjar.weixin.channel.bean.coupon;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(Include.NON_NULL)
+public class CouponListParam implements Serializable {
+
+ private static final long serialVersionUID = 7123047113279657365L;
+ /** 优惠券状态 {@link me.chanjar.weixin.channel.enums.WxCouponStatus} */
+ @JsonProperty("status")
+ private Integer status;
+
+ /** 第几页(最小填1) */
+ @JsonProperty("page")
+ private Integer page;
+
+ /** 每页数量(不超过200) */
+ @JsonProperty("page_size")
+ private Integer pageSize;
+
+ /** 分页上下文 */
+ @JsonProperty("page_ctx")
+ private String pageCtx;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponListResponse.java
new file mode 100644
index 0000000000..66d6f63eef
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponListResponse.java
@@ -0,0 +1,31 @@
+package me.chanjar.weixin.channel.bean.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class CouponListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -5330296358041282751L;
+ /** 优惠券id列表 */
+ @JsonProperty("coupons")
+ private List coupons;
+
+ /** 优惠券总数 */
+ @JsonProperty("total_num")
+ private Integer totalNum;
+
+ /** 优惠券上下文 */
+ @JsonProperty("page_ctx")
+ private String pageCtx;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponParam.java
new file mode 100644
index 0000000000..fa89b0a1e4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponParam.java
@@ -0,0 +1,50 @@
+package me.chanjar.weixin.channel.bean.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 优惠券参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class CouponParam extends CouponIdInfo {
+
+ private static final long serialVersionUID = -3663331372622943337L;
+ /** 优惠券类型 **/
+ @JsonProperty("type")
+ private Integer type;
+
+ /** 优惠券名称,最长10个中文字符 */
+ @JsonProperty("name")
+ private String name;
+
+ /** 优惠信息 **/
+ @JsonProperty("discount_info")
+ private DiscountInfo discountInfo;
+
+ /** 额外信息 **/
+ @JsonProperty("ext_info")
+ private ExtInfo extInfo;
+
+ /** 推广信息 **/
+ @JsonProperty("promote_info")
+ private PromoteInfo promoteInfo;
+
+ /** 领取信息 **/
+ @JsonProperty("receive_info")
+ private ReceiveInfo receiveInfo;
+
+ /** 优惠券有效信息 **/
+ @JsonProperty("valid_info")
+ private ValidInfo validInfo;
+
+ /** 优惠券自动生效信息 **/
+ @JsonProperty("auto_valid_info")
+ private AutoValidInfo autoValidInfo;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponStatusParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponStatusParam.java
new file mode 100644
index 0000000000..405ad52400
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/CouponStatusParam.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.coupon;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class CouponStatusParam extends CouponIdInfo {
+
+ private static final long serialVersionUID = -7108348049925634704L;
+ /** 状态 */
+ @JsonProperty("status")
+ private Integer status;
+
+ public CouponStatusParam() {
+ }
+
+ public CouponStatusParam(String couponId, Integer status) {
+ super(couponId);
+ this.status = status;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/DiscountCondition.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/DiscountCondition.java
new file mode 100644
index 0000000000..e249455526
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/DiscountCondition.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 折扣条件
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class DiscountCondition implements Serializable {
+
+ private static final long serialVersionUID = 3250293381093835082L;
+ /** 优惠券使用条件, 满 x 件商品可用 */
+ @JsonProperty("product_cnt")
+ private Integer productCnt;
+
+ /** 优惠券使用条件, 价格满 x 可用,单位分 */
+ @JsonProperty("product_price")
+ private Integer productPrice;
+
+ /** 优惠券使用条件, 指定商品 id 可用 */
+ @JsonProperty("product_ids")
+ private List productIds;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/DiscountInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/DiscountInfo.java
new file mode 100644
index 0000000000..7988e47ce6
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/DiscountInfo.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 优惠信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class DiscountInfo implements Serializable {
+
+ private static final long serialVersionUID = 3660070880545144112L;
+ /** 优惠券折扣数 * 1000, 例如 5.1折-> 5100 */
+ @JsonProperty("discount_num")
+ private Integer discountNum;
+
+ /** 优惠券减少金额, 单位分, 例如0.5元-> 50 */
+ @JsonProperty("discount_fee")
+ private Integer discountFee;
+
+ /** 优惠条件 */
+ @JsonProperty("discount_condition")
+ private DiscountCondition discountCondition;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/ExtInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/ExtInfo.java
new file mode 100644
index 0000000000..69cf3dc073
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/ExtInfo.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.channel.bean.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 额外信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class ExtInfo implements Serializable {
+
+ private static final long serialVersionUID = 9053035437087423233L;
+ /** 商品折扣券领取后跳转的商品id **/
+ @JsonProperty("jump_product_id")
+ private String jumpProductId;
+
+ /** 备注信息 **/
+ @JsonProperty("notes")
+ private String notes;
+
+ /** 优惠券有效时间 **/
+ @JsonProperty("valid_time")
+ private Long validTime;
+
+ /** 优惠券失效时间戳 **/
+ @JsonProperty("invalid_time")
+ private Long invalidTime;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/PromoteInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/PromoteInfo.java
new file mode 100644
index 0000000000..75d48e6d3e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/PromoteInfo.java
@@ -0,0 +1,21 @@
+package me.chanjar.weixin.channel.bean.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 推广信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class PromoteInfo implements Serializable {
+
+ private static final long serialVersionUID = -3030639750899957382L;
+ /** 推广类型 {@link me.chanjar.weixin.channel.enums.PromoteType} */
+ @JsonProperty("promote_type")
+ private Integer promoteType;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/ReceiveInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/ReceiveInfo.java
new file mode 100644
index 0000000000..9a602ac390
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/ReceiveInfo.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.channel.bean.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 领取信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class ReceiveInfo implements Serializable {
+
+ private static final long serialVersionUID = 755956808504040633L;
+ /** 优惠券领用结束时间 **/
+ @JsonProperty("end_time")
+ private Long endTime;
+
+ /** 单人限领张数 **/
+ @JsonProperty("limit_num_one_person")
+ private Integer limitNumOnePerson;
+
+ /** 优惠券领用开始时间 **/
+ @JsonProperty("start_time")
+ private Long startTime;
+
+ /** 优惠券领用总数 **/
+ @JsonProperty("total_num")
+ private Integer totalNum;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/StockInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/StockInfo.java
new file mode 100644
index 0000000000..07aaf4a1ec
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/StockInfo.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 库存信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class StockInfo implements Serializable {
+
+ private static final long serialVersionUID = -6078383881065929862L;
+ /** 优惠券剩余量 */
+ @JsonProperty("issued_num")
+ private Integer issuedNum;
+
+ /** 优惠券领用量 */
+ @JsonProperty("receive_num")
+ private Integer receiveNum;
+
+ /** 优惠券已用量 */
+ @JsonProperty("used_num")
+ private Integer usedNum;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/UserCoupon.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/UserCoupon.java
new file mode 100644
index 0000000000..06436a9e73
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/UserCoupon.java
@@ -0,0 +1,50 @@
+package me.chanjar.weixin.channel.bean.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 用户优惠券
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class UserCoupon extends UserCouponIdInfo {
+
+ private static final long serialVersionUID = -4777537717885622888L;
+ /** 优惠券状态 {@link me.chanjar.weixin.channel.enums.UserCouponStatus} */
+ @JsonProperty("status")
+ private Integer status;
+
+ /** 优惠券派发时间 */
+ @JsonProperty("create_time")
+ private Long createTime;
+
+ /** 优惠券更新时间 */
+ @JsonProperty("update_time")
+ private Long updateTime;
+
+ /** 优惠券生效时间 */
+ @JsonProperty("start_time")
+ private Long startTime;
+
+ /** 优惠券失效时间 */
+ @JsonProperty("end_time")
+ private Long endTime;
+
+ /** 附加信息 */
+ @JsonProperty("ext_info")
+ private UserExtInfo extInfo;
+
+ /** 优惠券使用的订单id */
+ @JsonProperty("order_id")
+ private String orderId;
+
+ /** 优惠券金额 */
+ @JsonProperty("discount_fee")
+ private Integer discountFee;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/UserCouponIdInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/UserCouponIdInfo.java
new file mode 100644
index 0000000000..d68d881c98
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/UserCouponIdInfo.java
@@ -0,0 +1,20 @@
+package me.chanjar.weixin.channel.bean.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 用户优惠券id
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class UserCouponIdInfo extends CouponIdInfo {
+
+ private static final long serialVersionUID = -8285585134793264542L;
+ /** 用户优惠券ID */
+ @JsonProperty("user_coupon_id")
+ private String userCouponId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/UserCouponIdParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/UserCouponIdParam.java
new file mode 100644
index 0000000000..aa2eb15421
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/UserCouponIdParam.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+
+/**
+ * @author Zeyes
+ */
+@Data
+public class UserCouponIdParam implements Serializable {
+
+ private static final long serialVersionUID = 3967276158727848348L;
+ /** 用户openid */
+ @JsonProperty("openid")
+ private String openid;
+
+ /** 用户优惠券ID */
+ @JsonProperty("user_coupon_id")
+ private String userCouponId;
+
+ public UserCouponIdParam() {
+ }
+
+ public UserCouponIdParam(String openid, String userCouponId) {
+ this.openid = openid;
+ this.userCouponId = userCouponId;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/UserCouponListParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/UserCouponListParam.java
new file mode 100644
index 0000000000..31a04cc742
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/UserCouponListParam.java
@@ -0,0 +1,22 @@
+package me.chanjar.weixin.channel.bean.coupon;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class UserCouponListParam extends CouponListParam {
+
+ private static final long serialVersionUID = -1056132009327357435L;
+ /** openId */
+ @JsonProperty("openid")
+ private String openId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/UserCouponListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/UserCouponListResponse.java
new file mode 100644
index 0000000000..2c3582e678
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/UserCouponListResponse.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class UserCouponListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 5201633937239352879L;
+ /** 优惠券id列表 */
+ @JsonProperty("user_coupon_list")
+ private List coupons;
+
+ /** 优惠券总数 */
+ @JsonProperty("total_num")
+ private Integer totalNum;
+
+ /** 优惠券上下文 */
+ @JsonProperty("page_ctx")
+ private String pageCtx;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/UserCouponResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/UserCouponResponse.java
new file mode 100644
index 0000000000..aeb9d89afb
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/UserCouponResponse.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class UserCouponResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 1434098386857953234L;
+ @JsonProperty("user_coupon")
+ private UserCoupon coupon;
+
+ @JsonProperty("openid")
+ private String openid;
+
+ @JsonProperty("unionid")
+ private String unionid;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/UserExtInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/UserExtInfo.java
new file mode 100644
index 0000000000..18962361ec
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/UserExtInfo.java
@@ -0,0 +1,21 @@
+package me.chanjar.weixin.channel.bean.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 用户优惠券附加信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class UserExtInfo implements Serializable {
+
+ private static final long serialVersionUID = 8304922825230343409L;
+ /** 优惠券核销时间 */
+ @JsonProperty("use_time")
+ private Long useTime;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/ValidInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/ValidInfo.java
new file mode 100644
index 0000000000..10df794324
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/coupon/ValidInfo.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.channel.bean.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 优惠券有效信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class ValidInfo implements Serializable {
+
+ private static final long serialVersionUID = -4550516248380285635L;
+ /** 优惠券有效期类型 {@link me.chanjar.weixin.channel.enums.CouponValidType} */
+ @JsonProperty("valid_type")
+ private Integer validType;
+
+ /** 优惠券有效天数,valid_type=2时才有意义 */
+ @JsonProperty("valid_day_num")
+ private Integer validDayNum;
+
+ /** 优惠券有效期开始时间,valid_type=1时才有意义 */
+ @JsonProperty("start_time")
+ private Long startTime;
+
+ /** 优惠券有效期结束时间,valid_type=1时才有意义 */
+ @JsonProperty("end_time")
+ private Long endTime;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/delivery/DeliveryCompanyInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/delivery/DeliveryCompanyInfo.java
new file mode 100644
index 0000000000..349d70cbb1
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/delivery/DeliveryCompanyInfo.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.bean.delivery;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 快递公司信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class DeliveryCompanyInfo implements Serializable {
+
+ private static final long serialVersionUID = 4225666604513570564L;
+ /** 快递公司id */
+ @JsonProperty("delivery_id")
+ private String id;
+
+ /** 快递公司名称 */
+ @JsonProperty("delivery_name")
+ private String name;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/delivery/DeliveryCompanyResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/delivery/DeliveryCompanyResponse.java
new file mode 100644
index 0000000000..d74a9439ea
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/delivery/DeliveryCompanyResponse.java
@@ -0,0 +1,22 @@
+package me.chanjar.weixin.channel.bean.delivery;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 快递公司列表响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class DeliveryCompanyResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -7695903997951385166L;
+ /** 快递公司 */
+ @JsonProperty("company_list")
+ private List companyList;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/delivery/DeliveryInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/delivery/DeliveryInfo.java
new file mode 100644
index 0000000000..23ab8dad2c
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/delivery/DeliveryInfo.java
@@ -0,0 +1,34 @@
+package me.chanjar.weixin.channel.bean.delivery;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 物流信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class DeliveryInfo implements Serializable {
+
+ private static final long serialVersionUID = -6205626967305385248L;
+ /** 快递单号 */
+ @JsonProperty("waybill_id")
+ private String waybillId;
+
+ /** 快递公司id,通过【获取快递公司列表】接口获得,非主流快递公司可以填OTHER */
+ @JsonProperty("delivery_id")
+ private String deliveryId;
+
+ /** 发货方式,1:自寄快递发货,3:虚拟商品无需物流发货(只有deliver_method=1的订单可以使用虚拟发货) */
+ @JsonProperty("deliver_type")
+ private Integer deliverType;
+
+ /** 包裹中商品信息 */
+ @JsonProperty("product_infos")
+ private List productInfos;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/delivery/DeliverySendParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/delivery/DeliverySendParam.java
new file mode 100644
index 0000000000..f486032bc4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/delivery/DeliverySendParam.java
@@ -0,0 +1,31 @@
+package me.chanjar.weixin.channel.bean.delivery;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 订单发货信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(Include.NON_NULL)
+public class DeliverySendParam implements Serializable {
+
+ private static final long serialVersionUID = 4555821308266899135L;
+ /** 订单ID */
+ @JsonProperty("order_id")
+ private String orderId;
+
+ /** 物流信息 */
+ @JsonProperty("delivery_list")
+ private List deliveryList;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/delivery/FreightProductInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/delivery/FreightProductInfo.java
new file mode 100644
index 0000000000..b184dea1d7
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/delivery/FreightProductInfo.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.delivery;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 包裹中商品信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class FreightProductInfo implements Serializable {
+
+ private static final long serialVersionUID = -3751269707150372172L;
+ /** 商品id */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** sku_id */
+ @JsonProperty("sku_id")
+ private String skuId;
+
+ /** 商品数量 */
+ @JsonProperty("product_cnt")
+ private String productCnt;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/AddressInfoList.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/AddressInfoList.java
new file mode 100644
index 0000000000..4d8c7ec4a5
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/AddressInfoList.java
@@ -0,0 +1,23 @@
+package me.chanjar.weixin.channel.bean.freight;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.AddressInfo;
+
+/**
+ * 地址列表
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class AddressInfoList implements Serializable {
+
+ private static final long serialVersionUID = 5923805297331862706L;
+ /** 地址列表 */
+ @JsonProperty("address_infos")
+ private List addressInfos;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/AllConditionFreeDetail.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/AllConditionFreeDetail.java
new file mode 100644
index 0000000000..fd9aee451d
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/AllConditionFreeDetail.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.channel.bean.freight;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 计费规则列表
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class AllConditionFreeDetail implements Serializable {
+
+ private static final long serialVersionUID = -1649520737632417036L;
+ /** 计费规则列表 */
+ @JsonProperty("condition_free_detail_list")
+ private List list;
+
+ @JsonIgnore
+ public void addDetail(ConditionFreeDetail detail) {
+ if (list == null) {
+ list = new ArrayList<>(16);
+ }
+ list.add(detail);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/AllFreightCalcMethod.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/AllFreightCalcMethod.java
new file mode 100644
index 0000000000..2c5523ebe4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/AllFreightCalcMethod.java
@@ -0,0 +1,31 @@
+package me.chanjar.weixin.channel.bean.freight;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import lombok.Data;
+
+/**
+ * 具体计费方法,默认运费,指定地区运费等
+ *
+ * @author Zeyes
+ */
+@Data
+public class AllFreightCalcMethod implements Serializable {
+
+ private static final long serialVersionUID = 6330919525271991949L;
+ /** 计算方法列表 */
+ @JsonProperty("freight_calc_method_list")
+ private List list;
+
+ public AllFreightCalcMethod() {
+ }
+
+ public void addDetail(FreightCalcMethod detail) {
+ if (list == null) {
+ list = new ArrayList<>(16);
+ }
+ list.add(detail);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/ConditionFreeDetail.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/ConditionFreeDetail.java
new file mode 100644
index 0000000000..68cb3b146e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/ConditionFreeDetail.java
@@ -0,0 +1,38 @@
+package me.chanjar.weixin.channel.bean.freight;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 计费规则
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class ConditionFreeDetail extends AddressInfoList {
+
+ private static final long serialVersionUID = 9204578767029379142L;
+ /** 最低件数 */
+ @JsonProperty("min_piece")
+ private Integer minPiece;
+
+ /** 最低重量 */
+ @JsonProperty("min_weight")
+ private Double minWeight;
+
+ /** 最低金额 */
+ @JsonProperty("min_amount")
+ private Integer minAmount;
+
+ /** 计费方式对应的选项是否已设置 */
+ @JsonProperty("valuation_flag")
+ private Integer valuationFlag;
+
+ /** 金额是否设置 */
+ @JsonProperty("amount_flag")
+ private Integer amountFlag;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/FreightCalcMethod.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/FreightCalcMethod.java
new file mode 100644
index 0000000000..aab949bc44
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/FreightCalcMethod.java
@@ -0,0 +1,43 @@
+package me.chanjar.weixin.channel.bean.freight;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 运费计算方法
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class FreightCalcMethod extends AddressInfoList {
+
+ private static final long serialVersionUID = -8857987538121721376L;
+ /** 是否默认运费 */
+ @JsonProperty("is_default")
+ private Boolean isDefault;
+
+ /** 快递公司 */
+ @JsonProperty("delivery_id")
+ private String deliveryId;
+
+ /** 首段运费需要满足的数量 */
+ @JsonProperty("first_val_amount")
+ private Integer firstValAmount;
+
+ /** 首段运费的金额 */
+ @JsonProperty("first_price")
+ private Integer firstPrice;
+
+ /** 续费的数量 */
+ @JsonProperty("second_val_amount")
+ private Integer secondValAmount;
+
+ /** 续费的金额 */
+ @JsonProperty("second_price")
+ private Integer secondPrice;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/FreightTemplate.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/FreightTemplate.java
new file mode 100644
index 0000000000..e28f90ad41
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/FreightTemplate.java
@@ -0,0 +1,71 @@
+package me.chanjar.weixin.channel.bean.freight;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.AddressInfo;
+
+/**
+ * 运费模板
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class FreightTemplate implements Serializable {
+
+ private static final long serialVersionUID = -7876281924385999053L;
+ /** 模板id */
+ @JsonProperty("template_id")
+ private String templateId;
+
+ /** 模板名称 */
+ @JsonProperty("name")
+ private String name;
+
+ /** 计费类型,PIECE:按件数,WEIGHT:按重量 */
+ @JsonProperty("valuation_type")
+ private String valuationType;
+
+ /** 发货时间期限 {@link me.chanjar.weixin.channel.enums.SendTime} */
+ @JsonProperty("send_time")
+ private String sendTime;
+
+ /** 发货地址 */
+ @JsonProperty("address_info")
+ private AddressInfo addressInfo;
+
+ /** 运输方式,EXPRESS:快递 */
+ @JsonProperty("delivery_type")
+ private String deliveryType;
+
+ /** 计费方式:FREE包邮 CONDITION_FREE条件包邮 NO_FREE不包邮 */
+ @JsonProperty("shipping_method")
+ private String shippingMethod;
+
+ /** 条件包邮详情 */
+ @JsonProperty("all_condition_free_detail")
+ private AllConditionFreeDetail allConditionFreeDetail;
+
+ /** 具体计费方法,默认运费,指定地区运费等 */
+ @JsonProperty("all_freight_calc_method")
+ private AllFreightCalcMethod allFreightCalcMethod;
+
+ /** 创建时间戳 */
+ @JsonProperty("create_time")
+ private Long createTime;
+
+ /** 更新时间戳 */
+ @JsonProperty("update_time")
+ private Long updateTime;
+
+ /** 是否默认模板 */
+ @JsonProperty("is_default")
+ private Boolean isDefault;
+
+ /** 不发货区域 */
+ @JsonProperty("not_send_area")
+ private NotSendArea notSendArea;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/NotSendArea.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/NotSendArea.java
new file mode 100644
index 0000000000..1c480fc227
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/NotSendArea.java
@@ -0,0 +1,18 @@
+package me.chanjar.weixin.channel.bean.freight;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 不发货区域
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class NotSendArea extends AddressInfoList {
+
+ private static final long serialVersionUID = -1836467830293286560L;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/TemplateAddParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/TemplateAddParam.java
new file mode 100644
index 0000000000..9c400533bf
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/TemplateAddParam.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.channel.bean.freight;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 运费模板 请求参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(Include.NON_NULL)
+public class TemplateAddParam implements Serializable {
+
+ private static final long serialVersionUID = 2602919369418149309L;
+ /** 起始位置 */
+ @JsonProperty("freight_template")
+ private FreightTemplate template;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/TemplateIdResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/TemplateIdResponse.java
new file mode 100644
index 0000000000..e895d066cb
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/TemplateIdResponse.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.freight;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 运费模板 列表 响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class TemplateIdResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 5179651364165620640L;
+ /** 运费模板id */
+ @JsonProperty("template_id")
+ private String templateId;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/TemplateInfoResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/TemplateInfoResponse.java
new file mode 100644
index 0000000000..f37e3dc2d1
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/TemplateInfoResponse.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.freight;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 运费模板 响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class TemplateInfoResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -8381510839783330617L;
+ /** 运费模板id */
+ @JsonProperty("freight_template")
+ private FreightTemplate template;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/TemplateListParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/TemplateListParam.java
new file mode 100644
index 0000000000..628d907eb1
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/TemplateListParam.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.freight;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import me.chanjar.weixin.channel.bean.base.OffsetParam;
+
+/**
+ * 运费模板 列表 请求参数
+ *
+ * @author Zeyes
+ */
+@Data
+@JsonInclude(Include.NON_NULL)
+@EqualsAndHashCode(callSuper = true)
+public class TemplateListParam extends OffsetParam {
+
+ private static final long serialVersionUID = -6716154891499581562L;
+
+ public TemplateListParam() {
+ }
+
+ public TemplateListParam(Integer offset, Integer limit) {
+ super(offset, limit);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/TemplateListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/TemplateListResponse.java
new file mode 100644
index 0000000000..a6fcd7d3e3
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/TemplateListResponse.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.freight;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 运费模板 列表 响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class TemplateListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 5375602442595264719L;
+ /** 运费模板 id 列表 */
+ @JsonProperty("template_id_list")
+ private List ids;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/AccountInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/AccountInfo.java
new file mode 100644
index 0000000000..f6248f96ba
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/AccountInfo.java
@@ -0,0 +1,53 @@
+package me.chanjar.weixin.channel.bean.fund;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 账户信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class AccountInfo implements Serializable {
+
+ private static final long serialVersionUID = -2107134853480093451L;
+ /** 账户类型 {@link me.chanjar.weixin.channel.enums.AccountType} */
+ @JsonProperty("bank_account_type")
+ private String bankAccountType;
+
+ /** 开户银行 */
+ @JsonProperty("account_bank")
+ private String accountBank;
+
+ /** 开户银行省市编码 */
+ @JsonProperty("bank_address_code")
+ private String bankAddressCode;
+
+ /** 开户银行联行号 */
+ @JsonProperty("bank_branch_id")
+ private String bankBranchId;
+
+ /** 开户银行全称 */
+ @JsonProperty("bank_name")
+ private String bankName;
+
+ /** 银行账号 */
+ @JsonProperty("account_number")
+ private String accountNumber;
+
+ /** 开户银行名称前端展示值 */
+ @JsonProperty("account_bank4show")
+ private String accountBank4show;
+
+ /** 账户名称 */
+ @JsonProperty("account_name")
+ private String accountName;
+
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/AccountInfoParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/AccountInfoParam.java
new file mode 100644
index 0000000000..ec6010bd07
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/AccountInfoParam.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.bean.fund;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 账户信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class AccountInfoParam implements Serializable {
+
+ private static final long serialVersionUID = 1689204583402779134L;
+ @JsonProperty("account_info")
+ private AccountInfo accountInfo;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/AccountInfoResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/AccountInfoResponse.java
new file mode 100644
index 0000000000..b54a34a2e7
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/AccountInfoResponse.java
@@ -0,0 +1,23 @@
+package me.chanjar.weixin.channel.bean.fund;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 账户信息响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class AccountInfoResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -8316068503468969533L;
+ /** 账户信息 */
+ @JsonProperty("account_info")
+ private AccountInfo accountInfo;
+
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/BalanceInfoResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/BalanceInfoResponse.java
new file mode 100644
index 0000000000..def7e86675
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/BalanceInfoResponse.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.fund;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 账户余额信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class BalanceInfoResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 4480496860612566921L;
+ /** 可提现余额 */
+ @JsonProperty("available_amount")
+ private Integer availableAmount;
+
+ /** 待结算余额 */
+ @JsonProperty("pending_amount")
+ private Integer pendingAmount;
+
+ /** 二级商户号 */
+ @JsonProperty("sub_mchid")
+ private String subMchid;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/FlowListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/FlowListResponse.java
new file mode 100644
index 0000000000..9306b4516a
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/FlowListResponse.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.fund;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 流水列表响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class FlowListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 8017827444308973489L;
+ /** 流水单号列表 */
+ @JsonProperty("flow_ids")
+ private List flowIds;
+
+ /** 是否还有下一页 */
+ @JsonProperty("has_more")
+ private boolean hasMore;
+
+ /** 分页参数,深翻页时使用 */
+ @JsonProperty("next_key")
+ private String nextKey;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/FlowRelatedInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/FlowRelatedInfo.java
new file mode 100644
index 0000000000..4edecbb3b1
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/FlowRelatedInfo.java
@@ -0,0 +1,45 @@
+package me.chanjar.weixin.channel.bean.fund;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 流水关联信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class FlowRelatedInfo implements Serializable {
+
+ private static final long serialVersionUID = 3757839018198212504L;
+ /** 关联类型, 1 订单, 2售后,3 提现,4 运费险 */
+ @JsonProperty("related_type")
+ private Integer relatedType;
+
+ /** 关联订单号 */
+ @JsonProperty("order_id")
+ private String orderId;
+
+ /** 关联售后单号 */
+ @JsonProperty("aftersale_id")
+ private String afterSaleId;
+
+ /** 关联提现单号 */
+ @JsonProperty("withdraw_id")
+ private String withdrawId;
+
+ /** 记账时间 */
+ @JsonProperty("bookkeeping_time")
+ private String bookkeepingTime;
+
+ /** 关联运费险单号 */
+ @JsonProperty("insurance_id")
+ private String insuranceId;
+
+ /** 关联支付单号 */
+ @JsonProperty("transaction_id")
+ private String transactionId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/FundsFlow.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/FundsFlow.java
new file mode 100644
index 0000000000..9b01e820fa
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/FundsFlow.java
@@ -0,0 +1,51 @@
+package me.chanjar.weixin.channel.bean.fund;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 资金流水
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class FundsFlow implements Serializable {
+
+ private static final long serialVersionUID = -2785498655066305510L;
+ /** 流水id */
+ @JsonProperty("flow_id")
+ private String flowId;
+
+ /** 资金类型,见 {@link me.chanjar.weixin.channel.enums.FundsType} */
+ @JsonProperty("funds_type")
+ private Integer fundsType;
+
+ /** 流水类型, 1 收入,2 支出 */
+ @JsonProperty("flow_type")
+ private Integer flowType;
+
+ /** 流水金额 */
+ @JsonProperty("amount")
+ private Integer amount;
+
+ /** 余额 */
+ @JsonProperty("balance")
+ private Integer balance;
+
+ /** 流水关联信息 */
+ @JsonProperty("related_info_list")
+ private List relatedInfos;
+
+ /** 记账时间 */
+ @JsonProperty("bookkeeping_time")
+ private String bookkeepingTime;
+
+ /** 备注 */
+ @JsonProperty("remark")
+ private String remark;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/FundsFlowResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/FundsFlowResponse.java
new file mode 100644
index 0000000000..7db351263f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/FundsFlowResponse.java
@@ -0,0 +1,23 @@
+package me.chanjar.weixin.channel.bean.fund;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 资金流水响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class FundsFlowResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -1130785908352355914L;
+ /** 流水信息 */
+ @JsonProperty("funds_flow")
+ private FundsFlow fundsFlow;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/FundsListParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/FundsListParam.java
new file mode 100644
index 0000000000..b5312e3a2a
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/FundsListParam.java
@@ -0,0 +1,49 @@
+package me.chanjar.weixin.channel.bean.fund;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 资金流水参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class FundsListParam implements Serializable {
+
+ private static final long serialVersionUID = 2998955690332382229L;
+ /** 页码,从1开始 */
+ @JsonProperty("page")
+ private Integer page;
+
+ /** 页数,不填默认为10 */
+ @JsonProperty("page_size")
+ protected Integer pageSize;
+
+ /** 流水产生的开始时间,uinx时间戳 */
+ @JsonProperty("start_time")
+ private Long startTime;
+
+ /** 流水产生的结束时间,unix时间戳 */
+ @JsonProperty("end_time")
+ private Long endTime;
+
+ /** 流水类型, 1 收入,2 支出 */
+ @JsonProperty("flow_type")
+ private Integer flowType;
+
+ /** 关联支付单号 */
+ @JsonProperty("transaction_id")
+ private String transactionId;
+
+ /**
+ * 分页参数,翻页时写入上一页返回的next_key(page为上一页加一, 并且page_size与上一页相同的时候才生效),page * page_size >= 10000时必填
+ */
+ @JsonProperty("next_key")
+ private String nextKey;
+
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/WithdrawDetailResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/WithdrawDetailResponse.java
new file mode 100644
index 0000000000..a1e726fb51
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/WithdrawDetailResponse.java
@@ -0,0 +1,55 @@
+package me.chanjar.weixin.channel.bean.fund;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 提现详情响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class WithdrawDetailResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 1473346677401168323L;
+ /** 金额 */
+ @JsonProperty("amount")
+ private Integer amount;
+
+ /** 创建时间 */
+ @JsonProperty("create_time")
+ private Long createTime;
+
+ /** 更新时间 */
+ @JsonProperty("update_time")
+ private Long updateTime;
+
+ /** 失败原因 */
+ @JsonProperty("reason")
+ private String reason;
+
+ /** 备注 */
+ @JsonProperty("remark")
+ private String remark;
+
+ /** 银行附言 */
+ @JsonProperty("bank_memo")
+ private String bankMemo;
+
+ /** 银行名称 */
+ @JsonProperty("bank_name")
+ private String bankName;
+
+ /** 银行账户 */
+ @JsonProperty("bank_num")
+ private String bankNum;
+
+ /** 提现状态 {@link me.chanjar.weixin.channel.enums.WithdrawStatus} */
+ @JsonProperty("status")
+ private String status;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/WithdrawListParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/WithdrawListParam.java
new file mode 100644
index 0000000000..a44b68567d
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/WithdrawListParam.java
@@ -0,0 +1,36 @@
+package me.chanjar.weixin.channel.bean.fund;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 提现列表参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class WithdrawListParam implements Serializable {
+
+ private static final long serialVersionUID = -672422656564313999L;
+ /** 页码,从1开始 */
+ @JsonProperty("page_num")
+ private Integer pageNum;
+
+ /** 页数 */
+ @JsonProperty("page_size")
+ private Integer pageSize;
+
+ /** 开始时间 */
+ @JsonProperty("start_time")
+ private Long startTime;
+
+ /** 结束时间 */
+ @JsonProperty("end_time")
+ private Long endTime;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/WithdrawListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/WithdrawListResponse.java
new file mode 100644
index 0000000000..b1dabc2a4b
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/WithdrawListResponse.java
@@ -0,0 +1,23 @@
+package me.chanjar.weixin.channel.bean.fund;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 提现列表响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class WithdrawListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -7950467108750325235L;
+ /** 提现单号列表 */
+ @JsonProperty("withdraw_ids")
+ private List withdrawIds;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/WithdrawSubmitParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/WithdrawSubmitParam.java
new file mode 100644
index 0000000000..65b8cdd12c
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/WithdrawSubmitParam.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.channel.bean.fund;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 提现提交参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class WithdrawSubmitParam implements Serializable {
+
+ private static final long serialVersionUID = 5801338663530567830L;
+ /** 提现金额(单位:分) */
+ @JsonProperty("amount")
+ private Integer amount;
+
+ /** 提现备注 */
+ @JsonProperty("remark")
+ private String remark;
+
+ /** 银行附言 */
+ @JsonProperty("bank_memo")
+ private String bankMemo;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/WithdrawSubmitResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/WithdrawSubmitResponse.java
new file mode 100644
index 0000000000..0002b158d2
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/WithdrawSubmitResponse.java
@@ -0,0 +1,23 @@
+package me.chanjar.weixin.channel.bean.fund;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 提现提交响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class WithdrawSubmitResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -8269579250564427758L;
+ /** 二维码ticket,可用于获取二维码和查询二维码状态 */
+ @JsonProperty("qrcode_ticket")
+ private String qrcodeTicket;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BankCityInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BankCityInfo.java
new file mode 100644
index 0000000000..04a69a8e87
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BankCityInfo.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.fund.bank;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 银行城市信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class BankCityInfo implements Serializable {
+
+ private static final long serialVersionUID = 374087891799491196L;
+ /** 城市名称 */
+ @JsonProperty("city_name")
+ private String cityName;
+
+ /** 城市编号 */
+ @JsonProperty("city_code")
+ private Integer cityCode;
+
+ /** 开户银行省市编码 */
+ @JsonProperty("bank_address_code")
+ private String bankAddressCode;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BankCityResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BankCityResponse.java
new file mode 100644
index 0000000000..5cb148c79b
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BankCityResponse.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.fund.bank;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 银行城市信息响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class BankCityResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -6212360101083304631L;
+ /** 银行城市信息列表 */
+ @JsonProperty("data")
+ private List data;
+
+ /** 总数 */
+ @JsonProperty("total_count")
+ private Integer totalCount;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BankInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BankInfo.java
new file mode 100644
index 0000000000..1bb58badb4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BankInfo.java
@@ -0,0 +1,46 @@
+package me.chanjar.weixin.channel.bean.fund.bank;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 银行信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class BankInfo implements Serializable {
+
+ private static final long serialVersionUID = -4837989875996346711L;
+ /** 开户银行 */
+ @JsonProperty("account_bank")
+ private String accountBank;
+
+ /** 银行编码 */
+ @JsonProperty("bank_code")
+ private String bankCode;
+
+ /** 银行联号 */
+ @JsonProperty("bank_id")
+ private String bankId;
+
+ /** 银行名称(不包括支行) */
+ @JsonProperty("bank_name")
+ private String bankName;
+
+ /** 银行类型(1.对公,2.对私) */
+ @JsonProperty("bank_type")
+ private Integer bankType;
+
+ /** 是否需要填写支行信息 */
+ @JsonProperty("need_branch")
+ private Boolean needBranch;
+
+ /** 支行联号 */
+ @JsonProperty("branch_id")
+ private String branchId;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BankInfoResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BankInfoResponse.java
new file mode 100644
index 0000000000..499d9fcbb5
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BankInfoResponse.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.fund.bank;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 银行信息响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class BankInfoResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 8583893898929290526L;
+ /** 银行信息列表 */
+ @JsonProperty("data")
+ private List data;
+
+ /** 总数 */
+ @JsonProperty("total_count")
+ private Integer totalCount;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BankListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BankListResponse.java
new file mode 100644
index 0000000000..9517859c42
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BankListResponse.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.fund.bank;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 银行信息响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class BankListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 7912035853286944260L;
+ /** 银行信息列表 */
+ @JsonProperty("data")
+ private List data;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BankProvinceInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BankProvinceInfo.java
new file mode 100644
index 0000000000..955a25e8ad
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BankProvinceInfo.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.bean.fund.bank;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 银行省份信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class BankProvinceInfo implements Serializable {
+
+ private static final long serialVersionUID = -3409931656361300144L;
+ /** 省份名称 */
+ @JsonProperty("province_name")
+ private String provinceName;
+
+ /** 省份编码 */
+ @JsonProperty("province_code")
+ private Integer provinceCode;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BankProvinceResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BankProvinceResponse.java
new file mode 100644
index 0000000000..f509d24304
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BankProvinceResponse.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.channel.bean.fund.bank;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 银行省份信息响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class BankProvinceResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -6187805847136359892L;
+ /** 银行省份信息列表 */
+ @JsonProperty("data")
+ private List data;
+
+ /** 总数 */
+ @JsonProperty("total_count")
+ private Integer totalCount;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BankSearchParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BankSearchParam.java
new file mode 100644
index 0000000000..abc9c1ec77
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BankSearchParam.java
@@ -0,0 +1,37 @@
+package me.chanjar.weixin.channel.bean.fund.bank;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 银行查询参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class BankSearchParam implements Serializable {
+
+ private static final long serialVersionUID = 6070269209439188188L;
+ /** 偏移量 */
+ @JsonProperty("offset")
+ private Integer offset;
+
+ /** 每页数据大小 */
+ @JsonProperty("limit")
+ private Integer limit;
+
+ /** 银行关键字 */
+ @JsonProperty("key_words")
+ private String keyWords;
+
+ /** 银行类型(1:对私银行,2:对公银行; 默认对公) */
+ @JsonProperty("bank_type")
+ private Integer bankType;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BranchInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BranchInfo.java
new file mode 100644
index 0000000000..c4cec9bc76
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BranchInfo.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.bean.fund.bank;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 分店信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class BranchInfo implements Serializable {
+
+ private static final long serialVersionUID = -2744729367131146892L;
+ /** 支行联号 */
+ @JsonProperty("branch_id")
+ private Integer branchId;
+
+ /** 银行全称(含支行) */
+ @JsonProperty("branch_name")
+ private String branchName;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BranchInfoResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BranchInfoResponse.java
new file mode 100644
index 0000000000..c7cfda4646
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BranchInfoResponse.java
@@ -0,0 +1,49 @@
+package me.chanjar.weixin.channel.bean.fund.bank;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 支行信息响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class BranchInfoResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -1419832502854175767L;
+ /** 总数 */
+ @JsonProperty("total_count")
+ private Integer totalCount;
+
+ /** 当前分页数量 */
+ @JsonProperty("count")
+ private Integer count;
+
+ /** 银行名称 */
+ @JsonProperty("account_bank")
+ private String accountBank;
+
+ /** 银行编码 */
+ @JsonProperty("account_bank_code")
+ private String accountBankCode;
+
+ /** 银行别名 */
+ @JsonProperty("bank_alias")
+ private String bankAlias;
+
+ /** 银行别名编码 */
+ @JsonProperty("bank_alias_code")
+ private String bankAliasCode;
+
+ /** 支行信息列表 */
+ @JsonProperty("data")
+ private List data;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BranchSearchParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BranchSearchParam.java
new file mode 100644
index 0000000000..47527efe1e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/bank/BranchSearchParam.java
@@ -0,0 +1,35 @@
+package me.chanjar.weixin.channel.bean.fund.bank;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 银行支行信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class BranchSearchParam implements Serializable {
+
+ private static final long serialVersionUID = -8800316690160248833L;
+ /** 银行编码,通过查询银行信息或者搜索银行信息获取 */
+ @JsonProperty("bank_code")
+ private String bankCode;
+
+ /** 城市编号,通过查询城市列表获取 */
+ @JsonProperty("city_code")
+ private String cityCode;
+
+ /** 偏移量 */
+ @JsonProperty("offset")
+ private Integer offset;
+
+ /** 限制个数 */
+ @JsonProperty("limit")
+ private Integer limit;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/qrcode/QrCheckResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/qrcode/QrCheckResponse.java
new file mode 100644
index 0000000000..e1a52ab9a3
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/qrcode/QrCheckResponse.java
@@ -0,0 +1,36 @@
+package me.chanjar.weixin.channel.bean.fund.qrcode;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 二维码校验响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class QrCheckResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -3860756719827268969L;
+ /** 扫码状态 {@link me.chanjar.weixin.channel.enums.QrCheckStatus} */
+ @JsonProperty("status")
+ private Integer status;
+
+ /** 业务返回错误码 */
+ @JsonProperty("self_check_err_code")
+ private Integer selfCheckErrCode;
+
+ /** 业务返回错误信息 */
+ @JsonProperty("self_check_err_msg")
+ private String selfCheckErrMsg;
+
+ /** 扫码者身份 0非管理员 1管理员 2次管理员 */
+ @JsonProperty("scan_user_type")
+ private Integer scanUserType;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/qrcode/QrCodeResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/qrcode/QrCodeResponse.java
new file mode 100644
index 0000000000..d6c015c0cd
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/fund/qrcode/QrCodeResponse.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.fund.qrcode;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 二维码响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class QrCodeResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 4521008628337929496L;
+ /** 二维码(base64编码二进制,需要base64解码) */
+ @JsonProperty("qrcode_buf")
+ private String qrcodeBuf;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/image/ChannelImageInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/image/ChannelImageInfo.java
new file mode 100644
index 0000000000..3e12c7e830
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/image/ChannelImageInfo.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.image;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 微信图片信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class ChannelImageInfo implements Serializable {
+
+ private static final long serialVersionUID = 8883519290965944530L;
+
+ /** 开放平台media_id */
+ @JsonProperty("media_id")
+ private String mediaId;
+
+ /** 图片链接,有访问频率限制 */
+ @JsonProperty("img_url")
+ private String url;
+
+ /** 微信支付media_id */
+ @JsonProperty("pay_media_id")
+ private String payMediaId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/image/ChannelImageResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/image/ChannelImageResponse.java
new file mode 100644
index 0000000000..903af375af
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/image/ChannelImageResponse.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.channel.bean.image;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import java.io.File;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class ChannelImageResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -4163511427507976489L;
+
+ @JsonIgnore
+ private File file;
+
+ private String contentType;
+
+ public ChannelImageResponse() {
+ }
+
+ public ChannelImageResponse(File file, String contentType) {
+ this.errCode = SUCCESS_CODE;
+ this.errMsg = "ok";
+ this.file = file;
+ this.contentType = contentType;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/image/QualificationFileId.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/image/QualificationFileId.java
new file mode 100644
index 0000000000..905720a8dc
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/image/QualificationFileId.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.image;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 资质文件id
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class QualificationFileId implements Serializable {
+
+ private static final long serialVersionUID = -546135264746778249L;
+
+ /** 文件id */
+ @JsonProperty("file_id")
+ private String id;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/image/QualificationFileResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/image/QualificationFileResponse.java
new file mode 100644
index 0000000000..5a4332885c
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/image/QualificationFileResponse.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.image;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 资质文件id响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class QualificationFileResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 5172377567441096813L;
+
+ /** 文件数据 */
+ @JsonProperty("data")
+ private QualificationFileId data;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/image/UploadImageResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/image/UploadImageResponse.java
new file mode 100644
index 0000000000..f1625bd3c4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/image/UploadImageResponse.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.image;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 微信图片信息响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class UploadImageResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -609315696774437877L;
+
+ /** 图片信息 */
+ @JsonProperty("pic_file")
+ private ChannelImageInfo imgInfo;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/AddressInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/AddressInfo.java
new file mode 100644
index 0000000000..1ffb01677c
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/AddressInfo.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.channel.bean.league;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 地址信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class AddressInfo implements Serializable {
+
+ private static final long serialVersionUID = -5719456688033731919L;
+ /** 邮编 */
+ @JsonProperty("postal_code")
+ private String postalCode;
+
+ /** 国标收货地址第一级地址 */
+ @JsonProperty("province_name")
+ private String provinceName;
+
+ /** 国标收货地址第二级地址 */
+ @JsonProperty("city_name")
+ private String cityName;
+
+ /** 国标收货地址第三级地址 */
+ @JsonProperty("county_name")
+ private String countyName;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/CatInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/CatInfo.java
new file mode 100644
index 0000000000..4fc2cfc95b
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/CatInfo.java
@@ -0,0 +1,22 @@
+package me.chanjar.weixin.channel.bean.league;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商品分类信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class CatInfo implements Serializable {
+
+ private static final long serialVersionUID = 8449223922139383888L;
+ /** 类目id */
+ @JsonProperty("cat_id")
+ private String catId;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/DescInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/DescInfo.java
new file mode 100644
index 0000000000..a29b07a294
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/DescInfo.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.channel.bean.league;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商详信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class DescInfo implements Serializable {
+
+ private static final long serialVersionUID = 5319244341160446531L;
+ /** 商品详情图片(最多20张)。如果添加时没录入,回包可能不包含该字段 */
+ @JsonProperty("imgs")
+ private List imgs;
+
+ /** 商品详情文字。如果添加时没录入,回包可能不包含该字 */
+ @JsonProperty("desc")
+ private String desc;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/ExpressInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/ExpressInfo.java
new file mode 100644
index 0000000000..6fbecac866
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/ExpressInfo.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.league;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 物流信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class ExpressInfo implements Serializable {
+
+ private static final long serialVersionUID = -4604691645808459334L;
+ /** 发货时间期限 */
+ @JsonProperty("send_time")
+ private String sendTime;
+
+ /** 发货地址 */
+ @JsonProperty("address_info")
+ private AddressInfo addressInfo;
+
+ /** 计费方式:FREE:包邮CONDITION_FREE:条件包邮NO_FREE:不包邮 */
+ @JsonProperty("shipping_method")
+ private String shippingMethod;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/SimpleProductInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/SimpleProductInfo.java
new file mode 100644
index 0000000000..9de16b849e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/SimpleProductInfo.java
@@ -0,0 +1,39 @@
+package me.chanjar.weixin.channel.bean.league;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商品信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class SimpleProductInfo implements Serializable {
+
+ private static final long serialVersionUID = -2444641123422095497L;
+ /** 标题 */
+ @JsonProperty("title")
+ protected String title;
+
+ /** 副标题 */
+ @JsonProperty("sub_title")
+ protected String subTitle;
+
+ /** 主图,多张,列表,最多9张,每张不超过2MB */
+ @JsonProperty("head_imgs")
+ protected List headImgs;
+
+ /** 商详信息 */
+ @JsonProperty("desc_info")
+ protected DescInfo descInfo;
+
+ /** 类目信息 */
+ @JsonProperty("cats")
+ protected List cats;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/BatchAddParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/BatchAddParam.java
new file mode 100644
index 0000000000..c22563359a
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/BatchAddParam.java
@@ -0,0 +1,63 @@
+package me.chanjar.weixin.channel.bean.league.product;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 批量添加商品参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class BatchAddParam implements Serializable {
+
+ private static final long serialVersionUID = -87989229725625901L;
+ /** 商品推广类别 */
+ @JsonProperty("type")
+ private Integer type;
+
+ /** 商品列表 */
+ @JsonProperty("list")
+ private List list;
+
+ /** 推广达人列表 */
+ @JsonProperty("finder_ids")
+ private List finderIds;
+
+ /** 推广开始时间戳 */
+ @JsonProperty("begin_time")
+ private Long beginTime;
+
+ /** 推广结束时间戳 */
+ @JsonProperty("end_time")
+ private Long endTime;
+
+ /** 是否永久推广 */
+ @JsonProperty("is_forerver")
+ private Boolean forever;
+
+
+ @Data
+ @NoArgsConstructor
+ @AllArgsConstructor
+ @JsonInclude(JsonInclude.Include.NON_NULL)
+ public static class Product implements Serializable {
+
+ private static final long serialVersionUID = 9025105293896488093L;
+ /** 商品id,不可重复数量不超过20 */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** 推广佣金[0, 90]% */
+ @JsonProperty("ratio")
+ private Integer ratio;
+
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/BatchAddResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/BatchAddResponse.java
new file mode 100644
index 0000000000..7a2f4f6840
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/BatchAddResponse.java
@@ -0,0 +1,44 @@
+package me.chanjar.weixin.channel.bean.league.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 批量添加商品响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class BatchAddResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 2686612709939873527L;
+ /** 商品id信息 */
+ @JsonProperty("result_info_list")
+ private List resultInfoList;
+
+
+ @Data
+ @NoArgsConstructor
+ @EqualsAndHashCode(callSuper = true)
+ public static class ResultInfo extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -534890760974302155L;
+ /** 商品id */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** 特殊推广商品计划id */
+ @JsonProperty("info_id")
+ private String infoId;
+
+ /** 推广失败达人列表 */
+ @JsonProperty("fail_finder_ids")
+ private List failFinderIds;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/ProductDeleteParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/ProductDeleteParam.java
new file mode 100644
index 0000000000..ccdf3ef0b4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/ProductDeleteParam.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.channel.bean.league.product;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商品删除请求
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ProductDeleteParam implements Serializable {
+
+ private static final long serialVersionUID = 9129737170370664633L;
+ /** 获取商品推广类别 */
+ @JsonProperty("type")
+ private Integer type;
+
+ /** 商品id type为普通推广商品时必填 */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** 特殊推广商品计划id type为特殊推广商品时必填 */
+ @JsonProperty("info_id")
+ private String infoId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/ProductDetailParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/ProductDetailParam.java
new file mode 100644
index 0000000000..7b2c6ae6f7
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/ProductDetailParam.java
@@ -0,0 +1,48 @@
+package me.chanjar.weixin.channel.bean.league.product;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商品详情请求
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ProductDetailParam implements Serializable {
+
+ private static final long serialVersionUID = 7624234965127527565L;
+ /** 获取商品推广类别 */
+ @JsonProperty("type")
+ private Integer type;
+
+ /** 商品id type为普通推广商品时必填 */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** 特殊推广商品计划id type为特殊推广商品时必填 */
+ @JsonProperty("info_id")
+ private String infoId;
+
+ /** 是否获取特殊推广商品绑定的达人列表, type为特殊推广商品时有效 */
+ @JsonProperty("need_relation")
+ private Boolean needRelation;
+
+ /** 拉取达人数 need_relation为真时必填 不超过50 */
+ @JsonProperty("page_size")
+ private Integer pageSize;
+
+ /** need_relation为真时有效,页面下标,下标从1开始,默认为1 */
+ @JsonProperty("page_index")
+ private Integer pageIndex;
+
+ /** need_relation为真时有效,是否需要返回该计划绑定达人总数 */
+ @JsonProperty("need_total_num")
+ private Boolean needTotalNum;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/ProductDetailResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/ProductDetailResponse.java
new file mode 100644
index 0000000000..05ea00c055
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/ProductDetailResponse.java
@@ -0,0 +1,96 @@
+package me.chanjar.weixin.channel.bean.league.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 商品详情响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class ProductDetailResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 5306524707144232861L;
+ /** 推广商品信息 */
+ @JsonProperty("item")
+ private Item item;
+
+
+ @Data
+ @NoArgsConstructor
+ public static class Item implements Serializable {
+
+ private static final long serialVersionUID = 9112142704638318861L;
+ /** 商品id */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** 商品推广类别 1普通推广商品 2定向推广商品 3专属推广商品 */
+ @JsonProperty("type")
+ private Integer type;
+
+ /** 商品推广状态 1已上架推广 2已下架推广 4已删除 5未达到准入标准 10待生效 */
+ @JsonProperty("status")
+ private Integer status;
+
+ /** 推广佣金[0, 90]% */
+ @JsonProperty("ratio")
+ private Integer ratio;
+
+ /** 特殊推广信息 */
+ @JsonProperty("exclusive_info")
+ private ExclusiveInfo exclusiveInfo;
+
+ /** 扩展信息 */
+ @JsonProperty("ext_info")
+ private ExtInfo extInfo;
+ }
+
+ @Data
+ @NoArgsConstructor
+ public static class ExclusiveInfo implements Serializable {
+
+ private static final long serialVersionUID = 6583124869090013797L;
+ /** 特殊推广商品计划id */
+ @JsonProperty("info_id")
+ private String infoId;
+
+ /** 推广开始时间戳 */
+ @JsonProperty("begin_time")
+ private Long beginTime;
+
+ /** 推广结束时间戳 */
+ @JsonProperty("end_time")
+ private Long endTime;
+
+ /** 是否永久推广 */
+ @JsonProperty("is_forerver")
+ private Boolean forever;
+
+ /** 推广达人视频号列表 */
+ @JsonProperty("finder_ids")
+ private List finderIds;
+
+ }
+
+ @Data
+ @NoArgsConstructor
+ public static class ExtInfo implements Serializable {
+
+ /** 是否类目禁售 */
+ @JsonProperty("is_sale_forbidden")
+ private Boolean saleForbidden;
+
+ /** 是否被官方封禁 */
+ @JsonProperty("is_banned")
+ private Boolean banned;
+
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/ProductListParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/ProductListParam.java
new file mode 100644
index 0000000000..18d52c82d6
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/ProductListParam.java
@@ -0,0 +1,47 @@
+package me.chanjar.weixin.channel.bean.league.product;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商品列表请求
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ProductListParam implements Serializable {
+
+ private static final long serialVersionUID = -1914139382459786057L;
+ /** 商品推广类别 */
+ @JsonProperty("type")
+ private Integer type;
+
+ /** 单页商品数(不超过100) */
+ @JsonProperty("page_size")
+ private Integer pageSize;
+
+ /** 页面下标,下标从1开始,默认为1 */
+ @JsonProperty("page_index")
+ private Integer pageIndex;
+
+ /** 商品id,拉取特殊推广商品时有效 */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** 视频号id,拉取特殊推广商品时有效 */
+ @JsonProperty("finder_id")
+ private String finderId;
+
+ /** 由上次请求返回,顺序翻页时需要传入, 会从上次返回的结果往后翻一页(填了该值后page_index不生效) */
+ @JsonProperty("last_buffer")
+ private String lastBuffer;
+
+ /** 是否需要返回满足筛选条件的商品总数(填last_buffer后该值无效) */
+ @JsonProperty("need_total_num")
+ private Boolean needTotalNum;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/ProductListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/ProductListResponse.java
new file mode 100644
index 0000000000..642884ce63
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/ProductListResponse.java
@@ -0,0 +1,52 @@
+package me.chanjar.weixin.channel.bean.league.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 商品更新响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class ProductListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -6192518391380515045L;
+ /** 商品列表 */
+ @JsonProperty("items")
+ private List- items;
+
+ /** 本次翻页的上下文,用于顺序翻页请求 */
+ @JsonProperty("last_buffer")
+ private String lastBuffer;
+
+ /** 商品总数 */
+ @JsonProperty("total_num")
+ private Integer totalNum;
+
+ /** 是否还有剩余商品 */
+ @JsonProperty("has_more")
+ private Boolean hasMore;
+
+ @Data
+ @NoArgsConstructor
+ public static class Item implements Serializable {
+
+ private static final long serialVersionUID = 5094378518992196239L;
+ /** 商品id */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** 特殊推广商品计划id */
+ @JsonProperty("info_id")
+ private String infoId;
+
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/ProductUpdateParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/ProductUpdateParam.java
new file mode 100644
index 0000000000..8188911519
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/ProductUpdateParam.java
@@ -0,0 +1,72 @@
+package me.chanjar.weixin.channel.bean.league.product;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商品更新请求
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ProductUpdateParam implements Serializable {
+
+ private static final long serialVersionUID = -3519313269193693460L;
+ /** 获取商品推广类别 */
+ @JsonProperty("type")
+ private Integer type;
+
+ /** 商品id type为普通推广商品时必填 */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** 特殊推广商品计划id type为特殊推广商品时必填 */
+ @JsonProperty("info_id")
+ private String infoId;
+
+ /** 更新操作类别 */
+ @JsonProperty("operate_type")
+ private Integer operateType;
+
+ /** 推广佣金[0, 90]% */
+ @JsonProperty("ratio")
+ private Integer ratio;
+
+ /** 特殊推广信息 */
+ @JsonProperty("exclusive_info")
+ private ExclusiveInfo exclusiveInfo;
+
+
+ /** 特殊推广信息 */
+ @Data
+ @NoArgsConstructor
+ public static class ExclusiveInfo implements Serializable {
+
+ private static final long serialVersionUID = -8120260214345369170L;
+ /** 推广开始时间戳 */
+ @JsonProperty("begin_time")
+ private Long beginTime;
+
+ /** 推广结束时间戳 */
+ @JsonProperty("end_time")
+ private Long endTime;
+
+ /** 是否永久推广 */
+ @JsonProperty("is_forerver")
+ private Boolean forever;
+
+ /** 新增推广达人视频号列表,不超过30个 */
+ @JsonProperty("add_finder_ids")
+ private List addFinderIds;
+
+ /** 删除推广达人视频号列表,不超过30个 */
+ @JsonProperty("del_finder_ids")
+ private List delFinderIds;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/ProductUpdateResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/ProductUpdateResponse.java
new file mode 100644
index 0000000000..7dae90569e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/product/ProductUpdateResponse.java
@@ -0,0 +1,23 @@
+package me.chanjar.weixin.channel.bean.league.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 商品更新响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class ProductUpdateResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 2144233059960259829L;
+ /** 特殊推广商品计划id */
+ @JsonProperty("info_id")
+ private String infoId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/promoter/PromoterInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/promoter/PromoterInfo.java
new file mode 100644
index 0000000000..7f817c6633
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/promoter/PromoterInfo.java
@@ -0,0 +1,37 @@
+package me.chanjar.weixin.channel.bean.league.promoter;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 达人
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class PromoterInfo implements Serializable {
+
+ private static final long serialVersionUID = -8851711325343107780L;
+ /** 视频号finder_id */
+ @JsonProperty("finder_id")
+ private String finderId;
+
+ /** 合作状态 0初始值 1邀请中 2达人已接受邀请 3达人已拒绝邀请 4已取消邀请 5已取消合作 10已删除 */
+ @JsonProperty("status")
+ private Integer status;
+
+ /** 达人邀请秒级时间戳 */
+ @JsonProperty("invite_time")
+ private Long inviteTime;
+
+ /** 累计合作商品数 */
+ @JsonProperty("sale_product_number")
+ private Integer saleProductNumber;
+
+ /** 合作动销GMV */
+ @JsonProperty("sale_gmv")
+ private Integer saleGmv;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/promoter/PromoterInfoResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/promoter/PromoterInfoResponse.java
new file mode 100644
index 0000000000..bebe6a6fcc
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/promoter/PromoterInfoResponse.java
@@ -0,0 +1,23 @@
+package me.chanjar.weixin.channel.bean.league.promoter;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 达人信息响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class PromoterInfoResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 6475158486029216487L;
+ /** 达人信息 */
+ @JsonProperty("promoter")
+ private PromoterInfo promoter;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/promoter/PromoterListParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/promoter/PromoterListParam.java
new file mode 100644
index 0000000000..128797bda8
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/promoter/PromoterListParam.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.league.promoter;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 达人列表请求
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class PromoterListParam implements Serializable {
+
+ private static final long serialVersionUID = -6179472484874537538L;
+ /** 页面下标,下标从1开始,默认为1 */
+ @JsonProperty("page_index")
+ protected Integer pageIndex;
+
+ /** 页面下标,下标从1开始,默认为1 */
+ @JsonProperty("page_size")
+ protected Integer pageSize;
+
+ /** 拉取该状态下的达人列表 */
+ private Integer status;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/promoter/PromoterListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/promoter/PromoterListResponse.java
new file mode 100644
index 0000000000..c193550369
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/promoter/PromoterListResponse.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.league.promoter;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 达人列表响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class PromoterListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 1411870432999885996L;
+ /** 达人finder_id列表 */
+ @JsonProperty("finder_ids")
+ private List finderIds;
+
+ /** 达人总数 */
+ @JsonProperty("total_num")
+ private Integer totalNum;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/BizBaseInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/BizBaseInfo.java
new file mode 100644
index 0000000000..39b77daa32
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/BizBaseInfo.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.league.supplier;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 小店基础信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class BizBaseInfo implements Serializable {
+
+ private static final long serialVersionUID = 3713638025924977002L;
+ /** 小店appid */
+ @JsonProperty("appid")
+ private String appid;
+
+ /** 小店头像 */
+ @JsonProperty("headimg_url")
+ private String headimgUrl;
+
+ /** 小店昵称 */
+ @JsonProperty("nickname")
+ private String nickname;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/CommissionInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/CommissionInfo.java
new file mode 100644
index 0000000000..356a058684
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/CommissionInfo.java
@@ -0,0 +1,41 @@
+package me.chanjar.weixin.channel.bean.league.supplier;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 跟佣信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class CommissionInfo implements Serializable {
+
+ private static final long serialVersionUID = 3027131215096984236L;
+ /** 商品带货状态 1已上架推广 2已下架推广 5已清退 */
+ @JsonProperty("status")
+ private Integer status;
+
+ /** 服务费率[0, 1000000] */
+ @JsonProperty("service_ratio")
+ private Integer serviceRatio;
+
+ /** 佣金费率[0, 1000000] */
+ @JsonProperty("ratio")
+ private Integer ratio;
+
+ /** unix时间戳,合作开始时间 */
+ @JsonProperty("start_time")
+ private Long startTime;
+
+ /** unix时间戳,合作结束时间 */
+ @JsonProperty("end_time")
+ private Long endTime;
+
+ /** 带货链接 */
+ @JsonProperty("link")
+ private String link;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/CommissionOrderListParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/CommissionOrderListParam.java
new file mode 100644
index 0000000000..2f8d27f52e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/CommissionOrderListParam.java
@@ -0,0 +1,53 @@
+package me.chanjar.weixin.channel.bean.league.supplier;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.TimeRange;
+
+/**
+ * 佣金单列表请求参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class CommissionOrderListParam implements Serializable {
+
+ private static final long serialVersionUID = 2805783646567362357L;
+ /** 佣金单所属小店appid */
+ @JsonProperty("appid")
+ private String appid;
+
+ /** 视频号finder_id */
+ @JsonProperty("finder_id")
+ private String finderId;
+
+ /** 视频号openfinderid */
+ @JsonProperty("openfinderid")
+ private String openfinderid;
+
+ /** 佣金单创建时间范围 */
+ @JsonProperty("create_time_range")
+ private TimeRange createTimeRange;
+
+ /** 佣金单更新时间范围 */
+ @JsonProperty("update_time_range")
+ private TimeRange updateTimeRange;
+
+ /** 订单ID,填此参数后其他过滤参数无效 */
+ @JsonProperty("order_id")
+ private String orderId;
+
+ /** 单页佣金单数(不超过30) */
+ @JsonProperty("page_size")
+ private Integer pageSize;
+
+ /** 由上次请求返回,顺序翻页时需要传入, 会从上次返回的结果往后翻一页 */
+ @JsonProperty("next_key")
+ private String nextKey;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/CommissionOrderListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/CommissionOrderListResponse.java
new file mode 100644
index 0000000000..6d7e1be4f8
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/CommissionOrderListResponse.java
@@ -0,0 +1,50 @@
+package me.chanjar.weixin.channel.bean.league.supplier;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+
+/**
+ * 团长订单列表响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class CommissionOrderListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 1143184321517598592L;
+ /** 商品id信息 */
+ @JsonProperty("list")
+ private List list;
+
+ /** 本次翻页的上下文,用于顺序翻页请求 */
+ @JsonProperty("next_key")
+ private String nextKey;
+
+ /** 是否还有剩余商品 */
+ @JsonProperty("has_more")
+ private Boolean hasMore;
+
+
+ @Data
+ @NoArgsConstructor
+ public static class ProductIdInfo implements Serializable {
+
+ private static final long serialVersionUID = -691189837681217282L;
+ /** 商品id */
+ @JsonProperty("order_id")
+ private String orderId;
+
+ /** skuid */
+ @JsonProperty("sku_id")
+ private String skuId;
+
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/CommissionOrderResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/CommissionOrderResponse.java
new file mode 100644
index 0000000000..d8c84e1473
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/CommissionOrderResponse.java
@@ -0,0 +1,174 @@
+package me.chanjar.weixin.channel.bean.league.supplier;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 佣金订单响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class CommissionOrderResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 7004553990771819977L;
+ /** 佣金单 */
+ @JsonProperty("commssion_order")
+ private CommissionOrder commissionOrder;
+
+
+ /** 佣金单 */
+ @Data
+ @NoArgsConstructor
+ public static class CommissionOrder implements Serializable {
+
+ private static final long serialVersionUID = 735931726521944716L;
+ /** 订单号 */
+ @JsonProperty("order_id")
+ private String orderId;
+
+ /** 商品skuid */
+ @JsonProperty("sku_id")
+ private String skuId;
+
+ /** 秒级时间戳 */
+ @JsonProperty("create_time")
+ private Long createTime;
+
+ /** 秒级时间戳 */
+ @JsonProperty("update_time")
+ private Long updateTime;
+
+ /** 佣金单状态,见{@link me.chanjar.weixin.channel.enums.CommissionOrderStatus} */
+ @JsonProperty("status")
+ private Integer status;
+
+ /** 订单详情 */
+ @JsonProperty("order_detail")
+ private OrderDetail orderDetail;
+ }
+
+ /** 订单详情 */
+ @Data
+ @NoArgsConstructor
+ public static class OrderDetail implements Serializable {
+
+ private static final long serialVersionUID = 8349635368396073000L;
+ /** 小店商家信息 */
+ @JsonProperty("shop_info")
+ private BizInfo shopInfo;
+
+ /** 佣金单商品信息 */
+ @JsonProperty("product_info")
+ private ProductInfo productInfo;
+
+ /** 订单信息 */
+ @JsonProperty("order_info")
+ private OrderInfo orderInfo;
+
+ /** 分佣信息 */
+ @JsonProperty("commission_info")
+ private CommissionInfo commissionInfo;
+
+ }
+
+ /** 小店商家信息 */
+ @Data
+ @NoArgsConstructor
+ public static class BizInfo implements Serializable {
+
+ private static final long serialVersionUID = -8229584987720782974L;
+ /** 所属小店appid */
+ @JsonProperty("appid")
+ private String appid;
+
+ }
+
+ /** 佣金单商品信息 */
+ @Data
+ @NoArgsConstructor
+ public static class ProductInfo implements Serializable {
+
+ private static final long serialVersionUID = -2790410903073956864L;
+ /** 商品id */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** sku小图 */
+ @JsonProperty("thumb_img")
+ private String thumbImg;
+
+ /** 可分佣金额 */
+ @JsonProperty("actual_payment")
+ private Integer actualPayment;
+
+ /** 商品标题 */
+ @JsonProperty("title")
+ private String title;
+
+ }
+
+ /** 订单信息 */
+ @Data
+ @NoArgsConstructor
+ public static class OrderInfo implements Serializable {
+
+ private static final long serialVersionUID = 7610425518539999170L;
+ /** 订单状态,枚举值见OrderStatus */
+ @JsonProperty("order_status")
+ private Integer status;
+
+ }
+
+ /** 分佣信息 */
+ @Data
+ @NoArgsConstructor
+ public static class CommissionInfo implements Serializable {
+
+ private static final long serialVersionUID = -2114290318872427720L;
+ /** 带货达人信息 */
+ @JsonProperty("finder_info")
+ private FinderInfo finderInfo;
+
+ /** 服务费率[0, 1000000] */
+ @JsonProperty("service_ratio")
+ private Integer serviceRatio;
+
+ /** 服务费金额 */
+ @JsonProperty("service_amount")
+ private Integer serviceAmount;
+
+ /** 服务费结算时间 */
+ @JsonProperty("profit_sharding_suc_time")
+ private Long profitShardingSucTime;
+
+ }
+
+ /** 带货达人信息 */
+ @Data
+ @NoArgsConstructor
+ public static class FinderInfo implements Serializable {
+
+ private static final long serialVersionUID = 7383486670949864257L;
+ /** 达人昵称 */
+ @JsonProperty("nickname")
+ private String nickname;
+
+ /** 佣金率[0, 1000000] */
+ @JsonProperty("ratio")
+ private Integer ratio;
+ /** 佣金 */
+ @JsonProperty("amount")
+ private Integer amount;
+
+ /** 视频号openfinderid */
+ @JsonProperty("openfinderid")
+ private String openfinderid;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/CoopProductDetailParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/CoopProductDetailParam.java
new file mode 100644
index 0000000000..494e86f999
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/CoopProductDetailParam.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.league.supplier;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 合作商品详情请求
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class CoopProductDetailParam implements Serializable {
+
+ private static final long serialVersionUID = 3515221514742929207L;
+ /** 商品id */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** 团长商品 所属小店appid */
+ @JsonProperty("appid")
+ private String appId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/CoopProductListParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/CoopProductListParam.java
new file mode 100644
index 0000000000..81743b51f2
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/CoopProductListParam.java
@@ -0,0 +1,34 @@
+package me.chanjar.weixin.channel.bean.league.supplier;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 合作商品详情请求
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class CoopProductListParam implements Serializable {
+
+ private static final long serialVersionUID = -9023029707828535352L;
+ /** 团长商品 所属小店appid */
+ @JsonProperty("appid")
+ private String appid;
+
+ /** 单页商品数(不超过30) */
+ @JsonProperty("page_size")
+ private Integer pageSize;
+
+ /** 由上次请求返回,顺序翻页时需要传入, 会从上次返回的结果往后翻一页 */
+ @JsonProperty("next_key")
+ private String nextKey;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/CoopProductListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/CoopProductListResponse.java
new file mode 100644
index 0000000000..39bf2bb96e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/CoopProductListResponse.java
@@ -0,0 +1,49 @@
+package me.chanjar.weixin.channel.bean.league.supplier;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 团长商品列表响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class CoopProductListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -5440144076389135839L;
+ /** 商品id信息 */
+ @JsonProperty("list")
+ private List list;
+
+ /** 本次翻页的上下文,用于顺序翻页请求 */
+ @JsonProperty("next_key")
+ private String nextKey;
+
+ /** 是否还有剩余商品 */
+ @JsonProperty("has_more")
+ private Boolean hasMore;
+
+
+ @Data
+ @NoArgsConstructor
+ public static class ProductIdInfo implements Serializable {
+
+ private static final long serialVersionUID = -7136011408769169462L;
+ /** 商品id */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** 所属小店appid */
+ @JsonProperty("appid")
+ private String appid;
+
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/CoopProductResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/CoopProductResponse.java
new file mode 100644
index 0000000000..eee78937b2
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/CoopProductResponse.java
@@ -0,0 +1,47 @@
+package me.chanjar.weixin.channel.bean.league.supplier;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 合作商品详情响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class CoopProductResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -4066427847985394479L;
+ /** 商品信息 */
+ @JsonProperty("item")
+ private Item item;
+
+
+ @Data
+ @NoArgsConstructor
+ public static class Item implements Serializable {
+
+ private static final long serialVersionUID = 6123572874440025928L;
+ /** 所属小店appid */
+ @JsonProperty("appid")
+ private String appid;
+
+ /** 商品id */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** 商品信息 */
+ @JsonProperty("product_info")
+ private ProductInfo productInfo;
+
+ /** 跟佣信息 */
+ @JsonProperty("commission_info")
+ private CommissionInfo commissionInfo;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/FlowListParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/FlowListParam.java
new file mode 100644
index 0000000000..99d2bf107f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/FlowListParam.java
@@ -0,0 +1,43 @@
+package me.chanjar.weixin.channel.bean.league.supplier;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 团长流水列表请求参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class FlowListParam implements Serializable {
+
+ private static final long serialVersionUID = 3128695806885851134L;
+ /** 页码,从1开始 */
+ @JsonProperty("page")
+ private Integer page;
+
+ /** 页数,不填默认为10 */
+ @JsonProperty("page_size")
+ private Integer pageSize;
+
+ /** 资金类型, 见 {@link me.chanjar.weixin.channel.enums.FundsType} */
+ @JsonProperty("funds_type")
+ private Integer fundsType;
+
+ /** 流水产生的开始时间,uinx时间戳 */
+ @JsonProperty("start_time")
+ private Long startTime;
+
+ /** 流水产生的结束时间,unix时间戳 */
+ @JsonProperty("end_time")
+ private Long endTime;
+
+ /** 分页参数,翻页时写入上一页返回的next_key(page为上一页加一,并且page_size与上一页相同的时候才生效),page * page_size >= 5000时必填 */
+ @JsonProperty("next_key")
+ private String nextKey;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/FundsFlowInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/FundsFlowInfo.java
new file mode 100644
index 0000000000..089c7048d5
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/FundsFlowInfo.java
@@ -0,0 +1,51 @@
+package me.chanjar.weixin.channel.bean.league.supplier;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+
+/**
+ * 团长资金流水详情
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class FundsFlowInfo implements Serializable {
+
+ private static final long serialVersionUID = 102705878551490327L;
+ /** 流水id */
+ @JsonProperty("flow_id")
+ private String flowId;
+
+ /** 资金类型, 1提现 2分账 */
+ @JsonProperty("funds_type")
+ private Integer fundsType;
+
+ /** 流水金额 单位:分 */
+ @JsonProperty("amount")
+ private Integer amount;
+
+ /** 余额 单位:分 */
+ @JsonProperty("balance")
+ private Integer balance;
+
+ /** 记账时间 */
+ @JsonProperty("bookkeeping_time")
+ private String bookkeepingTime;
+
+ /** 备注 */
+ @JsonProperty("remark")
+ private String remark;
+
+ /** 关联订单号 */
+ @JsonProperty("order_id")
+ private String orderId;
+
+ /** 关联提现单号 */
+ @JsonProperty("withdraw_id")
+ private String withdrawId;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/ProductInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/ProductInfo.java
new file mode 100644
index 0000000000..0c2dcae7a6
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/ProductInfo.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.league.supplier;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.league.ExpressInfo;
+import me.chanjar.weixin.channel.bean.league.SimpleProductInfo;
+
+/**
+ * 商品信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class ProductInfo extends SimpleProductInfo {
+
+ private static final long serialVersionUID = 5352334936089828219L;
+ /** 快递信息 */
+ @JsonProperty("express_info")
+ private ExpressInfo expressInfo;
+
+ /** sku信息 */
+ @JsonProperty("skus")
+ private List skus;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/ShopDetailResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/ShopDetailResponse.java
new file mode 100644
index 0000000000..14eaacb567
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/ShopDetailResponse.java
@@ -0,0 +1,89 @@
+package me.chanjar.weixin.channel.bean.league.supplier;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 合作小店详情响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class ShopDetailResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 188954608418544735L;
+ /** 小店详情 */
+ @JsonProperty("shop_detail")
+ private ShopDetail shopDetail;
+
+ /** 本次翻页的上下文,用于顺序翻页请求 */
+ @JsonProperty("next_key")
+ private String nextKey;
+
+ /** 是否还有剩余小店 */
+ @JsonProperty("has_more")
+ private Boolean hasMore;
+
+ /** 小店详情 */
+ @Data
+ @NoArgsConstructor
+ public static class ShopDetail implements Serializable {
+
+ private static final long serialVersionUID = -3454074422563804378L;
+ /** 小店基础信息 */
+ @JsonProperty("base_info")
+ private BizBaseInfo baseInfo;
+
+ /** 小店数据信息 */
+ @JsonProperty("data_info")
+ private ShopDataInfo dataInfo;
+
+ /** 合作状态Status 1邀请中 2已接受邀请 3已拒绝邀请 4取消邀请 5取消合作 */
+ @JsonProperty("status")
+ private Integer status;
+
+ /** 开始合作时间戳 */
+ @JsonProperty("approved_time")
+ private Long approvedTime;
+
+ }
+
+
+ /** 小店数据信息 */
+ @Data
+ @NoArgsConstructor
+ public static class ShopDataInfo implements Serializable {
+
+ private static final long serialVersionUID = 6603460255046252283L;
+ /** 合作动销GMV,单位:分 */
+ @JsonProperty("gmv")
+ private Integer gmv;
+
+ /** 历史合作商品数 */
+ @JsonProperty("product_number")
+ private Integer productNumber;
+
+ /** 已结算服务费,单位:分 */
+ @JsonProperty("settle_amount")
+ private Integer settleAmount;
+
+ /** 预计待结算服务费,单位:分 */
+ @JsonProperty("unsettle_amount")
+ private Integer unsettleAmount;
+
+ /** 今日新增合作商品数 */
+ @JsonProperty("product_number_today")
+ private Integer productNumberToday;
+
+ /** 今日动销商品数 */
+ @JsonProperty("product_number_sold_today")
+ private Integer productNumberSoldToday;
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/ShopListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/ShopListResponse.java
new file mode 100644
index 0000000000..1c7de7c4a7
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/ShopListResponse.java
@@ -0,0 +1,50 @@
+package me.chanjar.weixin.channel.bean.league.supplier;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 合作小店列表响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class ShopListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 1736467471867767456L;
+ /** 小店详情 */
+ @JsonProperty("shop_list")
+ private List shopList;
+
+ /** 本次翻页的上下文,用于顺序翻页请求 */
+ @JsonProperty("next_key")
+ private String nextKey;
+
+ /** 是否还有剩余小店 */
+ @JsonProperty("has_more")
+ private Boolean hasMore;
+
+ /** 小店详情 */
+ @Data
+ @NoArgsConstructor
+ public static class ShopDetail implements Serializable {
+
+ private static final long serialVersionUID = 8421286426372052694L;
+ /** 小店基础信息 */
+ @JsonProperty("base_info")
+ private BizBaseInfo baseInfo;
+
+ /** 小店状态 */
+ @JsonProperty("status")
+ private Integer status;
+ }
+
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/SkuInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/SkuInfo.java
new file mode 100644
index 0000000000..6c51910d47
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/SkuInfo.java
@@ -0,0 +1,40 @@
+package me.chanjar.weixin.channel.bean.league.supplier;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.AttrInfo;
+
+
+/**
+ * SkuInfo
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class SkuInfo implements Serializable {
+
+ private static final long serialVersionUID = 197261426211990640L;
+ /** skuID */
+ @JsonProperty("sku_id")
+ private String skuId;
+
+ /** sku小图。如果添加时没录入,回包可能不包含该字段 */
+ @JsonProperty("thumb_img")
+ private String thumbImg;
+
+ /** 售卖价格,以分为单位 */
+ @JsonProperty("sale_price")
+ private Integer salePrice;
+
+ /** sku库存 */
+ @JsonProperty("stock_num")
+ private Integer stockNum;
+
+ /** sku属性 */
+ @JsonProperty("sku_attrs")
+ private List skuAttrs;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/SupplierBalanceResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/SupplierBalanceResponse.java
new file mode 100644
index 0000000000..eaa45027da
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/SupplierBalanceResponse.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.league.supplier;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 团长余额响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class SupplierBalanceResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 5584817726976222436L;
+ /** 可提现余额 */
+ @JsonProperty("available_amount")
+ private Integer availableAmount;
+
+ /** 待结算余额 */
+ @JsonProperty("pending_amount")
+ private Integer pendingAmount;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/SupplierFlowDetailResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/SupplierFlowDetailResponse.java
new file mode 100644
index 0000000000..5ab0745fab
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/SupplierFlowDetailResponse.java
@@ -0,0 +1,23 @@
+package me.chanjar.weixin.channel.bean.league.supplier;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 团长流水明细响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class SupplierFlowDetailResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -3962482396458765234L;
+ /** 流水信息 */
+ @JsonProperty("funds_flow")
+ private FundsFlowInfo fundsFlow;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/SupplierFlowListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/SupplierFlowListResponse.java
new file mode 100644
index 0000000000..9178346d2f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/SupplierFlowListResponse.java
@@ -0,0 +1,31 @@
+package me.chanjar.weixin.channel.bean.league.supplier;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 资金流水列表 响应
+ *
+ * @author LiXiZe
+ * @date 2023-04-16
+ */
+@Data
+@NoArgsConstructor
+public class SupplierFlowListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -2954427554226407544L;
+ /** 流水单号列表 */
+ @JsonProperty("funds_flow_ids")
+ private List ids;
+
+ /** 是否还有下一页 */
+ @JsonProperty("has_more")
+ private Boolean hasMore;
+
+ /** 分页参数,深翻页时使用 */
+ @JsonProperty("next_key")
+ private String nextKey;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/window/AuthInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/window/AuthInfo.java
new file mode 100644
index 0000000000..22facd7a84
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/window/AuthInfo.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.channel.bean.league.window;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 授权信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class AuthInfo implements Serializable {
+
+ private static final long serialVersionUID = 6265034296219892453L;
+ /** 授权链接 */
+ @JsonProperty("auth_url")
+ private String authUrl;
+
+ /** 授权路径 */
+ @JsonProperty("auth_wxa_path")
+ private String authWxaPath;
+
+ /** appid */
+ @JsonProperty("auth_wxa_appid")
+ private String authWxaAppid;
+
+ /** 小程序name */
+ @JsonProperty("auth_wxa_username")
+ private String authWxaUsername;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/window/AuthInfoResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/window/AuthInfoResponse.java
new file mode 100644
index 0000000000..941762aecd
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/window/AuthInfoResponse.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.league.window;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 授权信息响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class AuthInfoResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 8336998502585278489L;
+ /** 授权链接信息 */
+ @JsonProperty("auth_info")
+ private AuthInfo authInfo;
+
+ /** 视频号openfinderid */
+ @JsonProperty("openfinderid")
+ private String openfinderid;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/window/AuthStatusResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/window/AuthStatusResponse.java
new file mode 100644
index 0000000000..b42bb0d179
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/window/AuthStatusResponse.java
@@ -0,0 +1,22 @@
+package me.chanjar.weixin.channel.bean.league.window;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 授权状态响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class AuthStatusResponse extends WxChannelBaseResponse {
+
+ /** 是否授权,0: 未授权, 1: 已授权 */
+ @JsonProperty("window_auth_status")
+ private Integer windowAuthStatus;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/window/ProductSearchParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/window/ProductSearchParam.java
new file mode 100644
index 0000000000..e43d450c6d
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/window/ProductSearchParam.java
@@ -0,0 +1,40 @@
+package me.chanjar.weixin.channel.bean.league.window;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 团长商品搜索参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ProductSearchParam implements Serializable {
+
+ private static final long serialVersionUID = -4771046746777827382L;
+ /** 团长appid */
+ @JsonProperty("appid")
+ private String appid;
+
+ /** 视频号openfinderid */
+ @JsonProperty("openfinderid")
+ private String openfinderid;
+
+ /** 起始位置(从0开始) */
+ @JsonProperty("offset")
+ private Integer offset;
+
+ /** page_size(默认100, 最大500) */
+ @JsonProperty("page_size")
+ private Integer pageSize;
+
+ /** 默认为false */
+ @JsonProperty("need_total_num")
+ private Boolean needTotalNum;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/window/WindowProductListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/window/WindowProductListResponse.java
new file mode 100644
index 0000000000..60b5a4a44d
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/window/WindowProductListResponse.java
@@ -0,0 +1,56 @@
+package me.chanjar.weixin.channel.bean.league.window;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 商品列表响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class WindowProductListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -1160519267422259848L;
+ /** 商品概要列表 */
+ @JsonProperty("list")
+ private List list;
+
+ /** 下一页的位置 */
+ @JsonProperty("next_offset")
+ private Integer nextOffset;
+
+ /** 后面是否还有商品 */
+ @JsonProperty("have_more")
+ private Boolean haveMore;
+
+ /** 商品总数 */
+ @JsonProperty("total_num")
+ private Integer totalNum;
+
+ /** 商品概要列表 */
+ @Data
+ @NoArgsConstructor
+ public static class ItemKey implements Serializable {
+
+ /** 团长appid */
+ @JsonProperty("appid")
+ private String appid;
+
+ /** 团长商品ID */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** 团长ID */
+ @JsonProperty("head_supplier_id")
+ private String headSupplierId;
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/window/WindowProductParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/window/WindowProductParam.java
new file mode 100644
index 0000000000..c0e062fd2a
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/window/WindowProductParam.java
@@ -0,0 +1,34 @@
+package me.chanjar.weixin.channel.bean.league.window;
+
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 团长商品
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class WindowProductParam implements Serializable {
+
+ private static final long serialVersionUID = 363738166094927337L;
+ /** 团长appid */
+ @JsonProperty("appid")
+ private String appid;
+
+ /** 视频号openfinderid */
+ @JsonProperty("openfinderid")
+ private String openfinderid;
+
+ /** 团长商品ID */
+ @JsonProperty("product_id")
+ private String productId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/window/WindowProductResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/window/WindowProductResponse.java
new file mode 100644
index 0000000000..071e0b2350
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/window/WindowProductResponse.java
@@ -0,0 +1,49 @@
+package me.chanjar.weixin.channel.bean.league.window;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.league.SimpleProductInfo;
+
+/**
+ * 商品详情响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class WindowProductResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -4671578350314241014L;
+ /** 商品详情 */
+ @JsonProperty("product_detail")
+ private ProductDetail productDetail;
+
+
+ /**
+ * 商品详情
+ */
+ @Data
+ @NoArgsConstructor
+ public static class ProductDetail implements Serializable {
+
+ private static final long serialVersionUID = -6574563870972328273L;
+ /** 所属小店appid */
+ @JsonProperty("appid")
+ private String appid;
+
+ /** 商品id */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** 商品信息 */
+ @JsonProperty("product_info")
+ private SimpleProductInfo productInfo;
+
+
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitSku.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitSku.java
new file mode 100644
index 0000000000..29ffbf921e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitSku.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.limit;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class LimitSku implements Serializable {
+
+ private static final long serialVersionUID = -1819737633227427482L;
+
+ /** 参与抢购的商品 ID 下,不同规格(SKU)的商品信息 */
+ @JsonProperty("sku_id")
+ private String skuId;
+
+ /** SKU的抢购价格,必须小于原价(原价为1分钱的商品无法创建抢购任务) */
+ @JsonProperty("sale_price")
+ private Integer salePrice;
+
+ /** 参与抢购的商品库存,必须小于等于现有库存 */
+ @JsonProperty("sale_stock")
+ private Integer saleStock;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitTaskAddResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitTaskAddResponse.java
new file mode 100644
index 0000000000..35ea00d68d
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitTaskAddResponse.java
@@ -0,0 +1,23 @@
+package me.chanjar.weixin.channel.bean.limit;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class LimitTaskAddResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -4742165348862157618L;
+
+ /** 限时抢购任务ID 创建成功后返回 */
+ @JsonProperty("task_id")
+ private String taskId;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitTaskInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitTaskInfo.java
new file mode 100644
index 0000000000..aefc4b8136
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitTaskInfo.java
@@ -0,0 +1,45 @@
+package me.chanjar.weixin.channel.bean.limit;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class LimitTaskInfo implements Serializable {
+
+ private static final long serialVersionUID = 3032226931637189351L;
+
+ /** 限时抢购任务ID */
+ @JsonProperty("task_id")
+ private String taskId;
+
+ /** 抢购商品ID */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** 限时抢购任务状态 */
+ @JsonProperty("status")
+ private Integer status;
+
+ /** 限时抢购任务创建时间(秒级时间戳) */
+ @JsonProperty("create_time")
+ private Long createTime;
+
+ /** 限时抢购任务开始时间(秒级时间戳) */
+ @JsonProperty("start_time")
+ private Long startTime;
+
+ /** 限时抢购任务结束时间(秒级时间戳) */
+ @JsonProperty("end_time")
+ private Long endTime;
+
+ /** sku列表 */
+ @JsonProperty("limited_discount_skus")
+ private List skus;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitTaskListParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitTaskListParam.java
new file mode 100644
index 0000000000..d608c8231e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitTaskListParam.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.limit;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import me.chanjar.weixin.channel.bean.base.StreamPageParam;
+
+/**
+ * @author Zeyes
+ */
+@Data
+public class LimitTaskListParam extends StreamPageParam {
+
+ private static final long serialVersionUID = -7227161890365102302L;
+
+
+ /** 抢购活动状态 */
+ @JsonProperty("status")
+ private Integer status;
+
+ public LimitTaskListParam() {
+ }
+
+ public LimitTaskListParam(Integer pageSize, String nextKey, Integer status) {
+ this.pageSize = pageSize;
+ this.nextKey = nextKey;
+ this.status = status;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitTaskListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitTaskListResponse.java
new file mode 100644
index 0000000000..688fd158dc
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitTaskListResponse.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.channel.bean.limit;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class LimitTaskListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 3604657299385130217L;
+
+
+ /** 限时抢购任务 */
+ @JsonProperty("limited_discount_tasks")
+ private List tasks;
+
+ /** 本次翻页的上下文,用于请求下一页 */
+ @JsonProperty("next_key")
+ private String nextKey;
+
+ /** 商品总数 */
+ @JsonProperty("total_num")
+ private Integer totalNum;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitTaskParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitTaskParam.java
new file mode 100644
index 0000000000..b89c072944
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitTaskParam.java
@@ -0,0 +1,36 @@
+package me.chanjar.weixin.channel.bean.limit;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class LimitTaskParam implements Serializable {
+
+ private static final long serialVersionUID = 3885409806249022528L;
+
+ /** 抢购商品ID */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** 限时抢购任务开始时间(秒级时间戳) */
+ @JsonProperty("start_time")
+ private Date startTime;
+
+ /** 限时抢购任务结束时间(秒级时间戳) */
+ @JsonProperty("end_time")
+ private Date endTime;
+
+ /** sku列表 */
+ @JsonProperty("limited_discount_skus")
+ private List skus;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/SessionMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/SessionMessage.java
new file mode 100644
index 0000000000..9b97cbf09d
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/SessionMessage.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.message;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * 会话消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class SessionMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = -429381568555605309L;
+
+ @JsonProperty("SessionFrom")
+ @JacksonXmlProperty(localName = "SessionFrom")
+ private String from;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/after/AfterSaleMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/after/AfterSaleMessage.java
new file mode 100644
index 0000000000..52beec7932
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/after/AfterSaleMessage.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.message.after;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * 售后消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class AfterSaleMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = -7263404451639198126L;
+ /** 状态信息 */
+ @JsonProperty("finder_shop_aftersale_status_update")
+ @JacksonXmlProperty(localName = "finder_shop_aftersale_status_update")
+ private AfterSaleStatusInfo info;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/after/AfterSaleStatusInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/after/AfterSaleStatusInfo.java
new file mode 100644
index 0000000000..06fd349da8
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/after/AfterSaleStatusInfo.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.channel.bean.message.after;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 售后信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class AfterSaleStatusInfo implements Serializable {
+
+ private static final long serialVersionUID = -7309656340583314591L;
+ /** 售后单号 */
+ @JsonProperty("after_sale_order_id")
+ @JacksonXmlProperty(localName = "after_sale_order_id")
+ private String afterSaleOrderId;
+
+ /** 售后单状态 */
+ @JsonProperty("status")
+ @JacksonXmlProperty(localName = "status")
+ private String status;
+
+ /** 订单id */
+ @JsonProperty("order_id")
+ @JacksonXmlProperty(localName = "order_id")
+ private String orderId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/after/ComplaintInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/after/ComplaintInfo.java
new file mode 100644
index 0000000000..adb0b7b392
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/after/ComplaintInfo.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.channel.bean.message.after;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 纠纷信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class ComplaintInfo implements Serializable {
+
+ private static final long serialVersionUID = 3988395560953978239L;
+ /** 纠纷单号 */
+ @JsonProperty("complaint_id")
+ @JacksonXmlProperty(localName = "complaint_id")
+ private String complaintId;
+
+ /** 小店售后单号 */
+ @JsonProperty("after_sale_order_id")
+ @JacksonXmlProperty(localName = "after_sale_order_id")
+ private String afterSaleOrderId;
+
+ /** 纠纷单状态 */
+ @JsonProperty("status")
+ @JacksonXmlProperty(localName = "status")
+ private Integer status;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/after/ComplaintMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/after/ComplaintMessage.java
new file mode 100644
index 0000000000..e10a9b365a
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/after/ComplaintMessage.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.message.after;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * 纠纷消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class ComplaintMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = 5358093415172409157L;
+ /** 状态信息 */
+ @JsonProperty("finder_shop_complaint")
+ @JacksonXmlProperty(localName = "finder_shop_complaint")
+ private ComplaintInfo info;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/coupon/CouponActionInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/coupon/CouponActionInfo.java
new file mode 100644
index 0000000000..f7a55ce0fb
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/coupon/CouponActionInfo.java
@@ -0,0 +1,48 @@
+package me.chanjar.weixin.channel.bean.message.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 优惠券操作消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class CouponActionInfo implements Serializable {
+
+ private static final long serialVersionUID = -4456716511656569552L;
+ /** 优惠券ID */
+ @JsonProperty("coupon_id")
+ @JacksonXmlProperty(localName = "coupon_id")
+ private String couponId;
+
+ /** 领券时间 */
+ @JsonProperty("create_time")
+ @JacksonXmlProperty(localName = "create_time")
+ private String createTime;
+
+ /** 删除时间 */
+ @JsonProperty("delete_time")
+ @JacksonXmlProperty(localName = "delete_time")
+ private String deleteTime;
+
+ /** 过期时间 */
+ @JsonProperty("expire_time")
+ @JacksonXmlProperty(localName = "expire_time")
+ private String expireTime;
+
+ /** 更新时间 */
+ @JsonProperty("change_time")
+ @JacksonXmlProperty(localName = "change_time")
+ private String changeTime;
+
+ /** 作废时间 */
+ @JsonProperty("invalid_time")
+ @JacksonXmlProperty(localName = "invalid_time")
+ private String invalidTime;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/coupon/CouponActionMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/coupon/CouponActionMessage.java
new file mode 100644
index 0000000000..7433b7a6c2
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/coupon/CouponActionMessage.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.message.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+
+/**
+ * 卡券操作 消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class CouponActionMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = 4910461800721504462L;
+ /** 优惠券信息 */
+ @JsonProperty("coupon_info")
+ @JacksonXmlProperty(localName = "coupon_info")
+ private CouponActionInfo couponInfo;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/coupon/CouponReceiveMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/coupon/CouponReceiveMessage.java
new file mode 100644
index 0000000000..448d815a58
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/coupon/CouponReceiveMessage.java
@@ -0,0 +1,60 @@
+package me.chanjar.weixin.channel.bean.message.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import java.util.Map;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+
+/**
+ * 用户领券 消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class CouponReceiveMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = 5121347165246528730L;
+ /** 领取的优惠券ID */
+ @JsonProperty("coupon_id")
+ @JacksonXmlProperty(localName = "coupon_id")
+ private String couponId;
+
+ /** 生成的用户券ID */
+ @JsonProperty("user_coupon_id")
+ @JacksonXmlProperty(localName = "user_coupon_id")
+ private String userCouponId;
+
+ /** 领券时间 */
+ @JsonProperty("receive_time")
+ @JacksonXmlProperty(localName = "receive_time")
+ private String receiveTime;
+
+ @JsonProperty("receive_info")
+ @JacksonXmlProperty(localName = "receive_info")
+ private void unpackNameFromNestedObject(Map map) {
+ if (map == null) {
+ return;
+ }
+ Object obj = null;
+ obj = map.get("coupon_id");
+ if (obj != null) {
+ this.couponId = (obj instanceof String ? (String) obj : String.valueOf(obj));
+ }
+ obj = map.get("user_coupon_id");
+ if (obj != null) {
+ this.userCouponId = (obj instanceof String ? (String) obj : String.valueOf(obj));
+ }
+ obj = map.get("receive_time");
+ if (obj != null) {
+ this.receiveTime = (obj instanceof String ? (String) obj : String.valueOf(obj));
+ }
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/coupon/UserCouponActionInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/coupon/UserCouponActionInfo.java
new file mode 100644
index 0000000000..1356c47fca
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/coupon/UserCouponActionInfo.java
@@ -0,0 +1,45 @@
+package me.chanjar.weixin.channel.bean.message.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 用户优惠券操作消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class UserCouponActionInfo implements Serializable {
+
+ private static final long serialVersionUID = -5948836918972669529L;
+ /** 优惠券ID */
+ @JsonProperty("coupon_id")
+ @JacksonXmlProperty(localName = "coupon_id")
+ private String couponId;
+
+ /** 用户券ID */
+ @JsonProperty("user_coupon_id")
+ @JacksonXmlProperty(localName = "user_coupon_id")
+ private String userCouponId;
+
+ /** 过期时间 */
+ @JsonProperty("expire_time")
+ @JacksonXmlProperty(localName = "expire_time")
+ private String expireTime;
+
+ /** 使用时间 */
+ @JsonProperty("use_time")
+ @JacksonXmlProperty(localName = "use_time")
+ private String useTime;
+
+ /** 返还时间 */
+ @JsonProperty("unuse_time")
+ @JacksonXmlProperty(localName = "unuse_time")
+ private String unuseTime;
+
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/coupon/UserCouponExpireMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/coupon/UserCouponExpireMessage.java
new file mode 100644
index 0000000000..26370e5142
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/coupon/UserCouponExpireMessage.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.message.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+
+/**
+ * 用户卡券过期 消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class UserCouponExpireMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = -2557475297107588372L;
+ /** 用户优惠券信息 */
+ @JsonProperty("user_coupon_info")
+ @JacksonXmlProperty(localName = "user_coupon_info")
+ private UserCouponActionInfo userCouponInfo;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/coupon/UserCouponUseMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/coupon/UserCouponUseMessage.java
new file mode 100644
index 0000000000..7b436743c3
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/coupon/UserCouponUseMessage.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.message.coupon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+
+/**
+ * 用户卡券使用 消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class UserCouponUseMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = -1051142666438578628L;
+ /** 用户优惠券信息 */
+ @JsonProperty("user_info")
+ @JacksonXmlProperty(localName = "user_info")
+ private UserCouponActionInfo userCouponInfo;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/fund/AccountNotifyMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/fund/AccountNotifyMessage.java
new file mode 100644
index 0000000000..b5a02ac834
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/fund/AccountNotifyMessage.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.message.fund;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * 账户变更通知 消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class AccountNotifyMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = 3846692537729725664L;
+ /** 账户信息 */
+ @JsonProperty("account_info")
+ @JacksonXmlProperty(localName = "account_info")
+ private BankNotifyInfo accountInfo;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/fund/BankNotifyInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/fund/BankNotifyInfo.java
new file mode 100644
index 0000000000..44ef398f8b
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/fund/BankNotifyInfo.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.message.fund;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 账户信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class BankNotifyInfo implements Serializable {
+
+ private static final long serialVersionUID = 4192569196686180014L;
+ /** 结算账户变更事件, 1.修改结算账户 */
+ @JsonProperty("event")
+ @JacksonXmlProperty(localName = "event")
+ private Integer event;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/fund/QrNotifyInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/fund/QrNotifyInfo.java
new file mode 100644
index 0000000000..83b466f07e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/fund/QrNotifyInfo.java
@@ -0,0 +1,34 @@
+package me.chanjar.weixin.channel.bean.message.fund;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 提现二维码回调 消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class QrNotifyInfo implements Serializable {
+
+ private static final long serialVersionUID = 2470016408300157273L;
+ /** 二维码ticket */
+ @JsonProperty("ticket")
+ @JacksonXmlProperty(localName = "ticket")
+ private String ticket;
+
+ /** 二维码状态,1.已确认 2.已取消 3.已失效 4.已扫码 */
+ @JsonProperty("status")
+ @JacksonXmlProperty(localName = "status")
+ private Integer status;
+
+ /** 扫码者身份, 0.非管理员 1.管理员 */
+ @JsonProperty("scan_user_type")
+ @JacksonXmlProperty(localName = "scan_user_type")
+ private Integer scanUserType;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/fund/QrNotifyMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/fund/QrNotifyMessage.java
new file mode 100644
index 0000000000..56e906a641
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/fund/QrNotifyMessage.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.message.fund;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * 提现二维码回调 消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class QrNotifyMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = -4705790895359679423L;
+ /** 账户信息 */
+ @JsonProperty("qrcode_info")
+ @JacksonXmlProperty(localName = "qrcode_info")
+ private QrNotifyInfo qrcodeInfo;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/fund/WithdrawNotifyInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/fund/WithdrawNotifyInfo.java
new file mode 100644
index 0000000000..810f40c95c
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/fund/WithdrawNotifyInfo.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.message.fund;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 提现通知信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class WithdrawNotifyInfo implements Serializable {
+
+ private static final long serialVersionUID = 2987401114254821956L;
+ /** 1.发起提现,生成二维码 2.扫码验证成功,申请提现 3.提现成功 4.提现失败 */
+ @JsonProperty("event")
+ @JacksonXmlProperty(localName = "event")
+ private Integer event;
+
+ /** 提现单号 */
+ @JsonProperty("withdraw_id")
+ @JacksonXmlProperty(localName = "withdraw_id")
+ private String withdrawId;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/fund/WithdrawNotifyMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/fund/WithdrawNotifyMessage.java
new file mode 100644
index 0000000000..ff45e73ec6
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/fund/WithdrawNotifyMessage.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.message.fund;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * 账户变更通知 消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class WithdrawNotifyMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = -2504086242143523430L;
+ /** 账户信息 */
+ @JsonProperty("withdraw_info")
+ @JacksonXmlProperty(localName = "withdraw_info")
+ private WithdrawNotifyInfo withdrawInfo;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderCancelInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderCancelInfo.java
new file mode 100644
index 0000000000..8ff3ead54e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderCancelInfo.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.message.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 订单取消信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class OrderCancelInfo extends OrderIdInfo {
+
+ private static final long serialVersionUID = -8022876997578127873L;
+ /** 1:用户取消;2:超时取消;3:全部商品售后完成,订单取消;4:超卖商家取消订单 */
+ @JsonProperty("cancel_type")
+ @JacksonXmlProperty(localName = "cancel_type")
+ private Integer cancelType;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderCancelMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderCancelMessage.java
new file mode 100644
index 0000000000..8e6b33c2ee
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderCancelMessage.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.message.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * 订单取消消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class OrderCancelMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = 5389546516473919310L;
+ /** 订单信息 */
+ @JsonProperty("order_info")
+ @JacksonXmlProperty(localName = "order_info")
+ private OrderCancelInfo orderInfo;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderConfirmInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderConfirmInfo.java
new file mode 100644
index 0000000000..bd212092a5
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderConfirmInfo.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.message.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 订单确认收货信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class OrderConfirmInfo extends OrderIdInfo {
+
+ private static final long serialVersionUID = -2569494642832261346L;
+ /** 1:用户确认收货;2:超时自动确认收货 */
+ @JsonProperty("confirm_type")
+ @JacksonXmlProperty(localName = "confirm_type")
+ private Integer confirmType;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderConfirmMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderConfirmMessage.java
new file mode 100644
index 0000000000..dda35041b2
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderConfirmMessage.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.message.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * 订单确认收货消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class OrderConfirmMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = 4219477394934480425L;
+ /** 订单信息 */
+ @JsonProperty("order_info")
+ @JacksonXmlProperty(localName = "order_info")
+ private OrderConfirmInfo orderInfo;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderDeliveryInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderDeliveryInfo.java
new file mode 100644
index 0000000000..ca3d26736a
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderDeliveryInfo.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.bean.message.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 订单发货信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class OrderDeliveryInfo extends OrderIdInfo {
+
+ private static final long serialVersionUID = 117962754344887556L;
+ /** 0:尚未全部发货;1:全部商品发货完成 */
+ @JsonProperty("finish_delivery")
+ @JacksonXmlProperty(localName = "finish_delivery")
+ private Integer finishDelivery;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderDeliveryMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderDeliveryMessage.java
new file mode 100644
index 0000000000..25d79e2c4d
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderDeliveryMessage.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.message.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * 订单发货消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class OrderDeliveryMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = -1440834047566984402L;
+ /** 订单信息 */
+ @JsonProperty("order_info")
+ @JacksonXmlProperty(localName = "order_info")
+ private OrderDeliveryInfo orderInfo;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderExtInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderExtInfo.java
new file mode 100644
index 0000000000..b4986f35c4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderExtInfo.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.message.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 订单其他信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class OrderExtInfo extends OrderIdInfo {
+
+ private static final long serialVersionUID = 4723533858047219828L;
+ /** 类型 1:联盟佣金信息 */
+ @JsonProperty("type")
+ @JacksonXmlProperty(localName = "type")
+ private Integer type;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderExtMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderExtMessage.java
new file mode 100644
index 0000000000..c5ede6c6bd
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderExtMessage.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.message.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * 订单状态消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class OrderExtMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = -3183077256476798756L;
+ /** 订单信息 */
+ @JsonProperty("order_info")
+ @JacksonXmlProperty(localName = "order_info")
+ private OrderExtInfo orderInfo;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderIdInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderIdInfo.java
new file mode 100644
index 0000000000..b9ac33b376
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderIdInfo.java
@@ -0,0 +1,23 @@
+package me.chanjar.weixin.channel.bean.message.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 订单id信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class OrderIdInfo implements Serializable {
+
+ private static final long serialVersionUID = 5547544436235032051L;
+ /** 订单ID */
+ @JsonProperty("order_id")
+ @JacksonXmlProperty(localName = "order_id")
+ private String orderId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderIdMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderIdMessage.java
new file mode 100644
index 0000000000..398c29bde4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderIdMessage.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.message.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * 订单id消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class OrderIdMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = 3793987364799712798L;
+ /** 订单信息 */
+ @JsonProperty("order_info")
+ @JacksonXmlProperty(localName = "order_info")
+ private OrderIdInfo orderInfo;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderPayInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderPayInfo.java
new file mode 100644
index 0000000000..d916c14a21
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderPayInfo.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.message.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 订单支付信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class OrderPayInfo extends OrderIdInfo {
+
+ private static final long serialVersionUID = -3502786073769735831L;
+ /** 支付时间,秒级时间戳 */
+ @JsonProperty("pay_time")
+ @JacksonXmlProperty(localName = "pay_time")
+ private Long payTime;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderPayMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderPayMessage.java
new file mode 100644
index 0000000000..ee1f458aba
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderPayMessage.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.message.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * 订单支付成功消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class OrderPayMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = 1083018549119427808L;
+ /** 订单信息 */
+ @JsonProperty("order_info")
+ @JacksonXmlProperty(localName = "order_info")
+ private OrderPayInfo orderInfo;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderSettleInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderSettleInfo.java
new file mode 100644
index 0000000000..b4f48b6fb8
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderSettleInfo.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.message.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 订单结算信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class OrderSettleInfo extends OrderIdInfo {
+
+ private static final long serialVersionUID = -1817955568383872053L;
+ /** 结算时间 */
+ @JsonProperty("settle_time")
+ @JacksonXmlProperty(localName = "settle_time")
+ private Long settleTime;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderSettleMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderSettleMessage.java
new file mode 100644
index 0000000000..2d3d1d96d6
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderSettleMessage.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.message.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * 订单结算消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class OrderSettleMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = -4001189226630840548L;
+ /** 订单信息 */
+ @JsonProperty("order_info")
+ @JacksonXmlProperty(localName = "order_info")
+ private OrderSettleInfo orderInfo;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderStatusMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderStatusMessage.java
new file mode 100644
index 0000000000..554c127b3b
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/order/OrderStatusMessage.java
@@ -0,0 +1,54 @@
+package me.chanjar.weixin.channel.bean.message.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import java.util.Map;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * 订单状态消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class OrderStatusMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = -356717038344749283L;
+ /** 订单ID */
+ @JsonProperty("order_id")
+ @JacksonXmlProperty(localName = "order_id")
+ private String orderId;
+
+ /** 订单状态 {@link me.chanjar.weixin.channel.enums.WxOrderStatus} */
+ @JsonProperty("status")
+ @JacksonXmlProperty(localName = "status")
+ private Integer status;
+
+ @JsonProperty("ProductOrderStatusUpdate")
+ @JacksonXmlProperty(localName = "ProductOrderStatusUpdate")
+ private void unpackNameFromNestedObject(Map map) {
+ if (map == null) {
+ return;
+ }
+ Object obj = null;
+ obj = map.get("order_id");
+ if (obj != null) {
+ this.orderId = (String) obj;
+ }
+ obj = map.get("status");
+ if (obj != null) {
+ if (obj instanceof Integer) {
+ this.status = (Integer) obj;
+ } else if (obj instanceof String) {
+ this.status = Integer.parseInt((String) obj);
+ }
+ }
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/product/BrandMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/product/BrandMessage.java
new file mode 100644
index 0000000000..9a7c021c9d
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/product/BrandMessage.java
@@ -0,0 +1,72 @@
+package me.chanjar.weixin.channel.bean.message.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import java.util.Map;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * 品牌消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class BrandMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = -3773902704930003105L;
+ /** 品牌库中的品牌编号 */
+ @JsonProperty("brand_id")
+ @JacksonXmlProperty(localName = "brand_id")
+ private String brandId;
+
+ /** 审核id */
+ @JsonProperty("audit_id")
+ @JacksonXmlProperty(localName = "audit_id")
+ private String auditId;
+
+ /** 审核状态, 1新增品牌 2更新品牌 3撤回品牌审核 4审核成功 5审核失败 6删除品牌 7品牌资质被系统撤销 */
+ @JsonProperty("status")
+ @JacksonXmlProperty(localName = "status")
+ private Integer status;
+
+ /** 相关信息 */
+ @JsonProperty("reason")
+ @JacksonXmlProperty(localName = "reason")
+ private String reason;
+
+ @JsonProperty("BrandEvent")
+ @JacksonXmlProperty(localName = "BrandEvent")
+ private void unpackNameFromNestedObject(Map map) {
+ if (map == null) {
+ return;
+ }
+ Object obj = null;
+ obj = map.get("brand_id");
+ if (obj != null) {
+ this.brandId = (obj instanceof String ? (String) obj : String.valueOf(obj));
+ }
+ obj = map.get("audit_id");
+ if (obj != null) {
+ this.auditId = (obj instanceof String ? (String) obj : String.valueOf(obj));
+ }
+ obj = map.get("status");
+ if (obj != null) {
+ if (obj instanceof Integer) {
+ this.status = (Integer) obj;
+ } else if (obj instanceof String) {
+ this.status = Integer.parseInt((String) obj);
+ }
+ }
+ obj = map.get("reason");
+ if (obj != null) {
+ this.reason = (obj instanceof String ? (String) obj : String.valueOf(obj));
+ }
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/product/CategoryAuditMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/product/CategoryAuditMessage.java
new file mode 100644
index 0000000000..f6d696d5c1
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/product/CategoryAuditMessage.java
@@ -0,0 +1,63 @@
+package me.chanjar.weixin.channel.bean.message.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import java.util.Map;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * 类目审核消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class CategoryAuditMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = 3192582751919917223L;
+ /** 审核id */
+ @JsonProperty("audit_id")
+ @JacksonXmlProperty(localName = "audit_id")
+ private String auditId;
+
+ /** 审核状态, 1:审核中, 2:审核拒绝, 3:审核通过, 12:主动取消申请单 */
+ @JsonProperty("status")
+ @JacksonXmlProperty(localName = "status")
+ private Integer status;
+
+ /** 相关信息 */
+ @JsonProperty("reason")
+ @JacksonXmlProperty(localName = "reason")
+ private String reason;
+
+ @JsonProperty("ProductCategoryAudit")
+ @JacksonXmlProperty(localName = "ProductCategoryAudit")
+ private void unpackNameFromNestedObject(Map map) {
+ if (map == null) {
+ return;
+ }
+ Object obj = null;
+ obj = map.get("audit_id");
+ if (obj != null) {
+ this.auditId = (obj instanceof String ? (String) obj : String.valueOf(obj));
+ }
+ obj = map.get("status");
+ if (obj != null) {
+ if (obj instanceof Integer) {
+ this.status = (Integer) obj;
+ } else if (obj instanceof String) {
+ this.status = Integer.parseInt((String) obj);
+ }
+ }
+ obj = map.get("reason");
+ if (obj != null) {
+ this.reason = (obj instanceof String ? (String) obj : String.valueOf(obj));
+ }
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/product/SpuAuditMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/product/SpuAuditMessage.java
new file mode 100644
index 0000000000..569b53781e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/product/SpuAuditMessage.java
@@ -0,0 +1,83 @@
+package me.chanjar.weixin.channel.bean.message.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import java.util.Map;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * SPU审核消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class SpuAuditMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = 1763291928383078102L;
+ /** 商品id */
+ @JsonProperty("product_id")
+ @JacksonXmlProperty(localName = "product_id")
+ private String productId;
+
+ /**
+ * 审核状态, 2:审核不通过;3:审核通过 商品状态, 5:上架;11:自主下架;13:系统下架
+ */
+ @JsonProperty("status")
+ @JacksonXmlProperty(localName = "status")
+ private Integer status;
+
+ /** 审核/下架原因,非必填字段 */
+ @JsonProperty("reason")
+ @JacksonXmlProperty(localName = "reason")
+ private String reason;
+
+
+
+ @JsonProperty("ProductSpuAudit")
+ @JacksonXmlProperty(localName = "ProductSpuAudit")
+ public void ProductSpuAudit(Map map) {
+ this.unpackNameFromNestedObject(map);
+ }
+
+ @JsonProperty("ProductSpuUpdate")
+ @JacksonXmlProperty(localName = "ProductSpuUpdate")
+ public void ProductSpuUpdate(Map map) {
+ this.unpackNameFromNestedObject(map);
+ }
+
+ @JsonProperty("ProductSpuListing")
+ @JacksonXmlProperty(localName = "ProductSpuListing")
+ public void ProductSpuListing(Map map) {
+ this.unpackNameFromNestedObject(map);
+ }
+
+ private void unpackNameFromNestedObject(Map map) {
+ if (map == null) {
+ return;
+ }
+ Object obj = null;
+ obj = map.get("product_id");
+ if (obj != null) {
+ this.productId = (obj instanceof String ? (String) obj : String.valueOf(obj));
+ }
+ obj = map.get("status");
+ if (obj != null) {
+ if (obj instanceof Integer) {
+ this.status = (Integer) obj;
+ } else if (obj instanceof String) {
+ this.status = Integer.parseInt((String) obj);
+ }
+ }
+ obj = map.get("reason");
+ if (obj != null) {
+ this.reason = (obj instanceof String ? (String) obj : String.valueOf(obj));
+ }
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/product/SpuStatusMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/product/SpuStatusMessage.java
new file mode 100644
index 0000000000..7fb9f272e8
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/product/SpuStatusMessage.java
@@ -0,0 +1,72 @@
+package me.chanjar.weixin.channel.bean.message.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import java.util.Map;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * SPU状态消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class SpuStatusMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = 6872830451279856492L;
+ /** 商家自定义商品id */
+ @JsonProperty("out_product_id")
+ @JacksonXmlProperty(localName = "out_product_id")
+ private String outProductId;
+
+ /** 平台商品id */
+ @JsonProperty("product_id")
+ @JacksonXmlProperty(localName = "product_id")
+ private String productId;
+
+ /** 当前商品上下架状态 参考 {@link me.chanjar.weixin.channel.enums.SpuStatus } */
+ @JsonProperty("status")
+ @JacksonXmlProperty(localName = "status")
+ private Integer status;
+
+ /** 相关信息 */
+ @JsonProperty("reason")
+ @JacksonXmlProperty(localName = "reason")
+ private String reason;
+
+ @JsonProperty("OpenProductSpuStatusUpdate")
+ @JacksonXmlProperty(localName = "OpenProductSpuStatusUpdate")
+ private void unpackNameFromNestedObject(Map map) {
+ if (map == null) {
+ return;
+ }
+ Object obj = null;
+ obj = map.get("out_product_id");
+ if (obj != null) {
+ this.outProductId = (obj instanceof String ? (String) obj : String.valueOf(obj));
+ }
+ obj = map.get("product_id");
+ if (obj != null) {
+ this.productId = (obj instanceof String ? (String) obj : String.valueOf(obj));
+ }
+ obj = map.get("status");
+ if (obj != null) {
+ if (obj instanceof Integer) {
+ this.status = (Integer) obj;
+ } else if (obj instanceof String) {
+ this.status = Integer.parseInt((String) obj);
+ }
+ }
+ obj = map.get("reason");
+ if (obj != null) {
+ this.reason = (obj instanceof String ? (String) obj : String.valueOf(obj));
+ }
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/supplier/SupplierItemInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/supplier/SupplierItemInfo.java
new file mode 100644
index 0000000000..49bbb0548b
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/supplier/SupplierItemInfo.java
@@ -0,0 +1,44 @@
+package me.chanjar.weixin.channel.bean.message.supplier;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 团长商品变更信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class SupplierItemInfo implements Serializable {
+
+ private static final long serialVersionUID = -1971161027976024360L;
+ /** 商品变更类型,1:新增商品;2:更新商品 */
+ @JsonProperty("event_type")
+ @JacksonXmlProperty(localName = "event_type")
+ private Integer eventType;
+
+ /** 团长商品所属小店appid */
+ @JsonProperty("appid")
+ @JacksonXmlProperty(localName = "appid")
+ private String appid;
+
+ /** 商品id */
+ @JsonProperty("product_id")
+ @JacksonXmlProperty(localName = "product_id")
+ private String productId;
+
+ /** 商品版本号 */
+ @JsonProperty("version")
+ @JacksonXmlProperty(localName = "version")
+ private String version;
+
+ /** 商品更新字段,当event_type = 2时有值。commission_ratio、service_ratio、status、active_time分别表示佣金、服务费、商品状态和合作生效时间有变更 */
+ @JsonProperty("update_fields")
+ @JacksonXmlProperty(localName = "update_fields")
+ private List updateFields;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/supplier/SupplierItemMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/supplier/SupplierItemMessage.java
new file mode 100644
index 0000000000..2403aa0c60
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/supplier/SupplierItemMessage.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.message.supplier;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * 团长商品变更 消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class SupplierItemMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = -4520611382070764349L;
+ /** 账户信息 */
+ @JsonProperty("item_info")
+ @JacksonXmlProperty(localName = "item_info")
+ private SupplierItemInfo itemInfo;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/AfterSaleDetail.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/AfterSaleDetail.java
new file mode 100644
index 0000000000..5401a588bf
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/AfterSaleDetail.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 售后信息详情
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class AfterSaleDetail implements Serializable {
+
+ private static final long serialVersionUID = -3786573982841041144L;
+
+ /** 正在售后流程的售后单数 */
+ @JsonProperty("on_aftersale_order_cnt")
+ private Integer onAfterSaleOrderCnt;
+
+ /** 售后单列表 */
+ @JsonProperty("aftersale_order_list")
+ private List afterSaleOrderList;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/AfterSaleOrderInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/AfterSaleOrderInfo.java
new file mode 100644
index 0000000000..118feba35b
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/AfterSaleOrderInfo.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 售后信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class AfterSaleOrderInfo implements Serializable {
+
+ private static final long serialVersionUID = 3938545222231426455L;
+
+ /** 售后单ID */
+ @JsonProperty("aftersale_order_id")
+ private String afterSaleOrderId;
+
+ public String getAfterSaleOrderId() {
+ return afterSaleOrderId;
+ }
+
+ public void setAfterSaleOrderId(String afterSaleOrderId) {
+ this.afterSaleOrderId = afterSaleOrderId;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/ChangeOrderInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/ChangeOrderInfo.java
new file mode 100644
index 0000000000..f6485085bb
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/ChangeOrderInfo.java
@@ -0,0 +1,31 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 订单修改信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class ChangeOrderInfo implements Serializable {
+
+ private static final long serialVersionUID = 4932726847720452340L;
+
+ /** 商品id */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** 商品sku */
+ @JsonProperty("sku_id")
+ private String skuId;
+
+ /** 订单中该商品修改后的总价,以分为单位 */
+ @JsonProperty("change_price")
+ private String changePrice;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/DeliveryProductInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/DeliveryProductInfo.java
new file mode 100644
index 0000000000..5427a49839
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/DeliveryProductInfo.java
@@ -0,0 +1,48 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.delivery.FreightProductInfo;
+
+/**
+ * 发货物流信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class DeliveryProductInfo implements Serializable {
+
+ private static final long serialVersionUID = -8110532854439612471L;
+ /** 快递单号 */
+ @JsonProperty("waybill_id")
+ private String waybillId;
+
+ /** 快递公司编码 */
+ @JsonProperty("delivery_id")
+ private String deliveryId;
+
+ /** 包裹中商品信息 */
+ @JsonProperty("product_infos")
+ private List productInfos;
+
+ /** 快递公司名称 */
+ @JsonProperty("delivery_name")
+ private String deliveryName;
+
+ /** 发货时间,秒级时间戳 */
+ @JsonProperty("delivery_time")
+ private Long deliveryTime;
+
+ /** 配送方式,枚举值见DeliveryType {@link me.chanjar.weixin.channel.enums.DeliveryType} */
+ @JsonProperty("deliver_type")
+ private Integer deliverType;
+
+ /** 发货地址 */
+ @JsonProperty("delivery_address")
+ private OrderAddressInfo deliveryAddress;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/DeliveryUpdateParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/DeliveryUpdateParam.java
new file mode 100644
index 0000000000..6aca6feed4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/DeliveryUpdateParam.java
@@ -0,0 +1,51 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.delivery.FreightProductInfo;
+
+/**
+ * 修改物流参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class DeliveryUpdateParam implements Serializable {
+
+ /** 订单ID */
+ @JsonProperty("order_id")
+ private String orderId;
+
+ /** 物流公司ID */
+ @JsonProperty("delivery_list")
+ private List deliveryList;
+
+ @Data
+ @NoArgsConstructor
+ @JsonInclude(JsonInclude.Include.NON_NULL)
+ public static class DeliveryInfo implements Serializable {
+
+ private static final long serialVersionUID = 1348000697768633889L;
+ /** 快递单号 */
+ @JsonProperty("waybill_id")
+ private String waybillId;
+
+ /** 快递公司编码 */
+ @JsonProperty("delivery_id")
+ private String deliveryId;
+
+ /** 配送方式,枚举值见DeliveryType {@link me.chanjar.weixin.channel.enums.DeliveryType} */
+ @JsonProperty("deliver_type")
+ private Integer deliverType;
+
+ /** 包裹中商品信息 */
+ @JsonProperty("product_infos")
+ private List productInfos;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderAddressInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderAddressInfo.java
new file mode 100644
index 0000000000..ff3e1ba332
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderAddressInfo.java
@@ -0,0 +1,23 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.AddressInfo;
+
+/**
+ * 地址信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class OrderAddressInfo extends AddressInfo {
+
+ private static final long serialVersionUID = 3062707865189774795L;
+ /** 虚拟发货订单联系方式(deliver_method=1时返回) */
+ @JsonProperty("virtual_order_tel_number")
+ private String virtualOrderTelNumber;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderAddressParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderAddressParam.java
new file mode 100644
index 0000000000..55eb6a8655
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderAddressParam.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.AddressInfo;
+
+/**
+ * 订单地址参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(Include.NON_NULL)
+public class OrderAddressParam implements Serializable {
+
+ private static final long serialVersionUID = 2277618297276466650L;
+
+ /** 订单id */
+ @JsonProperty("order_id")
+ private String orderId;
+
+ /** 地址信息 */
+ @JsonProperty("user_address")
+ private AddressInfo userAddress;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderCommissionInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderCommissionInfo.java
new file mode 100644
index 0000000000..78e391e774
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderCommissionInfo.java
@@ -0,0 +1,45 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 分佣信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class OrderCommissionInfo implements Serializable {
+
+ private static final long serialVersionUID = -3046852309683467272L;
+ /** 商品skuid */
+ @JsonProperty("sku_id")
+ private String skuId;
+
+ /** 分账方昵称 */
+ @JsonProperty("nickname")
+ private String nickname;
+
+ /** 分账方类型,0:达人,1:团长 */
+ @JsonProperty("type")
+ private Integer type;
+
+ /** 分账状态, 1:未结算,2:已结算 */
+ @JsonProperty("status")
+ private Integer status;
+
+ /** 分账金额 */
+ @JsonProperty("amount")
+ private Integer amount;
+
+ /** 达人视频号id */
+ @JsonProperty("finder_id")
+ private String finderId;
+
+ /** 达人openfinderid */
+ @JsonProperty("openfinderid")
+ private String openFinderId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderCouponInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderCouponInfo.java
new file mode 100644
index 0000000000..a8f020c0ef
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderCouponInfo.java
@@ -0,0 +1,21 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 卡券信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class OrderCouponInfo implements Serializable {
+
+ private static final long serialVersionUID = -2033350505767196339L;
+ /** 用户优惠券id */
+ @JsonProperty("user_coupon_id")
+ private String userCouponId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderDeliveryInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderDeliveryInfo.java
new file mode 100644
index 0000000000..dce5460141
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderDeliveryInfo.java
@@ -0,0 +1,35 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 物流信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class OrderDeliveryInfo implements Serializable {
+
+ private static final long serialVersionUID = -5348922760017557397L;
+ /** 地址信息 */
+ @JsonProperty("address_info")
+ private OrderAddressInfo addressInfo;
+
+ /** 发货物流信息 */
+ @JsonProperty("delivery_product_info")
+ private List deliveryProductInfos;
+
+ /** 发货完成时间,秒级时间戳 */
+ @JsonProperty("ship_done_time")
+ private Long shipDoneTime;
+
+ /** 订单发货方式,0普通物流 1虚拟发货,由商品的同名字段决定 */
+ @JsonProperty("deliver_method")
+ private Integer deliverMethod;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderDetailInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderDetailInfo.java
new file mode 100644
index 0000000000..1f4d55924d
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderDetailInfo.java
@@ -0,0 +1,55 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 订单详细数据
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class OrderDetailInfo implements Serializable {
+
+ private static final long serialVersionUID = 3916307299998005676L;
+ /** 商品列表 */
+ @JsonProperty("product_infos")
+ private List productInfos;
+
+ /** 支付信息 */
+ @JsonProperty("pay_info")
+ private OrderPayInfo payInfo;
+
+ /** 价格信息 */
+ @JsonProperty("price_info")
+ private OrderPriceInfo priceInfo;
+
+ /** 配送信息 */
+ @JsonProperty("delivery_info")
+ private OrderDeliveryInfo deliveryInfo;
+
+ /** 优惠券信息 */
+ @JsonProperty("coupon_info")
+ private OrderCouponInfo couponInfo;
+
+ /** 额外信息 */
+ @JsonProperty("ext_info")
+ private OrderExtInfo extInfo;
+
+ /** 分佣信息 */
+ @JsonProperty("commission_infos")
+ private List commissionInfos;
+
+ /** 分享信息 */
+ @JsonProperty("sharer_info")
+ private OrderSharerInfo sharerInfo;
+
+ /** 结算信息 */
+ @JsonProperty("settle_info")
+ private OrderSettleInfo settleInfo;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderExtInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderExtInfo.java
new file mode 100644
index 0000000000..3338d1a428
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderExtInfo.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 订单备注信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class OrderExtInfo implements Serializable {
+
+ private static final long serialVersionUID = 4568097877621455429L;
+ /** 用户备注 */
+ @JsonProperty("customer_notes")
+ private String customerNotes;
+
+ /** 商家备注 */
+ @JsonProperty("merchant_notes")
+ private String merchantNotes;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderIdParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderIdParam.java
new file mode 100644
index 0000000000..f1e92e1339
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderIdParam.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 订单id参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(Include.NON_NULL)
+public class OrderIdParam implements Serializable {
+
+ private static final long serialVersionUID = -8616582197963359789L;
+ /** 订单ID */
+ @JsonProperty("order_id")
+ private String orderId;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderInfo.java
new file mode 100644
index 0000000000..894b36f7af
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderInfo.java
@@ -0,0 +1,50 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 视频号小店订单
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class OrderInfo implements Serializable {
+
+ private static final long serialVersionUID = -4562618835611282016L;
+ /** 订单号 */
+ @JsonProperty("order_id")
+ protected String orderId;
+
+ /** 订单状态,枚举值见 {@link me.chanjar.weixin.channel.enums.WxOrderStatus} */
+ @JsonProperty("status")
+ protected Integer status;
+
+ /** 买家身份标识 */
+ @JsonProperty("openid")
+ protected String openid;
+
+ /** union id */
+ @JsonProperty("unionid")
+ protected String unionid;
+
+ /** 订单详细数据信息 */
+ @JsonProperty("order_detail")
+ protected OrderDetailInfo orderDetail;
+
+ /** 售后信息 */
+ @JsonProperty("aftersale_detail")
+ protected AfterSaleDetail afterSaleDetail;
+
+ /** 创建时间 秒级时间戳 */
+ @JsonProperty("create_time")
+ protected Integer createTime;
+
+ /** 更新时间 秒级时间戳 */
+ @JsonProperty("update_time")
+ protected Integer updateTime;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderInfoResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderInfoResponse.java
new file mode 100644
index 0000000000..0b6fd53c17
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderInfoResponse.java
@@ -0,0 +1,23 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 订单信息响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class OrderInfoResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 935829924760021624L;
+ /** 订单信息 */
+ @JsonProperty("order")
+ private OrderInfo order;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderListParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderListParam.java
new file mode 100644
index 0000000000..a84da3d2e8
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderListParam.java
@@ -0,0 +1,39 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.StreamPageParam;
+import me.chanjar.weixin.channel.bean.base.TimeRange;
+
+/**
+ * 获取订单列表参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JsonInclude(Include.NON_NULL)
+public class OrderListParam extends StreamPageParam {
+
+ private static final long serialVersionUID = 3780097459964746890L;
+ /** 订单创建时间范围 */
+ @JsonProperty("create_time_range")
+ private TimeRange createTimeRange;
+
+ /** 订单更新时间范围 */
+ @JsonProperty("update_time_range")
+ private TimeRange updateTimeRange;
+
+ /** 订单状态,枚举值见 {@link me.chanjar.weixin.channel.enums.WxOrderStatus} */
+ @JsonProperty("status")
+ private Integer status;
+
+ /** 买家身份标识 */
+ @JsonProperty("openid")
+ private Integer openid;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderListResponse.java
new file mode 100644
index 0000000000..454abc59d9
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderListResponse.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 订单列表 响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class OrderListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -6198624448684807852L;
+ /** 订单id列表 */
+ @JsonProperty("order_id_list")
+ private List ids;
+
+ /** 分页参数,下一页请求回传 */
+ @JsonProperty("next_key")
+ private String nextKey;
+
+ /** 是否还有下一页,true:有下一页;false:已经结束,没有下一页。 */
+ @JsonProperty("has_more")
+ private Boolean hasMore;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderPayInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderPayInfo.java
new file mode 100644
index 0000000000..6c912f7c45
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderPayInfo.java
@@ -0,0 +1,34 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 支付信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class OrderPayInfo implements Serializable {
+
+ private static final long serialVersionUID = -5085386252699113948L;
+ /** 预支付id */
+ @JsonProperty("prepayId")
+ private String prepayId;
+
+ /** 预支付时间,秒级时间戳 */
+ @JsonProperty("prepay_time")
+ private Long prepayTime;
+
+ /** 支付时间,秒级时间戳 */
+ @JsonProperty("pay_time")
+ private Long payTime;
+
+ /** 支付单号 */
+ @JsonProperty("transaction_id")
+ private String transactionId;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderPriceInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderPriceInfo.java
new file mode 100644
index 0000000000..89bef2daed
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderPriceInfo.java
@@ -0,0 +1,58 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商店订单价格信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class OrderPriceInfo implements Serializable {
+
+ private static final long serialVersionUID = 5216506688949493432L;
+ /** 商品总价,单位为分 */
+ @JsonProperty("product_price")
+ private Integer productPrice;
+
+ /** 订单金额,单位为分 */
+ @JsonProperty("order_price")
+ private Integer orderPrice;
+
+ /** 运费,单位为分 */
+ @JsonProperty("freight")
+ private Integer freight;
+
+ /** 优惠金额,单位为分 */
+ @JsonProperty("discounted_price")
+ private Integer discountedPrice;
+
+ /** 是否有优惠 */
+ @JsonProperty("is_discounted")
+ private Boolean isDiscounted;
+
+ /** 订单原始价格,单位为分 */
+ @JsonProperty("original_order_price")
+ private Integer originalOrderPrice;
+
+ /** 商品预估价格,单位为分 */
+ @JsonProperty("estimate_product_price")
+ private Integer estimateProductPrice;
+
+ /** 改价后降低金额,单位为分 */
+ @JsonProperty("change_down_price")
+ private Integer changeDownPrice;
+
+ /** 改价后运费,单位为分 */
+ @JsonProperty("change_freight")
+ private Integer changeFreight;
+
+ /** 是否修改运费 */
+ @JsonProperty("is_change_freight")
+ private Boolean changeFreighted;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderPriceParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderPriceParam.java
new file mode 100644
index 0000000000..30f74501c4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderPriceParam.java
@@ -0,0 +1,46 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+
+/**
+ * 订单价格参数
+ *
+ * @author Zeyes
+ */
+@Data
+@JsonInclude(Include.NON_NULL)
+public class OrderPriceParam implements Serializable {
+
+ private static final long serialVersionUID = -7925819981481556218L;
+ /** 订单id */
+ @JsonProperty("order_id")
+ private String orderId;
+
+ /** 是否修改运费 */
+ @JsonProperty("change_express")
+ private Boolean changeExpress;
+
+ /** 修改后的运费价格(change_express=true时必填),以分为单位 */
+ @JsonProperty("express_fee")
+ private Integer expressFee;
+
+ /** 改价列表 */
+ @JsonProperty("change_order_infos")
+ private List changeOrderInfos;
+
+ public OrderPriceParam() {
+ }
+
+ public OrderPriceParam(String orderId, Integer expressFee, List changeOrderInfos) {
+ this.orderId = orderId;
+ // expressFee不为空时,表示修改运费
+ this.changeExpress = (expressFee != null);
+ this.expressFee = expressFee;
+ this.changeOrderInfos = changeOrderInfos;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderProductInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderProductInfo.java
new file mode 100644
index 0000000000..3d5d7a92cb
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderProductInfo.java
@@ -0,0 +1,95 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.AttrInfo;
+
+/**
+ * 订单商品信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class OrderProductInfo implements Serializable {
+
+ private static final long serialVersionUID = -2193536732955185928L;
+ /** 商品spu id */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** sku_id */
+ @JsonProperty("sku_id")
+ private String skuId;
+
+ /** sku小图 */
+ @JsonProperty("thumb_img")
+ private String thumbImg;
+
+ /** sku数量 */
+ @JsonProperty("sku_cnt")
+ private Integer skuCnt;
+
+ /** 售卖价格(单位:分) */
+ @JsonProperty("sale_price")
+ private Integer salePrice;
+
+ /** 商品标题 */
+ @JsonProperty("title")
+ private String title;
+
+ /** 正在售后/退款流程中的 sku 数量 */
+ @JsonProperty("on_aftersale_sku_cnt")
+ private Integer onAfterSaleSkuCnt;
+
+ /** 完成售后/退款的 sku 数量 */
+ @JsonProperty("finish_aftersale_sku_cnt")
+ private Integer finishAfterSaleSkuCnt;
+
+ /** 商品编码 */
+ @JsonProperty("sku_code")
+ private String skuCode;
+
+ /** 市场价格(单位:分) */
+ @JsonProperty("market_price")
+ private Integer marketPrice;
+
+ /** sku属性 */
+ @JsonProperty("sku_attrs")
+ private List skuAttrs;
+
+ /** sku实付价格 */
+ @JsonProperty("real_price")
+ private Integer realPrice;
+
+ /** 商品外部spu id */
+ @JsonProperty("out_product_id")
+ private String outProductId;
+
+ /** 商品外部sku id */
+ @JsonProperty("out_sku_id")
+ private String outSkuId;
+
+ /** 是否有优惠金额,非必填,默认为false */
+ @JsonProperty("is_discounted")
+ private Boolean isDiscounted;
+
+ /** 优惠后 sku 价格,非必填,is_discounted为 true 时有值 */
+ @JsonProperty("estimate_price")
+ private Integer estimatePrice;
+
+ /** 是否修改过价格,非必填,默认为false */
+ @JsonProperty("is_change_price")
+ private Boolean changePriced;
+
+ /** 改价后 sku 价格,非必填,is_change_price为 true 时有值 */
+ @JsonProperty("change_price")
+ private Integer changePrice;
+
+ /** 区域库存id */
+ @JsonProperty("out_warehouse_id")
+ private String outWarehouseId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderRemarkParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderRemarkParam.java
new file mode 100644
index 0000000000..707ec0d96b
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderRemarkParam.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 订单备注
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class OrderRemarkParam implements Serializable {
+
+ private static final long serialVersionUID = 2285714780419948468L;
+ /** 订单id */
+ @JsonProperty("order_id")
+ private String orderId;
+
+ /** 备注内容 */
+ @JsonProperty("merchant_notes")
+ private String merchantNotes;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSearchCondition.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSearchCondition.java
new file mode 100644
index 0000000000..012b0fca49
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSearchCondition.java
@@ -0,0 +1,41 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 订单 搜索条件
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(Include.NON_EMPTY)
+public class OrderSearchCondition implements Serializable {
+
+ private static final long serialVersionUID = 5492584333971883140L;
+ /** 商品标题关键词 */
+ @JsonProperty("title")
+ private String title;
+
+ /** 商品编码 */
+ @JsonProperty("sku_code")
+ private String skuCode;
+
+ /** 收件人 */
+ @JsonProperty("user_name")
+ private String userName;
+
+ /** 收件人电话 */
+ @JsonProperty("tel_number")
+ private String telNumber;
+
+ /** 选填,只搜一个订单时使用 */
+ @JsonProperty("order_id")
+ private String orderId;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSearchParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSearchParam.java
new file mode 100644
index 0000000000..0a9483e0d5
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSearchParam.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.StreamPageParam;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(Include.NON_EMPTY)
+public class OrderSearchParam extends StreamPageParam {
+
+ private static final long serialVersionUID = 5737520097455135218L;
+ /** 商品标题关键词 */
+ @JsonProperty("search_condition")
+ private OrderSearchCondition searchCondition;
+
+ /** 不填该参数:全部订单 0:没有正在售后的订单, 1:正在售后单数量大于等于1的订单 */
+ @JsonProperty("on_aftersale_order_exist")
+ private Integer onAfterSaleOrderExist;
+
+ /** 订单状态 {@link me.chanjar.weixin.channel.enums.WxOrderStatus} */
+ @JsonProperty("on_aftersale_order_exist")
+ private Integer status;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSettleInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSettleInfo.java
new file mode 100644
index 0000000000..c264a6289a
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSettleInfo.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 结算信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class OrderSettleInfo implements Serializable {
+
+ private static final long serialVersionUID = 2140632631448343656L;
+ /** 预计技术服务费(单位为分) */
+ @JsonProperty("predict_commission_fee")
+ private Integer predictCommissionFee;
+
+ /** 实际技术服务费(单位为分)(未结算时本字段为空) */
+ @JsonProperty("commission_fee")
+ private Integer commissionFee;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSharerInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSharerInfo.java
new file mode 100644
index 0000000000..be66463445
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSharerInfo.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 分享信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class OrderSharerInfo implements Serializable {
+
+ private static final long serialVersionUID = 7183259072254660971L;
+ /** 分享员openid */
+ @JsonProperty("sharer_openid")
+ private String sharerOpenid;
+
+ /** 分享员unionid */
+ @JsonProperty("sharer_unionid")
+ private String sharerUnionid;
+
+ /** 分享员类型,0:普通分享员,1:店铺分享员 */
+ @JsonProperty("sharer_type")
+ private Integer sharerType;
+
+ /** 分享场景 {@link me.chanjar.weixin.channel.enums.ShareScene} */
+ @JsonProperty("share_scene")
+ private Integer shareScene;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/DescriptionInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/DescriptionInfo.java
new file mode 100644
index 0000000000..b97473e3d3
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/DescriptionInfo.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商品详情
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class DescriptionInfo implements Serializable {
+
+ private static final long serialVersionUID = 3402153796734747882L;
+
+ /** 商品详情图文,字符类型,最长不超过2000 */
+ @JsonProperty("desc")
+ private String desc;
+
+ /** 商品详情图片,图片类型,最多不超过50张 */
+ @JsonProperty("imgs")
+ private List imgs;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExpressInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExpressInfo.java
new file mode 100644
index 0000000000..0c21d9610e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExpressInfo.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 运费信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class ExpressInfo implements Serializable {
+
+ private static final long serialVersionUID = 3274035362148612426L;
+
+ /** 运费模板ID(先通过获取运费模板接口merchant/getfreighttemplatelist拿到),若deliver_method=1,则不用填写 */
+ @JsonProperty("template_id")
+ private String templateId;
+
+ /** 商品重量,单位克,若当前运费模版计价方式为[按重量],则必填 */
+ @JsonProperty("weight")
+ private Integer weight;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExtraServiceInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExtraServiceInfo.java
new file mode 100644
index 0000000000..aeaf1a8cd6
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExtraServiceInfo.java
@@ -0,0 +1,23 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class ExtraServiceInfo implements Serializable {
+
+ private static final long serialVersionUID = -5517806977282063174L;
+
+ /**
+ * 是否支持七天无理由退货,0-不支持七天无理由, 1-支持七天无理由, 2-支持七天无理由(定制商品除外)。 管理规则请参见七天无理由退货管理规则。类目是否必须支持七天无理由退货,
+ * 可参考文档获取类目信息中的字段attr.seven_day_return
+ */
+ @JsonProperty("seven_day_return")
+ private Integer sevenDayReturn;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/LimitInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/LimitInfo.java
new file mode 100644
index 0000000000..389773d5e7
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/LimitInfo.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 限时购信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class LimitInfo implements Serializable {
+
+ private static final long serialVersionUID = -4670198322237114719L;
+
+ /** 限购周期类型,0无限购(默认),1按自然日限购,2按自然周限购,3按自然月限购 */
+ @JsonProperty("period_type")
+ private Integer periodType;
+
+ /** 限购周期类型,0无限购(默认),1按自然日限购,2按自然周限购,3按自然月限购 */
+ @JsonProperty("limited_buy_num")
+ private Integer num;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuDeliverInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuDeliverInfo.java
new file mode 100644
index 0000000000..d1f10dc5f8
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuDeliverInfo.java
@@ -0,0 +1,43 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * sku发货信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class SkuDeliverInfo implements Serializable {
+
+ private static final long serialVersionUID = 8046963723772755406L;
+
+ /** sku库存情况。0:现货(默认),1:全款预售。部分类目支持全款预售,具体参考文档获取类目信息中的字段attr.pre_sale */
+ @JsonProperty("stock_type")
+ private Integer stockType;
+
+ /** sku发货节点,该字段仅对stock_type=1有效。0:付款后n天发货,1:预售结束后n天发货 */
+ @JsonProperty("full_payment_presale_delivery_type")
+ private Integer fullPaymentPresaleDeliveryType;
+
+ /** sku预售周期开始时间,秒级时间戳,该字段仅对delivery_type=1有效。 */
+ @JsonProperty("presale_begin_time")
+ private Long presaleBeginTime;
+
+ /**
+ * sku预售周期结束时间,秒级时间戳,该字段仅对delivery_type=1有效。限制:预售结束时间距离现在<=30天, 即presale_end_time - now <= 2592000。预售时间区间<=15天,
+ * 即presale_end_time - presale_begin_time <= 1296000
+ */
+ @JsonProperty("presale_end_time")
+ private Long presaleEndTime;
+
+ /**
+ * sku发货时效,即付款后/预售结束后{full_payment_presale_delivery_time}天内发货, 该字段仅对stock_type=1时有效。范围是[4, 15]的整数。
+ */
+ @JsonProperty("full_payment_presale_delivery_time")
+ private Integer fullPaymentPresaleDeliveryTime;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuInfo.java
new file mode 100644
index 0000000000..3b46708039
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuInfo.java
@@ -0,0 +1,66 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import me.chanjar.weixin.channel.bean.base.AttrInfo;
+
+/**
+ * SKU信息
+ *
+ * @author Zeyes
+ */
+@Data
+public class SkuInfo implements Serializable {
+
+ private static final long serialVersionUID = -8734396136299597845L;
+
+ /** 商家自定义商品ID */
+ @JsonProperty("out_product_id")
+ private String outProductId;
+
+ /** 商家自定义skuID */
+ @JsonProperty("out_sku_id")
+ private String outSkuId;
+
+ /** sku小图 */
+ @JsonProperty("thumb_img")
+ private String thumbImg;
+
+ /** 售卖价格,以分为单位,数字类型,最大不超过10000000(1000万元) */
+ @JsonProperty("sale_price")
+ private Integer salePrice;
+
+ /** 市场价格,以分为单位,数字类型,最大不超过10000000(1000万元),且必须比sale_price大 */
+ @JsonProperty("market_price")
+ private Integer marketPrice;
+
+ /** 库存,数字类型,最大不超过10000000(1000万) */
+ @JsonProperty("stock_num")
+ private Integer stockNum;
+
+ /** 商品编码,字符类型,最长不超过20 */
+ @JsonProperty("sku_code")
+ private String skuCode;
+
+ /** SKU属性 */
+ @JsonProperty("sku_attrs")
+ private List attrs;
+
+ /** sku发货信息 */
+ @JsonProperty("sku_deliver_info")
+ private SkuDeliverInfo skuDeliverInfo;
+
+ /** skuID */
+ @JsonProperty("sku_id")
+ private Long skuId;
+
+ public SkuInfo() {
+ }
+
+ public SkuInfo(String outProductId, String outSkuId) {
+ this.outProductId = outProductId;
+ this.outSkuId = outSkuId;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockInfo.java
new file mode 100644
index 0000000000..a0dccb1329
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockInfo.java
@@ -0,0 +1,35 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商品库存
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class SkuStockInfo implements Serializable {
+
+ private static final long serialVersionUID = 4719729125885685958L;
+
+ /** 通用库存数量 */
+ @JsonProperty("normal_stock_num")
+ private Integer normalStockNum;
+
+ /** 限时抢购库存数量 */
+ @JsonProperty("limited_discount_stock_num")
+ private Integer limitedDiscountStockNum;
+
+ /** 区域库存 */
+ @JsonProperty("warehouse_stocks")
+ private List warehouseStocks;
+
+ /** 库存总量:通用库存数量 + 限时抢购库存数量 + 区域库存总量 */
+ @JsonProperty("total_stock_num")
+ private Integer totalStockNum;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockParam.java
new file mode 100644
index 0000000000..cf7374e75e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockParam.java
@@ -0,0 +1,34 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class SkuStockParam implements Serializable {
+
+ private static final long serialVersionUID = -5542939078361208816L;
+
+ /** 内部商品ID */
+ @JsonProperty("product_id")
+ protected String productId;
+
+ /** 内部sku_id */
+ @JsonProperty("sku_id")
+ protected String skuId;
+
+ /** 修改类型。1: 增加;2:减少;3:设置 */
+ @JsonProperty("diff_type")
+ protected Integer diffType;
+
+ /** 增加、减少或者设置的库存值 */
+ @JsonProperty("num")
+ protected Integer num;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockResponse.java
new file mode 100644
index 0000000000..9cbd6f18c0
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockResponse.java
@@ -0,0 +1,22 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 库存信息响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class SkuStockResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -2156342792354605826L;
+
+ /** 库存信息 */
+ private SkuStockInfo data;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuCategory.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuCategory.java
new file mode 100644
index 0000000000..8adc311f95
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuCategory.java
@@ -0,0 +1,22 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商品类目id
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class SpuCategory implements Serializable {
+
+ private static final long serialVersionUID = -8500610555473351789L;
+
+ /** 类目id */
+ @JsonProperty("cat_id")
+ private String id;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuGetResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuGetResponse.java
new file mode 100644
index 0000000000..b01682802f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuGetResponse.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 商品信息 响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class SpuGetResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -8955745006296226140L;
+
+ /** 商品线上数据,入参data_type==2时不返回该字段;入参data_type==3且商品未处于上架状态,不返回该字段 */
+ @JsonProperty("product")
+ private SpuInfo product;
+
+ /** 商品草稿数据,入参data_type==1时不返回该字段 */
+ @JsonProperty("edit_product")
+ private SpuInfo editProduct;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuInfo.java
new file mode 100644
index 0000000000..7e3834f10e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuInfo.java
@@ -0,0 +1,97 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.AttrInfo;
+
+/**
+ * Spu信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class SpuInfo extends SpuSimpleInfo {
+
+ private static final long serialVersionUID = -1183209029245287297L;
+
+ /** 标题,字符类型,最少不低于3,最长不超过60。商品标题不得仅为数字、字母、字符或上述三种的组合 */
+ @JsonProperty("title")
+ private String title;
+
+ /** 副标题,最多18字符 */
+ @JsonProperty("sub_title")
+ private String subTitle;
+
+ /** 主图,多张,列表,图片类型,最多不超过9张 */
+ @JsonProperty("head_imgs")
+ private List headImgs;
+
+ /** 发货方式,若为无需快递(仅对部分类目开放),则无需填写运费模版id。0:快递发货;1:无需快递;默认0 */
+ @JsonProperty("deliver_method")
+ private Integer deliverMethod;
+
+ /** 商品详情 */
+ @JsonProperty("desc_info")
+ private DescriptionInfo descInfo;
+
+ /** 商品类目,大小恒等于3(一二三级类目) */
+ @JsonProperty("cats")
+ private List cats;
+
+ /** 商品参数 */
+ @JsonProperty("attrs")
+ private List attrs;
+
+ /** 商品编码 */
+ @JsonProperty("spu_code")
+ private String spuCode;
+
+ /** 品牌id,无品牌为2100000000 */
+ @JsonProperty("brand_id")
+ private String brandId;
+
+ /** 商品资质图片(最多5张) */
+ @JsonProperty("qualifications")
+ private List qualifications;
+
+ /** 运费信息 */
+ @JsonProperty("express_info")
+ private ExpressInfo expressInfo;
+
+ /** 售后说明 */
+ @JsonProperty("aftersale_desc")
+ private String afterSaleDesc;
+
+ /** 限购信息 */
+ @JsonProperty("limited_info")
+ @JsonInclude(Include.NON_EMPTY)
+ private LimitInfo limitInfo;
+
+ /** 附加服务 */
+ @JsonProperty("extra_service")
+ private ExtraServiceInfo extraService;
+
+ /** 商品线上状态 {@link me.chanjar.weixin.channel.enums.SpuStatus } */
+ @JsonProperty("status")
+ private Integer status;
+
+ /** 商品草稿状态 */
+ @JsonProperty("edit_status")
+ private Integer editStatus;
+
+ /** 最低价格 */
+ @JsonProperty("min_price")
+ private Integer minPrice;
+
+ /** 创建时间 yyyy-MM-dd HH:mm:ss */
+ @JsonProperty("create_time")
+ private String createTime;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuListParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuListParam.java
new file mode 100644
index 0000000000..775bdf990d
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuListParam.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import me.chanjar.weixin.channel.bean.base.StreamPageParam;
+
+/**
+ * 商品列表查询参数
+ *
+ * @author Zeyes
+ */
+@Data
+@JsonInclude(Include.NON_NULL)
+public class SpuListParam extends StreamPageParam {
+
+ private static final long serialVersionUID = -242932365961748404L;
+
+ /** 商品状态 */
+ @JsonProperty("status")
+ private Integer status;
+
+ public SpuListParam() {
+ }
+
+ public SpuListParam(Integer pageSize, String nextKey, Integer status) {
+ this.pageSize = pageSize;
+ this.nextKey = nextKey;
+ this.status = status;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuListResponse.java
new file mode 100644
index 0000000000..421725c04b
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuListResponse.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 商品列表信息 响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class SpuListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -7448819335418389308L;
+
+ /** 总数 */
+ @JsonProperty("total_num")
+ private Integer totalNum;
+
+ /** 本次翻页的上下文,用于请求下一页 */
+ @JsonProperty("next_key")
+ private String nextKey;
+
+ /** 商品 id 列表 */
+ @JsonProperty("product_ids")
+ private List ids;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuSimpleInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuSimpleInfo.java
new file mode 100644
index 0000000000..b1ab3febe7
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuSimpleInfo.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class SpuSimpleInfo implements Serializable {
+
+ private static final long serialVersionUID = 5583726432139404883L;
+
+ /** 交易组件平台内部商品ID */
+ @JsonProperty("product_id")
+ protected String productId;
+
+ /** 商家自定义商品ID */
+ @JsonProperty("out_product_id")
+ protected String outProductId;
+
+ /** sku数组 */
+ @JsonProperty("skus")
+ protected List skus;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuUpdateResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuUpdateResponse.java
new file mode 100644
index 0000000000..815ee4412c
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuUpdateResponse.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 商品信息 响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class SpuUpdateResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -7072796795527767292L;
+
+ /** 商品信息 */
+ @JsonProperty("data")
+ private SpuInfo data;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/WarehouseStockInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/WarehouseStockInfo.java
new file mode 100644
index 0000000000..bb239c9492
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/WarehouseStockInfo.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class WarehouseStockInfo implements Serializable {
+
+ private static final long serialVersionUID = 3184902895765107425L;
+
+ /** 区域库存外部id */
+ @JsonProperty("out_warehouse_id")
+ private String outWarehouseId;
+
+ /** 区域库存数量 */
+ @JsonProperty("num")
+ private Integer num;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/FinderSceneInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/FinderSceneInfo.java
new file mode 100644
index 0000000000..76d54d90c9
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/FinderSceneInfo.java
@@ -0,0 +1,38 @@
+package me.chanjar.weixin.channel.bean.sharer;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 视频号场景信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class FinderSceneInfo implements Serializable {
+
+ private static final long serialVersionUID = 5298261857489231549L;
+ /** 视频号唯一标识 */
+ @JsonProperty("promoter_id")
+ private String promoterId;
+
+ /** 视频号昵称 */
+ @JsonProperty("finder_nickname")
+ private String finderNickname;
+
+ /** 直播间唯一标识 */
+ @JsonProperty("live_export_id")
+ private String liveExportId;
+
+ /** 短视频唯一标识 */
+ @JsonProperty("video_export_id")
+ private String videoExportId;
+
+ /** 短视频标题 */
+ @JsonProperty("video_title")
+ private String videoTitle;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerBindResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerBindResponse.java
new file mode 100644
index 0000000000..4a0f8f2bb4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerBindResponse.java
@@ -0,0 +1,31 @@
+package me.chanjar.weixin.channel.bean.sharer;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 分享员绑定响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class SharerBindResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 7078787380791500161L;
+ /** 邀请二维码的图片二进制base64编码,3天有效 */
+ @JsonProperty("qrcode_img_base64")
+ private String qrcodeImgBase64;
+
+ public String getQrcodeImgBase64() {
+ return qrcodeImgBase64;
+ }
+
+ public void setQrcodeImgBase64(String qrcodeImgBase64) {
+ this.qrcodeImgBase64 = qrcodeImgBase64;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerInfo.java
new file mode 100644
index 0000000000..73aaeddbd4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerInfo.java
@@ -0,0 +1,39 @@
+package me.chanjar.weixin.channel.bean.sharer;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+
+/**
+ * 分享员信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class SharerInfo implements Serializable {
+
+ private static final long serialVersionUID = -4373597470611742887L;
+ /** 分享员openid */
+ @JsonProperty("openid")
+ private String openid;
+
+ /** 分享员unionid */
+ @JsonProperty("unionid")
+ private String unionid;
+
+ /** 分享员openid */
+ @JsonProperty("nickname")
+ private String nickname;
+
+ /** 绑定时间 */
+ @JsonProperty("bind_time")
+ private Long bindTime;
+
+ /** 分享员类型 {@link me.chanjar.weixin.channel.enums.SharerType} */
+ @JsonProperty("sharer_type")
+ private Integer sharerType;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerInfoResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerInfoResponse.java
new file mode 100644
index 0000000000..554109c1a9
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerInfoResponse.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.bean.sharer;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 分享员信息响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class SharerInfoResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 1090517907546557929L;
+ /** 分享员信息 */
+ @JsonProperty("sharer_info_list")
+ private List list;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerListParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerListParam.java
new file mode 100644
index 0000000000..97ab2797b8
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerListParam.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.sharer;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import me.chanjar.weixin.channel.bean.base.PageParam;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@JsonInclude(Include.NON_NULL)
+public class SharerListParam extends PageParam {
+
+ private static final long serialVersionUID = -2454284952706596246L;
+ /** 分享员类型 {@link me.chanjar.weixin.channel.enums.SharerType} */
+ @JsonProperty("sharer_type")
+ private Integer sharerType;
+
+ public SharerListParam() {
+ }
+
+ public SharerListParam(Integer page, Integer pageSize, Integer sharerType) {
+ super(page, pageSize);
+ this.sharerType = sharerType;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerOrder.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerOrder.java
new file mode 100644
index 0000000000..b184187b35
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerOrder.java
@@ -0,0 +1,38 @@
+package me.chanjar.weixin.channel.bean.sharer;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 分享员订单
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class SharerOrder implements Serializable {
+
+ private static final long serialVersionUID = 1528673402572025670L;
+ /** 订单号 */
+ @JsonProperty("order_id")
+ private String orderId;
+
+ /** 分享场景 {@link me.chanjar.weixin.channel.enums.ShareScene} */
+ @JsonProperty("sharer_scene")
+ private Integer sharerScene;
+
+ /** 分享员openid */
+ @JsonProperty("sharer_openid")
+ private String sharerOpenid;
+
+ /** 分享员类型 {@link me.chanjar.weixin.channel.enums.SharerType} */
+ @JsonProperty("sharer_type")
+ private Integer sharerType;
+
+ /** 视频号场景信息 */
+ @JsonProperty("finder_scene_info")
+ private FinderSceneInfo sceneInfo;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerOrderParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerOrderParam.java
new file mode 100644
index 0000000000..191dfc6ec3
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerOrderParam.java
@@ -0,0 +1,36 @@
+package me.chanjar.weixin.channel.bean.sharer;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.PageParam;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JsonInclude(Include.NON_NULL)
+public class SharerOrderParam extends PageParam {
+
+ private static final long serialVersionUID = 5240085870008898601L;
+ /** 分享员openid */
+ @JsonProperty("openid")
+ private Integer openid;
+
+ /** 分享场景 */
+ @JsonProperty("share_scene")
+ private Integer shareScene;
+
+ /** 订单创建开始时间 */
+ @JsonProperty("start_time")
+ private Long startTime;
+
+ /** 订单创建结束时间 */
+ @JsonProperty("end_time")
+ private Long endTime;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerOrderResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerOrderResponse.java
new file mode 100644
index 0000000000..c84da4114b
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerOrderResponse.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.sharer;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 分享员订单响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class SharerOrderResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 2807417719466178508L;
+ /** 分享员订单 */
+ @JsonProperty("order_list")
+ private List list;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerSearchParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerSearchParam.java
new file mode 100644
index 0000000000..a2669775cb
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerSearchParam.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.channel.bean.sharer;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@JsonInclude(Include.NON_NULL)
+public class SharerSearchParam implements Serializable {
+
+ private static final long serialVersionUID = -6763899740755735718L;
+ /** 分享员openid */
+ @JsonProperty("openid")
+ private String openid;
+
+ /** 微信号 */
+ @JsonProperty("username")
+ private String username;
+
+ public SharerSearchParam() {
+ }
+
+ public SharerSearchParam(String openid, String username) {
+ this.openid = openid;
+ this.username = username;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerSearchResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerSearchResponse.java
new file mode 100644
index 0000000000..52631521df
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerSearchResponse.java
@@ -0,0 +1,40 @@
+package me.chanjar.weixin.channel.bean.sharer;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 分享员绑定响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class SharerSearchResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -5346019069466917659L;
+ /** 分享员openid */
+ @JsonProperty("openid")
+ private String openid;
+
+ /** 分享员unionid */
+ @JsonProperty("unionid")
+ private String unionid;
+
+ /** 分享员openid */
+ @JsonProperty("nickname")
+ private String nickname;
+
+ /** 绑定时间 */
+ @JsonProperty("bind_time")
+ private Long bindTime;
+
+ /** 分享员类型 {@link me.chanjar.weixin.channel.enums.SharerType} */
+ @JsonProperty("sharer_type")
+ private Integer sharerType;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerUnbindParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerUnbindParam.java
new file mode 100644
index 0000000000..cd8f21d409
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerUnbindParam.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.bean.sharer;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(Include.NON_NULL)
+public class SharerUnbindParam implements Serializable {
+
+ private static final long serialVersionUID = -4515654492511136037L;
+ /** openid列表 */
+ @JsonProperty("openid_list")
+ private List openIds;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerUnbindResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerUnbindResponse.java
new file mode 100644
index 0000000000..9166bc0b58
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/sharer/SharerUnbindResponse.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.channel.bean.sharer;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 分享员解绑响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class SharerUnbindResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -2395560383862569445L;
+ /** 成功列表 */
+ @JsonProperty("success_openid")
+ private List successList;
+
+ /** 失败列表,可重试 */
+ @JsonProperty("fail_openid")
+ private List failList;
+
+ /** 拒绝列表,不可重试(openid错误,未到解绑时间等) */
+ @JsonProperty("refuse_openid")
+ private List refuseList;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/shop/ShopInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/shop/ShopInfo.java
new file mode 100644
index 0000000000..b2209a4309
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/shop/ShopInfo.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.shop;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 店铺信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class ShopInfo implements Serializable {
+
+ /** 店铺名称 */
+ @JsonProperty("nickname")
+ private String nickname;
+
+ /** 店铺头像URL */
+ @JsonProperty("headimg_url")
+ private String headImgUrl;
+
+ /** 店铺类型,目前为"企业"或"个体工商户" */
+ @JsonProperty("subject_type")
+ private String subjectType;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/shop/ShopInfoResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/shop/ShopInfoResponse.java
new file mode 100644
index 0000000000..b4317ad3c0
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/shop/ShopInfoResponse.java
@@ -0,0 +1,19 @@
+package me.chanjar.weixin.channel.bean.shop;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 店铺基本信息响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class ShopInfoResponse extends WxChannelBaseResponse {
+
+ @JsonProperty("info")
+ private ShopInfo info;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/LocationPriorityResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/LocationPriorityResponse.java
new file mode 100644
index 0000000000..5959cb746d
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/LocationPriorityResponse.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.bean.warehouse;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 仓库优先级响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class LocationPriorityResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -4037484169497319150L;
+
+ /** 按照out_warehouse_id排序优先级从高到低 */
+ @JsonProperty("priority_sort")
+ private List prioritySort;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/PriorityLocationParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/PriorityLocationParam.java
new file mode 100644
index 0000000000..0b304487a7
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/PriorityLocationParam.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.warehouse;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 带优先级的仓库区域
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class PriorityLocationParam extends WarehouseLocation {
+
+ private static final long serialVersionUID = -3087702364669180903L;
+
+ /** 按照out_warehouse_id排序优先级从高到低 */
+ @JsonProperty("priority_sort")
+ private List prioritySort;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/StockGetParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/StockGetParam.java
new file mode 100644
index 0000000000..99e00a4801
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/StockGetParam.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.warehouse;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class StockGetParam implements Serializable {
+
+ private static final long serialVersionUID = -4144913434092446664L;
+ /** 商品ID */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** skuID */
+ @JsonProperty("sku_id")
+ private String skuId;
+
+ /** 外部仓库ID */
+ @JsonProperty("out_warehouse_id")
+ private String outWarehouseId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/UpdateLocationParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/UpdateLocationParam.java
new file mode 100644
index 0000000000..5b71c0a4b4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/UpdateLocationParam.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.warehouse;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 仓库区域
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class UpdateLocationParam implements Serializable {
+
+ private static final long serialVersionUID = 6102771485047925091L;
+
+ /** 外部仓库ID */
+ @JsonProperty("out_warehouse_id")
+ private String outWarehouseId;
+
+ /** 覆盖区域 */
+ @JsonProperty("cover_locations")
+ private List coverLocations;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/Warehouse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/Warehouse.java
new file mode 100644
index 0000000000..7ca07e637f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/Warehouse.java
@@ -0,0 +1,36 @@
+package me.chanjar.weixin.channel.bean.warehouse;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 仓库
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class Warehouse implements Serializable {
+
+ private static final long serialVersionUID = -2322154583471063637L;
+
+ /** 外部仓库ID,一个店铺下,同一个外部ID只能创建一个仓库,最大32字符 */
+ @JsonProperty("out_warehouse_id")
+ private String outWarehouseId;
+
+ /** 仓库名称 */
+ @JsonProperty("name")
+ private String name;
+
+ /** 仓库介绍 */
+ @JsonProperty("intro")
+ private String intro;
+
+ /** 覆盖区域,可以在创建后添加 */
+ @JsonProperty("cover_locations")
+ private List coverLocations;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/WarehouseIdsResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/WarehouseIdsResponse.java
new file mode 100644
index 0000000000..57c989a56b
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/WarehouseIdsResponse.java
@@ -0,0 +1,48 @@
+package me.chanjar.weixin.channel.bean.warehouse;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import java.util.Map;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 仓库id列表响应
+ *
+ * @author Zeyes
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class WarehouseIdsResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 3974529583232187473L;
+
+ /** 外部仓库ID列表 */
+ @JsonProperty("out_warehouse_ids")
+ private List ids;
+
+ /** 本次翻页的上下文,用于请求下一页,如果是空,则当前是最后一页 */
+ @JsonProperty("next_key")
+ private String nextKey;
+
+ public WarehouseIdsResponse() {
+ }
+
+ @JsonProperty("data")
+ private void unpackNameFromNestedObject(Map map) {
+ if (map == null) {
+ return;
+ }
+ Object obj = map.get("out_warehouse_ids");
+ if (obj != null) {
+ if (obj instanceof List) {
+ this.ids = (List) obj;
+ }
+ }
+ obj = map.get("next_key");
+ if (obj != null) {
+ this.nextKey = (String) obj;
+ }
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/WarehouseLocation.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/WarehouseLocation.java
new file mode 100644
index 0000000000..33309522bb
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/WarehouseLocation.java
@@ -0,0 +1,36 @@
+package me.chanjar.weixin.channel.bean.warehouse;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 仓库区域
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class WarehouseLocation implements Serializable {
+
+ private static final long serialVersionUID = 1626579682640060352L;
+
+ /** 省份地址编码 */
+ @JsonProperty("address_id1")
+ private Integer addressId1;
+
+ /** 市地址编码 */
+ @JsonProperty("address_id2")
+ private Integer addressId2;
+
+ /** 区地址编码 */
+ @JsonProperty("address_id3")
+ private Integer addressId3;
+
+ /** 街道地址编码 */
+ @JsonProperty("address_id4")
+ private Integer addressId4;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/WarehouseLocationParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/WarehouseLocationParam.java
new file mode 100644
index 0000000000..2b64e55dea
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/WarehouseLocationParam.java
@@ -0,0 +1,22 @@
+package me.chanjar.weixin.channel.bean.warehouse;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import lombok.Data;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@JsonInclude(Include.NON_NULL)
+public class WarehouseLocationParam extends WarehouseLocation {
+
+ private static final long serialVersionUID = 3347484433136057123L;
+
+ public WarehouseLocationParam() {
+ }
+
+ public WarehouseLocationParam(Integer addressId1, Integer addressId2, Integer addressId3, Integer addressId4) {
+ super(addressId1, addressId2, addressId3, addressId4);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/WarehouseParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/WarehouseParam.java
new file mode 100644
index 0000000000..77ac1a8134
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/WarehouseParam.java
@@ -0,0 +1,20 @@
+package me.chanjar.weixin.channel.bean.warehouse;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 仓库
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class WarehouseParam extends Warehouse {
+
+ private static final long serialVersionUID = -3412047348380785225L;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/WarehouseResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/WarehouseResponse.java
new file mode 100644
index 0000000000..fa96771d67
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/WarehouseResponse.java
@@ -0,0 +1,21 @@
+package me.chanjar.weixin.channel.bean.warehouse;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 仓库响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class WarehouseResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 3206095869486573824L;
+ /** 仓库库存 */
+ @JsonProperty("data")
+ private Warehouse data;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/WarehouseStockParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/WarehouseStockParam.java
new file mode 100644
index 0000000000..5a4354504d
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/WarehouseStockParam.java
@@ -0,0 +1,22 @@
+package me.chanjar.weixin.channel.bean.warehouse;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.product.SkuStockParam;
+
+/**
+ * 库存参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class WarehouseStockParam extends SkuStockParam {
+
+ private static final long serialVersionUID = -5121207621628542490L;
+
+ /** 外部仓库ID */
+ @JsonProperty("out_warehouse_id")
+ private String outWarehouseId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/WarehouseStockResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/WarehouseStockResponse.java
new file mode 100644
index 0000000000..64d0d2b5b0
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/warehouse/WarehouseStockResponse.java
@@ -0,0 +1,34 @@
+package me.chanjar.weixin.channel.bean.warehouse;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.Map;
+import lombok.Data;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 仓库库存响应
+ *
+ * @author Zeyes
+ */
+@Data
+public class WarehouseStockResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 1810645965041317763L;
+ /** 仓库库存 */
+ @JsonProperty("num")
+ private Integer num;
+
+ public WarehouseStockResponse() {
+ }
+
+ @JsonProperty("data")
+ private void unpackNameFromNestedObject(Map map) {
+ if (map == null) {
+ return;
+ }
+ Object obj = map.get("num");
+ if (obj != null) {
+ this.num = (Integer) obj;
+ }
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/common/ChannelWxError.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/common/ChannelWxError.java
new file mode 100644
index 0000000000..eb8cda4996
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/common/ChannelWxError.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.common;
+
+import me.chanjar.weixin.channel.enums.WxChannelErrorMsgEnum;
+import me.chanjar.weixin.common.error.WxError;
+
+/**
+ * 微信视频号错误码
+ *
+ * @author Zeyes
+ */
+public class ChannelWxError extends WxError {
+
+ private static final long serialVersionUID = -2638512715814977441L;
+
+ public ChannelWxError() {
+ }
+
+ public ChannelWxError(int errorCode, String errorMsgEn) {
+ super(errorCode, errorMsgEn);
+ if (WxChannelErrorMsgEnum.findMsgByCode(errorCode) != null) {
+ this.setErrorMsg(WxChannelErrorMsgEnum.findMsgByCode(errorCode));
+ }
+ this.setErrorMsgEn(errorMsgEn);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/config/WxChannelConfig.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/config/WxChannelConfig.java
new file mode 100644
index 0000000000..ad24234fb0
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/config/WxChannelConfig.java
@@ -0,0 +1,185 @@
+package me.chanjar.weixin.channel.config;
+
+import java.util.concurrent.locks.Lock;
+import me.chanjar.weixin.channel.api.BaseWxChannelService;
+import me.chanjar.weixin.common.bean.WxAccessToken;
+import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
+
+/**
+ * 视频号小店配置
+ *
+ * @author Zeyes
+ */
+public interface WxChannelConfig {
+
+ /**
+ * Gets access token.
+ *
+ * @return the access token
+ */
+ String getAccessToken();
+
+ /**
+ * Gets access token lock.
+ *
+ * @return the access token lock
+ */
+ Lock getAccessTokenLock();
+
+ /**
+ * Is access token expired boolean.
+ *
+ * @return the boolean
+ */
+ boolean isAccessTokenExpired();
+
+ /**
+ * 强制将access token过期掉
+ */
+ void expireAccessToken();
+
+ /**
+ * 应该是线程安全的
+ *
+ * @param accessToken 要更新的WxAccessToken对象
+ */
+ void updateAccessToken(WxAccessToken accessToken);
+
+ /**
+ * 应该是线程安全的
+ *
+ * @param accessToken 新的accessToken值
+ * @param expiresInSeconds 过期时间,以秒为单位
+ */
+ void updateAccessToken(String accessToken, int expiresInSeconds);
+
+ /**
+ * Gets appid.
+ *
+ * @return the appid
+ */
+ String getAppid();
+
+ /**
+ * Gets secret.
+ *
+ * @return the secret
+ */
+ String getSecret();
+
+ /**
+ * Gets token.
+ *
+ * @return the token
+ */
+ String getToken();
+
+ /**
+ * Gets aes key.
+ *
+ * @return the aes key
+ */
+ String getAesKey();
+
+ /**
+ * Gets msg data format.
+ *
+ * @return the msg data format
+ */
+ String getMsgDataFormat();
+
+ /**
+ * Gets expires time.
+ *
+ * @return the expires time
+ */
+ long getExpiresTime();
+
+ /**
+ * Gets http proxy host.
+ *
+ * @return the http proxy host
+ */
+ String getHttpProxyHost();
+
+ /**
+ * Gets http proxy port.
+ *
+ * @return the http proxy port
+ */
+ int getHttpProxyPort();
+
+ /**
+ * Gets http proxy username.
+ *
+ * @return the http proxy username
+ */
+ String getHttpProxyUsername();
+
+ /**
+ * Gets http proxy password.
+ *
+ * @return the http proxy password
+ */
+ String getHttpProxyPassword();
+
+ /**
+ * http 请求重试间隔
+ *
+ * {@link BaseWxChannelService#setRetrySleepMillis(int)(int)}
+ *
+ */
+ int getRetrySleepMillis();
+
+ /**
+ * http 请求最大重试次数
+ *
+ * {@link BaseWxChannelService#setMaxRetryTimes(int)}
+ *
+ */
+ int getMaxRetryTimes();
+
+ /**
+ * http client builder
+ *
+ * @return ApacheHttpClientBuilder apache http client builder
+ */
+ ApacheHttpClientBuilder getApacheHttpClientBuilder();
+
+ /**
+ * 是否自动刷新token
+ *
+ * @return the boolean
+ */
+ boolean autoRefreshToken();
+
+ /**
+ * 设置自定义的apiHost地址
+ * 具体取值,可以参考https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Interface_field_description.html
+ *
+ * @param apiHostUrl api域名地址
+ */
+ void setApiHostUrl(String apiHostUrl);
+
+ /**
+ * 获取自定义的apiHost地址,用于替换原请求中的https://api.weixin.qq.com
+ * 具体取值,可以参考https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Interface_field_description.html
+ *
+ * @return 自定义的api域名地址
+ */
+ String getApiHostUrl();
+
+ /**
+ * 获取自定义的获取accessToken地址,用于向自定义统一服务获取accessToken
+ *
+ * @return 自定义的获取accessToken地址
+ */
+ String getAccessTokenUrl();
+
+ /**
+ * 设置自定义的获取accessToken地址 可用于设置获取accessToken的自定义服务
+ *
+ * @param accessTokenUrl 自定义的获取accessToken地址
+ */
+ void setAccessTokenUrl(String accessTokenUrl);
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/config/impl/WxChannelDefaultConfigImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/config/impl/WxChannelDefaultConfigImpl.java
new file mode 100644
index 0000000000..e32bcad83e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/config/impl/WxChannelDefaultConfigImpl.java
@@ -0,0 +1,233 @@
+package me.chanjar.weixin.channel.config.impl;
+
+import java.io.File;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import lombok.Getter;
+import me.chanjar.weixin.channel.config.WxChannelConfig;
+import me.chanjar.weixin.channel.util.JsonUtils;
+import me.chanjar.weixin.common.bean.WxAccessToken;
+import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
+
+/**
+ * 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化
+ *
+ * @author Zeyes
+ */
+@Getter
+public class WxChannelDefaultConfigImpl implements WxChannelConfig {
+
+ protected volatile String appid;
+ protected volatile String token;
+ protected Lock accessTokenLock = new ReentrantLock();
+ /**
+ * 临时文件目录.
+ */
+ protected volatile File tmpDirFile;
+ private volatile String msgDataFormat;
+ private volatile String secret;
+ private volatile String accessToken;
+ private volatile String aesKey;
+ private volatile long expiresTime;
+ private volatile String httpProxyHost;
+ private volatile int httpProxyPort;
+ private volatile String httpProxyUsername;
+ private volatile String httpProxyPassword;
+
+ private volatile int retrySleepMillis = 1000;
+ private volatile int maxRetryTimes = 5;
+ private volatile ApacheHttpClientBuilder apacheHttpClientBuilder;
+ private String apiHostUrl;
+ private String accessTokenUrl;
+
+ /**
+ * 会过期的数据提前过期时间,默认预留200秒的时间
+ */
+ protected long expiresAheadInMillis(int expiresInSeconds) {
+ return System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
+ }
+
+ /**
+ * 判断 expiresTime 是否已经过期
+ */
+ protected boolean isExpired(long expiresTime) {
+ return System.currentTimeMillis() > expiresTime;
+ }
+
+ @Override
+ public String getAccessToken() {
+ return this.accessToken;
+ }
+
+ public void setAccessToken(String accessToken) {
+ this.accessToken = accessToken;
+ }
+
+ @Override
+ public Lock getAccessTokenLock() {
+ return this.accessTokenLock;
+ }
+
+ public void setAccessTokenLock(Lock accessTokenLock) {
+ this.accessTokenLock = accessTokenLock;
+ }
+
+ @Override
+ public boolean isAccessTokenExpired() {
+ return isExpired(this.expiresTime);
+ }
+
+ @Override
+ public synchronized void updateAccessToken(WxAccessToken accessToken) {
+ updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
+ }
+
+ @Override
+ public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) {
+ setAccessToken(accessToken);
+ setExpiresTime(expiresAheadInMillis(expiresInSeconds));
+ }
+
+
+ @Override
+ public void expireAccessToken() {
+ this.expiresTime = 0;
+ }
+
+ @Override
+ public String getSecret() {
+ return this.secret;
+ }
+
+ public void setSecret(String secret) {
+ this.secret = secret;
+ }
+
+ @Override
+ public String getToken() {
+ return this.token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+
+ @Override
+ public long getExpiresTime() {
+ return this.expiresTime;
+ }
+
+ public void setExpiresTime(long expiresTime) {
+ this.expiresTime = expiresTime;
+ }
+
+ @Override
+ public String getAesKey() {
+ return this.aesKey;
+ }
+
+ public void setAesKey(String aesKey) {
+ this.aesKey = aesKey;
+ }
+
+ @Override
+ public String getMsgDataFormat() {
+ return this.msgDataFormat;
+ }
+
+ public void setMsgDataFormat(String msgDataFormat) {
+ this.msgDataFormat = msgDataFormat;
+ }
+
+ @Override
+ public String getHttpProxyHost() {
+ return this.httpProxyHost;
+ }
+
+ public void setHttpProxyHost(String httpProxyHost) {
+ this.httpProxyHost = httpProxyHost;
+ }
+
+ @Override
+ public int getHttpProxyPort() {
+ return this.httpProxyPort;
+ }
+
+ public void setHttpProxyPort(int httpProxyPort) {
+ this.httpProxyPort = httpProxyPort;
+ }
+
+ @Override
+ public String getHttpProxyUsername() {
+ return this.httpProxyUsername;
+ }
+
+ public void setHttpProxyUsername(String httpProxyUsername) {
+ this.httpProxyUsername = httpProxyUsername;
+ }
+
+ @Override
+ public String getHttpProxyPassword() {
+ return this.httpProxyPassword;
+ }
+
+ public void setHttpProxyPassword(String httpProxyPassword) {
+ this.httpProxyPassword = httpProxyPassword;
+ }
+
+ @Override
+ public int getRetrySleepMillis() {
+ return this.retrySleepMillis;
+ }
+
+ public void setRetrySleepMillis(int retrySleepMillis) {
+ this.retrySleepMillis = retrySleepMillis;
+ }
+
+ @Override
+ public int getMaxRetryTimes() {
+ return this.maxRetryTimes;
+ }
+
+ public void setMaxRetryTimes(int maxRetryTimes) {
+ this.maxRetryTimes = maxRetryTimes;
+ }
+
+ @Override
+ public String toString() {
+ return JsonUtils.encode(this);
+ }
+
+ @Override
+ public ApacheHttpClientBuilder getApacheHttpClientBuilder() {
+ return this.apacheHttpClientBuilder;
+ }
+
+ public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) {
+ this.apacheHttpClientBuilder = apacheHttpClientBuilder;
+ }
+
+ @Override
+ public boolean autoRefreshToken() {
+ return true;
+ }
+
+ @Override
+ public void setApiHostUrl(String apiHostUrl) {
+ this.apiHostUrl = apiHostUrl;
+ }
+
+ @Override
+ public void setAccessTokenUrl(String accessTokenUrl) {
+ this.accessTokenUrl = accessTokenUrl;
+ }
+
+ @Override
+ public String getAppid() {
+ return appid;
+ }
+
+ public void setAppid(String appid) {
+ this.appid = appid;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/config/impl/WxChannelRedisConfigImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/config/impl/WxChannelRedisConfigImpl.java
new file mode 100644
index 0000000000..cbb289c899
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/config/impl/WxChannelRedisConfigImpl.java
@@ -0,0 +1,73 @@
+package me.chanjar.weixin.channel.config.impl;
+
+import java.util.concurrent.TimeUnit;
+import me.chanjar.weixin.common.redis.WxRedisOps;
+
+/**
+ * 基于redis存储的微信视频号小店配置类
+ *
+ * @author Zeyes
+ */
+public class WxChannelRedisConfigImpl extends WxChannelDefaultConfigImpl {
+
+ private static final String ACCESS_TOKEN_KEY_TPL = "%s:access_token:%s";
+ private static final String LOCK_KEY_TPL = "%s:lock:%s:";
+
+ private final WxRedisOps redisOps;
+ private final String keyPrefix;
+
+ private volatile String accessTokenKey;
+ private volatile String lockKey;
+
+ public WxChannelRedisConfigImpl(WxRedisOps redisOps, String keyPrefix) {
+ this.redisOps = redisOps;
+ this.keyPrefix = keyPrefix;
+ }
+
+ @Override
+ public void setAppid(String appId) {
+ super.setAppid(appId);
+ this.accessTokenKey = String.format(ACCESS_TOKEN_KEY_TPL, this.keyPrefix, appId);
+ this.lockKey = String.format(LOCK_KEY_TPL, this.keyPrefix, appId);
+ super.accessTokenLock = this.redisOps.getLock(lockKey.concat("accessTokenLock"));
+ }
+
+ //------------------------------------------------------------------------
+ // token相关
+ //------------------------------------------------------------------------
+ @Override
+ public String getAccessToken() {
+ return redisOps.getValue(this.accessTokenKey);
+ }
+
+ @Override
+ public boolean isAccessTokenExpired() {
+ Long expire = redisOps.getExpire(this.accessTokenKey);
+ return expire == null || expire < 2;
+ }
+
+ @Override
+ public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) {
+ redisOps.setValue(this.accessTokenKey, accessToken, expiresInSeconds - 200, TimeUnit.SECONDS);
+ }
+
+ @Override
+ public void expireAccessToken() {
+ redisOps.expire(this.accessTokenKey, 0, TimeUnit.SECONDS);
+ }
+
+
+ @Override
+ public String toString() {
+ return "WxChannelRedisConfigImpl{" +
+ "appid='" + appid + '\'' +
+ ", token='" + token + '\'' +
+ ", accessTokenLock=" + accessTokenLock +
+ ", tmpDirFile=" + tmpDirFile +
+ ", redisOps=" + redisOps +
+ ", keyPrefix='" + keyPrefix + '\'' +
+ ", accessTokenKey='" + accessTokenKey + '\'' +
+ ", lockKey='" + lockKey + '\'' +
+ '}';
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/config/impl/WxChannelRedissonConfigImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/config/impl/WxChannelRedissonConfigImpl.java
new file mode 100644
index 0000000000..d5de517163
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/config/impl/WxChannelRedissonConfigImpl.java
@@ -0,0 +1,89 @@
+package me.chanjar.weixin.channel.config.impl;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import lombok.NonNull;
+import me.chanjar.weixin.common.bean.WxAccessToken;
+import me.chanjar.weixin.common.redis.RedissonWxRedisOps;
+import me.chanjar.weixin.common.redis.WxRedisOps;
+import org.apache.commons.lang3.StringUtils;
+import org.redisson.api.RedissonClient;
+
+/**
+ * 基于Redisson的实现
+ *
+ * @author yuanqixun
+ * created on 2020/5/3
+ */
+public class WxChannelRedissonConfigImpl extends WxChannelDefaultConfigImpl {
+
+ protected static final String LOCK_KEY = "wx_channel_lock:";
+ protected static final String MA_ACCESS_TOKEN_KEY = "wx_channel_access_token_key:";
+
+ /**
+ * redis 存储的 key 的前缀,可为空
+ */
+ protected String keyPrefix;
+ protected String accessTokenKey;
+ protected String lockKey;
+
+ private final WxRedisOps redisOps;
+
+ public WxChannelRedissonConfigImpl(@NonNull RedissonClient redissonClient, String keyPrefix) {
+ this(new RedissonWxRedisOps(redissonClient), keyPrefix);
+ }
+
+ public WxChannelRedissonConfigImpl(@NonNull RedissonClient redissonClient) {
+ this(redissonClient, null);
+ }
+
+ private WxChannelRedissonConfigImpl(@NonNull WxRedisOps redisOps, String keyPrefix) {
+ this.redisOps = redisOps;
+ this.keyPrefix = keyPrefix;
+ }
+
+ @Override
+ public void setAppid(String appid) {
+ super.setAppid(appid);
+ String prefix = StringUtils.isBlank(keyPrefix) ? "" :
+ (StringUtils.endsWith(keyPrefix, ":") ? keyPrefix : (keyPrefix + ":"));
+ lockKey = prefix + LOCK_KEY.concat(appid);
+ accessTokenKey = prefix + MA_ACCESS_TOKEN_KEY.concat(appid);
+ }
+
+ protected Lock getLockByKey(String key) {
+ return redisOps.getLock(key);
+ }
+
+ @Override
+ public Lock getAccessTokenLock() {
+ return getLockByKey(this.lockKey.concat(":").concat("accessToken"));
+ }
+
+ @Override
+ public String getAccessToken() {
+ return redisOps.getValue(this.accessTokenKey);
+ }
+
+ @Override
+ public boolean isAccessTokenExpired() {
+ Long expire = redisOps.getExpire(this.accessTokenKey);
+ return expire == null || expire < 2;
+ }
+
+ @Override
+ public void updateAccessToken(WxAccessToken accessToken) {
+ redisOps.setValue(this.accessTokenKey, accessToken.getAccessToken(), accessToken.getExpiresIn(), TimeUnit.SECONDS);
+ }
+
+ @Override
+ public void updateAccessToken(String accessToken, int expiresInSeconds) {
+ redisOps.setValue(this.accessTokenKey, accessToken, expiresInSeconds, TimeUnit.SECONDS);
+ }
+
+ @Override
+ public void expireAccessToken() {
+ redisOps.expire(this.accessTokenKey, 0, TimeUnit.SECONDS);
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/constant/MessageEventConstants.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/constant/MessageEventConstants.java
new file mode 100644
index 0000000000..e0e419efc6
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/constant/MessageEventConstants.java
@@ -0,0 +1,70 @@
+package me.chanjar.weixin.channel.constant;
+
+/**
+ * 消息回调
+ *
+ * @author Zeyes
+ */
+public interface MessageEventConstants {
+ /** 品牌资质事件回调 */
+ String BRAND = "channels_ec_brand";
+ /** 商品审核结果 */
+ String PRODUCT_SPU_AUDIT = "product_spu_audit";
+ /** 商品上下架 */
+ String PRODUCT_SPU_STATUS_UPDATE = "product_spu_listing";
+ /** 商品更新 */
+ String PRODUCT_SPU_UPDATE = "product_spu_update";
+ /** 类目审核结果 */
+ String PRODUCT_CATEGORY_AUDIT = "product_category_audit";
+ /** 订单下单 */
+ String ORDER_NEW = "channels_ec_order_new";
+ /** 订单取消 */
+ String ORDER_CANCEL = "channels_ec_order_cancel";
+ /** 订单支付成功 */
+ String ORDER_PAY = "channels_ec_order_pay";
+ /** 订单发货 */
+ String ORDER_DELIVER = "channels_ec_order_deliver";
+ /** 订单确认收货 */
+ String ORDER_CONFIRM = "channels_ec_order_confirm";
+ /** 订单结算成功 */
+ String ORDER_SETTLE = "channels_ec_order_settle";
+ /** 订单其他信息更新 */
+ String ORDER_EXT_INFO_UPDATE = "channels_ec_order_ext_info_update";
+ /** 订单状态更新 */
+ String ORDER_STATUS_UPDATE = "product_order_status_update";
+ /** 售后单更新通知 */
+ String AFTER_SALE_UPDATE = "channels_ec_aftersale_update";
+ /** 纠纷更新通知 */
+ String COMPLAINT_NOTIFY = "channels_ec_complaint_update";
+ // 优惠券相关
+ /** 优惠券领取通知 */
+ String RECEIVE_COUPON = "channels_ec_coupon_receive";
+ /** 创建优惠券通知 */
+ String CREATE_COUPON = "channels_ec_coupon_create";
+ /** 优惠券删除通知 */
+ String DELETE_COUPON = "channels_ec_coupon_delete";
+ /** 优惠券过期通知 */
+ String EXPIRE_COUPON = "channels_ec_coupon_expire";
+ /** 更新优惠券信息通知 */
+ String UPDATE_COUPON_INFO = "channels_ec_coupon_info_change";
+ /** 优惠券作废通知 */
+ String INVALID_COUPON = "channels_ec_coupon_invalid";
+ /** 用户优惠券过期通知 */
+ String USER_COUPON_EXPIRE = "channels_ec_user_coupon_expire";
+ /** 优惠券返还通知 */
+ String USER_COUPON_UNUSE = "channels_ec_user_coupon_unuse";
+ /** 优惠券核销通知 */
+ String USER_COUPON_USE = "channels_ec_user_coupon_use";
+ // 资金相关
+ /** 结算账户变更回调 */
+ String ACCOUNT_NOTIFY = "channels_ec_acct_notify";
+ /** 提现回调 */
+ String WITHDRAW_NOTIFY = "channels_ec_withdraw_notify";
+ /** 提现二维码回调 */
+ String QRCODE_STATUS = "qrcode_status";
+ // 团长
+ String SUPPLIER_ITEM_UPDATE = "head_supplier_item_update";
+ // 其他
+ /** 进入会话事件 */
+ String USER_ENTER_TEMP_SESSION = "user_enter_tempsession";
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/constant/WxChannelApiUrlConstants.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/constant/WxChannelApiUrlConstants.java
new file mode 100644
index 0000000000..03047dd3bd
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/constant/WxChannelApiUrlConstants.java
@@ -0,0 +1,350 @@
+package me.chanjar.weixin.channel.constant;
+
+import lombok.experimental.UtilityClass;
+
+/**
+ * 视频号小店接口地址常量
+ *
+ * @author Zeyes
+ */
+@UtilityClass
+public class WxChannelApiUrlConstants {
+
+ /**
+ * 获取access_token.
+ */
+ public static final String GET_ACCESS_TOKEN_URL =
+ "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
+
+ /** 基础接口 */
+ public interface Basics {
+
+ /** 获取店铺基本信息 */
+ String GET_SHOP_INFO = "https://api.weixin.qq.com/channels/ec/basics/info/get";
+ /** 上传图片 */
+ String IMG_UPLOAD_URL = "https://api.weixin.qq.com/channels/ec/basics/img/upload";
+ /** 上传资质图片 */
+ String UPLOAD_QUALIFICATION_FILE = "https://api.weixin.qq.com/channels/ec/basics/qualification/upload";
+ /** 下载图片 */
+ String GET_IMG_URL = "https://api.weixin.qq.com/channels/ec/basics/media/get";
+ /** 获取地址编码 */
+ String GET_ADDRESS_CODE = "https://api.weixin.qq.com/channels/ec/basics/addresscode/get";
+ }
+
+ /** 商品类目相关接口 */
+ public interface Category {
+
+ /** 获取所有的类目 */
+ String LIST_ALL_CATEGORY_URL = "https://api.weixin.qq.com/channels/ec/category/all";
+ /** 获取类目详情 */
+ String GET_CATEGORY_DETAIL_URL = "https://api.weixin.qq.com/channels/ec/category/detail";
+ /** 获取可用的子类目详情 */
+ String AVAILABLE_CATEGORY_URL = "https://api.weixin.qq.com/channels/ec/category/availablesoncategories/get";
+ /** 上传类目资质 */
+ String ADD_CATEGORY_URL = "https://api.weixin.qq.com/channels/ec/category/add";
+ /** 获取类目审核结果 */
+ String GET_CATEGORY_AUDIT_URL = "https://api.weixin.qq.com/channels/ec/category/audit/get";
+ /** 取消类目提审 */
+ String CANCEL_CATEGORY_AUDIT_URL = "https://api.weixin.qq.com/channels/ec/category/audit/cancel";
+ /** 获取账号申请通过的类目和资质信息 */
+ String LIST_PASS_CATEGORY_URL = "https://api.weixin.qq.com/channels/ec/category/list/get";
+ }
+
+ /** 品牌资质相关接口 */
+ public interface Brand {
+
+ /** 获取品牌库列表 */
+ String ALL_BRAND_URL = "https://api.weixin.qq.com/channels/ec/brand/all";
+ /** 新增品牌资质 */
+ String ADD_BRAND_URL = "https://api.weixin.qq.com/channels/ec/brand/add";
+ /** 更新品牌资质 */
+ String UPDATE_BRAND_URL = "https://api.weixin.qq.com/channels/ec/brand/update";
+ /** 撤回品牌资质审核 */
+ String CANCEL_BRAND_AUDIT_URL = "https://api.weixin.qq.com/channels/ec/brand/audit/cancel";
+ /** 删除品牌资质 */
+ String DELETE_BRAND_URL = "https://api.weixin.qq.com/channels/ec/brand/delete";
+ /** 获取品牌资质申请详情 */
+ String GET_BRAND_URL = "https://api.weixin.qq.com/channels/ec/brand/get";
+ /** 获取品牌资质申请列表 */
+ String LIST_BRAND_URL = "https://api.weixin.qq.com/channels/ec/brand/list/get";
+ /** 获取生效中的品牌资质列表 */
+ String LIST_BRAND_VALID_URL = "https://api.weixin.qq.com/channels/ec/brand/valid/list/get";
+ }
+
+ /** 商品操作相关接口 */
+ public interface Spu {
+
+ /** 添加商品 */
+ String SPU_ADD_URL = "https://api.weixin.qq.com/channels/ec/product/add";
+ /** 删除商品 */
+ String SPU_DEL_URL = "https://api.weixin.qq.com/channels/ec/product/delete";
+ /** 获取商品详情 */
+ String SPU_GET_URL = "https://api.weixin.qq.com/channels/ec/product/get";
+ /** 获取商品列表 */
+ String SPU_LIST_URL = "https://api.weixin.qq.com/channels/ec/product/list/get";
+ /** 更新商品 */
+ String SPU_UPDATE_URL = "https://api.weixin.qq.com/channels/ec/product/update";
+ /** 上架商品 */
+ String SPU_LISTING_URL = "https://api.weixin.qq.com/channels/ec/product/listing";
+ /** 下架商品 */
+ String SPU_DELISTING_URL = "https://api.weixin.qq.com/channels/ec/product/delisting";
+ /** 撤回商品审核 */
+ String CANCEL_AUDIT_URL = "https://api.weixin.qq.com/channels/ec/product/audit/cancel";
+ /** 获取实时库存 */
+ String SPU_GET_STOCK_URL = "https://api.weixin.qq.com/channels/ec/product/stock/get";
+ /** 更新商品库存 */
+ String SPU_UPDATE_STOCK_URL = "https://api.weixin.qq.com/channels/ec/product/stock/update";
+ /** 添加限时抢购任务 */
+ String ADD_LIMIT_TASK_URL = "https://api.weixin.qq.com/channels/ec/product/limiteddiscounttask/add";
+ /** 拉取限时抢购任务列表 */
+ String LIST_LIMIT_TASK_URL = "https://api.weixin.qq.com/channels/ec/product/limiteddiscounttask/list/get";
+ /** 停止限时抢购任务 */
+ String STOP_LIMIT_TASK_URL = "https://api.weixin.qq.com/channels/ec/product/limiteddiscounttask/stop";
+ /** 删除限时抢购任务 */
+ String DELETE_LIMIT_TASK_URL = "https://api.weixin.qq.com/channels/ec/product/limiteddiscounttask/delete";
+ }
+
+ /** 区域仓库 */
+ public interface Warehouse {
+
+ /** 添加区域仓库 */
+ String ADD_WAREHOUSE_URL = "https://api.weixin.qq.com/channels/ec/warehouse/create";
+ /** 获取区域仓库列表 */
+ String LIST_WAREHOUSE_URL = "https://api.weixin.qq.com/channels/ec/warehouse/list/get";
+ /** 获取区域仓库详情 */
+ String GET_WAREHOUSE_URL = "https://api.weixin.qq.com/channels/ec/warehouse/get";
+ /** 更新区域仓库详情 */
+ String UPDATE_WAREHOUSE_URL = "https://api.weixin.qq.com/channels/ec/warehouse/detail/update";
+ /** 批量增加覆盖区域 */
+ String ADD_COVER_AREA_URL = "https://api.weixin.qq.com/channels/ec/warehouse/coverlocations/add";
+ /** 批量删除覆盖区域 */
+ String DELETE_COVER_AREA_URL = "https://api.weixin.qq.com/channels/ec/warehouse/coverlocations/del";
+ /** 设置指定地址下的仓的优先级 */
+ String SET_WAREHOUSE_PRIORITY_URL = "https://api.weixin.qq.com/channels/ec/warehouse/address/prioritysort/set";
+ /** 获取指定地址下的仓的优先级 */
+ String GET_WAREHOUSE_PRIORITY_URL = "https://api.weixin.qq.com/channels/ec/warehouse/address/prioritysort/get";
+ /** 更新区域仓库存 */
+ String UPDATE_WAREHOUSE_STOCK_URL = "https://api.weixin.qq.com/channels/ec/warehouse/stock/update";
+ /** 获取区域仓库存 */
+ String GET_WAREHOUSE_STOCK_URL = "https://api.weixin.qq.com/channels/ec/warehouse/stock/get";
+ }
+
+ /** 订单相关接口 */
+ public interface Order {
+
+ /** 获取订单列表 */
+ String ORDER_LIST_URL = "https://api.weixin.qq.com/channels/ec/order/list/get";
+ /** 获取订单详情 */
+ String ORDER_GET_URL = "https://api.weixin.qq.com/channels/ec/order/get";
+ /** 更改订单价格 */
+ String UPDATE_PRICE_URL = "https://api.weixin.qq.com/channels/ec/order/price/update";
+ /** 修改订单备注 */
+ String UPDATE_REMARK_URL = "https://api.weixin.qq.com/channels/ec/order/merchantnotes/update";
+ /** 更修改订单地址 */
+ String UPDATE_ADDRESS_URL = "https://api.weixin.qq.com/channels/ec/order/address/update";
+ /** 修改物流信息 */
+ String UPDATE_EXPRESS_URL = "https://api.weixin.qq.com/channels/ec/order/deliveryinfo/update";
+ /** 订单搜索 */
+ String ORDER_SEARCH_URL = "https://api.weixin.qq.com/channels/ec/order/search";
+ }
+
+ /** 售后相关接口 */
+ public interface AfterSale {
+
+ /** 获取售后列表 */
+ String AFTER_SALE_LIST_URL = "https://api.weixin.qq.com/channels/ec/aftersale/getaftersalelist";
+ /** 获取售后单 */
+ String AFTER_SALE_GET_URL = "https://api.weixin.qq.com/channels/ec/aftersale/getaftersaleorder";
+ /** 同意售后 */
+ String AFTER_SALE_ACCEPT_URL = "https://api.weixin.qq.com/channels/ec/aftersale/acceptapply";
+ /** 拒绝售后 */
+ String AFTER_SALE_REJECT_URL = "https://api.weixin.qq.com/channels/ec/aftersale/rejectapply";
+ /** 上传退款凭证 */
+ String AFTER_SALE_UPLOAD_URL = "https://api.weixin.qq.com/channels/ec/aftersale/uploadrefundcertificate";
+ }
+
+ /** 纠纷相关接口 */
+ public interface Complaint {
+
+ /** 商家补充纠纷单留言 */
+ String ADD_COMPLAINT_MATERIAL_URL = "https://api.weixin.qq.com/channels/ec/aftersale/addcomplaintmaterial";
+ /** 商家举证 */
+ String ADD_COMPLAINT_PROOF_URL = "https://api.weixin.qq.com/channels/ec/aftersale/addcomplaintproof";
+ /** 获取纠纷单 */
+ String GET_COMPLAINT_ORDER_URL = "https://api.weixin.qq.com/channels/ec/aftersale/getcomplaintorder";
+ }
+
+ /** 物流相关接口 */
+ public interface Delivery {
+
+ /** 获取快递公司列表 */
+ String GET_DELIVERY_COMPANY_URL = "https://api.weixin.qq.com/channels/ec/order/deliverycompanylist/get";
+ /** 订单发货 */
+ String DELIVERY_SEND_URL = "https://api.weixin.qq.com/channels/ec/order/delivery/send";
+ }
+
+ /** 运费模板相关接口 */
+ public interface FreightTemplate {
+
+ /** 获取运费模板列表 */
+ String LIST_TEMPLATE_URL = "https://api.weixin.qq.com/channels/ec/merchant/getfreighttemplatelist";
+ /** 查询运费模版 */
+ String GET_TEMPLATE_URL = "https://api.weixin.qq.com/channels/ec/merchant/getfreighttemplatedetail";
+ /** 增加运费模版 */
+ String ADD_TEMPLATE_URL = "https://api.weixin.qq.com/channels/ec/merchant/addfreighttemplate";
+ /** 更新运费模版 */
+ String UPDATE_TEMPLATE_URL = "https://api.weixin.qq.com/channels/ec/merchant/updatefreighttemplate";
+ }
+
+ /** 地址管理相关接口 */
+ public interface Address {
+
+ /** 增加地址 */
+ String ADD_ADDRESS_URL = "https://api.weixin.qq.com/channels/ec/merchant/address/add";
+ /** 获取地址列表 */
+ String LIST_ADDRESS_URL = "https://api.weixin.qq.com/channels/ec/merchant/address/list";
+ /** 获取地址详情 */
+ String GET_ADDRESS_URL = "https://api.weixin.qq.com/channels/ec/merchant/address/get";
+ /** 更新地址 */
+ String UPDATE_ADDRESS_URL = "https://api.weixin.qq.com/channels/ec/merchant/address/update";
+ /** 删除地址 */
+ String DELETE_ADDRESS_URL = "https://api.weixin.qq.com/channels/ec/merchant/address/delete";
+ }
+
+ /** 优惠券相关接口 */
+ public interface Coupon {
+
+ /** 创建优惠券 */
+ String CREATE_COUPON_URL = "https://api.weixin.qq.com/channels/ec/coupon/create";
+ /** 更新优惠券 */
+ String UPDATE_COUPON_URL = "https://api.weixin.qq.com/channels/ec/coupon/update";
+ /** 更新优惠券状态 */
+ String UPDATE_COUPON_STATUS_URL = "https://api.weixin.qq.com/channels/ec/coupon/update_status";
+ /** 获取优惠券详情 */
+ String GET_COUPON_URL = "https://api.weixin.qq.com/channels/ec/coupon/get";
+ /** 获取优惠券ID列表 */
+ String LIST_COUPON_URL = "https://api.weixin.qq.com/channels/ec/coupon/get_list";
+ /** 获取用户优惠券ID列表 */
+ String LIST_USER_COUPON_URL = "https://api.weixin.qq.com/channels/ec/coupon/get_user_coupon_list";
+ /** 获取用户优惠券详情 */
+ String GET_USER_COUPON_URL = "https://api.weixin.qq.com/channels/ec/coupon/get_user_coupon";
+ }
+
+ /** 分享员相关接口 */
+ public interface Share {
+
+ /** 邀请分享员 */
+ String BIND_SHARER_URL = "https://api.weixin.qq.com/channels/ec/sharer/bind";
+ /** 获取绑定的分享员 */
+ String SEARCH_SHARER_URL = "https://api.weixin.qq.com/channels/ec/sharer/search_sharer";
+ /** 获取绑定的分享员列表 */
+ String LIST_SHARER_URL = "https://api.weixin.qq.com/channels/ec/sharer/get_sharer_list";
+ /** 获取分享员订单列表 */
+ String LIST_SHARER_ORDER_URL = "https://api.weixin.qq.com/channels/ec/sharer/get_sharer_order_list";
+ /** 解绑分享员 */
+ String UNBIND_SHARER_URL = "https://api.weixin.qq.com/channels/ec/sharer/unbind";
+ }
+
+ /** 资金相关接口 */
+ public interface Fund {
+
+ /** 获取账户余额 */
+ String GET_BALANCE_URL = "https://api.weixin.qq.com/channels/ec/funds/getbalance";
+ /** 获取结算账户 */
+ String GET_BANK_ACCOUNT_URL = "https://api.weixin.qq.com/channels/ec/funds/getbankacct";
+ /** 获取资金流水详情 */
+ String GET_BALANCE_FLOW_DETAIL_URL = "https://api.weixin.qq.com/channels/ec/league/funds/getfundsflowdetail";
+ /** 获取资金流水列表 */
+ String GET_BALANCE_FLOW_LIST_URL = "https://api.weixin.qq.com/channels/ec/league/funds/getfundsflowlist";
+ /** 获取提现记录 */
+ String GET_WITHDRAW_DETAIL_URL = "https://api.weixin.qq.com/channels/ec/funds/getwithdrawdetail";
+ /** 获取提现记录列表 */
+ String GET_WITHDRAW_LIST_URL = "https://api.weixin.qq.com/channels/ec/funds/getwithdrawlist";
+ /** 修改结算账户 */
+ String SET_BANK_ACCOUNT_URL = "https://api.weixin.qq.com/channels/ec/funds/setbankacct";
+ /** 商户提现 */
+ String WITHDRAW_URL = "https://api.weixin.qq.com/channels/ec/funds/submitwithdraw";
+ /** 根据卡号查银行信息 */
+ String GET_BANK_BY_NUM_URL = "https://api.weixin.qq.com/shop/funds/getbankbynum";
+ /** 搜索银行列表 */
+ String GET_BANK_LIST_URL = "https://api.weixin.qq.com/shop/funds/getbanklist";
+ /** 查询城市列表 */
+ String GET_CITY_URL = "https://api.weixin.qq.com/shop/funds/getcity";
+ /** 查询大陆银行省份列表 */
+ String GET_PROVINCE_URL = "https://api.weixin.qq.com/shop/funds/getprovince";
+ /** 查询支行列表 */
+ String GET_SUB_BANK_URL = "https://api.weixin.qq.com/shop/funds/getsubbranch";
+ /** 获取二维码 */
+ String GET_QRCODE_URL = "https://api.weixin.qq.com/shop/funds/qrcode/get";
+ /** 查询扫码状态 */
+ String CHECK_QRCODE_URL = "https://api.weixin.qq.com/shop/funds/qrcode/check";
+ }
+
+ /** 优选联盟相关接口 */
+ public interface League {
+
+ /** 添加团长商品到橱窗 */
+ String ADD_SUPPLIER_GOODS_URL = "https://api.weixin.qq.com/channels/ec/league/headsupplier/window/add";
+ /** 查询橱窗上团长商品列表 */
+ String LIST_SUPPLIER_GOODS_URL = "https://api.weixin.qq.com/channels/ec/league/headsupplier/window/getall";
+ /** 从橱窗移除团长商品 */
+ String REMOVE_SUPPLIER_GOODS_URL = "https://api.weixin.qq.com/channels/ec/league/headsupplier/window/remove";
+ /** 查询橱窗上团长商品详情 */
+ String GET_SUPPLIER_GOODS_URL = "https://api.weixin.qq.com/channels/ec/league/headsupplier/window/getdetail";
+ /** 获取达人橱窗授权链接 */
+ String GET_SUPPLIER_AUTH_URL = "https://api.weixin.qq.com/channels/ec/league/headsupplier/windowauth/get";
+ /** 获取达人橱窗授权状态 */
+ String GET_SUPPLIER_AUTH_STATUS_URL = "https://api.weixin.qq.com/channels/ec/league/headsupplier/windowauth/status/get";
+ /** 获取团长账户余额 */
+ String GET_SUPPLIER_BALANCE_URL = "https://api.weixin.qq.com/channels/ec/league/headsupplier/funds/balance/get";
+ /** 获取资金流水详情 */
+ String GET_SUPPLIER_BALANCE_FLOW_DETAIL_URL = "https://api.weixin.qq.com/channels/ec/league/headsupplier/funds/flowdetail/get";
+ /** 获取资金流水列表 */
+ String GET_SUPPLIER_BALANCE_FLOW_LIST_URL = "https://api.weixin.qq.com/channels/ec/league/headsupplier/funds/flowlist/get";
+ /** 获取合作商品详情 */
+ String GET_SUPPLIER_ITEM_URL = "https://api.weixin.qq.com/channels/ec/league/headsupplier/item/get";
+ /** 获取合作商品列表 */
+ String GET_SUPPLIER_ITEM_LIST_URL = "https://api.weixin.qq.com/channels/ec/league/headsupplier/item/list/get";
+ /** 获取佣金单详情 */
+ String GET_SUPPLIER_ORDER_URL = "https://api.weixin.qq.com/channels/ec/league/headsupplier/order/get";
+ /** 获取佣金单列表 */
+ String GET_SUPPLIER_ORDER_LIST_URL = "https://api.weixin.qq.com/channels/ec/league/headsupplier/order/list/get";
+ /** 获取合作小店详情 */
+ String GET_SUPPLIER_SHOP_URL = "https://api.weixin.qq.com/channels/ec/league/headsupplier/shop/get";
+ /** 获取合作小店列表 */
+ String GET_SUPPLIER_SHOP_LIST_URL = "https://api.weixin.qq.com/channels/ec/league/headsupplier/shop/list/get";
+ /** 新增达人 */
+ String ADD_PROMOTER_URL = "https://api.weixin.qq.com/channels/ec/league/promoter/add";
+ /** 编辑达人 */
+ String EDIT_PROMOTER_URL = "https://api.weixin.qq.com/channels/ec/league/promoter/upd";
+ /** 删除达人 */
+ String DELETE_PROMOTER_URL = "https://api.weixin.qq.com/channels/ec/league/promoter/delete";
+ /** 获取达人详情信息 */
+ String GET_PROMOTER_URL = "https://api.weixin.qq.com/channels/ec/league/promoter/get";
+ /** 拉取商店达人列表 */
+ String GET_PROMOTER_LIST_URL = "https://api.weixin.qq.com/channels/ec/league/promoter/list/get";
+ /** 批量新增联盟商品 */
+ String BATCH_ADD_LEAGUE_ITEM_URL = "https://api.weixin.qq.com/channels/ec/league/item/batchadd";
+ /** 更新联盟商品信息 */
+ String UPDATE_LEAGUE_ITEM_URL = "https://api.weixin.qq.com/channels/ec/league/item/upd";
+ /** 删除联盟商品 */
+ String DELETE_LEAGUE_ITEM_URL = "https://api.weixin.qq.com/channels/ec/league/item/delete";
+ /** 拉取联盟商品详情 */
+ String GET_LEAGUE_ITEM_URL = "https://api.weixin.qq.com/channels/ec/league/item/get";
+ /** 拉取联盟商品推广列表 */
+ String GET_LEAGUE_ITEM_LIST_URL = "https://api.weixin.qq.com/channels/ec/league/item/list/get";
+ }
+
+ /** 视频号助手开放接口 */
+ public interface Assistant {
+
+ /** 上架商品到橱窗 */
+ String ADD_WINDOW_PRODUCT_URL = "https://api.weixin.qq.com/channels/ec/window/product/add";
+ /** 获取橱窗商品详情 */
+ String GET_WINDOW_PRODUCT_URL = "https://api.weixin.qq.com/channels/ec/window/product/get";
+ /** 获取已添加到橱窗的商品列表 */
+ String LIST_WINDOW_PRODUCT_URL = "https://api.weixin.qq.com/channels/ec/window/product/list/get";
+ /** 下架橱窗商品 */
+ String OFF_WINDOW_PRODUCT_URL = "https://api.weixin.qq.com/channels/ec/window/product/off";
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/AccountType.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/AccountType.java
new file mode 100644
index 0000000000..96cfc43956
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/AccountType.java
@@ -0,0 +1,43 @@
+package me.chanjar.weixin.channel.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 视频号小店 账户类型
+ *
+ * @author Zeyes
+ */
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum AccountType {
+ /** 对公银行账户 */
+ ACCOUNT_TYPE_BUSINESS("ACCOUNT_TYPE_BUSINESS", "对公银行账户"),
+ /** 经营者个人银行卡 */
+ ACCOUNT_TYPE_PRIVATE("ACCOUNT_TYPE_PRIVATE", "经营者个人银行卡"),
+
+ ;
+
+ private final String key;
+ private final String value;
+
+ AccountType(String key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public static AccountType getByKey(String key) {
+ for (AccountType reason : AccountType.values()) {
+ if (reason.getKey().equals(key)) {
+ return reason;
+ }
+ }
+ return ACCOUNT_TYPE_PRIVATE;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/AfterSaleStatus.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/AfterSaleStatus.java
new file mode 100644
index 0000000000..60e77d9e53
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/AfterSaleStatus.java
@@ -0,0 +1,60 @@
+package me.chanjar.weixin.channel.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 视频号小店 售后单状态
+ *
+ * @author Zeyes
+ */
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum AfterSaleStatus {
+ /** 用户取消申请 */
+ USER_CANCELD("USER_CANCELD", "用户取消申请"),
+ /** 商家受理中 */
+ MERCHANT_PROCESSING("MERCHANT_PROCESSING", "商家受理中"),
+ /** 商家拒绝退款 */
+ MERCHANT_REJECT_REFUND("MERCHANT_REJECT_REFUND", "商家拒绝退款"),
+ /** 商家拒绝退货退款 */
+ MERCHANT_REJECT_RETURN("MERCHANT_REJECT_RETURN", "商家拒绝退货退款"),
+ /** 待买家退货 */
+ USER_WAIT_RETURN("USER_WAIT_RETURN", "待买家退货"),
+ /** 7 售后单关闭 */
+ RETURN_CLOSED("RETURN_CLOSED", "退货退款关闭"),
+ /** 8 待商家收货 */
+ MERCHANT_WAIT_RECEIPT("MERCHANT_WAIT_RECEIPT", "待商家收货"),
+ /** 商家逾期未退款 */
+ MERCHANT_OVERDUE_REFUND("MERCHANT_OVERDUE_REFUND", "商家逾期未退款"),
+ /** 退款完成 */
+ MERCHANT_REFUND_SUCCESS("MERCHANT_REFUND_SUCCESS", "退款完成"),
+ /** 退货退款完成 */
+ MERCHANT_RETURN_SUCCESS("MERCHANT_RETURN_SUCCESS", "退货退款完成"),
+ /** 11 平台退款中 */
+ PLATFORM_REFUNDING("PLATFORM_REFUNDING", "平台退款中"),
+ /** 25 平台退款失败 */
+ PLATFORM_REFUND_FAIL("PLATFORM_REFUND_FAIL", "平台退款失败"),
+ /** 待用户确认 */
+ USER_WAIT_CONFIRM("USER_WAIT_CONFIRM", "待用户确认"),
+ /** 商家打款失败,客服关闭售后 */
+ MERCHANT_REFUND_RETRY_FAIL("MERCHANT_REFUND_RETRY_FAIL", "商家打款失败,客服关闭售后"),
+ /** 售后关闭 */
+ MERCHANT_FAIL("MERCHANT_FAIL", "售后关闭"),
+ ;
+
+ private final String key;
+ private final String value;
+
+ AfterSaleStatus(String key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/AfterSaleType.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/AfterSaleType.java
new file mode 100644
index 0000000000..8cbdf521f5
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/AfterSaleType.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.channel.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 售后类型
+ *
+ * @author Zeyes
+ */
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum AfterSaleType {
+ /** 1 仅退款 */
+ REFUND_ONLY("REFUND", "仅退款"),
+ /** 2 退货退款 */
+ REFUND_GOODS("RETURN", "退货退款");
+
+ private final String key;
+ private final String value;
+
+ AfterSaleType(String key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/AfterSalesReason.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/AfterSalesReason.java
new file mode 100644
index 0000000000..c3409a05cd
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/AfterSalesReason.java
@@ -0,0 +1,63 @@
+package me.chanjar.weixin.channel.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 视频号小店 售后原因
+ *
+ * @author Zeyes
+ */
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum AfterSalesReason {
+ /** 拍错/多拍 */
+ INCORRECT_SELECTION("INCORRECT_SELECTION", "拍错/多拍"),
+ /** 不想要了 */
+ NO_LONGER_WANT("NO_LONGER_WANT", "不想要了"),
+ /** 无快递信息 */
+ NO_EXPRESS_INFO("NO_EXPRESS_INFO", "无快递信息"),
+ /** 包裹为空 */
+ EMPTY_PACKAGE("EMPTY_PACKAGE", "包裹为空"),
+ /** 已拒签包裹 */
+ REJECT_RECEIVE_PACKAGE("REJECT_RECEIVE_PACKAGE", "已拒签包裹"),
+ /** 快递长时间未送达 */
+ NOT_DELIVERED_TOO_LONG("NOT_DELIVERED_TOO_LONG", "快递长时间未送达了"),
+ /** 与商品描述不符 */
+ NOT_MATCH_PRODUCT_DESC("NOT_MATCH_PRODUCT_DESC", "与商品描述不符"),
+ /** 质量问题 */
+ QUALITY_ISSUE("QUALITY_ISSUE", "质量问题"),
+ /** 卖家发错货 */
+ SEND_WRONG_GOODS("SEND_WRONG_GOODS", "卖家发错货"),
+ /** 三无产品 */
+ THREE_NO_PRODUCT("THREE_NO_PRODUCT", "三无产品"),
+ /** 假冒产品 */
+ FAKE_PRODUCT("FAKE_PRODUCT", "假冒产品"),
+ /** 其它 */
+ OTHERS("OTHERS", "其它"),
+ ;
+
+ private final String key;
+ private final String value;
+
+ AfterSalesReason(String key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public static AfterSalesReason getByKey(String key) {
+ for (AfterSalesReason reason : AfterSalesReason.values()) {
+ if (reason.getKey().equals(key)) {
+ return reason;
+ }
+ }
+ // 找不到就返回其他了
+ return OTHERS;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/CommissionOrderStatus.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/CommissionOrderStatus.java
new file mode 100644
index 0000000000..bdf29d2765
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/CommissionOrderStatus.java
@@ -0,0 +1,37 @@
+package me.chanjar.weixin.channel.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 佣金订单状态
+ *
+ * @author Zeyes
+ */
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum CommissionOrderStatus {
+
+ /** 20 未结算 */
+ NOT_SETTLED(20, "未结算"),
+ /** 100 已结算 */
+ SETTLED(100, "已结算"),
+ /** 200 取消结算 */
+ CANCEL_SETTLED(200, "取消结算"),
+
+ ;
+
+ private final int key;
+ private final String val;
+
+ CommissionOrderStatus(int key, String val) {
+ this.key = key;
+ this.val = val;
+ }
+
+ public int getKey() {
+ return key;
+ }
+
+ public String getVal() {
+ return val;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/ComplaintItemType.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/ComplaintItemType.java
new file mode 100644
index 0000000000..d7f1aae8ec
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/ComplaintItemType.java
@@ -0,0 +1,112 @@
+package me.chanjar.weixin.channel.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 纠纷历史操作类型
+ *
+ * @author Zeyes
+ */
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum ComplaintItemType {
+ /** 1 申请平台介入 */
+ APPLY_PLATFORM_INTERVENTION(1, "申请平台介入"),
+ /** 2 用户留言 */
+ USER_MESSAGE(2, "用户留言"),
+ /** 3 商家留言 */
+ MERCHANT_MESSAGE(3, "商家留言"),
+ /** 4 提交投诉成功 */
+ SUBMIT_COMPLAINT_SUCCESS(4, "提交投诉成功"),
+ /** 5 投诉已取消 */
+ COMPLAINT_CANCELLED(5, "投诉已取消"),
+ /** 6 商家已超时 */
+ MERCHANT_TIMEOUT(6, "商家已超时"),
+ /** 7 用户补充凭证 */
+ USER_SUPPLEMENTARY_EVIDENCE(7, "用户补充凭证"),
+ /** 8 商家补充凭证 */
+ MERCHANT_SUPPLEMENTARY_EVIDENCE(8, "商家补充凭证"),
+ /** 10 待商家处理纠纷 */
+ WAIT_MERCHANT_HANDLE_DISPUTE(10, "待商家处理纠纷"),
+ /** 11 待平台处理 */
+ WAIT_PLATFORM_HANDLE(11, "待平台处理"),
+ /** 12 取消平台介入 */
+ CANCEL_PLATFORM_INTERVENTION(12, "取消平台介入"),
+ /** 13 平台处理中 */
+ PLATFORM_PROCESSING(13, "平台处理中"),
+ /** 14 待用户补充凭证 */
+ WAIT_USER_SUPPLEMENTARY_EVIDENCE(14, "待用户补充凭证"),
+ /** 16 待商家补充凭证 */
+ WAIT_MERCHANT_SUPPLEMENTARY_EVIDENCE(16, "待商家补充凭证"),
+ /** 18 待双方补充凭证 */
+ WAIT_BOTH_PARTIES_SUPPLEMENTARY_EVIDENCE(18, "待双方补充凭证"),
+ /** 20 待商家确认 */
+ WAIT_MERCHANT_CONFIRM(20, "待商家确认"),
+ /** 21 商家申诉中 */
+ MERCHANT_APPEALING(21, "商家申诉中"),
+ /** 22 调解完成 */
+ MEDIATION_COMPLETE(22, "调解完成"),
+ /** 23 待平台核实 */
+ WAIT_PLATFORM_VERIFY(23, "待平台核实"),
+ /** 24 重新退款中 */
+ REFUNDING_AGAIN(24, "重新退款中"),
+ /** 26 调解关闭 */
+ MEDIATION_CLOSED(26, "调解关闭"),
+ /** 30 平台判定用户责任 */
+ PLATFORM_JUDGMENT_USER_RESPONSIBILITY(30, "平台判定用户责任"),
+ /** 31 平台判定商家责任 */
+ PLATFORM_JUDGMENT_MERCHANT_RESPONSIBILITY(31, "平台判定商家责任"),
+ /** 32 平台判定双方责任 */
+ PLATFORM_JUDGMENT_BOTH_PARTIES_RESPONSIBILITY(32, "平台判定双方责任"),
+ /** 33 平台判定无责任 */
+ PLATFORM_JUDGMENT_NO_RESPONSIBILITY(33, "平台判定无责任"),
+ /** 34 平台判定申诉无效 */
+ PLATFORM_JUDGMENT_APPEAL_INVALID(34, "平台判定申诉无效"),
+ /** 35 平台判定申诉生效 */
+ PLATFORM_JUDGMENT_APPEAL_EFFECTIVE(35, "平台判定申诉生效"),
+ /** 36 平台判定退款有效 */
+ PLATFORM_JUDGMENT_REFUND_EFFECTIVE(36, "平台判定退款有效"),
+ /** 37 平台判定退款无效 */
+ PLATFORM_JUDGMENT_REFUND_INVALID(37, "平台判定退款无效"),
+ /** 50 用户发起退款 */
+ USER_INITIATE_REFUND(50, "用户发起退款"),
+ /** 51 商家拒绝退款 */
+ MERCHANT_REFUSE_REFUND(51, "商家拒绝退款"),
+ /** 52 用户取消申请 */
+ USER_CANCEL_APPLICATION(52, "用户取消申请"),
+ /** 56 待买家退货 */
+ WAIT_BUYER_RETURN_GOODS(56, "待买家退货"),
+ /** 57 退货退款关闭 */
+ REFUND_CLOSED(57, "退货退款关闭"),
+ /** 58 待商家收货 */
+ WAIT_MERCHANT_RECEIVE_GOODS(58, "待商家收货"),
+ /** 59 商家逾期未退款 */
+ MERCHANT_OVERDUE_REFUND(59, "商家逾期未退款"),
+ /** 60 退款完成 */
+ REFUND_COMPLETE(60, "退款完成"),
+ /** 61 退货退款完成 */
+ REFUND_GOODS_COMPLETE(61, "退货退款完成"),
+ /** 62 平台退款中 */
+ PLATFORM_REFUNDING(62, "平台退款中"),
+ /** 63 平台退款失败 */
+ PLATFORM_REFUND_FAILED(63, "平台退款失败"),
+ /** 64 待用户确认 */
+ WAIT_USER_CONFIRM(64, "待用户确认"),
+
+ ;
+
+ private final int key;
+ private final String value;
+
+ ComplaintItemType(int key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public int getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/ComplaintStatus.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/ComplaintStatus.java
new file mode 100644
index 0000000000..c11c5fc432
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/ComplaintStatus.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 纠纷单状态
+ *
+ * @author Zeyes
+ */
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum ComplaintStatus {
+
+ ;
+
+ private final int key;
+ private final String value;
+
+ ComplaintStatus(int key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public int getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/CouponType.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/CouponType.java
new file mode 100644
index 0000000000..9001f286ab
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/CouponType.java
@@ -0,0 +1,45 @@
+package me.chanjar.weixin.channel.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 视频号小店 优惠券 推广类型
+ *
+ * @author Zeyes
+ */
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum CouponType {
+ /** 1 商品条件折券 */
+ C_1(1, "商品条件折券"),
+ /** 2 商品满减券 */
+ C_2(2, "商品满减券"),
+ /** 3 商品统一折扣券 */
+ C_3(3, "商品统一折扣券"),
+ /** 4 商品直减券 */
+ C_4(4, "商品直减券"),
+ /** 101 店铺条件折扣券 */
+ C_101(101, "店铺条件折扣券"),
+ /** 102 店铺满减券 */
+ C_102(102, "店铺满减券"),
+ /** 103 店铺统一折扣券 */
+ C_103(103, "店铺统一折扣券"),
+ /** 104 店铺直减券 */
+ C_104(104, "店铺直减券"),
+ ;
+
+ private final int key;
+ private final String val;
+
+ CouponType(int key, String val) {
+ this.key = key;
+ this.val = val;
+ }
+
+ public int getKey() {
+ return key;
+ }
+
+ public String getVal() {
+ return val;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/CouponValidType.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/CouponValidType.java
new file mode 100644
index 0000000000..bb037cbbdf
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/CouponValidType.java
@@ -0,0 +1,34 @@
+package me.chanjar.weixin.channel.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 视频号小店 优惠券 推广类型
+ *
+ * @author Zeyes
+ */
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum CouponValidType {
+ /** 指定时间范围生效 */
+ COUPON_VALID_TYPE_TIME(1, "指定时间范围生效"),
+ /** 生效天数 */
+ COUPON_VALID_TYPE_DAY(2, "生效天数"),
+
+ ;
+
+ private final int key;
+ private final String val;
+
+ CouponValidType(int key, String val) {
+ this.key = key;
+ this.val = val;
+ }
+
+ public int getKey() {
+ return key;
+ }
+
+ public String getVal() {
+ return val;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/DeliveryType.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/DeliveryType.java
new file mode 100644
index 0000000000..8a024ca6f7
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/DeliveryType.java
@@ -0,0 +1,42 @@
+package me.chanjar.weixin.channel.enums;
+
+/**
+ * 快递类型
+ *
+ * @author Zeyes
+ */
+public enum DeliveryType {
+ /** 1 自寄快递 */
+ SELF_DELIVERY(1, "自寄快递"),
+ /** 2 在线签约快递单 */
+ ONLINE_DELIVERY(2, "在线签约快递单"),
+ /** 3 虚拟商品无需物流发货 */
+ VIRTUAL_DELIVERY(3, "虚拟商品无需物流发货"),
+ /** 4 在线快递散单 */
+ ONLINE_DELIVERY_SCATTER(4, "在线快递散单");
+
+ private final Integer key;
+ private final String value;
+
+ DeliveryType(Integer key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public static DeliveryType getDeliveryType(Integer key) {
+ for (DeliveryType deliveryType : DeliveryType.values()) {
+ if (deliveryType.getKey().equals(key)) {
+ return deliveryType;
+ }
+ }
+ return null;
+ }
+
+ public Integer getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/FundsType.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/FundsType.java
new file mode 100644
index 0000000000..ea3f8873ec
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/FundsType.java
@@ -0,0 +1,50 @@
+package me.chanjar.weixin.channel.enums;
+
+/**
+ * 资金类型
+ *
+ * @author Zeyes
+ */
+public enum FundsType {
+
+ /** 1 订单支付收入 */
+ ORDER_PAY_INCOME(1, "订单支付收入"),
+ /** 2 订单手续费 */
+ ORDER_FEE(2, "订单手续费"),
+ /** 3 退款 */
+ REFUND(3, "退款"),
+ /** 4 提现 */
+ WITHDRAW(4, "提现"),
+ /** 5 提现失败退票 */
+ WITHDRAW_FAIL(5, "提现失败退票"),
+ /** 6 导购分账 */
+ GUIDE_SHARE(6, "导购分账"),
+ /** 7 联盟分账 */
+ LEAGUE_SHARE(7, "联盟分账"),
+ /** 8 运费险分账 */
+ FREIGHT_SHARE(8, "运费险分账"),
+ /** 9 联盟平台抽佣 */
+ LEAGUE_COMMISSION(9, "联盟平台抽佣"),
+ /** 10 小店抽佣 */
+ SHOP_COMMISSION(10, "小店抽佣"),
+ /** 99 分账 */
+ SHARE(99, "分账"),
+
+ ;
+
+ private final int key;
+ private final String value;
+
+ FundsType(int key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public int getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/MessageType.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/MessageType.java
new file mode 100644
index 0000000000..4406104d9f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/MessageType.java
@@ -0,0 +1,21 @@
+package me.chanjar.weixin.channel.enums;
+
+/**
+ * 消息类型
+ *
+ * @author Zeyes
+ */
+public enum MessageType {
+ EVENT("event"),
+ ;
+
+ private final String key;
+
+ MessageType(String key) {
+ this.key = key;
+ }
+
+ public String getKey() {
+ return key;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/PromoteType.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/PromoteType.java
new file mode 100644
index 0000000000..fa0bd60913
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/PromoteType.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 视频号小店 优惠券 推广类型
+ *
+ * @author Zeyes
+ */
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum PromoteType {
+ PROMOTE_TYPE_SHOP(1, "小店内推广");
+
+ private final int key;
+ private final String val;
+
+ PromoteType(int key, String val) {
+ this.key = key;
+ this.val = val;
+ }
+
+ public int getKey() {
+ return key;
+ }
+
+ public String getVal() {
+ return val;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/QrCheckStatus.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/QrCheckStatus.java
new file mode 100644
index 0000000000..b0b2d64e31
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/QrCheckStatus.java
@@ -0,0 +1,46 @@
+package me.chanjar.weixin.channel.enums;
+
+/**
+ * 二维码核销状态
+ *
+ * @author Zeyes
+ */
+public enum QrCheckStatus {
+ /** 0 未扫码 */
+ NOT_SCAN(0, "未扫码"),
+ /** 1 已确认 */
+ CONFIRMED(1, "已确认"),
+ /** 2 已取消 */
+ CANCEL(2, "已取消"),
+ /** 3 已失效 */
+ INVALID(3, "已失效"),
+ /** 4 已扫码 */
+ SCAN(4, "已扫码"),
+
+ ;
+
+ private final int key;
+ private final String value;
+
+ QrCheckStatus(int key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public static QrCheckStatus getByKey(Integer key) {
+ for (QrCheckStatus status : QrCheckStatus.values()) {
+ if (status.getKey() == key) {
+ return status;
+ }
+ }
+ return NOT_SCAN;
+ }
+
+ public int getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SendTime.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SendTime.java
new file mode 100644
index 0000000000..85e4d4f0d6
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SendTime.java
@@ -0,0 +1,67 @@
+package me.chanjar.weixin.channel.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 视频号小店 发货时间
+ *
+ * @author Zeyes
+ */
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum SendTime {
+// /** 4小时内发货 */
+// FOUR_HOUR("SendTime_FOUR_HOUR", "4小时内发货"),
+// /** 8小时内发货 */
+// EIGHT_HOUR("SendTime_EIGHT_HOUR", "8小时内发货"),
+// /** 12小时内发货 */
+// TWELVE_HOUR("SendTime_TWELVE_HOUR", "12小时内发货"),
+// /** 16小时内发货 */
+// SIXTEEN_HOUR("SendTime_SIXTEEN_HOUR", "16小时内发货"),
+// /** 20小时内发货 */
+// TWENTY_HOUR("SendTime_TWENTY_HOUR", "20小时内发货"),
+ /** 24小时内发货 */
+ TWENTYFOUR_HOUR("SendTime_TWENTYFOUR_HOUR", "24小时内发货"),
+ /** 48小时内发货 */
+ FOUTYEIGHT_HOUR("SendTime_FOUTYEIGHT_HOUR", "48小时内发货"),
+ /** 3天内发货 */
+ THREE_DAY("SendTime_THREE_DAY", "3天内发货"),
+// /** 5天内发货 */
+// FIVE_DAY("SendTime_FIVE_DAY", "5天内发货"),
+// /** 7天内发货 */
+// SEVEN_DAY("SendTime_SEVEN_DAY", "7天内发货"),
+// /** 10天内发货 */
+// TEN_DAY("SendTime_TEN_DAY", "10天内发货"),
+// /** 12天内发货 */
+// TWELVE_DAY("SendTime_TWELVE_DAY", "12天内发货"),
+// /** 14天内发货 */
+// FOUTEEN_DAY("SendTime_FOUTEEN_DAY", "14天内发货"),
+// /** 16天内发货 */
+// SIXTEEN_DAY("SendTime_SIXTEEN_DAY", "16天内发货"),
+// /** 20天内发货 */
+// TWENTY_DAY("SendTime_TWENTY_DAY", "20天内发货"),
+// /** 25天内发货 */
+// TWENTYFIVE_DAY("SendTime_TWENTYFIVE_DAY", "25天内发货"),
+// /** 30天内发货 */
+// THIRY_DAY("SendTime_THIRY_DAY", "30天内发货"),
+// /** 35天内发货 */
+// THIRYFIVE_DAY("SendTime_THIRYFIVE_DAY", "35天内发货"),
+// /** 45天内发货 */
+// FOURTYFIVE_DAY("SendTime_FOURTYFIVE_DAY", "45天内发货"),
+ ;
+
+ private final String key;
+ private final String value;
+
+ SendTime(String key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/ShareScene.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/ShareScene.java
new file mode 100644
index 0000000000..b4428dbb24
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/ShareScene.java
@@ -0,0 +1,41 @@
+package me.chanjar.weixin.channel.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 分享场景
+ *
+ * @author Zeyes
+ */
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum ShareScene {
+ /** 1 直播间 */
+ LIVE_ROOM(1, "直播间"),
+ /** 2 橱窗 */
+ WINDOW(2, "橱窗"),
+ /** 3 短视频 */
+ SHORT_VIDEO(3, "短视频"),
+ /** 4 视频号主页 */
+ CHANNEL_HOME(4, "视频号主页"),
+ /** 5 商品详情页 */
+ PRODUCT_DETAIL(5, "商品详情页"),
+
+ ;
+
+
+ private final Integer key;
+ private final String value;
+
+ ShareScene(Integer key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public Integer getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SharerType.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SharerType.java
new file mode 100644
index 0000000000..8f0da3d760
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SharerType.java
@@ -0,0 +1,35 @@
+package me.chanjar.weixin.channel.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 分享员类型
+ *
+ * @author Zeyes
+ */
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum SharerType {
+ /** 0 普通分享员 */
+ NORMAL(0, "普通分享员"),
+ /** 1 企业分享员 */
+ ENTERPRISE(1, "企业分享员"),
+
+ ;
+
+
+ private final Integer key;
+ private final String value;
+
+ SharerType(Integer key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public Integer getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SpuEditStatus.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SpuEditStatus.java
new file mode 100644
index 0000000000..3d6063b8cf
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SpuEditStatus.java
@@ -0,0 +1,40 @@
+package me.chanjar.weixin.channel.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 商品编辑状态
+ *
+ * @author Zeyes
+ */
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum SpuEditStatus {
+ /** 0 初始值 */
+ INIT(0, "初始值"),
+ /** 1 编辑中 */
+ SUBMIT(1, "编辑中"),
+ /** 2 审核中 */
+ ING(2, "审核中"),
+ /** 3 审核失败 */
+ FAIL(3, "审核失败"),
+ /** 4 审核成功 */
+ SUCCESS(4, "审核成功"),
+ /** 5 商品信息写入中 */
+ WRITING(5, "商品信息写入中");
+
+ private final int status;
+ private final String desc;
+
+ SpuEditStatus(int status, String desc) {
+ this.status = status;
+ this.desc = desc;
+ }
+
+ public int getStatus() {
+ return status;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SpuStatus.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SpuStatus.java
new file mode 100644
index 0000000000..a74fee6b07
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SpuStatus.java
@@ -0,0 +1,39 @@
+package me.chanjar.weixin.channel.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 视频号小店 商品上下架状态
+ *
+ * @author Zeyes
+ */
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum SpuStatus {
+
+ /** 0 初始值 */
+ INIT(0, "未上架"),
+ /** 5 上架 */
+ UP(5, "上架"),
+ /** 6 回收站 */
+ TRASH(6, "回收站"),
+ /** 11 自主下架 */
+ DOWN(11, "自主下架"),
+ /** 13 违规下架/风控系统下架 */
+ SYSTEM_DOWN(13, "违规下架");
+
+ private final int status;
+ private final String desc;
+
+ SpuStatus(int status, String desc) {
+ this.status = status;
+ this.desc = desc;
+ }
+
+ public int getStatus() {
+ return status;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/UserCouponStatus.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/UserCouponStatus.java
new file mode 100644
index 0000000000..ce7e97df6c
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/UserCouponStatus.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.channel.enums;
+
+/**
+ * 视频号小店 用户优惠券状态
+ *
+ * @author Zeyes
+ */
+public enum UserCouponStatus {
+ /** 100 生效中 */
+ VALID(100, "生效中"),
+ /** 101 已过期 */
+ EXPIRED(101, "已过期"),
+ /** 102 已使用 */
+ USED(102, "已使用"),
+
+ ;
+
+ private final int key;
+ private final String val;
+
+ UserCouponStatus(int key, String val) {
+ this.key = key;
+ this.val = val;
+ }
+
+ public int getKey() {
+ return key;
+ }
+
+ public String getVal() {
+ return val;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/WithdrawStatus.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/WithdrawStatus.java
new file mode 100644
index 0000000000..2d1737cbd0
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/WithdrawStatus.java
@@ -0,0 +1,51 @@
+package me.chanjar.weixin.channel.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 视频号小店 提现状态
+ *
+ * @author Zeyes
+ */
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum WithdrawStatus {
+ /** 受理成功 */
+ CREATE_SUCCESS("CREATE_SUCCESS", "受理成功"),
+ /** 提现成功 */
+ SUCCESS("SUCCESS", "提现成功"),
+ /** 提现失败 */
+ FAIL("FAIL", "提现失败"),
+ /** 提现退票 */
+ REFUND("REFUND", "提现退票"),
+ /** 关单 */
+ CLOSE("CLOSE", "关单"),
+ /** 业务单已创建 */
+ INIT("INIT", "业务单已创建"),
+ ;
+
+ private final String key;
+ private final String value;
+
+ WithdrawStatus(String key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public static WithdrawStatus getByKey(String key) {
+ for (WithdrawStatus reason : WithdrawStatus.values()) {
+ if (reason.getKey().equals(key)) {
+ return reason;
+ }
+ }
+ // 找不到就返回其他了
+ return FAIL;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/WxChannelErrorMsgEnum.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/WxChannelErrorMsgEnum.java
new file mode 100644
index 0000000000..4a699c20d0
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/WxChannelErrorMsgEnum.java
@@ -0,0 +1,63 @@
+package me.chanjar.weixin.channel.enums;
+
+import com.google.common.collect.Maps;
+import java.util.Map;
+import lombok.Getter;
+
+/**
+ * 微信视频号全局返回码
+ *
+ * @author Zeyes
+ */
+@Getter
+public enum WxChannelErrorMsgEnum {
+ /**
+ * 系统繁忙,此时请开发者稍候再试 system error
+ */
+ CODE_1(-1, "系统繁忙,此时请开发者稍候再试"),
+
+ /**
+ * 请求成功 ok
+ */
+ CODE_0(0, "请求成功"),
+
+ /**
+ * AppSecret 错误或者 AppSecret 不属于这个小店,请开发者确认 AppSecret 的正确性
+ */
+ CODE_40001(40001, "AppSecret 错误或者 AppSecret 不属于这个小店,请开发者确认 AppSecret 的正确性"),
+
+ /**
+ * 请确保 grant_type 字段值为 client_credential
+ */
+ CODE_40002(40002, "请确保 grant_type 字段值为 client_credential"),
+
+ /**
+ * 不合法的 AppID,请开发者检查 AppID 的正确性,避免异常字符,注意大小写
+ */
+ CODE_40013(40013, "不合法的 AppID,请开发者检查 AppID 的正确性,避免异常字符,注意大小写"),
+
+ ;
+
+ private final int code;
+ private final String msg;
+
+ WxChannelErrorMsgEnum(int code, String msg) {
+ this.code = code;
+ this.msg = msg;
+ }
+
+ static final Map valueMap = Maps.newHashMap();
+
+ static {
+ for (WxChannelErrorMsgEnum value : WxChannelErrorMsgEnum.values()) {
+ valueMap.put(value.code, value.msg);
+ }
+ }
+
+ /**
+ * 通过错误代码查找其中文含义.
+ */
+ public static String findMsgByCode(int code) {
+ return valueMap.getOrDefault(code, null);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/WxCouponStatus.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/WxCouponStatus.java
new file mode 100644
index 0000000000..593873fbe4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/WxCouponStatus.java
@@ -0,0 +1,35 @@
+package me.chanjar.weixin.channel.enums;
+
+/**
+ * 视频号小店 优惠券状态
+ *
+ * @author Zeyes
+ */
+public enum WxCouponStatus {
+ /** 1 初始 */
+ INIT(1, "初始"),
+ /** 2 生效 */
+ VALID(2, "生效"),
+ /** 4 已作废 */
+ INVALID(4, "已作废"),
+ /** 5 删除 */
+ DELETE(5, "删除"),
+
+ ;
+
+ private final int key;
+ private final String val;
+
+ WxCouponStatus(int key, String val) {
+ this.key = key;
+ this.val = val;
+ }
+
+ public int getKey() {
+ return key;
+ }
+
+ public String getVal() {
+ return val;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/WxOrderStatus.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/WxOrderStatus.java
new file mode 100644
index 0000000000..b064335221
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/WxOrderStatus.java
@@ -0,0 +1,73 @@
+package me.chanjar.weixin.channel.enums;
+
+/**
+ * 视频号小店 订单状态
+ *
+ * @author Zeyes
+ */
+public enum WxOrderStatus {
+ /** 10 待付款 */
+ UNPAID(10, "待付款"),
+ /** 20 待发货(已付款/用户已付尾款) */
+ PAID(20, "待发货"),
+ /** 21 部分发货 */
+ PART_DELIVERY(21, "部分发货"),
+ /** 30 待收货 */
+ DELIVERY(30, "待收货"),
+ /** 100 完成 */
+ COMPLETED(100, "已完成"),
+ /** 190 商品超卖商家取消订单 */
+ UNPAID_CANCEL(190, "已取消"),
+ /** 200 全部商品售后之后,订单取消 */
+ ALL_AFTER_SALE(200, "已取消"),
+ /** 250 用户主动取消/待付款超时取消/商家取消 */
+ CANCEL(250, "已取消");
+
+ private final int key;
+
+ private final String val;
+
+ WxOrderStatus(int key, String val) {
+ this.key = key;
+ this.val = val;
+ }
+
+ public int getKey() {
+ return key;
+ }
+
+ public String getVal() {
+ return val;
+ }
+
+ /**
+ * 获取状态中文
+ *
+ * @param key 状态码
+ * @return 状态
+ */
+ public static String getStatusStr(Integer key) {
+ if (key == null) {
+ return "未知";
+ }
+ for (WxOrderStatus status : WxOrderStatus.values()) {
+ if (key.equals(status.getKey())) {
+ return status.getVal();
+ }
+ }
+ return String.valueOf(key);
+ }
+
+ /**
+ * 判断是否在取消状态
+ *
+ * @param key key
+ * @return boolean
+ */
+ public static boolean isCancel(Integer key) {
+ if (key == null) {
+ return false;
+ }
+ return key.equals(UNPAID_CANCEL.key) || key.equals(ALL_AFTER_SALE.key) || key.equals(CANCEL.key);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/ChannelFileUploadRequestExecutor.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/ChannelFileUploadRequestExecutor.java
new file mode 100644
index 0000000000..576f1c286a
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/ChannelFileUploadRequestExecutor.java
@@ -0,0 +1,66 @@
+package me.chanjar.weixin.channel.executor;
+
+
+import java.io.File;
+import java.io.IOException;
+import me.chanjar.weixin.common.enums.WxType;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.util.http.RequestExecutor;
+import me.chanjar.weixin.common.util.http.RequestHttp;
+import me.chanjar.weixin.common.util.http.ResponseHandler;
+import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpHost;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.mime.HttpMultipartMode;
+import org.apache.http.entity.mime.MultipartEntityBuilder;
+import org.apache.http.impl.client.CloseableHttpClient;
+
+/**
+ * 视频号小店 图片上传接口 请求的参数是File, 返回的结果是String
+ *
+ * @author Zeyes
+ */
+public class ChannelFileUploadRequestExecutor implements RequestExecutor {
+
+ protected RequestHttp requestHttp;
+
+ public ChannelFileUploadRequestExecutor(RequestHttp requestHttp) {
+ this.requestHttp = requestHttp;
+ }
+
+ @Override
+ public String execute(String uri, File file, WxType wxType) throws WxErrorException, IOException {
+ HttpPost httpPost = new HttpPost(uri);
+ if (requestHttp.getRequestHttpProxy() != null) {
+ RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build();
+ httpPost.setConfig(config);
+ }
+ if (file != null) {
+ HttpEntity entity = MultipartEntityBuilder
+ .create()
+ .addBinaryBody("media", file)
+ .setMode(HttpMultipartMode.RFC6532)
+ .build();
+ httpPost.setEntity(entity);
+ }
+ try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) {
+ return Utf8ResponseHandler.INSTANCE.handleResponse(response);
+ } finally {
+ httpPost.releaseConnection();
+ }
+ }
+
+ @Override
+ public void execute(String uri, File data, ResponseHandler handler, WxType wxType)
+ throws WxErrorException, IOException {
+ handler.handle(this.execute(uri, data, wxType));
+ }
+
+ public static RequestExecutor create(RequestHttp requestHttp) {
+ return new ChannelFileUploadRequestExecutor(requestHttp);
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/ChannelMediaDownloadRequestExecutor.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/ChannelMediaDownloadRequestExecutor.java
new file mode 100644
index 0000000000..1b81dc6d15
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/ChannelMediaDownloadRequestExecutor.java
@@ -0,0 +1,151 @@
+package me.chanjar.weixin.channel.executor;
+
+import static org.apache.commons.io.FileUtils.openOutputStream;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.bean.image.ChannelImageResponse;
+import me.chanjar.weixin.channel.util.JsonUtils;
+import me.chanjar.weixin.common.enums.WxType;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.util.http.RequestExecutor;
+import me.chanjar.weixin.common.util.http.RequestHttp;
+import me.chanjar.weixin.common.util.http.ResponseHandler;
+import me.chanjar.weixin.common.util.http.apache.InputStreamResponseHandler;
+import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.Header;
+import org.apache.http.HttpHost;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.entity.ContentType;
+import org.apache.http.impl.client.CloseableHttpClient;
+
+/**
+ * 下载媒体文件请求执行器
+ *
+ * @author Zeyes
+ */
+@Slf4j
+public class ChannelMediaDownloadRequestExecutor implements RequestExecutor {
+
+ protected RequestHttp requestHttp;
+ protected File tmpDirFile;
+
+ private static final Pattern PATTERN = Pattern.compile(".*filename=\"(.*)\"");
+
+ public ChannelMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) {
+ this.requestHttp = requestHttp;
+ this.tmpDirFile = tmpDirFile;
+ }
+
+ @Override
+ public ChannelImageResponse execute(String uri, String data, WxType wxType) throws WxErrorException, IOException {
+ if (data != null) {
+ if (uri.indexOf('?') == -1) {
+ uri += '?';
+ }
+ uri += uri.endsWith("?") ? data : '&' + data;
+ }
+
+ HttpGet httpGet = new HttpGet(uri);
+ if (requestHttp.getRequestHttpProxy() != null) {
+ RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build();
+ httpGet.setConfig(config);
+ }
+
+ try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpGet);
+ InputStream inputStream = InputStreamResponseHandler.INSTANCE.handleResponse(response)) {
+ Header[] contentTypeHeader = response.getHeaders("Content-Type");
+ String contentType = null;
+ if (contentTypeHeader != null && contentTypeHeader.length > 0) {
+ contentType = contentTypeHeader[0].getValue();
+ if (contentType.startsWith(ContentType.APPLICATION_JSON.getMimeType())) {
+ // application/json; encoding=utf-8 下载媒体文件出错
+ String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response);
+ return JsonUtils.decode(responseContent, ChannelImageResponse.class);
+ }
+ }
+
+ String fileName = this.getFileName(response);
+ if (StringUtils.isBlank(fileName)) {
+ fileName = String.valueOf(System.currentTimeMillis());
+ }
+
+ String baseName = FilenameUtils.getBaseName(fileName);
+ if (StringUtils.isBlank(fileName) || baseName.length() < 3) {
+ baseName = String.valueOf(System.currentTimeMillis());
+ }
+ String extension = FilenameUtils.getExtension(fileName);
+ if (StringUtils.isBlank(extension)) {
+ extension = "unknown";
+ }
+ File file = createTmpFile(inputStream, baseName, extension, tmpDirFile);
+ ChannelImageResponse result = new ChannelImageResponse(file, contentType);
+ return result;
+ } finally {
+ httpGet.releaseConnection();
+ }
+ }
+
+ @Override
+ public void execute(String uri, String data, ResponseHandler handler, WxType wxType)
+ throws WxErrorException, IOException {
+ handler.handle(this.execute(uri, data, wxType));
+ }
+
+ public static RequestExecutor create(RequestHttp requestHttp, File tmpDirFile) {
+ return new ChannelMediaDownloadRequestExecutor(requestHttp, tmpDirFile);
+ }
+
+ /**
+ * 创建临时文件
+ *
+ * @param inputStream 输入文件流
+ * @param name 文件名
+ * @param ext 扩展名
+ * @param tmpDirFile 临时文件夹目录
+ */
+ public static File createTmpFile(InputStream inputStream, String name, String ext, File tmpDirFile)
+ throws IOException {
+ File resultFile = File.createTempFile(name, '.' + ext, tmpDirFile);
+ resultFile.deleteOnExit();
+ try (InputStream in = inputStream; OutputStream out = openOutputStream(resultFile)) {
+ IOUtils.copy(in, out);
+ }
+ return resultFile;
+ }
+
+ private String getFileName(CloseableHttpResponse response) throws WxErrorException {
+ Header[] contentDispositionHeader = response.getHeaders("Content-disposition");
+ if (contentDispositionHeader == null || contentDispositionHeader.length == 0) {
+ return createDefaultFileName();
+ }
+ return this.extractFileNameFromContentString(contentDispositionHeader[0].getValue());
+ }
+
+ private String createDefaultFileName() {
+ return UUID.randomUUID().toString();
+ }
+
+ private String extractFileNameFromContentString(String content) throws WxErrorException {
+ if (content == null || content.length() == 0) {
+ return createDefaultFileName();
+ }
+ Matcher m = PATTERN.matcher(content);
+ if (m.matches()) {
+ return m.group(1);
+ }
+ return createDefaultFileName();
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/WxChannelMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/WxChannelMessage.java
new file mode 100644
index 0000000000..f6e3386a5a
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/WxChannelMessage.java
@@ -0,0 +1,125 @@
+package me.chanjar.weixin.channel.message;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlCData;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import java.io.Serializable;
+import me.chanjar.weixin.channel.util.JsonUtils;
+
+/**
+ * 视频号 消息 兼容Json和xml
+ *
+ * @author Zeyes
+ */
+@JacksonXmlRootElement(localName = "xml")
+public class WxChannelMessage implements Serializable {
+
+ private static final long serialVersionUID = -6929595548318897649L;
+
+ @JsonProperty("ToUserName")
+ @JacksonXmlProperty(localName = "ToUserName")
+ @JacksonXmlCData
+ private String toUser;
+
+ @JsonProperty("FromUserName")
+ @JacksonXmlProperty(localName = "FromUserName")
+ @JacksonXmlCData
+ private String fromUser;
+
+ @JsonProperty("CreateTime")
+ @JacksonXmlProperty(localName = "CreateTime")
+ private Long createTime;
+
+ @JsonProperty("MsgType")
+ @JacksonXmlProperty(localName = "MsgType")
+ @JacksonXmlCData
+ private String msgType;
+
+ @JsonProperty("Event")
+ @JacksonXmlProperty(localName = "Event")
+ @JacksonXmlCData
+ private String event;
+
+ @JsonProperty("Encrypt")
+ @JacksonXmlProperty(localName = "Encrypt")
+ @JacksonXmlCData
+ private String encrypt;
+
+ @JsonProperty("MsgId")
+ @JacksonXmlProperty(localName = "MsgId")
+ private Long msgId;
+
+ @JsonProperty("MsgID")
+ @JacksonXmlProperty(localName = "MsgID")
+ private void msgIdFill(Long msgId) {
+ if (msgId != null) {
+ this.msgId = msgId;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return this.toJson();
+ }
+
+ public String toJson() {
+ return JsonUtils.encode(this);
+ }
+
+ public String getToUser() {
+ return toUser;
+ }
+
+ public String getFromUser() {
+ return fromUser;
+ }
+
+ public Long getCreateTime() {
+ return createTime;
+ }
+
+ public String getMsgType() {
+ return msgType;
+ }
+
+ public String getEvent() {
+ return event;
+ }
+
+ public String getEncrypt() {
+ return encrypt;
+ }
+
+ public Long getMsgId() {
+ return msgId;
+ }
+
+ public void setToUser(String toUser) {
+ this.toUser = toUser;
+ }
+
+ public void setFromUser(String fromUser) {
+ this.fromUser = fromUser;
+ }
+
+ public void setCreateTime(Long createTime) {
+ this.createTime = createTime;
+ }
+
+ public void setMsgType(String msgType) {
+ this.msgType = msgType;
+ }
+
+ public void setEvent(String event) {
+ this.event = event;
+ }
+
+ public void setEncrypt(String encrypt) {
+ this.encrypt = encrypt;
+ }
+
+ public void setMsgId(Long msgId) {
+ this.msgId = msgId;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/WxChannelMessageRouter.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/WxChannelMessageRouter.java
new file mode 100644
index 0000000000..8ccc2c5050
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/WxChannelMessageRouter.java
@@ -0,0 +1,225 @@
+package me.chanjar.weixin.channel.message;
+
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.WxChannelService;
+import me.chanjar.weixin.common.api.WxErrorExceptionHandler;
+import me.chanjar.weixin.common.api.WxMessageDuplicateChecker;
+import me.chanjar.weixin.common.api.WxMessageInMemoryDuplicateCheckerSingleton;
+import me.chanjar.weixin.common.session.InternalSession;
+import me.chanjar.weixin.common.session.InternalSessionManager;
+import me.chanjar.weixin.common.session.StandardSessionManager;
+import me.chanjar.weixin.common.session.WxSessionManager;
+import me.chanjar.weixin.common.util.LogExceptionHandler;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * 消息路由器
+ *
+ * @author Zeyes
+ */
+@Data
+@Slf4j
+public class WxChannelMessageRouter {
+ /** 规则列表 */
+ private final List> rules = new ArrayList<>();
+ /** 线程池 */
+ private ExecutorService executorService;
+ /** 异常处理器 */
+ private WxErrorExceptionHandler exceptionHandler;
+ /** 消息重复检查器 */
+ private WxMessageDuplicateChecker messageDuplicateChecker;
+
+ public WxChannelMessageRouter() {
+ ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("WxChMsgRouter-pool-%d").build();
+ this.executorService = new ThreadPoolExecutor(2, 100,
+ 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), namedThreadFactory);
+ //this.sessionManager = new StandardSessionManager();
+ this.exceptionHandler = new LogExceptionHandler();
+ this.messageDuplicateChecker = WxMessageInMemoryDuplicateCheckerSingleton.getInstance();
+ }
+
+ /**
+ * 使用自定义的 {@link ExecutorService}.
+ */
+ public WxChannelMessageRouter(ExecutorService executorService) {
+ this.executorService = executorService;
+ this.exceptionHandler = new LogExceptionHandler();
+ this.messageDuplicateChecker = WxMessageInMemoryDuplicateCheckerSingleton.getInstance();
+ }
+
+ /**
+ * 系统退出前,应该调用该方法
+ */
+ public void shutDownExecutorService() {
+ this.executorService.shutdown();
+ }
+
+ /**
+ * 系统退出前,应该调用该方法,增加了超时时间检测
+ */
+ public void shutDownExecutorService(Integer second) {
+ this.executorService.shutdown();
+ try {
+ if (!this.executorService.awaitTermination(second, TimeUnit.SECONDS)) {
+ this.executorService.shutdownNow();
+ if (!this.executorService.awaitTermination(second, TimeUnit.SECONDS)) {
+ log.error("线程池未关闭!");
+ }
+ }
+ } catch (InterruptedException ie) {
+ this.executorService.shutdownNow();
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ /**
+ *
+ * 设置自定义的 {@link ExecutorService}
+ * 如果不调用该方法,默认使用内置的
+ *
+ */
+ public void setExecutorService(ExecutorService executorService) {
+ this.executorService = executorService;
+ }
+
+ /**
+ * 消息路由入口
+ *
+ * @param message 消息
+ * @param content 原始消息(解密之后的)
+ * @param appId appId
+ * @param service 服务实例
+ * @return 返回值
+ */
+ public Object route(final WxChannelMessage message, final String content, final String appId,
+ final WxChannelService service) {
+ return this.route(message, content, appId, new HashMap<>(2), service, new StandardSessionManager());
+ }
+
+ /**
+ * 路由微信消息
+ *
+ * @param message 消息
+ * @param content 消息原始内容
+ * @param context 上下文
+ * @return Object
+ */
+ public Object route(final WxChannelMessage message, final String content, final String appId,
+ final Map context, final WxChannelService service, final WxSessionManager sessionManager) {
+ // 如果是重复消息,那么就不做处理
+ if (isMsgDuplicated(message)) {
+ return null;
+ }
+
+ final List> matchRules = new ArrayList<>();
+
+ // 收集匹配的规则
+ for (final WxChannelMessageRouterRule extends WxChannelMessage> rule : this.rules) {
+ if (rule.isMatch(message)) {
+ matchRules.add(rule);
+ if (!rule.isNext()) {
+ break;
+ }
+ }
+ }
+
+ if (matchRules.size() == 0) {
+ return null;
+ }
+ final List> futures = new ArrayList<>();
+ Object result = null;
+ for (final WxChannelMessageRouterRule extends WxChannelMessage> rule : matchRules) {
+ // 返回最后一个非异步的rule的执行结果
+ if (rule.isAsync()) {
+ futures.add(
+ this.executorService.submit(() -> {
+ rule.process(message, content, appId, context, service, sessionManager, exceptionHandler);
+ })
+ );
+ } else {
+ result = rule.process(message, content, appId, context, service, sessionManager, exceptionHandler);
+ // 在同步操作结束,session访问结束
+ sessionEndAccess(sessionManager, message, false);
+ }
+ }
+
+ if (futures.size() > 0) {
+ this.executorService.submit(() -> {
+ for (Future> future : futures) {
+ try {
+ future.get();
+ // 异步操作结束,session访问结束
+ sessionEndAccess(sessionManager, message, true);
+ } catch (InterruptedException | ExecutionException e) {
+ log.error("Error happened when wait task finish", e);
+ }
+ }
+ });
+ }
+ return result;
+ }
+
+ /**
+ * 判断消息是否重复
+ *
+ * @param wxMessage 消息
+ * @return 是否重复
+ */
+ private boolean isMsgDuplicated(WxChannelMessage wxMessage) {
+ String messageId = this.generateMessageId(wxMessage);
+ return this.messageDuplicateChecker.isDuplicate(messageId);
+ }
+
+ /**
+ * 生成消息id
+ *
+ * @return 消息id
+ */
+ private String generateMessageId(WxChannelMessage wxMessage) {
+ StringBuilder sb = new StringBuilder();
+ if (wxMessage.getMsgId() == null) {
+ sb.append(wxMessage.getCreateTime())
+ .append("-").append(wxMessage.getFromUser())
+ .append("-").append(StringUtils.trimToEmpty(wxMessage.getEvent()));
+ } else {
+ sb.append(wxMessage.getMsgId())
+ .append("-").append(wxMessage.getCreateTime())
+ .append("-").append(wxMessage.getFromUser());
+ }
+
+ if (StringUtils.isNotEmpty(wxMessage.getToUser())) {
+ sb.append("-").append(wxMessage.getToUser());
+ }
+ return sb.toString();
+ }
+
+ /**
+ * 对session的访问结束
+ *
+ * @param sessionManager session管理器
+ * @param message 消息
+ * @param sync 是否同步 打印log用
+ */
+ private void sessionEndAccess(WxSessionManager sessionManager, WxChannelMessage message, boolean sync) {
+ log.debug("End session access: async={}, sessionId={}", sync, message.getFromUser());
+ InternalSession session = ((InternalSessionManager) sessionManager).findSession(message.getFromUser());
+ if (session != null) {
+ session.endAccess();
+ }
+ }
+
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/WxChannelMessageRouterRule.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/WxChannelMessageRouterRule.java
new file mode 100644
index 0000000000..60c5e9f83e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/WxChannelMessageRouterRule.java
@@ -0,0 +1,172 @@
+package me.chanjar.weixin.channel.message;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import lombok.Data;
+import lombok.Singular;
+import lombok.experimental.Accessors;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.WxChannelService;
+import me.chanjar.weixin.channel.enums.MessageType;
+import me.chanjar.weixin.channel.message.rule.WxChannelMessageHandler;
+import me.chanjar.weixin.channel.message.rule.WxChannelMessageInterceptor;
+import me.chanjar.weixin.channel.message.rule.WxChannelMessageMatcher;
+import me.chanjar.weixin.channel.util.JsonUtils;
+import me.chanjar.weixin.channel.util.XmlUtils;
+import me.chanjar.weixin.common.api.WxErrorExceptionHandler;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.session.WxSessionManager;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@Accessors(chain = true)
+@Slf4j
+public class WxChannelMessageRouterRule {
+ /** 是否异步, 默认是true */
+ private boolean async = true;
+ /** 消息类型 */
+ private String msgType;
+ /** 事件类型 */
+ private String event;
+ /** 自定义匹配器 */
+ private WxChannelMessageMatcher matcher;
+ /** 进入下一个rule,默认是false */
+ private boolean next = false;
+ /** 消息处理器 */
+ @Singular
+ private List> handlers = new ArrayList<>(4);
+ /** 消息拦截器 */
+ @Singular
+ private List interceptors = new ArrayList<>(4);
+ /** 消息类型 */
+ private Class messageClass;
+
+ public WxChannelMessageRouterRule() {
+ }
+
+ /**
+ * 设置事件
+ *
+ * @param event 事件
+ * @return this
+ */
+ public WxChannelMessageRouterRule setEvent(String event) {
+ this.msgType = MessageType.EVENT.getKey();
+ this.event = event;
+ return this;
+ }
+
+ /**
+ * 测试消息是否匹配规则
+ *
+ * @param message 消息
+ * @return 是否匹配
+ */
+ protected boolean isMatch(WxChannelMessage message) {
+ String msgType = message.getMsgType() == null ? null : message.getMsgType().toLowerCase();
+ String event = message.getEvent() == null ? null : message.getEvent().toLowerCase();
+
+ boolean matchMsgType = this.msgType == null || this.msgType.toLowerCase().equals(msgType);
+ boolean matchEvent = this.event == null || this.event.toLowerCase().equals(event);
+ boolean matchMatcher = this.matcher == null || this.matcher.match(message);
+
+ return matchMsgType && matchEvent && matchMatcher;
+ }
+
+ /**
+ * 处理微信推送过来的消息
+ *
+ * @param message 消息
+ * @param content 消息原始内容
+ * @param appId appId
+ * @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个
+ * @param service 服务实例
+ * @param sessionManager session管理器
+ * @param exceptionHandler 异常处理器
+ * @return 返回消息
+ */
+ protected Object process(WxChannelMessage message, String content, String appId, Map context,
+ WxChannelService service, WxSessionManager sessionManager, WxErrorExceptionHandler exceptionHandler) {
+ if (context == null) {
+ context = new HashMap<>(16);
+ }
+ // 重新反序列化消息
+ T tempMessage = deserialize(content, messageClass, service);
+ if (tempMessage == null) {
+ log.error("消息重新反序列化失败,请检查消息格式是否正确或者指定正确的messageClass");
+ return null;
+ }
+
+ Object outMessage = null;
+ try {
+ // 如果拦截器不通过,返回null
+ for (WxChannelMessageInterceptor interceptor : this.interceptors) {
+ if (!interceptor.intercept(message, content, context, service, sessionManager)) {
+ return null;
+ }
+ }
+
+ // 交给handler处理
+ for (WxChannelMessageHandler handler : this.handlers) {
+ // 返回最后handler的结果
+ if (handler == null) {
+ continue;
+ }
+
+ outMessage = handler.handle(tempMessage, content, appId, context, sessionManager);
+ }
+ } catch (WxErrorException e) {
+ exceptionHandler.handle(e);
+ }
+ return outMessage;
+ }
+
+ /**
+ * 重新反序列化消息
+ *
+ * @param content 消息内容
+ * @param clazz 消息类型
+ * @param service 服务实例
+ * @return T
+ */
+ private T deserialize(String content, Class clazz, WxChannelService service) {
+ String msgFormat = service.getConfig().getMsgDataFormat();
+ T t = deserialize(content, clazz, msgFormat);
+ if (t != null) {
+ return t;
+ }
+ // 如果指定的消息格式不正确,根据内容猜猜格式
+ if (StringUtils.isNotBlank(content)) {
+ if (content.startsWith("")) {
+ t = deserialize(content, clazz, "XML");
+ } else if (content.startsWith("{")){
+ t = deserialize(content, clazz, "JSON");
+ }
+ }
+ return t;
+ }
+
+ /**
+ * 重新反序列化消息
+ *
+ * @param content 消息内容
+ * @param clazz 消息类型
+ * @param msgFormat 消息格式
+ * @return T
+ */
+ private T deserialize(String content, Class clazz, String msgFormat) {
+ T message = null;
+ // 重新反序列化原始消息
+ if (msgFormat == null || msgFormat.equalsIgnoreCase("JSON")) {
+ message = JsonUtils.decode(content, clazz);
+ } else {
+ message = XmlUtils.decode(content, clazz);
+ }
+ return message;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/rule/HandlerConsumer.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/rule/HandlerConsumer.java
new file mode 100644
index 0000000000..522290b178
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/rule/HandlerConsumer.java
@@ -0,0 +1,12 @@
+package me.chanjar.weixin.channel.message.rule;
+
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * @author Zeyes
+ */
+@FunctionalInterface
+public interface HandlerConsumer {
+
+ void accept(T t, U u, V v, W w, X x);
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/rule/WxChannelMessageHandler.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/rule/WxChannelMessageHandler.java
new file mode 100644
index 0000000000..4918365bf9
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/rule/WxChannelMessageHandler.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.message.rule;
+
+import java.util.Map;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.session.WxSessionManager;
+
+/**
+ * 处理视频号推送消息的处理器
+ *
+ * @author Zeyes
+ */
+public interface WxChannelMessageHandler {
+
+ /**
+ * 处理消息
+ *
+ * @param message 消息
+ * @param content 消息原始内容
+ * @param appId appId
+ * @param context 上下文
+ * @param sessionManager session管理器
+ * @return 输出消息 格式可能是String/Xml/Json,视情况而定
+ *
+ * @throws WxErrorException 异常
+ */
+ Object handle(T message, String content, String appId, Map context, WxSessionManager sessionManager)
+ throws WxErrorException;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/rule/WxChannelMessageInterceptor.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/rule/WxChannelMessageInterceptor.java
new file mode 100644
index 0000000000..dbb06cb6cc
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/rule/WxChannelMessageInterceptor.java
@@ -0,0 +1,31 @@
+package me.chanjar.weixin.channel.message.rule;
+
+import java.util.Map;
+import me.chanjar.weixin.channel.api.WxChannelService;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.session.WxSessionManager;
+
+/**
+ * 微信消息拦截器,可以用来做验证
+ *
+ * @author Zeyes
+ */
+public interface WxChannelMessageInterceptor {
+
+ /**
+ * 拦截微信消息
+ *
+ * @param message 消息
+ * @param content 消息原始内容
+ * @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个
+ * @param service 服务实例
+ * @param sessionManager session管理器
+ * @return true代表OK,false代表不OK
+ *
+ * @throws WxErrorException 异常
+ */
+ boolean intercept(WxChannelMessage message, String content, Map context, WxChannelService service,
+ WxSessionManager sessionManager) throws WxErrorException;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/rule/WxChannelMessageMatcher.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/rule/WxChannelMessageMatcher.java
new file mode 100644
index 0000000000..c6e6824ca0
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/rule/WxChannelMessageMatcher.java
@@ -0,0 +1,20 @@
+package me.chanjar.weixin.channel.message.rule;
+
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * 消息匹配器,用在消息路由的时候
+ *
+ * @author Zeyes
+ */
+public interface WxChannelMessageMatcher {
+
+ /**
+ * 消息是否匹配某种模式
+ *
+ * @param message 消息
+ * @return 是否匹配
+ */
+ boolean match(WxChannelMessage message);
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/util/JsonUtils.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/util/JsonUtils.java
new file mode 100644
index 0000000000..ce7e754e00
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/util/JsonUtils.java
@@ -0,0 +1,100 @@
+package me.chanjar.weixin.channel.util;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.json.JsonReadFeature;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.json.JsonMapper;
+import java.io.IOException;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Json序列化/反序列化工具类
+ *
+ * @author Zeyes
+ */
+@Slf4j
+public class JsonUtils {
+
+ private static final JsonMapper JSON_MAPPER = new JsonMapper();
+
+ static {
+ JSON_MAPPER.enable(JsonReadFeature.ALLOW_JAVA_COMMENTS.mappedFeature());
+ JSON_MAPPER.enable(JsonReadFeature.ALLOW_UNQUOTED_FIELD_NAMES.mappedFeature());
+ JSON_MAPPER.enable(JsonReadFeature.ALLOW_SINGLE_QUOTES.mappedFeature());
+ JSON_MAPPER.enable(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature());
+ JSON_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+ JSON_MAPPER.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+ JSON_MAPPER.disable(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES);
+ }
+
+ private JsonUtils() {
+ }
+
+ /**
+ * 对象序列化
+ *
+ * @param obj 对象
+ * @return json
+ */
+ public static String encode(Object obj) {
+ try {
+ return JSON_MAPPER.writeValueAsString(obj);
+ } catch (IOException e) {
+ log.error("encode(Object)", e);
+ }
+ return null;
+ }
+
+ /**
+ * 对象序列化
+ *
+ * @param objectMapper ObjectMapper
+ * @param obj obj
+ * @return json
+ */
+ public static String encode(ObjectMapper objectMapper, Object obj) {
+ try {
+ return objectMapper.writeValueAsString(obj);
+ } catch (IOException e) {
+ log.error("encode(Object)", e);
+ }
+ return null;
+ }
+
+ /**
+ * 将json反序列化成对象
+ *
+ * @param json json
+ * @param valueType Class
+ * @return T
+ */
+ public static T decode(String json, Class valueType) {
+ if (json == null || json.length() <= 0) {
+ return null;
+ }
+ try {
+ return JSON_MAPPER.readValue(json, valueType);
+ } catch (IOException e) {
+ log.info("decode(String, Class)", e);
+ }
+ return null;
+ }
+
+ /**
+ * 将json反序列化为对象
+ *
+ * @param json json
+ * @param typeReference TypeReference
+ * @return T
+ */
+ public static T decode(String json, TypeReference typeReference) {
+ try {
+ return (T) JSON_MAPPER.readValue(json, typeReference);
+ } catch (IOException e) {
+ log.info("decode(String, JsonTypeReference)", e);
+ }
+ return null;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/util/ResponseUtils.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/util/ResponseUtils.java
new file mode 100644
index 0000000000..865eab6354
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/util/ResponseUtils.java
@@ -0,0 +1,63 @@
+package me.chanjar.weixin.channel.util;
+
+
+import static me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse.INTERNAL_ERROR_CODE;
+
+import java.lang.reflect.InvocationTargetException;
+import lombok.experimental.UtilityClass;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * 响应工具类
+ *
+ * @author Zeyes
+ */
+@Slf4j
+@UtilityClass
+public class ResponseUtils {
+
+ /**
+ * 将json反序列化成对象
+ *
+ * @param json json
+ * @param valueType Class
+ * @return T
+ */
+ public static