Преглед изворни кода

#733 微信卡券增加会员卡新增,卡券二维码,添加白名单,新增卡券货架等接口

yuanqixun пре 6 година
родитељ
комит
f90f72fc9c
28 измењених фајлова са 1531 додато и 29 уклоњено
  1. 30 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCardService.java
  2. 21 5
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMemberCardService.java
  3. 53 4
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java
  4. 164 12
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImpl.java
  5. 33 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/Abstract.java
  6. 61 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/AdvancedInfo.java
  7. 190 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/BaseInfo.java
  8. 69 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/BonusRule.java
  9. 34 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CardColor.java
  10. 21 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CardSceneType.java
  11. 39 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CustomCell1.java
  12. 43 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CustomField.java
  13. 51 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/DateInfo.java
  14. 17 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/DateInfoType.java
  15. 152 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCard.java
  16. 21 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCardCreateRequest.java
  17. 27 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/PayInfo.java
  18. 27 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/Sku.java
  19. 33 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/SwipeCard.java
  20. 33 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/TextImageList.java
  21. 52 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/TimeLimit.java
  22. 52 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/UseCondition.java
  23. 47 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardCreateResult.java
  24. 67 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardLandingPageCreateRequest.java
  25. 40 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardLandingPageCreateResult.java
  26. 40 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardQrcodeCreateResult.java
  27. 25 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/WxMpMemberCardCreateMessage.java
  28. 89 8
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImplTest.java

+ 30 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCardService.java

@@ -2,12 +2,16 @@ package me.chanjar.weixin.mp.api;
 
 import me.chanjar.weixin.common.bean.WxCardApiSignature;
 import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.mp.bean.card.WxMpCardLandingPageCreateRequest;
+import me.chanjar.weixin.mp.bean.card.WxMpCardLandingPageCreateResult;
+import me.chanjar.weixin.mp.bean.card.WxMpCardQrcodeCreateResult;
 import me.chanjar.weixin.mp.bean.result.WxMpCardResult;
 
 /**
  * 卡券相关接口
  *
  * @author YuJian(mgcnrx11@hotmail.com) on 01/11/2016
+ * @author yuanqixun 2018-08-29
  */
 public interface WxMpCardService {
   String CARD_GET = "https://api.weixin.qq.com/card/get";
@@ -16,6 +20,9 @@ public interface WxMpCardService {
   String CARD_CODE_GET = "https://api.weixin.qq.com/card/code/get";
   String CARD_CODE_CONSUME = "https://api.weixin.qq.com/card/code/consume";
   String CARD_CODE_MARK = "https://api.weixin.qq.com/card/code/mark";
+  String CARD_TEST_WHITELIST = "https://api.weixin.qq.com/card/testwhitelist/set";
+  String CARD_QRCODE_CREAET = "https://api.weixin.qq.com/card/qrcode/create";
+  String CARD_LANDING_PAGE_CREAET = "https://api.weixin.qq.com/card/landingpage/create";
 
   /**
    * 得到WxMpService
@@ -122,4 +129,27 @@ public interface WxMpCardService {
    * <br> 可由 com.google.gson.JsonParser#parse 等方法直接取JSON串中的某个字段。
    */
   String getCardDetail(String cardId) throws WxErrorException;
+
+  /**
+   * 添加测试白名单
+   * @param openid 用户的openid
+   * @return
+   */
+  String addTestWhiteList(String openid) throws WxErrorException;
+
+  /**
+   * 创建卡券二维码
+   * @param cardId 卡券编号
+   * @param outerStr 二维码标识
+   * @return WxMpCardQrcodeCreateResult
+   */
+  WxMpCardQrcodeCreateResult createQrcodeCard(String cardId, String outerStr) throws WxErrorException;
+
+  /**
+   * 创建卡券货架
+   * @param createRequest 货架创建参数
+   * @return
+   * @throws WxErrorException
+   */
+  WxMpCardLandingPageCreateResult createLandingPage(WxMpCardLandingPageCreateRequest createRequest) throws WxErrorException;
 }

+ 21 - 5
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMemberCardService.java

@@ -1,10 +1,9 @@
 package me.chanjar.weixin.mp.api;
 
 import me.chanjar.weixin.common.error.WxErrorException;
-import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardActivatedMessage;
-import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUpdateMessage;
-import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUpdateResult;
-import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUserInfoResult;
+import me.chanjar.weixin.mp.bean.card.WxMpCardCreateResult;
+import me.chanjar.weixin.mp.bean.card.WxMpCardQrcodeCreateResult;
+import me.chanjar.weixin.mp.bean.membercard.*;
 
 /**
  * 会员卡相关接口
@@ -20,10 +19,26 @@ public interface WxMpMemberCardService {
   WxMpService getWxMpService();
 
   /**
+   * 会员卡创建接口
+   * @param createJson
+   * @return
+   * @throws WxErrorException
+   */
+  WxMpCardCreateResult createMemberCard(String createJson) throws WxErrorException;
+
+  /**
+   * 会员卡创建接口
+   * @param createMessageMessage
+   * @return WxMpCardCreateResult
+   * @throws WxErrorException
+   */
+  WxMpCardCreateResult createMemberCard(WxMpMemberCardCreateMessage createMessageMessage) throws WxErrorException;
+
+  /**
    * 会员卡激活接口
    *
    * @param activatedMessage 激活所需参数
-   * @return 调用返回的JSON字符串。
+   * @return 返回json字符串
    * @throws WxErrorException 接口调用失败抛出的异常
    */
   String activateMemberCard(WxMpMemberCardActivatedMessage activatedMessage) throws WxErrorException;
@@ -50,4 +65,5 @@ public interface WxMpMemberCardService {
    * @throws WxErrorException 接口调用失败抛出的异常
    */
   WxMpMemberCardUpdateResult updateUserMemberCard(WxMpMemberCardUpdateMessage updateUserMessage) throws WxErrorException;
+
 }

+ 53 - 4
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java

@@ -1,9 +1,6 @@
 package me.chanjar.weixin.mp.api.impl;
 
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import com.google.gson.JsonPrimitive;
+import com.google.gson.*;
 import com.google.gson.reflect.TypeToken;
 import me.chanjar.weixin.common.bean.WxCardApiSignature;
 import me.chanjar.weixin.common.error.WxError;
@@ -13,6 +10,9 @@ import me.chanjar.weixin.common.util.crypto.SHA1;
 import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
 import me.chanjar.weixin.mp.api.WxMpCardService;
 import me.chanjar.weixin.mp.api.WxMpService;
+import me.chanjar.weixin.mp.bean.card.WxMpCardLandingPageCreateRequest;
+import me.chanjar.weixin.mp.bean.card.WxMpCardLandingPageCreateResult;
+import me.chanjar.weixin.mp.bean.card.WxMpCardQrcodeCreateResult;
 import me.chanjar.weixin.mp.bean.result.WxMpCardResult;
 import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
 import org.slf4j.Logger;
@@ -30,6 +30,8 @@ public class WxMpCardServiceImpl implements WxMpCardService {
 
   private WxMpService wxMpService;
 
+  private static final Gson GSON = new Gson();
+
   public WxMpCardServiceImpl(WxMpService wxMpService) {
     this.wxMpService = wxMpService;
   }
@@ -236,4 +238,51 @@ public class WxMpCardServiceImpl implements WxMpCardService {
 
     return responseContent;
   }
+
+  /**
+   * 添加测试白名单
+   *
+   * @param openid 用户的openid
+   * @return
+   */
+  public String addTestWhiteList(String openid) throws WxErrorException {
+    JsonArray array = new JsonArray();
+    array.add(openid);
+    JsonObject jsonObject = new JsonObject();
+    jsonObject.add("openid", array);
+    String respone = this.wxMpService.post(CARD_TEST_WHITELIST, GSON.toJson(jsonObject));
+    return respone;
+  }
+
+  /**
+   * 创建卡券二维码
+   * @param cardId
+   * @param outerStr
+   * @return
+   */
+  public WxMpCardQrcodeCreateResult createQrcodeCard(String cardId, String outerStr) throws WxErrorException {
+    JsonObject jsonObject = new JsonObject();
+    jsonObject.addProperty("action_name", "QR_CARD");
+    jsonObject.addProperty("expire_seconds", 1800);
+    JsonObject actionInfoJson = new JsonObject();
+    JsonObject cardJson = new JsonObject();
+    cardJson.addProperty("card_id", cardId);
+    cardJson.addProperty("outer_str", outerStr);
+    actionInfoJson.add("card", cardJson);
+    jsonObject.add("action_info", actionInfoJson);
+    String response = this.wxMpService.post(CARD_QRCODE_CREAET, GSON.toJson(jsonObject));
+    return WxMpCardQrcodeCreateResult.fromJson(response);
+  }
+
+  /**
+   * 创建卡券货架接口
+   * @param request
+   * @return
+   * @throws WxErrorException
+   */
+  @Override
+  public WxMpCardLandingPageCreateResult createLandingPage(WxMpCardLandingPageCreateRequest request) throws WxErrorException {
+    String response = this.wxMpService.post(CARD_LANDING_PAGE_CREAET,GSON.toJson(request));
+    return WxMpCardLandingPageCreateResult.fromJson(response);
+  }
 }

+ 164 - 12
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImpl.java

@@ -1,31 +1,29 @@
 package me.chanjar.weixin.mp.api.impl;
 
-import com.google.gson.Gson;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
+import com.google.gson.*;
 import com.google.gson.reflect.TypeToken;
 import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.util.json.WxGsonBuilder;
 import me.chanjar.weixin.mp.api.WxMpMemberCardService;
 import me.chanjar.weixin.mp.api.WxMpService;
-import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardActivatedMessage;
-import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUpdateMessage;
-import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUpdateResult;
-import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUserInfoResult;
+import me.chanjar.weixin.mp.bean.card.*;
+import me.chanjar.weixin.mp.bean.membercard.*;
 import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
  * 会员卡相关接口的实现类
  *
- * @author YuJian(mgcnrx11@gmail.com)
+ * @author YuJian(mgcnrx11 @ gmail.com)
  * @version 2017/7/8
  */
 public class WxMpMemberCardServiceImpl implements WxMpMemberCardService {
 
   private final Logger log = LoggerFactory.getLogger(WxMpMemberCardServiceImpl.class);
 
+  private static final String MEMBER_CARD_CREAET = "https://api.weixin.qq.com/card/create";
   private static final String MEMBER_CARD_ACTIVATE = "https://api.weixin.qq.com/card/membercard/activate";
   private static final String MEMBER_CARD_USER_INFO_GET = "https://api.weixin.qq.com/card/membercard/userinfo/get";
   private static final String MEMBER_CARD_UPDATE_USER = "https://api.weixin.qq.com/card/membercard/updateuser";
@@ -47,10 +45,163 @@ public class WxMpMemberCardServiceImpl implements WxMpMemberCardService {
   }
 
   /**
+   * 会员卡创建接口
+   *
+   * @param createJson 创建json
+   * @return 调用返回的JSON字符串。
+   * @throws WxErrorException 接口调用失败抛出的异常
+   */
+  @Override
+  public WxMpCardCreateResult createMemberCard(String createJson) throws WxErrorException {
+    WxMpMemberCardCreateMessage createMessage = WxGsonBuilder.create().fromJson(createJson, WxMpMemberCardCreateMessage.class);
+    return createMemberCard(createMessage);
+  }
+
+  /**
+   * 会员卡创建接口
+   *
+   * @param createMessageMessage 创建所需参数
+   * @return WxMpCardCreateResult。
+   * @throws WxErrorException 接口调用失败抛出的异常
+   */
+  @Override
+  public WxMpCardCreateResult createMemberCard(WxMpMemberCardCreateMessage createMessageMessage) throws WxErrorException {
+    //校验请求对象合法性
+    WxMpCardCreateResult validResult = validCheck(createMessageMessage);
+    if (!validResult.isSuccess())
+      return validResult;
+    String response = this.wxMpService.post(MEMBER_CARD_CREAET, GSON.toJson(createMessageMessage));
+    return WxMpCardCreateResult.fromJson(response);
+  }
+
+  private WxMpCardCreateResult validCheck(WxMpMemberCardCreateMessage createMessageMessage) throws WxErrorException {
+    if (createMessageMessage == null) {
+      return WxMpCardCreateResult.failure("对象不能为空");
+    }
+    MemberCardCreateRequest cardCreateRequest = createMessageMessage.getCardCreateRequest();
+    if (createMessageMessage == null) {
+      return WxMpCardCreateResult.failure("会员卡对象不能为空");
+    }
+    String cardType = cardCreateRequest.getCardType();
+    if (!StringUtils.equals(cardType, "MEMBER_CARD")) {
+      return WxMpCardCreateResult.failure("卡券类型必须等于MEMBER_CARD");
+    }
+    MemberCard memberCard = cardCreateRequest.getMemberCard();
+
+    if (StringUtils.isEmpty(memberCard.getPrerogative())) {
+      return WxMpCardCreateResult.failure("会员卡特权说明不能为空:prerogative");
+    }
+    //卡片激活规则
+    if (!memberCard.isAutoActivate() && !memberCard.isWxActivate() && StringUtils.isEmpty(memberCard.getActivateUrl())) {
+      return WxMpCardCreateResult.failure("会员卡激活方式为接口激活,activate_url不能为空");
+    }
+
+    //积分支持
+//    if(memberCard.isSupplyBonus() && StringUtils.isEmpty(memberCard.getBonusUrl())){
+//      return WxMpCardCreateResult.failure("会员卡支持积分,bonus_url不能为空");
+//    }
+//    if(memberCard.isSupplyBonus() && memberCard.getBonusRule() == null){
+//      return WxMpCardCreateResult.failure("会员卡支持积分,bonus_rule不能为空");
+//    }
+    BaseInfo baseInfo = memberCard.getBaseInfo();
+    if (baseInfo == null) {
+      return WxMpCardCreateResult.failure("会员卡基本信息对象base_info不能为空");
+    }
+
+    if (StringUtils.isBlank(baseInfo.getLogoUrl())) {
+      return WxMpCardCreateResult.failure("会员卡基本信息的商户logo:logo_url不能为空");
+    }
+
+    if (StringUtils.isBlank(baseInfo.getCodeType())) {
+      return WxMpCardCreateResult.failure("会员卡基本信息的条码类型:code_type不能为空");
+    }
+
+    if (StringUtils.isBlank(baseInfo.getBrandName())) {
+      return WxMpCardCreateResult.failure("会员卡基本信息的商户名字:brand_name不能为空");
+    }
+
+    if (StringUtils.length(baseInfo.getBrandName()) > 12) {
+      return WxMpCardCreateResult.failure("会员卡基本信息的商户名字:brand_name长度不能大于12个汉字");
+    }
+
+    if (StringUtils.isBlank(baseInfo.getTitle())) {
+      return WxMpCardCreateResult.failure("会员卡基本信息的卡券名称:title不能为空");
+    }
+
+    if (StringUtils.length(baseInfo.getTitle()) > 9) {
+      return WxMpCardCreateResult.failure("会员卡基本信息的卡券名称:title长度不能大于9个汉字");
+    }
+
+    if (StringUtils.isBlank(baseInfo.getColor())) {
+      return WxMpCardCreateResult.failure("会员卡基本信息的卡颜色:color不能为空");
+    }
+
+    CardColor cardColor = null;
+    try {
+      cardColor = CardColor.valueOf(baseInfo.getColor());
+    } catch (IllegalArgumentException ex) {
+
+    }
+    if (cardColor == null) {
+      return WxMpCardCreateResult.failure("会员卡基本信息的卡颜色:" + baseInfo.getColor() + "不支持");
+    }
+
+    if (StringUtils.isBlank(baseInfo.getNotice())) {
+      return WxMpCardCreateResult.failure("会员卡基本信息的使用提醒:notice不能为空");
+    }
+
+    if (StringUtils.isBlank(baseInfo.getDescription())) {
+      return WxMpCardCreateResult.failure("会员卡基本信息的使用说明:description不能为空");
+    }
+
+    if (baseInfo.getSku() == null) {
+      return WxMpCardCreateResult.failure("会员卡基本信息的商品信息:sku不能为空");
+    }
+
+    DateInfo dateInfo = baseInfo.getDateInfo();
+    if (dateInfo == null) {
+      return WxMpCardCreateResult.failure("会员卡基本信息的使用日期:date_info不能为空");
+    }
+
+    DateInfoType dateInfoType = null;
+    try {
+      dateInfoType = DateInfoType.valueOf(dateInfo.getType());
+    } catch (IllegalArgumentException ex) {
+
+    }
+
+    if (dateInfoType == null) {
+      return WxMpCardCreateResult.failure("会员卡基本信息的使用日期类型:" + dateInfo.getType() + "不合法");
+    }
+
+    //固定时长
+    if (dateInfoType == DateInfoType.DATE_TYPE_FIX_TERM && (dateInfo.getFixedTerm() == null || dateInfo.getFixedBeginTerm() == null)) {
+      return WxMpCardCreateResult.failure("会员卡基本信息的使用日期为:" + dateInfoType.getDescription() + ",fixedTerm和fixedBeginTerm不能为空");
+    }
+
+    //固定期限
+    if (dateInfoType == DateInfoType.DATE_TYPE_FIX_TIME_RANGE && (dateInfo.getBeginTimestamp() == null || dateInfo.getEndTimestamp() == null)) {
+      return WxMpCardCreateResult.failure("会员卡基本信息的使用日期为:" + dateInfoType.getDescription() + ",beginTimestamp 和 endTimestamp 不能为空");
+    }
+    if (dateInfoType == DateInfoType.DATE_TYPE_FIX_TIME_RANGE && (dateInfo.getBeginTimestamp() < System.currentTimeMillis() || dateInfo.getEndTimestamp() < System.currentTimeMillis() || dateInfo.getBeginTimestamp() > dateInfo.getEndTimestamp())) {
+      return WxMpCardCreateResult.failure("会员卡基本信息的使用日期为:" + dateInfoType.getDescription() + ",beginTimestamp和endTimestamp的值不合法,请检查");
+    }
+
+    if (!baseInfo.isUseAllLocations() && StringUtils.isBlank(baseInfo.getLocationIdList())) {
+      return WxMpCardCreateResult.failure("会员卡基本信息的门店使用范围选择指定门店,门店列表:locationIdList不能为空");
+    }
+
+    //TODO 高级信息
+
+
+    return WxMpCardCreateResult.success();
+  }
+
+  /**
    * 会员卡激活接口
    *
    * @param activatedMessage 激活所需参数
-   * @return 调用返回的JSON字符串。
+   * @return WxMpCardCreateResult
    * @throws WxErrorException 接口调用失败抛出的异常
    */
   @Override
@@ -70,7 +221,7 @@ public class WxMpMemberCardServiceImpl implements WxMpMemberCardService {
   public WxMpMemberCardUserInfoResult getUserInfo(String cardId, String code) throws WxErrorException {
     JsonObject jsonObject = new JsonObject();
     jsonObject.addProperty("card_id", cardId);
-    jsonObject.addProperty("code",code);
+    jsonObject.addProperty("code", code);
 
     String responseContent = this.getWxMpService().post(MEMBER_CARD_USER_INFO_GET, jsonObject.toString());
     JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
@@ -81,7 +232,7 @@ public class WxMpMemberCardServiceImpl implements WxMpMemberCardService {
 
   /**
    * 当会员持卡消费后,支持开发者调用该接口更新会员信息。会员卡交易后的每次信息变更需通过该接口通知微信,便于后续消息通知及其他扩展功能。
-   *
+   * <p>
    * 1.开发者可以同时传入add_bonus和bonus解决由于同步失败带来的幂等性问题。同时传入add_bonus和bonus时
    * add_bonus作为积分变动消息中的变量值,而bonus作为卡面上的总积分额度显示。余额变动同理。
    * 2.开发者可以传入is_notify_bonus控制特殊的积分对账变动不发送消息,余额变动同理。
@@ -101,4 +252,5 @@ public class WxMpMemberCardServiceImpl implements WxMpMemberCardService {
       new TypeToken<WxMpMemberCardUpdateResult>() {
       }.getType());
   }
+
 }

+ 33 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/Abstract.java

@@ -0,0 +1,33 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.io.Serializable;
+
+/**
+ * 封面摘要
+ * author:yuanqixun
+ * date:2018-08-25 00:35
+ */
+@Data
+public class Abstract implements Serializable {
+
+    /**
+     * 摘要
+     */
+    @SerializedName("abstract")
+    private String abstractInfo;
+
+    /**
+     * 封面图片列表,仅支持填入一 个封面图片链接, 上传图片接口 上传获取图片获得链接,填写 非CDN链接会报错,并在此填入。 建议图片尺寸像素850*350
+     */
+    @SerializedName("icon_url_list")
+    private String iconUrlList;
+
+    public String toString(){
+        return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
+    }
+}

+ 61 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/AdvancedInfo.java

@@ -0,0 +1,61 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+//子对象列表
+
+/**
+ * 微信会员卡高级字段信息
+ * author:yuanqixun
+ * date:2018-08-25 00:36
+ */
+@Data
+public class AdvancedInfo implements Serializable {
+
+//    public AdvancedInfo(){
+//        useCondition = new UseCondition();
+//        abstractInfo = new Abstract();
+//        textImageList = new ArrayList<>();
+//        timeLimit = new TimeLimit();
+//    }
+
+    /**
+     * 使用门槛(条件),若不填写使用条件则在券面拼写 :无最低消费限制,全场通用,不限品类;并在使用说明显示: 可与其他优惠共享
+     */
+    @SerializedName( "use_condition")
+    private UseCondition useCondition;
+
+    /**
+     * 封面摘要
+     */
+    @SerializedName( "abstract")
+    private Abstract abstractInfo;
+
+    /**
+     * 图文列表,显示在详情内页 ,优惠券券开发者须至少传入 一组图文列表
+     */
+    @SerializedName( "text_image_list")
+    private List<TextImageList> textImageList;
+
+    /**
+     * 商家服务类型,数组类型:BIZ_SERVICE_DELIVER 外卖服务; BIZ_SERVICE_FREE_PARK 停车位; BIZ_SERVICE_WITH_PET 可带宠物; BIZ_SERVICE_FREE_WIFI 免费wifi, 可多选
+     */
+    @SerializedName( "business_service")
+    private String businessService;
+
+    /**
+     * 使用时段限制
+     */
+    @SerializedName( "time_limit")
+    private TimeLimit timeLimit;
+
+    public String toString(){
+        return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
+    }
+}

+ 190 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/BaseInfo.java

@@ -0,0 +1,190 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.io.Serializable;
+//子对象列表
+
+/**
+ * 微信会员卡基本信息
+ * author:yuanqixun
+ * date:2018-08-25 00:36
+ */
+@Data
+public class BaseInfo implements Serializable {
+
+  /**
+   * 卡券的商户logo,建议像素为300*300。
+   */
+  @SerializedName("logo_url")
+  private String logoUrl;
+
+  /**
+   * Code展示类型,"CODE_TYPE_TEXT" 文本 "CODE_TYPE_BARCODE" 一维码 "CODE_TYPE_QRCODE" 二维码 "CODE_TYPE_ONLY_QRCODE" 仅显示二维码 "CODE_TYPE_ONLY_BARCODE" 仅显示一维码 "CODE_TYPE_NONE" 不显示任何码型
+   */
+  @SerializedName("code_type")
+  private String codeType = "CODE_TYPE_QRCODE";
+
+  /**
+   * 支付功能结构体,swipe_card结构
+   */
+  @SerializedName("pay_info")
+  private PayInfo payInfo;
+
+  /**
+   * 商户名字,字数上限为12个汉字
+   */
+  @SerializedName("brand_name")
+  private String brandName;
+
+  /**
+   * 卡券名,字数上限为9个汉字 (建议涵盖卡券属性、服务及金额)。
+   */
+  @SerializedName("title")
+  private String title;
+
+  /**
+   * 券颜色,按色彩规范标注填写Color010-Color100
+   */
+  @SerializedName("color")
+  private String color;
+
+  /**
+   * 卡券使用提醒,字数上限为16个汉字
+   */
+  @SerializedName("notice")
+  private String notice;
+
+  /**
+   * 卡券使用说明,字数上限为1024个汉字。
+   */
+  @SerializedName("description")
+  private String description;
+
+  /**
+   * 商品信息
+   */
+  @SerializedName("sku")
+  private Sku sku;
+
+  /**
+   * 使用日期,有效期的信息。
+   */
+  @SerializedName("date_info")
+  private DateInfo dateInfo;
+
+  /**
+   * 是否自定义Code码,填写true或false,默认为false 通常自有优惠码系统的开发者选择自定义Code码,详情见 是否自定义code
+   */
+  @SerializedName("use_custom_code")
+  private boolean useCustomCode;
+
+  /**
+   * 是否指定用户领取,填写true或false。默认为false
+   */
+  @SerializedName("bind_openid")
+  private boolean bindOpenid;
+
+  /**
+   * 客服电话
+   */
+  @SerializedName("service_phone")
+  private String servicePhone;
+
+  /**
+   * 门店位置ID,调用 POI门店管理接口 获取门店位置ID。
+   */
+  @SerializedName("location_id_list")
+  private String locationIdList;
+
+  /**
+   * 会员卡是否支持全部门店,填写后商户门店更新时会自动同步至卡券
+   */
+  @SerializedName("use_all_locations")
+  private boolean useAllLocations = true;
+
+  /**
+   * 卡券中部居中的按钮,仅在卡券激活后且可用状态 时显示
+   */
+  @SerializedName("center_title")
+  private String centerTitle;
+
+  /**
+   * 显示在入口下方的提示语,仅在卡券激活后且可用状态时显示
+   */
+  @SerializedName("center_sub_title")
+  private String centerSubTitle;
+
+  /**
+   * 顶部居中的url,仅在卡券激活后且可用状态时显示
+   */
+  @SerializedName("center_url")
+  private String centerUrl;
+
+  /**
+   * 自定义跳转外链的入口名字
+   */
+  @SerializedName("custom_url_name")
+  private String customUrlName;
+
+  /**
+   * 自定义跳转的URL
+   */
+  @SerializedName("custom_url")
+  private String customUrl;
+
+  /**
+   * 显示在入口右侧的提示语
+   */
+  @SerializedName("custom_url_sub_title")
+  private String customUrlSubTitle;
+
+  /**
+   * 营销场景的自定义入口名称
+   */
+  @SerializedName("promotion_url_name")
+  private String promotionUrlName;
+
+  /**
+   * 入口跳转外链的地址链接
+   */
+  @SerializedName("promotion_url")
+  private String promotionUrl;
+
+  /**
+   * 显示在营销入口右侧的提示语
+   */
+  @SerializedName("promotion_url_sub_title")
+  private String promotionUrlSubTitle;
+
+  /**
+   * 每人可领券的数量限制,建议会员卡每人限领一张
+   */
+  @SerializedName("get_limit")
+  private Integer getLimit=1;
+
+  /**
+   * 卡券领取页面是否可分享,默认为true
+   */
+  @SerializedName("can_share")
+  private boolean canShare;
+
+  /**
+   * 卡券是否可转赠,默认为true
+   */
+  @SerializedName("can_give_friend")
+  private boolean canGiveFriend;
+
+  /**
+   * 用户点击进入会员卡时推送事件,填写true为用户点击进入会员卡时推送事件,默认为false。详情见 进入会员卡事件推送
+   */
+  @SerializedName("need_push_on_view")
+  private boolean needPushOnView;
+
+  public String toString() {
+    return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
+  }
+}

+ 69 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/BonusRule.java

@@ -0,0 +1,69 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.io.Serializable;
+
+/**
+ * 积分规则
+ * author:yuanqixun
+ * date:2018-08-25 00:33
+ */
+@Data
+public class BonusRule implements Serializable {
+
+  /**
+   * 消费金额,以分为单位。
+   */
+  @SerializedName("cost_money_unit")
+  private Integer costMoneyUnit;
+
+  /**
+   * 对应增加的积分
+   */
+  @SerializedName("increase_bonus")
+  private Integer increaseBonus;
+
+  /**
+   * 用户单次可获取的积分上限
+   */
+  @SerializedName("max_increase_bonus")
+  private Integer maxIncreaseBonus;
+
+  /**
+   * 初始设置积分
+   */
+  @SerializedName("init_increase_bonus")
+  private Integer initIncreaseBonus;
+
+  /**
+   * 每使用积分
+   */
+  @SerializedName("cost_bonus_unit")
+  private Integer costBonusUnit;
+
+  /**
+   * 抵扣xx元,这里以分为单位)
+   */
+  @SerializedName("reduce_money")
+  private Integer reduceMoney;
+
+  /**
+   * 抵扣条件,满xx元(这里以分为单位)可用。
+   */
+  @SerializedName("least_moneyto_use_bonus")
+  private Integer leastMoneytoUseBonus;
+
+  /**
+   * 抵扣条件,单笔最多使用xx积分。
+   */
+  @SerializedName("max_reduce_bonus")
+  private Integer maxReduceBonus;
+
+  public String toString() {
+    return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
+  }
+}

+ 34 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CardColor.java

@@ -0,0 +1,34 @@
+package me.chanjar.weixin.mp.bean.card;
+
+/**
+ * 会员卡颜色
+ * @author yuanqixun
+ * @date 2018-08-29
+ */
+public enum CardColor{
+    Color010("#63b359"),
+    Color020("#2c9f67"),
+    Color030("#509fc9"),
+    Color040("#5885cf"),
+    Color050("#9062c0"),
+    Color060("#d09a45"),
+    Color070("#e4b138"),
+    Color080("#ee903c"),
+    Color081("#f08500"),
+    Color082("#a9d92d"),
+    Color090("#dd6549"),
+    Color100("#cc463d"),
+    Color101("#cf3e36"),
+    Color102("#5E6671");
+
+    private String type;
+
+    CardColor(String type) {
+        this.type = type;
+    }
+
+    public String getValue() {
+        return type;
+    }
+
+}

+ 21 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CardSceneType.java

@@ -0,0 +1,21 @@
+package me.chanjar.weixin.mp.bean.card;
+
+public enum CardSceneType {
+  SCENE_NEAR_BY("附近"),
+  SCENE_MENU("自定义菜单"),
+  SCENE_QRCODE("二维码"),
+  SCENE_ARTICLE("公众号文章"),
+  SCENE_H5("H5"),
+  SCENE_IVR("自动回复"),
+  SCENE_CARD_CUSTOM_CELL("卡券自定义cell");
+
+  private String description;
+
+  CardSceneType(String description) {
+    this.description = description;
+  }
+
+  public String getDescription() {
+    return description;
+  }
+}

+ 39 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CustomCell1.java

@@ -0,0 +1,39 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.io.Serializable;
+
+/**
+ * 自定义会员信息类目
+ * author:yuanqixun
+ * date:2018-08-25 00:34
+ */
+@Data
+public class CustomCell1 implements Serializable {
+
+    /**
+     * 入口名称
+     */
+    @SerializedName("name")
+    private String name;
+
+    /**
+     * 入口右侧提示语,6个汉字内。
+     */
+    @SerializedName("tips")
+    private String tips;
+
+    /**
+     * 入口跳转链接。
+     */
+    @SerializedName("url")
+    private String url;
+
+    public String toString(){
+        return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
+    }
+}

+ 43 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CustomField.java

@@ -0,0 +1,43 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.io.Serializable;
+
+/**
+ * 自定义会员信息类目
+ * author:yuanqixun
+ * date:2018-08-25 00:34
+ */
+@Data
+public class CustomField implements Serializable {
+
+  /**
+   * 半自定义名称,当开发者变更这类类目信息的value值时 可以选择触发系统模板消息通知用户。 FIELD_NAME_TYPE_LEVEL 等级 FIELD_NAME_TYPE_COUPON 优惠券 FIELD_NAME_TYPE_STAMP 印花 FIELD_NAME_TYPE_DISCOUNT 折扣 FIELD_NAME_TYPE_ACHIEVEMEN 成就 FIELD_NAME_TYPE_MILEAGE 里程 FIELD_NAME_TYPE_SET_POINTS 集点 FIELD_NAME_TYPE_TIMS 次数
+   */
+  @SerializedName("name_type")
+  private String nameType;
+
+  /**
+   * 自定义名称,当开发者变更这类类目信息的value值时 不会触发系统模板消息通知用户
+   */
+  @SerializedName("name")
+  private String name;
+
+  /**
+   * 点击类目跳转外链url
+   */
+  @SerializedName("url")
+  private String url;
+
+  public String getNameType() {
+    return nameType;
+  }
+
+  public String toString() {
+    return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
+  }
+}

+ 51 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/DateInfo.java

@@ -0,0 +1,51 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.io.Serializable;
+
+/**
+ * 使用日期,有效期的信息
+ * author:yuanqixun
+ * date:2018-08-25 00:31
+ */
+@Data
+public class DateInfo implements Serializable {
+
+  /**
+   * 使用时间的类型,支持固定时长有效类型 固定日期有效类型 永久有效类型:DATE_TYPE_FIX_TERM_RANGE、DATE_TYPE_FIX_TERM 、DATE_TYPE_PERMANENT
+   */
+  @SerializedName("type")
+  private String type = "DATE_TYPE_PERMANENT";
+
+  /**
+   * 起用时间,type为DATE_TYPE_FIX_TIME_RANGE时专用, 表示起用时间。从1970年1月1日00:00:00至起用时间的秒数 ( 东八区时间,UTC+8,单位为秒 )
+   */
+  @SerializedName("begin_timestamp")
+  private Long beginTimestamp;
+
+  /**
+   * 结束时间,type为DATE_TYPE_FIX_TERM_RANGE时专用,表示结束时间 ( 东八区时间,UTC+8,单位为秒 )
+   */
+  @SerializedName("end_timestamp")
+  private Long endTimestamp;
+
+  /**
+   * 自领取后多少天内有效,type为DATE_TYPE_FIX_TERM时专用,表示自领取后多少天内有效,领取后当天有效填写0(单位为天)
+   */
+  @SerializedName("fixed_term")
+  private Integer fixedTerm;
+
+  /**
+   * 自领取后多少天开始生效,type为DATE_TYPE_FIX_TERM时专用,表示自领取后多少天开始生效。(单位为天)
+   */
+  @SerializedName("fixed_begin_term")
+  private Integer fixedBeginTerm;
+
+  public String toString() {
+    return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
+  }
+}

+ 17 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/DateInfoType.java

@@ -0,0 +1,17 @@
+package me.chanjar.weixin.mp.bean.card;
+
+public enum DateInfoType {
+  DATE_TYPE_PERMANENT("永久有效类型"),
+  DATE_TYPE_FIX_TIME_RANGE("固定日期"),
+  DATE_TYPE_FIX_TERM("固定时长");
+
+  private String description;
+
+  DateInfoType(String description) {
+    this.description = description;
+  }
+
+  public String getDescription() {
+    return description;
+  }
+}

+ 152 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCard.java

@@ -0,0 +1,152 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.io.Serializable;
+
+@Data
+public final class MemberCard implements Serializable {
+
+  /**
+   * 会员卡背景图
+   */
+  @SerializedName("background_pic_url")
+  private String backgroundPicUrl;
+
+  /**
+   * 基本信息
+   */
+  @SerializedName("base_info")
+  private BaseInfo baseInfo;
+
+  /**
+   * 特权说明
+   */
+  @SerializedName("prerogative")
+  private String prerogative;
+
+  /**
+   * 自动激活
+   */
+  @SerializedName("auto_activate")
+  private boolean autoActivate;
+
+  /**
+   * 是否一键开卡
+   */
+  @SerializedName("wx_activate")
+  private boolean wxActivate;
+
+  /**
+   * 显示积分
+   */
+  @SerializedName("supply_bonus")
+  private boolean supplyBonus;
+
+  /**
+   * 查看积分外链,设置跳转外链查看积分详情。仅适用于积分无法通过激活接口同步的情况下使用该字段。
+   */
+  @SerializedName("bonus_url")
+  private String bonusUrl;
+
+  /**
+   * 支持储值
+   */
+  @SerializedName("supply_balance")
+  private boolean supplyBalance;
+
+  /**
+   * 余额外链,仅适用于余额无法通过激活接口同步的情况下使用该字段。
+   */
+  @SerializedName("balance_url")
+  private String balanceUrl;
+
+  /**
+   * 自定义会员类目1,会员卡激活后显示
+   */
+  @SerializedName("custom_field1")
+  private CustomField customField1;
+
+  /**
+   * 自定义会员类目2
+   */
+  @SerializedName("custom_field2")
+  private CustomField customField2;
+
+  /**
+   * 自定义会员类目3
+   */
+  @SerializedName("custom_field3")
+  private CustomField customField3;
+
+  /**
+   * 积分清零规则
+   */
+  @SerializedName("bonus_cleared")
+  private String bonusCleared;
+
+  /**
+   * 积分规则
+   */
+  @SerializedName("bonus_rules")
+  private String bonusRules;
+
+  /**
+   * 储值规则
+   */
+  @SerializedName("balance_rules")
+  private String balanceRules;
+
+  /**
+   * 激活会员卡的url
+   */
+  @SerializedName("activate_url")
+  private String activateUrl;
+
+  /**
+   * 激活会原卡url对应的小程序user_name,仅可跳转该公众号绑定的小程序
+   */
+  @SerializedName("activate_app_brand_user_name")
+  private String activateAppBrandUserName;
+
+  /**
+   * 激活会原卡url对应的小程序path
+   */
+  @SerializedName("activate_app_brand_pass")
+  private String activateAppBrandPass;
+
+  /**
+   * 自定义会员信息类目,会员卡激活后显示。
+   */
+  @SerializedName("custom_cell1")
+  private CustomCell1 customCell1;
+
+  /**
+   * 积分规则,JSON结构积分规则 。
+   */
+  @SerializedName("bonus_rule")
+  private BonusRule bonusRule;
+
+  /**
+   * 折扣,该会员卡享受的折扣优惠,填10就是九折。
+   */
+  private Integer discount;
+
+  /**
+   * 创建优惠券特有的高级字段
+   */
+  @SerializedName("advanced_info")
+  private AdvancedInfo advancedInfo;
+
+  public String toString() {
+    return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
+  }
+
+  public static MemberCard fromJson(String json) {
+    return WxMpGsonBuilder.INSTANCE.create().fromJson(json, MemberCard.class);
+  }
+}

+ 21 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCardCreateRequest.java

@@ -0,0 +1,21 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.io.Serializable;
+
+@Data
+public class MemberCardCreateRequest implements Serializable {
+  @SerializedName("card_type")
+  private String cardType = "MEMBER_CARD";
+
+  @SerializedName("member_card")
+  private MemberCard memberCard;
+
+  public String toString() {
+    return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
+  }
+}

+ 27 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/PayInfo.java

@@ -0,0 +1,27 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.io.Serializable;
+
+/**
+ * 支付功能
+ * author:yuanqixun
+ * date:2018-08-25 00:33
+ */
+@Data
+public class PayInfo implements Serializable {
+
+    /**
+     * 刷卡功能
+     */
+    @SerializedName( "swipe_card")
+    private SwipeCard swipeCard;
+
+    public String toString(){
+        return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
+    }
+}

+ 27 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/Sku.java

@@ -0,0 +1,27 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.io.Serializable;
+
+/**
+ * 商品信息
+ * author:yuanqixun
+ * date:2018-08-25 00:32
+ */
+@Data
+public class Sku implements Serializable {
+
+    /**
+     * 卡券库存的数量,不支持填写0,上限为100000000。
+     */
+    @SerializedName("quantity")
+    private Integer quantity=100000000;
+
+    public String toString(){
+        return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
+    }
+}

+ 33 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/SwipeCard.java

@@ -0,0 +1,33 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.io.Serializable;
+
+/**
+ * 刷卡功能
+ * author:yuanqixun
+ * date:2018-08-25 00:33
+ */
+@Data
+public class SwipeCard implements Serializable {
+
+    /**
+     * 是否设置该会员卡支持拉出微信支付刷卡界面
+     */
+    @SerializedName( "is_swipe_card")
+    private boolean isSwipeCard;
+
+    /**
+     * 是否设置该会员卡中部的按钮同时支持微信支付刷卡和会员卡二维码
+     */
+    @SerializedName( "is_pay_and_qrcode")
+    private boolean isPayAndQrcode;
+
+    public String toString(){
+        return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
+    }
+}

+ 33 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/TextImageList.java

@@ -0,0 +1,33 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.io.Serializable;
+
+/**
+ * 图文列表
+ * author:yuanqixun
+ * date:2018-08-25 00:35
+ */
+@Data
+public class TextImageList implements Serializable {
+
+    /**
+     * 图片链接,必须调用 上传图片接口 上传图片获得链接,并在此填入, 否则报错
+     */
+    @SerializedName( "image_url")
+    private String imageUrl;
+
+    /**
+     * 图文描述
+     */
+    @SerializedName("text")
+    private String text;
+
+    public String toString(){
+        return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
+    }
+}

+ 52 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/TimeLimit.java

@@ -0,0 +1,52 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.io.Serializable;
+//子对象列表
+
+/**
+ * 使用时段限制
+ * author:yuanqixun
+ * date:2018-08-25 00:34
+ */
+@Data
+public class TimeLimit implements Serializable {
+
+    /**
+     * 限制类型枚举值,支持填入 MONDAY 周一 TUESDAY 周二 WEDNESDAY 周三 THURSDAY 周四 FRIDAY 周五 SATURDAY 周六 SUNDAY 周日 此处只控制显示, 不控制实际使用逻辑,不填默认不显示
+     */
+    @SerializedName("type")
+    private String type;
+
+    /**
+     * 起始时间(小时),当前type类型下的起始时间(小时) ,如当前结构体内填写了MONDAY, 此处填写了10,则此处表示周一 10:00可用
+     */
+    @SerializedName( "begin_hour")
+    private Integer beginHour;
+
+    /**
+     * 起始时间(分钟),如当前结构体内填写了MONDAY, begin_hour填写10,此处填写了59, 则此处表示周一 10:59可用
+     */
+    @SerializedName( "begin_minute")
+    private Integer beginMinute;
+
+    /**
+     * 结束时间(小时),如当前结构体内填写了MONDAY, 此处填写了20, 则此处表示周一 10:00-20:00可用
+     */
+    @SerializedName( "end_hour")
+    private Integer endHour;
+
+    /**
+     * 结束时间(分钟),如当前结构体内填写了MONDAY, begin_hour填写10,此处填写了59, 则此处表示周一 10:59-00:59可用
+     */
+    @SerializedName( "end_minute")
+    private Integer endMinute;
+
+    public String toString(){
+        return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
+    }
+}

+ 52 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/UseCondition.java

@@ -0,0 +1,52 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.io.Serializable;
+//子对象列表
+
+/**
+ * 使用门槛
+ * author:yuanqixun
+ * date:2018-08-25 00:35
+ */
+@Data
+public class UseCondition implements Serializable {
+
+    /**
+     * 指定可用的商品类目,仅用于代金券类型 ,填入后将在券面拼写适用于xxx
+     */
+    @SerializedName( "accept_category")
+    private String acceptCategory;
+
+    /**
+     * 指定不可用的商品类目,仅用于代金券类型 ,填入后将在券面拼写不适用于xxxx
+     */
+    @SerializedName( "reject_category")
+    private String rejectCategory;
+
+    /**
+     * 满减门槛字段,可用于兑换券和代金券 ,填入后将在全面拼写消费满xx元可用
+     */
+    @SerializedName( "least_cost")
+    private Integer leastCost;
+
+    /**
+     * 购买xx可用类型门槛,仅用于兑换 ,填入后自动拼写购买xxx可用
+     */
+    @SerializedName( "object_use_for")
+    private String objectUseFor;
+
+    /**
+     * 不可以与其他类型共享门槛,填写false时系统将在使用须知里 拼写“不可与其他优惠共享”, 填写true时系统将在使用须知里 拼写“可与其他优惠共享”, 默认为true
+     */
+    @SerializedName( "can_use_with_other_discount")
+    private boolean canUseWithOtherDiscount;
+
+    public String toString(){
+        return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
+    }
+}

+ 47 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardCreateResult.java

@@ -0,0 +1,47 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.io.Serializable;
+
+@Data
+public class WxMpCardCreateResult implements Serializable {
+  private static final long serialVersionUID = -128818731449449537L;
+  @SerializedName("card_id")
+  private String cardId;
+  private Integer errcode;
+  private String errmsg;
+
+  public boolean isSuccess() {
+    return 0 == errcode;
+  }
+
+  public static WxMpCardCreateResult fromJson(String json) {
+    return WxMpGsonBuilder.create().fromJson(json, WxMpCardCreateResult.class);
+  }
+
+  public static WxMpCardCreateResult failure(String errmsg) {
+    WxMpCardCreateResult result = new WxMpCardCreateResult();
+    result.setErrcode(500);
+    result.setErrmsg(errmsg);
+    return result;
+  }
+
+  public static WxMpCardCreateResult success() {
+    WxMpCardCreateResult result = new WxMpCardCreateResult();
+    result.setErrcode(0);
+    result.setErrmsg("ok");
+    return result;
+  }
+
+  @Override
+  public String toString() {
+    return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
+  }
+
+}
+

+ 67 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardLandingPageCreateRequest.java

@@ -0,0 +1,67 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.io.Serializable;
+
+@Data
+public class WxMpCardLandingPageCreateRequest implements Serializable {
+
+  /**
+   * 页面的banner图片链接,须调用,建议尺寸为640*300。
+   */
+  private String banner;
+
+  /**
+   * 页面的title
+   */
+  @SerializedName("page_title")
+  private String title;
+
+  @SerializedName("can_share")
+  private boolean canShare;
+
+  /**
+   * 投放页面的场景值;
+   * SCENE_NEAR_BY 附近
+   * SCENE_MENU 自定义菜单
+   * SCENE_QRCODE 二维码
+   * SCENE_ARTICLE 公众号文章
+   * SCENE_H5 h5页面
+   * SCENE_IVR 自动回复
+   * SCENE_CARD_CUSTOM_CELL 卡券自定义cell
+   */
+  private String scene;
+
+  @SerializedName("card_list")
+  private JsonArray cardList;
+
+  public void addCard(String cardId, String thumbUrl) {
+    if (StringUtils.isNoneBlank(cardId, thumbUrl)) {
+      if (cardList == null)
+        cardList = new JsonArray();
+      JsonObject cardJson = new JsonObject();
+      cardJson.addProperty("card_id", cardId);
+      cardJson.addProperty("thumb_url", thumbUrl);
+      cardList.add(cardJson);
+    }
+  }
+
+  public static WxMpCardLandingPageCreateRequest fromJson(String json) {
+    return WxMpGsonBuilder.create().fromJson(json, WxMpCardLandingPageCreateRequest.class);
+  }
+
+  @Override
+  public String toString() {
+    return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
+  }
+
+}
+

+ 40 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardLandingPageCreateResult.java

@@ -0,0 +1,40 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.io.Serializable;
+
+@Data
+public class WxMpCardLandingPageCreateResult implements Serializable {
+  private Integer errcode;
+  private String errmsg;
+
+  /**
+   * 货架链接。
+   */
+  private String url;
+  /**
+   * 货架ID。货架的唯一标识
+   */
+  @SerializedName("page_id")
+  private Integer pageId;
+
+  public boolean isSuccess() {
+    return 0 == errcode;
+  }
+
+  public static WxMpCardLandingPageCreateResult fromJson(String json) {
+    return WxMpGsonBuilder.create().fromJson(json, WxMpCardLandingPageCreateResult.class);
+  }
+
+  @Override
+  public String toString() {
+    return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
+  }
+
+}
+

+ 40 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardQrcodeCreateResult.java

@@ -0,0 +1,40 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.io.Serializable;
+
+@Data
+public class WxMpCardQrcodeCreateResult implements Serializable {
+  private static final long serialVersionUID = -128818731449449537L;
+  private Integer errcode;
+  private String errmsg;
+  private String ticket;
+
+  @SerializedName("expire_seconds")
+  private Integer expireSeconds;
+
+  private String url;
+
+  @SerializedName("show_qrcode_url")
+  private String showQrcodeUrl;
+
+  public boolean isSuccess() {
+    return 0 == errcode;
+  }
+
+  public static WxMpCardQrcodeCreateResult fromJson(String json) {
+    return WxMpGsonBuilder.create().fromJson(json, WxMpCardQrcodeCreateResult.class);
+  }
+
+  @Override
+  public String toString() {
+    return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
+  }
+
+}
+

+ 25 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/WxMpMemberCardCreateMessage.java

@@ -0,0 +1,25 @@
+package me.chanjar.weixin.mp.bean.membercard;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.mp.bean.card.MemberCardCreateRequest;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.io.Serializable;
+
+@Data
+public final class WxMpMemberCardCreateMessage implements Serializable {
+
+  @SerializedName("card")
+  private MemberCardCreateRequest cardCreateRequest;
+
+  public String toString() {
+    return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
+  }
+
+  public static WxMpMemberCardCreateMessage fromJson(String json) {
+    return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpMemberCardCreateMessage.class);
+  }
+}

Разлика између датотеке није приказан због своје велике величине
+ 89 - 8
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImplTest.java