From b20e09ccf0505eac6d134c653e8ec5287b86369b Mon Sep 17 00:00:00 2001 From: Kit Date: Thu, 12 Sep 2019 10:31:19 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A4=BC=E5=93=81=E5=8D=A1API=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/foxinmy/weixin4j/api/MchApi.java | 37 +- .../weixin4j/model/card/CardCoupons.java | 52 +++ .../foxinmy/weixin4j/model/card/CardInfo.java | 183 +++++++++ .../foxinmy/weixin4j/model/card/CardItem.java | 77 ++++ .../weixin4j/model/card/CouponBaseInfo.java | 224 ++++++++++- .../foxinmy/weixin4j/model/card/GiftCard.java | 219 +++++++++++ .../weixin4j/model/card/GiftCardOrder.java | 11 + .../weixin4j/model/card/GiftCardPage.java | 351 +++++++++++++++++ .../weixin4j/model/card/PageTheme.java | 249 ++++++++++++ .../foxinmy/weixin4j/model/card/PicItem.java | 66 ++++ .../weixin4j/model/card/VoucherCard.java | 122 ++++++ .../foxinmy/weixin4j/type/card/CardType.java | 7 +- .../weixin4j/type/card/SubCardType.java | 19 + .../com/foxinmy/weixin4j/mp/WeixinProxy.java | 207 ++++++++++ .../com/foxinmy/weixin4j/mp/api/CardApi.java | 360 +++++++++++++++++- .../foxinmy/weixin4j/mp/api/weixin.properties | 28 ++ 16 files changed, 2171 insertions(+), 41 deletions(-) create mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/CardInfo.java create mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/CardItem.java create mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/GiftCard.java create mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/GiftCardOrder.java create mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/GiftCardPage.java create mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/PageTheme.java create mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/PicItem.java create mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/VoucherCard.java create mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/card/SubCardType.java diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/MchApi.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/MchApi.java index 6e07f29f..8f89afe8 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/MchApi.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/MchApi.java @@ -32,6 +32,8 @@ public class MchApi extends BaseApi { private final static ResourceBundle WEIXIN_BUNDLE; + private final static String PEM_CERT_PREFIX = "-----BEGIN CERTIFICATE-----"; + static { WEIXIN_BUNDLE = ResourceBundle.getBundle("com/foxinmy/weixin4j/payment/weixin"); } @@ -93,21 +95,28 @@ public class MchApi extends BaseApi { */ protected WeixinRequestExecutor getWeixinSSLExecutor() throws WeixinException { if (weixinSSLExecutor == null) { - try { - InputStream is = null; - File certificate = new File( - Weixin4jConfigUtil.replaceClassPathValue(weixinAccount.getCertificateFile())); - if (!certificate.exists() || !certificate.isFile()) { - is = Weixin4jConfigUtil.CLASSLOADER.getResourceAsStream(certificate.getName()); - } else { - is = new FileInputStream(certificate); + if(weixinAccount.getCertificateFile().startsWith(PEM_CERT_PREFIX)){ + // 证书是PEM格式,直接使用PEM内容生成请求执行类 + this.weixinSSLExecutor = weixinExecutor.createSSLRequestExecutor(weixinAccount.getMchId(), + weixinAccount.getCertificateFile(), weixinAccount.getCertificateKey()); + }else { + // 证书是p12格式,读取证书文件并生成请求执行类 + try { + InputStream is = null; + File certificate = new File( + Weixin4jConfigUtil.replaceClassPathValue(weixinAccount.getCertificateFile())); + if (!certificate.exists() || !certificate.isFile()) { + is = Weixin4jConfigUtil.CLASSLOADER.getResourceAsStream(certificate.getName()); + } else { + is = new FileInputStream(certificate); + } + if (is == null) { + throw new WeixinException("Invalid certificate file : " + certificate.toString()); + } + this.weixinSSLExecutor = weixinExecutor.createSSLRequestExecutor(weixinAccount.getCertificateKey(), is); + } catch (IOException e) { + throw new WeixinException("IO Error on createSSLRequestExecutor", e); } - if (is == null) { - throw new WeixinException("Invalid certificate file : " + certificate.toString()); - } - this.weixinSSLExecutor = weixinExecutor.createSSLRequestExecutor(weixinAccount.getCertificateKey(), is); - } catch (IOException e) { - throw new WeixinException("IO Error on createSSLRequestExecutor", e); } } return this.weixinSSLExecutor; diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/CardCoupons.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/CardCoupons.java index dab7f995..b22e93bc 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/CardCoupons.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/CardCoupons.java @@ -38,6 +38,30 @@ public final class CardCoupons { public static MemberCard.Builder customMemberCard(){ return new MemberCard.Builder(); } + + /** + * 礼品卡信息构造器 + * + * @return + */ + public static GiftCard.Builder customGiftCard() { + return new GiftCard.Builder(); + } + + /** + * 礼品卡货架主题信息构造器 + * + * @return + */ + public static PageTheme.Builder customCardPageTheme(){ return new PageTheme.Builder(); } + + /** + * 礼品卡货架信息构造器 + * + * @return + */ + public static GiftCardPage.Builder customCardPage(){ return new GiftCardPage.Builder(); } + /** * 创建代金券 * @@ -122,4 +146,32 @@ public final class CardCoupons { MemberCard memberCard = new MemberCard(baseBuilder.build(), memberCardBudiler); return memberCard; } + + /** + * 创建单品类礼品卡 + * + * @param baseBuilder + * 卡券基础信息构造器 必填 + * @param giftCardBuilder + * 礼品卡自身参数构造器 必填 + * @return + */ + public static VoucherCard createVoucherCard(CouponBaseInfo.Builder baseBuilder, GiftCard.Builder giftCardBuilder){ + baseBuilder.build(); + VoucherCard voucherCard = new VoucherCard(baseBuilder.build(), giftCardBuilder); + return voucherCard; + } + + /** + * 创建储值类礼品卡 + * + * @param baseBuilder + * @param giftCardBuilder + * @return + */ + public static GiftCard createGiftCard(CouponBaseInfo.Builder baseBuilder, GiftCard.Builder giftCardBuilder){ + baseBuilder.build(); + GiftCard giftCard = new GiftCard(baseBuilder.build(), giftCardBuilder); + return giftCard; + } } \ No newline at end of file diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/CardInfo.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/CardInfo.java new file mode 100644 index 00000000..757e4cc5 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/CardInfo.java @@ -0,0 +1,183 @@ +package com.foxinmy.weixin4j.model.card; + +import com.alibaba.fastjson.annotation.JSONField; + +/** + * 已领取的礼品卡信息 + * 用于查询用户的礼品卡信息时,作为参数或返回对象 + * + * @author kit (kit@muses.cc) + * @date 2018-11-23 + */ +public class CardInfo { + /** + * 礼品卡的code + */ + private String code; + /** + * 礼品卡的card_id + */ + @JSONField(name = "card_id") + private String cardId; + /** + * 生效时间 + */ + @JSONField(name = "begin_time") + private long beginTime; + /** + * 结束时间 + */ + @JSONField(name = "end_time") + private long endTime; + /** + * 当前的余额额度 + */ + private int balance; + /** + * 礼品卡卡面显示的卡号,若没设置则与code相同 + */ + @JSONField(name = "card_number") + private String cardNumber; + /** + * 用于支持商家激活时针对单个礼品卡分配自定义的礼品卡背景。 + */ + @JSONField(name = "background_pic_url") + private String backgroundPicUrl; + /** + * 自定义金额消耗记录,不超过14个汉字。 + */ + @JSONField(name = "record_balance") + private String recordBalance; + /** + * 创建时字段custom_field1定义类型的最新数值,限制为4个汉字,12字节。 + */ + @JSONField(name = "custom_field_value1") + private String customFieldValue1; + /** + * 创建时字段custom_field2定义类型的最新数值,限制为4个汉字,12字节。 + */ + @JSONField(name = "custom_field_value2") + private String customFieldValue2; + /** + * 创建时字段custom_field3定义类型的最新数值,限制为4个汉字,12字节。 + */ + @JSONField(name = "custom_field_value3") + private String customFieldValue3; + /** + * 控制本次积分变动后转赠入口是否出现 + */ + @JSONField(name = "can_give_friend") + private Boolean canGiveFriend; + /** + * 该卡的价格 + */ + private int price; + /** + * 祝福语 + */ + @JSONField(name = "default_gifting_msg") + private String defaultGiftingMsg; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getCardId() { + return cardId; + } + + public void setCardId(String cardId) { + this.cardId = cardId; + } + + public long getBeginTime() { + return beginTime; + } + + public void setBeginTime(long beginTime) { + this.beginTime = beginTime; + } + + public long getEndTime() { + return endTime; + } + + public void setEndTime(long endTime) { + this.endTime = endTime; + } + + public int getBalance() { + return balance; + } + + public void setBalance(int balance) { + this.balance = balance; + } + + public String getCardNumber() { + return cardNumber; + } + + public void setCardNumber(String cardNumber) { + this.cardNumber = cardNumber; + } + + public String getBackgroundPicUrl() { + return backgroundPicUrl; + } + + public void setBackgroundPicUrl(String backgroundPicUrl) { + this.backgroundPicUrl = backgroundPicUrl; + } + + public String getRecordBalance() { + return recordBalance; + } + + public void setRecordBalance(String recordBalance) { + this.recordBalance = recordBalance; + } + + public String getCustomFieldValue1() { + return customFieldValue1; + } + + public void setCustomFieldValue1(String customFieldValue1) { + this.customFieldValue1 = customFieldValue1; + } + + public String getCustomFieldValue2() { + return customFieldValue2; + } + + public void setCustomFieldValue2(String customFieldValue2) { + this.customFieldValue2 = customFieldValue2; + } + + public String getCustomFieldValue3() { + return customFieldValue3; + } + + public void setCustomFieldValue3(String customFieldValue3) { + this.customFieldValue3 = customFieldValue3; + } + + public Boolean getCanGiveFriend() { + return canGiveFriend; + } + + public void setCanGiveFriend(Boolean canGiveFriend) { + this.canGiveFriend = canGiveFriend; + } + + public void CardItem(){} + + public void CardItem(String code, String cardId){ + this.code = code; + this.cardId = cardId; + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/CardItem.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/CardItem.java new file mode 100644 index 00000000..ecb99ea7 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/CardItem.java @@ -0,0 +1,77 @@ +package com.foxinmy.weixin4j.model.card; + +import com.alibaba.fastjson.annotation.JSONField; + +/** + * 礼品卡货架主题内的礼品卡描述项 + * + * @author kit(kit.li@qq.com) + * @date 2018年10月30日 + */ +public class CardItem { + /** + * 待上架的card_id + */ + @JSONField(name = "card_id") + private String cardId; + /** + * 商品名,不填写默认为卡名称 + */ + private String title; + /** + * 商品缩略图,1000像素*600像素以下 + */ + @JSONField(name = "pic_url") + private String picUrl; + /** + * 商品简介 + */ + private String desc; + + public CardItem(){ + + } + + public CardItem(String cardId) { + this.cardId = cardId; + } + + public CardItem(String cardId, String title, String picUrl, String desc) { + this.cardId = cardId; + this.title = title; + this.picUrl = picUrl; + this.desc = desc; + } + + public String getCardId() { + return cardId; + } + + public String getTitle() { + return title; + } + + public String getPicUrl() { + return picUrl; + } + + public String getDesc() { + return desc; + } + + public void setCardId(String cardId) { + this.cardId = cardId; + } + + public void setTitle(String title) { + this.title = title; + } + + public void setPicUrl(String picUrl) { + this.picUrl = picUrl; + } + + public void setDesc(String desc) { + this.desc = desc; + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/CouponBaseInfo.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/CouponBaseInfo.java index 8b4bf1f4..1aec6d7f 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/CouponBaseInfo.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/CouponBaseInfo.java @@ -21,7 +21,18 @@ import com.foxinmy.weixin4j.type.card.CardColor; */ public class CouponBaseInfo implements Serializable { - private static final long serialVersionUID = -5725424121330101716L; + private static final long serialVersionUID = -5725424121330101717L; + + /** + * 礼品卡信息,目前只有一个价格属性,礼品卡时必填 + */ + @JSONField(name = "giftcard_info") + private JSONObject giftcardInfo; + /** + * 礼品卡最大可赠送次数,必填 + */ + @JSONField(name = "max_give_friend_times") + private int maxGiveFriendTimes; /** * 卡券的商户logo,建议像素为300*300。 */ @@ -71,7 +82,7 @@ public class CouponBaseInfo implements Serializable { @JSONField(name = "use_custom_code") private Boolean useCustomCode; /** - * 指定特殊用户群体 + * 指定特殊用户群体,礼品卡建议填写false */ @JSONField(name = "bind_openid") private Boolean bindOpenId; @@ -140,12 +151,12 @@ public class CouponBaseInfo implements Serializable { */ private String source; /** - * 每人可领券的数量限制,不填写默认为50。 + * 每人可领券的数量限制,不填写默认为50。礼品卡时须填0,不限制 */ @JSONField(name = "get_limit") private int limitNum; /** - * 卡券领取页面是否可分享 + * 卡券领取页面是否可分享,礼品卡建议填写false */ @JSONField(name = "can_share") private boolean canShare; @@ -157,9 +168,41 @@ public class CouponBaseInfo implements Serializable { @JSONField(name = "need_push_on_view") private Boolean needPushOnView; + /** + * 礼品卡用属性,自定义cell对应的小程序username,格式为公众号原始id@app。如:gh_86a091e50ad4@app 选填 + */ + @JSONField(name = "center_app_brand_user_name") + private String centerAppBrandUserName; + /** + * 礼品卡用属性,自定义cell对应的小程序路径. 如:pages/index/index 选填 + */ + @JSONField(name = "center_app_brand_pass") + private String centerAppBrandPass; + /** + * 礼品卡用属性,自定义cell对应的小程序username,格式为公众号原始id@app 选填 + */ + @JSONField(name = "custom_app_brand_user_name") + private String customAppBrandUserName; + /** + * 礼品卡用属性,自定义cell对应的小程序路径。选填 + */ + @JSONField(name = "custom_app_brand_pass") + private String customAppBrandPass; + /** + * 礼品卡用属性,自定义cell对应的小程序username,格式为公众号原始id@app 选填 + */ + @JSONField(name = "promotion_app_brand_user_name") + private String promotionAppBrandUserName; + /** + * 礼品卡用属性,自定义cell对应的小程序路径 + */ + @JSONField(name = "promotion_app_brand_pass") + private String promotionAppBrandPass; private CouponBaseInfo(Builder builder) { + this.giftcardInfo = builder.giftcardInfo; this.logoUrl = builder.logoUrl; + this.maxGiveFriendTimes = builder.maxGiveFriendTimes; this.brandName = builder.brandName; this.title = builder.title; this.codeType = builder.codeType; @@ -176,12 +219,18 @@ public class CouponBaseInfo implements Serializable { this.centerTitle = builder.centerTitle; this.centerUrl = builder.centerUrl; this.centerSubTitle = builder.centerSubTitle; + this.centerAppBrandUserName = builder.centerAppBrandUserName; + this.centerAppBrandPass = builder.centerAppBrandPass; this.customTitle = builder.customTitle; this.customUrl = builder.customUrl; this.customSubTitle = builder.customSubTitle; + this.customAppBrandUserName = builder.customAppBrandUserName; + this.customAppBrandPass = builder.customAppBrandPass; this.promotionTitle = builder.promotionTitle; this.promotionUrl = builder.promotionUrl; this.promotionSubTitle = builder.promotionSubTitle; + this.promotionAppBrandUserName = builder.promotionAppBrandUserName; + this.promotionAppBrandPass = builder.promotionAppBrandPass; this.source = builder.source; this.limitNum = builder.limitNum; this.canShare = builder.canShare; @@ -301,23 +350,86 @@ public class CouponBaseInfo implements Serializable { return needPushOnView; } + public JSONObject getGiftcardInfo() { + return giftcardInfo; + } + + public int getMaxGiveFriendTimes() { + return maxGiveFriendTimes; + } + + public Boolean getUseCustomCode() { + return useCustomCode; + } + + public Boolean getBindOpenId() { + return bindOpenId; + } + + public String getCenterAppBrandUserName() { + return centerAppBrandUserName; + } + + public String getCenterAppBrandPass() { + return centerAppBrandPass; + } + + public String getCustomAppBrandUserName() { + return customAppBrandUserName; + } + + public String getCustomAppBrandPass() { + return customAppBrandPass; + } + + public String getPromotionAppBrandUserName() { + return promotionAppBrandUserName; + } + + public String getPromotionAppBrandPass() { + return promotionAppBrandPass; + } + @Override public String toString() { - return "logoUrl=" + logoUrl + ", brandName=" + brandName + ", title=" - + title + ", codeType=" + codeType + ", cardColor=" + cardColor - + ", notice=" + notice + ", description=" + description - + ", sku=" + sku + ", date=" + date + ", useCustomCode=" - + useCustomCode + ", bindOpenId=" + bindOpenId - + ", servicePhone=" + servicePhone + ", locationIds=" - + locationIds + ", useAllLocation=" + useAllLocation - + ", centerTitle=" + centerTitle + ", centerUrl=" + centerUrl - + ", centerSubTitle=" + centerSubTitle + ", customTitle=" - + customTitle + ", customUrl=" + customUrl - + ", customSubTitle=" + customSubTitle + ", promotionTitle=" - + promotionTitle + ", promotionUrl=" + promotionUrl - + ", promotionSubTitle=" + promotionSubTitle + ", source=" - + source + ", limitNum=" + limitNum + ", canShare=" + canShare - + ", canGiveFriend=" + canGiveFriend; + return "CouponBaseInfo{" + + "giftcardInfo=" + giftcardInfo + + ", maxGiveFriendTimes=" + maxGiveFriendTimes + + ", logoUrl='" + logoUrl + '\'' + + ", brandName='" + brandName + '\'' + + ", title='" + title + '\'' + + ", codeType=" + codeType + + ", cardColor=" + cardColor + + ", notice='" + notice + '\'' + + ", description='" + description + '\'' + + ", sku=" + sku + + ", date=" + date + + ", useCustomCode=" + useCustomCode + + ", bindOpenId=" + bindOpenId + + ", servicePhone='" + servicePhone + '\'' + + ", locationIds=" + locationIds + + ", useAllLocation=" + useAllLocation + + ", centerTitle='" + centerTitle + '\'' + + ", centerUrl='" + centerUrl + '\'' + + ", centerSubTitle='" + centerSubTitle + '\'' + + ", customTitle='" + customTitle + '\'' + + ", customUrl='" + customUrl + '\'' + + ", customSubTitle='" + customSubTitle + '\'' + + ", promotionTitle='" + promotionTitle + '\'' + + ", promotionUrl='" + promotionUrl + '\'' + + ", promotionSubTitle='" + promotionSubTitle + '\'' + + ", source='" + source + '\'' + + ", limitNum=" + limitNum + + ", canShare=" + canShare + + ", canGiveFriend=" + canGiveFriend + + ", needPushOnView=" + needPushOnView + + ", centerAppBrandUserName='" + centerAppBrandUserName + '\'' + + ", centerAppBrandPass='" + centerAppBrandPass + '\'' + + ", customAppBrandUserName='" + customAppBrandUserName + '\'' + + ", customAppBrandPass='" + customAppBrandPass + '\'' + + ", promotionAppBrandUserName='" + promotionAppBrandUserName + '\'' + + ", promotionAppBrandPass='" + promotionAppBrandPass + '\'' + + '}'; } public void cleanCantUpdateField() { @@ -337,10 +449,18 @@ public class CouponBaseInfo implements Serializable { * @since JDK 1.6 */ public static final class Builder { + /** + * 礼品卡信息,目前只有一个礼品卡的价格属性,必填 + */ + private JSONObject giftcardInfo; /** * 卡券的商户logo,建议像素为300*300 */ private String logoUrl; + /** + * 礼品卡最大可赠送次数,必填 + */ + private int maxGiveFriendTimes; /** * 商户名字,字数上限为12个汉字,如:海底捞 */ @@ -452,11 +572,37 @@ public class CouponBaseInfo implements Serializable { * 用户点击进入卡券时推送事件 */ private boolean needPushOnView; + /** + * 自定义cell对应的小程序username,格式为公众号原始id@app。如:gh_86a091e50ad4@app 选填 + */ + private String centerAppBrandUserName; + /** + * 自定义cell对应的小程序路径. 如:pages/index/index 选填 + */ + private String centerAppBrandPass; + /** + * 自定义cell对应的小程序username,格式为公众号原始id@app 选填 + */ + private String customAppBrandUserName; + /** + * 自定义cell对应的小程序路径。选填 + */ + private String customAppBrandPass; + /** + * 自定义cell对应的小程序username,格式为公众号原始id@app + */ + private String promotionAppBrandUserName; + /** + * 自定义cell对应的小程序路径 + */ + private String promotionAppBrandPass; /** * 默认永久有效 */ public Builder() { + this.giftcardInfo = new JSONObject(); + this.maxGiveFriendTimes = 1; this.sku = new JSONObject(); this.date = new JSONObject(); this.date.put("type",CardActiveType.DATE_TYPE_PERMANENT); @@ -466,6 +612,46 @@ public class CouponBaseInfo implements Serializable { this.limitNum = 50; } + public Builder customAppBrandPass(String pass){ + this.customAppBrandPass = pass; + return this; + } + + public Builder centerAppBrandUserName(String name){ + this.centerAppBrandUserName = name; + return this; + } + + public Builder centerAppBrandPass(String pass){ + this.centerAppBrandPass = pass; + return this; + } + + public Builder customAppBrandUserName(String name){ + this.customAppBrandUserName = name; + return this; + } + + public Builder promotionAppBrandUserName(String userName){ + this.promotionAppBrandUserName = userName; + return this; + } + + public Builder promotionAppBrandPass(String pass){ + this.promotionAppBrandPass = pass; + return this; + } + + public Builder maxGiveFriendTimes(int times){ + this.maxGiveFriendTimes = times; + return this; + } + + public Builder price(int price){ + this.giftcardInfo.put("price", price); + return this; + } + /** * 设置商户logo * diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/GiftCard.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/GiftCard.java new file mode 100644 index 00000000..a62d69f5 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/GiftCard.java @@ -0,0 +1,219 @@ +package com.foxinmy.weixin4j.model.card; + +import com.alibaba.fastjson.annotation.JSONField; +import com.foxinmy.weixin4j.type.card.CardType; +import com.foxinmy.weixin4j.type.card.SubCardType; + +/** + * 储值类礼品卡 + * + * @author kit(kit.li@qq.com) + * @date 2018年10月26日 + */ +public class GiftCard extends CardCoupon { + + /** + * 子卡券类型 + */ + @JSONField(name = "sub_card_type") + private final String subCardType; + /** + * 礼品卡背景图片,非必需 + */ + @JSONField(name = "background_pic_url") + private String backgroundPicUrl; + /** + * 是否支持积分,填写true或者false。默认为false + */ + @JSONField(name = "supply_bonus") + private boolean supplyBonus; + /** + * 是否支持余额,填写true或者false。默认为false + */ + @JSONField(name = "supply_balance") + private boolean supplyBalance; + /** + * 自定义会员信息类目,会员卡激活后显示,包含name和url字段 + */ + @JSONField(name = "custom_field1") + private MemCardCustomField customField1; + /** + * 自定义会员信息类目,会员卡激活后显示,包含name和url字段 + */ + @JSONField(name = "custom_field2") + private MemCardCustomField customField2; + /** + * 自定义会员信息类目,会员卡激活后显示,包含name和url字段 + */ + @JSONField(name = "custom_field3") + private MemCardCustomField customField3; + /** + * 是否自动激活,若开发者不需要额外激活流程则填写true。 + */ + @JSONField(name = "auto_activate") + private boolean autoActivate; + /** + * 初始余额,用户购买礼品卡后卡面上显示的初始余额 + */ + @JSONField(name = "init_balance") + private Integer initBalance; + + public GiftCard(CouponBaseInfo baseInfo, GiftCard.Builder builder){ + super(baseInfo); + this.subCardType = SubCardType.VOUCHER.name(); + this.autoActivate = builder.isAutoActivate(); + this.backgroundPicUrl = builder.getBackgroundPicUrl(); + this.customField1 = builder.getCustomField1(); + this.customField2 = builder.getCustomField2(); + this.customField3 = builder.getCustomField3(); + this.supplyBalance = builder.isSupplyBalance(); + this.supplyBonus = builder.isSupplyBonus(); + this.initBalance = builder.getInitBalance(); + } + + @JSONField(serialize = false) + @Override + public CardType getCardType() { + return CardType.GENERAL_COUPON; + } + + public static final class Builder { + private String backgroundPicUrl; + private boolean supplyBonus; + private boolean supplyBalance; + private boolean autoActivate; + private Integer initBalance; + private MemCardCustomField customField1; + private MemCardCustomField customField2; + private MemCardCustomField customField3; + + public Builder(){ + this.autoActivate = true; + this.supplyBalance = false; + this.supplyBonus = false; + } + + public String getBackgroundPicUrl() { + return backgroundPicUrl; + } + + public boolean isSupplyBonus() { + return supplyBonus; + } + + public boolean isSupplyBalance() { + return supplyBalance; + } + + public boolean isAutoActivate() { + return autoActivate; + } + + public Integer getInitBalance() { + return initBalance; + } + + public MemCardCustomField getCustomField1() { + return customField1; + } + + public MemCardCustomField getCustomField2() { + return customField2; + } + + public MemCardCustomField getCustomField3() { + return customField3; + } + + /** + * 设置礼品卡背景图片 + * @param url + * @return + */ + public Builder backgroundPicUrl(String url){ + this.backgroundPicUrl = url; + return this; + } + + /** + * 设置是否支持积分(目前未清楚单品类礼品卡是否支持积分) + * @param supplyBonus + * @return + */ + public Builder supplyBonus(boolean supplyBonus){ + this.supplyBonus = supplyBonus; + return this; + } + + /** + * 设置是否支持余额(需礼品卡类型为GIFT_CARD,单品类礼品卡VOUCHER并非用于储值) + * 注意事项:开发者仅能在supply_balance和custom_field1、custom_field2、custom_field3中选择最多3个填写,否则报错。 + * @param supplyBalance + * @return + */ + public Builder supplyBalance(boolean supplyBalance){ + this.supplyBalance = supplyBalance; + return this; + } + + /** + * 设置礼品卡是否自动激活,若开发者不需要额外激活流程则填写true。 + * @param autoActivate + * @return + */ + public Builder autoActivate(boolean autoActivate){ + this.autoActivate = autoActivate; + return this; + } + + /** + * 设置初始化的余额(需礼品卡类型为GIFT_CARD,单品类礼品卡VOUCHER并非用于储值) + * @param initBalance + * @return + */ + public Builder initBalance(Integer initBalance){ + this.initBalance = initBalance; + return this; + } + + /** + * 设置自定义会员信息类目 + * 注意事项:开发者仅能在supply_balance和custom_field1、custom_field2、custom_field3中选择最多3个填写,否则报错。 + * @param name 自定义信息类目名称 + * @param url 自定义信息类目跳转url + * @return + */ + public Builder customField1(String name, String url){ + MemCardCustomField field = new MemCardCustomField(name, url, null); + this.customField1 = field; + return this; + } + + /** + * 设置自定义会员信息类目 + * 注意事项:开发者仅能在supply_balance和custom_field1、custom_field2、custom_field3中选择最多3个填写,否则报错。 + * @param name 自定义信息类目名称 + * @param url 自定义信息类目跳转url + * @return + */ + public Builder customField2(String name, String url){ + MemCardCustomField field = new MemCardCustomField(name, url, null); + this.customField2 = field; + return this; + } + + /** + * 设置自定义会员信息类目 + * 注意事项:开发者仅能在supply_balance和custom_field1、custom_field2、custom_field3中选择最多3个填写,否则报错。 + * @param name 自定义信息类目名称 + * @param url 自定义信息类目跳转url + * @return + */ + public Builder customField3(String name, String url){ + MemCardCustomField field = new MemCardCustomField(name, url, null); + this.customField3 = field; + return this; + } + } + +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/GiftCardOrder.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/GiftCardOrder.java new file mode 100644 index 00000000..c96d77c8 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/GiftCardOrder.java @@ -0,0 +1,11 @@ +package com.foxinmy.weixin4j.model.card; + +/** + * 礼品卡销售订单信息 + * + * @author kit (kit.li@qq.com) + */ +public class GiftCardOrder { + private String orderId; + private String pageId; +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/GiftCardPage.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/GiftCardPage.java new file mode 100644 index 00000000..e993a0b9 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/GiftCardPage.java @@ -0,0 +1,351 @@ +package com.foxinmy.weixin4j.model.card; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.annotation.JSONField; + +/** + * 礼品卡货架 + * + * @author kit(kit.li@qq.com) + * @date 2018年10月30日 + */ +public class GiftCardPage { + @JSONField(name = "page_id") + private String pageId; + /** + * 礼品卡货架名称 + */ + @JSONField(name = "page_title") + private String title; + /** + * 是否支持一次购买多张及发送至群,填true或者false,若填true则支持,默认为false + */ + @JSONField(name = "support_multi") + private Boolean supportMulti; + /** + * 礼品卡货架是否支持买给自己,填true或者false,若填true则支持,默认为false + */ + @JSONField(name = "support_buy_for_self") + private Boolean supportBuyForSelf; + /** + * 礼品卡货架主题页顶部banner图片,须先将图片上传至CDN,建议尺寸为750px*630px + */ + @JSONField(name = "banner_pic_url") + private String bannerPicUrl; + /** + * 主题结构体 + */ + @JSONField(name = "theme_list") + private JSONArray themeList; + /** + * 主题分类列表 + */ + @JSONField(name = "category_list") + private JSONArray categoryList; + /** + * 商家地址 + */ + private String address; + /** + * 商家服务电话 + */ + @JSONField(name = "service_phone") + private String servicePhone; + /** + * 商家使用说明,用于描述退款、发票等流程 + */ + @JSONField(name = "biz_description") + private String description; + /** + * 该货架的订单是否支持开发票,填true或者false,若填true则需要使用API设置支付后开票功能,默认为false + */ + @JSONField(name = "need_receipt") + private Boolean needReceipt; + /** + * 商家自定义链接,用于承载退款、发票等流程 + */ + @JSONField(name = "cell_1") + private JSONObject cell1; + /** + * 商家自定义链接,用于承载退款、发票等流程 + */ + @JSONField(name = "cell_2") + private JSONObject cell2; + + public String getPageId() { return pageId; } + + public String getTitle() { + return title; + } + + public Boolean getSupportMulti() { + return supportMulti; + } + + public Boolean getSupportBuyForSelf() { + return supportBuyForSelf; + } + + public String getBannerPicUrl() { + return bannerPicUrl; + } + + public JSONArray getThemeList() { + return themeList; + } + + public JSONArray getCategoryList() { + return categoryList; + } + + public String getAddress() { + return address; + } + + public String getServicePhone() { + return servicePhone; + } + + public String getDescription() { + return description; + } + + public Boolean getNeedReceipt() { + return needReceipt; + } + + public JSONObject getCell1() { + return cell1; + } + + public JSONObject getCell2() { + return cell2; + } + + public GiftCardPage(Builder builder){ + this.pageId = builder.pageId; + this.address = builder.address; + this.bannerPicUrl = builder.bannerPicUrl; + this.categoryList = builder.categoryList; + this.cell1 = builder.cell1; + this.cell2 = builder.cell2; + this.description = builder.description; + this.needReceipt = builder.needReceipt; + this.servicePhone = builder.servicePhone; + this.supportBuyForSelf = builder.supportBuyForSelf; + this.supportMulti = builder.supportMulti; + this.themeList = builder.themeList; + this.title = builder.title; + } + + public static class Builder{ + /** + * 货架ID,只在货架更新时用到 + */ + private String pageId; + /** + * 礼品卡货架名称 + */ + private String title; + /** + * 是否支持一次购买多张及发送至群,填true或者false,若填true则支持,默认为false + */ + private Boolean supportMulti; + /** + * 礼品卡货架是否支持买给自己,填true或者false,若填true则支持,默认为false + */ + private Boolean supportBuyForSelf; + /** + * 礼品卡货架主题页顶部banner图片,须先将图片上传至CDN,建议尺寸为750px*630px + */ + private String bannerPicUrl; + /** + * 主题结构体 + */ + private JSONArray themeList; + /** + * 主题分类列表 + */ + private JSONArray categoryList; + /** + * 商家地址 + */ + private String address; + /** + * 商家服务电话 + */ + private String servicePhone; + /** + * 商家使用说明,用于描述退款、发票等流程 + */ + private String description; + /** + * 该货架的订单是否支持开发票,填true或者false,若填true则需要使用API设置支付后开票功能,默认为false + */ + private Boolean needReceipt; + /** + * 商家自定义链接,用于承载退款、发票等流程 + */ + private JSONObject cell1; + /** + * 商家自定义链接,用于承载退款、发票等流程 + */ + private JSONObject cell2; + + public Builder(){ + this.themeList = new JSONArray(); + this.categoryList = null; + } + + public Builder pageId(String pageId){ + this.pageId = pageId; + return this; + } + + /** + * 设置礼品卡货架名称 + * + * @param title + * @return + */ + public Builder title(String title){ + this.title = title; + return this; + } + + /** + * 设置是否支持一次购买多张及发送至群 + * + * @param supportMulti + * @return + */ + public Builder supportMulti(boolean supportMulti){ + this.supportMulti = Boolean.valueOf(supportMulti); + return this; + } + + /** + * 设置礼品卡货架是否支持买给自己 + * + * @param supportBuyForSelf + * @return + */ + public Builder supportBuyForSelf(boolean supportBuyForSelf){ + this.supportBuyForSelf = Boolean.valueOf(supportBuyForSelf); + return this; + } + + /** + * 设置礼品卡货架主题页顶部banner图片 + * + * @param url + * @return + */ + public Builder bannerPicUrl(String url){ + this.bannerPicUrl = url; + return this; + } + + /** + * 添加一个主题 + * + * @param theme + * @return + */ + public Builder themeList(PageTheme theme){ + this.themeList.add(theme); + return this; + } + + /** + * 添加一个主题分类 + * + * @param title + * @return + */ + public Builder categoryList(String title){ + if(this.categoryList==null){ + this.categoryList = new JSONArray(); + } + JSONObject category = new JSONObject(); + category.put("title", title); + this.categoryList.add(category); + return this; + } + + /** + * 设置商家地址 + * + * @param address + * @return + */ + public Builder address(String address){ + this.address = address; + return this; + } + + /** + * 设置商家服务电话 + * + * @param phoneNo + * @return + */ + public Builder servicePhone(String phoneNo){ + this.servicePhone = phoneNo; + return this; + } + + /** + * 设置商家使用说明 + * + * @param description + * @return + */ + public Builder description(String description){ + this.description = description; + return this; + } + + /** + * 设置该货架的订单是否支持开发票 + * + * @param needReceipt + * @return + */ + public Builder needReceipt(boolean needReceipt){ + this.needReceipt = Boolean.valueOf(needReceipt); + return this; + } + + /** + * 设置商家自定义链接 + * + * @param title + * @param url + * @return + */ + public Builder cell1(String title, String url){ + JSONObject cell = new JSONObject(); + cell.put("title", title); + cell.put("url", url); + this.cell1 = cell; + return this; + } + + /** + * 设置商家自定义链接 + * + * @param title + * @param url + * @return + */ + public Builder cell2(String title, String url){ + JSONObject cell = new JSONObject(); + cell.put("title", title); + cell.put("url", url); + this.cell2 = cell; + return this; + } + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/PageTheme.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/PageTheme.java new file mode 100644 index 00000000..94e6d847 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/PageTheme.java @@ -0,0 +1,249 @@ +package com.foxinmy.weixin4j.model.card; + +import com.alibaba.fastjson.annotation.JSONField; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * 礼品卡货架主题 + * + * @author kit(kit.li@qq.com) + * @date 2018年10月30日 + */ +public class PageTheme { + /** + * 主题的封面图片,须先将图片上传至CDN 大小控制在1000px*600px + */ + @JSONField(name = "theme_pic_url") + private String cover; + /** + * 主题名称,如“圣诞”“感恩家人” + */ + private String title; + /** + * 主题title的颜色,直接传入色值 + */ + @JSONField(name = "title_color") + private String titleColor; + /** + * 礼品卡列表,表示主题可选择的礼品卡,由cardid及标题文字组成 + */ + @JSONField(name = "item_list") + private List itemList; + /** + * 礼品卡可选择的封面图 + */ + @JSONField(name = "pic_item_list") + private List picItemList; + /** + * 当前主题所属主题分类的索引,对应主题分类列表category_list内的title字段, 若填写了category_list则每个主题必填该序号 + */ + @JSONField(name = "category_index") + private Integer categoryIndex; + /** + * 该主题购买页是否突出商品名显示 + */ + @JSONField(name = "show_sku_title_first") + private Boolean showSkuTitleFirst; + /** + * 是否将当前主题设置为banner主题(主推荐) + */ + @JSONField(name = "is_banner") + private Boolean bannerTheme; + + public PageTheme(Builder builder){ + this.cover = builder.cover; + this.title = builder.title; + this.titleColor = builder.titleColor; + this.itemList = builder.itemList; + this.picItemList = builder.picItemList; + this.categoryIndex = builder.categoryIndex; + this.showSkuTitleFirst = builder.showSkuTitleFirst; + this.bannerTheme = builder.bannerTheme; + } + + public String getCover() { + return cover; + } + + public String getTitle() { + return title; + } + + public String getTitleColor() { + return titleColor; + } + + public List getItemList() { + return itemList; + } + + public List getPicItemList() { + return picItemList; + } + + public Integer getCategoryIndex() { + return categoryIndex; + } + + public Boolean getShowSkuTitleFirst() { + return showSkuTitleFirst; + } + + public Boolean getBannerTheme() { + return bannerTheme; + } + + public static class Builder{ + /** + * 主题的封面图片,须先将图片上传至CDN 大小控制在1000px*600px + */ + private String cover; + /** + * 主题名称,如“圣诞”“感恩家人” + */ + private String title; + /** + * 主题title的颜色,直接传入色值 + */ + private String titleColor; + /** + * 礼品卡列表,表示主题可选择的礼品卡,由cardid及标题文字组成 + */ + private List itemList; + /** + * 礼品卡可选择的封面图 + */ + private List picItemList; + /** + * 主题标号,对应category_list内的title字段, 若填写了category_list则每个主题必填该序号 + */ + private Integer categoryIndex; + /** + * 该主题购买页是否突出商品名显示 + */ + private Boolean showSkuTitleFirst; + /** + * 是否将当前主题设置为banner主题(主推荐) + */ + private Boolean bannerTheme; + + public Builder(){ + this.itemList = new ArrayList(); + this.picItemList = new ArrayList(); + } + + /** + * 设置主题的封面图片 + * + * @param cover + * @return + */ + public Builder cover(String cover){ + this.cover = cover; + return this; + } + + /** + * 设置主题名称 + * + * @param title + * @return + */ + public Builder title(String title){ + this.title = title; + return this; + } + + /** + * 设置主题title的颜色 + * + * @param titleColor + * 直接设置色值,如:#FB966E + * @return + */ + public Builder titleColor(String titleColor){ + this.titleColor = titleColor; + return this; + } + + /** + * 添加一个或多个礼品卡内容 + * + * @param items + * @return + */ + public Builder cardItems(CardItem... items){ + this.itemList = Arrays.asList(items); + return this; + } + + /** + * 添加一个礼品卡内容 + * + * @param item + * @return + */ + public Builder addCardItem(CardItem item){ + this.itemList.add(item); + return this; + } + + /** + * 添加一个或多个礼品卡封面图 + * + * @param items + * @return + */ + public Builder picItems(PicItem... items){ + this.picItemList = Arrays.asList(items); + return this; + } + + /** + * 添加一个礼品卡封面图 + * + * @param item + * @return + */ + public Builder addPicItem(PicItem item){ + this.picItemList.add(item); + return this; + } + + /** + * 设置所属主题分类的索引号 + * + * @param index + * @return + */ + public Builder categoryIndex(Integer index){ + this.categoryIndex = index; + return this; + } + + /** + * 设置该主题购买页是否突出商品名显示 + * + * @param isShow + * @return + */ + public Builder showSkuTitleFirst(Boolean isShow){ + this.showSkuTitleFirst = isShow; + return this; + } + + /** + * 设置是否将当前主题设置为banner主题(主推荐) + * + * @param isBanner + * @return + */ + public Builder bannerTheme(Boolean isBanner){ + this.bannerTheme = isBanner; + return this; + } + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/PicItem.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/PicItem.java new file mode 100644 index 00000000..7b197057 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/PicItem.java @@ -0,0 +1,66 @@ +package com.foxinmy.weixin4j.model.card; + +import com.alibaba.fastjson.annotation.JSONField; + +/** + * 礼品卡货架主题中的卡面结构体 + * + * @author kit(kit.li@qq.com) + * @date 2018年10月30日 + */ +public class PicItem { + /** + * 卡面图片,须先将图片上传至CDN,大小控制在1000 x 600像素以下 + */ + @JSONField(name = "background_pic_url") + private String backgroundPicUrl; + /** + * 自定义的卡面的标识, 非必填 + */ + @JSONField(name = "outer_img_id") + private String outerImgId; + /** + * 该卡面对应的默认祝福语,当用户没有编辑内容时会随卡默认填写为用户祝福内容 + */ + @JSONField(name = "default_gifting_msg") + private String defaultGiftingMsg; + + public PicItem(){ + + } + + public PicItem(String backgroundPicUrl, String defaultGiftingMsg) { + this.backgroundPicUrl = backgroundPicUrl; + this.defaultGiftingMsg = defaultGiftingMsg; + } + + public PicItem(String backgroundPicUrl, String outerImgId, String defaultGiftingMsg) { + this.backgroundPicUrl = backgroundPicUrl; + this.outerImgId = outerImgId; + this.defaultGiftingMsg = defaultGiftingMsg; + } + + public String getBackgroundPicUrl() { + return backgroundPicUrl; + } + + public String getOuterImgId() { + return outerImgId; + } + + public String getDefaultGiftingMsg() { + return defaultGiftingMsg; + } + + public void setBackgroundPicUrl(String backgroundPicUrl) { + this.backgroundPicUrl = backgroundPicUrl; + } + + public void setOuterImgId(String outerImgId) { + this.outerImgId = outerImgId; + } + + public void setDefaultGiftingMsg(String defaultGiftingMsg) { + this.defaultGiftingMsg = defaultGiftingMsg; + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/VoucherCard.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/VoucherCard.java new file mode 100644 index 00000000..bb549c39 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/VoucherCard.java @@ -0,0 +1,122 @@ +package com.foxinmy.weixin4j.model.card; + +import com.alibaba.fastjson.annotation.JSONField; +import com.foxinmy.weixin4j.type.card.CardType; +import com.foxinmy.weixin4j.type.card.SubCardType; + +/** + * 单品类型礼品卡 + * 指该礼品卡用于兑换指定单品,如汉堡礼品卡 + * + * @className VoucherCardCoupon + * @author kit(kit.li@qq.com) + * @date 2018年10月23日 + */ +public class VoucherCard extends CardCoupon { + + /** + * 子卡券类型 + */ + @JSONField(name = "sub_card_type") + private final String subCardType; + /** + * 礼品卡背景图片,非必需 + */ + @JSONField(name = "background_pic_url") + private String backgroundPicUrl; + /** + * 是否支持积分,填写true或者false。默认为false + */ + @JSONField(name = "supply_bonus") + private boolean supplyBonus; + /** + * 是否支持余额,填写true或者false。默认为false + */ + @JSONField(name = "supply_balance") + private boolean supplyBalance; + /** + * 自定义会员信息类目,会员卡激活后显示,包含name和url字段 + */ + @JSONField(name = "custom_field1") + private MemCardCustomField customField1; + /** + * 自定义会员信息类目,会员卡激活后显示,包含name和url字段 + */ + @JSONField(name = "custom_field2") + private MemCardCustomField customField2; + /** + * 自定义会员信息类目,会员卡激活后显示,包含name和url字段 + */ + @JSONField(name = "custom_field3") + private MemCardCustomField customField3; + /** + * 是否自动激活,若开发者不需要额外激活流程则填写true。 + */ + @JSONField(name = "auto_activate") + private boolean autoActivate; + + public String getSubCardType() { + return subCardType; + } + + public String getBackgroundPicUrl() { + return backgroundPicUrl; + } + + public boolean isSupplyBonus() { + return supplyBonus; + } + + public boolean isSupplyBalance() { + return supplyBalance; + } + + public MemCardCustomField getCustomField1() { + return customField1; + } + + public MemCardCustomField getCustomField2() { + return customField2; + } + + public MemCardCustomField getCustomField3() { + return customField3; + } + + public boolean isAutoActivate() { + return autoActivate; + } + + public VoucherCard(CouponBaseInfo baseInfo, GiftCard.Builder builder){ + super(baseInfo); + this.subCardType = SubCardType.VOUCHER.name(); + this.autoActivate = builder.isAutoActivate(); + this.backgroundPicUrl = builder.getBackgroundPicUrl(); + this.customField1 = builder.getCustomField1(); + this.customField2 = builder.getCustomField2(); + this.customField3 = builder.getCustomField3(); + this.supplyBalance = false; + this.supplyBonus = builder.isSupplyBonus();; + } + + @JSONField(serialize = false) + @Override + public CardType getCardType() { + return CardType.GENERAL_CARD; + } + + @Override + public String toString() { + return "VoucherCardCoupon [" + + "subCardType='" + subCardType + '\'' + + ", backgroundPicUrl='" + backgroundPicUrl + '\'' + + ", supplyBonus=" + supplyBonus + + ", supplyBalance=" + supplyBalance + + ", customField1=" + customField1 + + ", customField2=" + customField2 + + ", customField3=" + customField3 + + ", autoActivate=" + autoActivate + + ", " + super.toString() + + ']'; + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/card/CardType.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/card/CardType.java index f9354e7f..9ae48928 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/card/CardType.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/card/CardType.java @@ -34,5 +34,10 @@ public enum CardType { /** * 会员卡 */ - MEMBER_CARD; + MEMBER_CARD, + + /** + * 通用(礼品)卡 + */ + GENERAL_CARD } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/card/SubCardType.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/card/SubCardType.java new file mode 100644 index 00000000..00d32183 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/card/SubCardType.java @@ -0,0 +1,19 @@ +package com.foxinmy.weixin4j.type.card; + +/** + * 礼品卡类型 + * + * @className SubCardType + * @author kit(kit.li@qq.com) + * @date 2018年10月23日 + */ +public enum SubCardType { + /** + * 礼品卡 + */ + GIFT_CARD, + /** + * 兑换卡 + */ + VOUCHER +} diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java index d527d39d..4b38057f 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java @@ -4,6 +4,7 @@ import java.io.InputStream; import java.util.Date; import java.util.List; +import com.alibaba.fastjson.JSONObject; import com.foxinmy.weixin4j.cache.CacheStorager; import com.foxinmy.weixin4j.cache.FileCacheStorager; import com.foxinmy.weixin4j.exception.WeixinException; @@ -14,6 +15,7 @@ import com.foxinmy.weixin4j.model.WeixinAccount; import com.foxinmy.weixin4j.model.card.CardCoupon; import com.foxinmy.weixin4j.model.card.CardCoupons; import com.foxinmy.weixin4j.model.card.CardQR; +import com.foxinmy.weixin4j.model.card.GiftCardPage; import com.foxinmy.weixin4j.model.media.MediaCounter; import com.foxinmy.weixin4j.model.media.MediaDownloadResult; import com.foxinmy.weixin4j.model.media.MediaItem; @@ -2010,6 +2012,17 @@ public class WeixinProxy { return cardApi.createCardCoupon(cardCoupon); } + /** + * 查询某个card_id的创建信息、审核状态以及库存数量。 + * + * @param cardId + * @return + * @throws WeixinException + */ + public JSONObject getCardInfo(String cardId) throws WeixinException { + return cardApi.getCardInfo(cardId); + } + /** * 设置卡券买单:创建卡券之后,开发者可以通过设置微信买单接口设置该card_id支持微信买单功能。值得开发者注意的是, * 设置买单的card_id必须已经配置了门店,否则会报错。 @@ -2064,6 +2077,200 @@ public class WeixinProxy { return cardApi.createCardQR(expireSeconds, cardQRs); } + /** + * 微信礼品卡货架创建接口,开发者可以通过该接口创建一个礼品卡货架并且用于公众号、门店的礼品卡售卖。 + * + * @param page + * 货架对象 + * @return 货架ID + * @throws WeixinException + * @see 微信礼品卡 + */ + public String addGiftCardPage(GiftCardPage page) throws WeixinException { + return cardApi.addGiftCardPage(page); + } + + /** + * 查询礼品卡货架信息接口 + * + * @param pageId + * 货架ID + * @return + * @throws WeixinException + */ + public JSONObject getGiftCardPage(String pageId) throws WeixinException { + return cardApi.getGiftCardPage(pageId); + } + + /** + * 下架一个礼品卡货架 + * + * @param pageId + * @return + * @throws WeixinException + */ + public ApiResult maintainGiftCardPage(String pageId) throws WeixinException { + return cardApi.maintainGiftCardPage(pageId); + } + + /** + * 下架所有礼品卡货架 + * + * @return + * @throws WeixinException + */ + public ApiResult maintainAllGiftCardPage() throws WeixinException { + return cardApi.maintainAllGiftCardPage(); + } + + /** + * 查询当前商户下所有的礼品卡货架id + * + * @return + * @throws WeixinException + */ + public String[] getGiftCardPageIdList() throws WeixinException { + return cardApi.getGiftCardPageIdList(); + } + + /** + * 修改礼品卡货架信息接口 + * + * @param page + * 货架对象 + * @return + * @throws WeixinException + */ + public ApiResult updateGiftCardPage(GiftCardPage page) throws WeixinException { + return cardApi.updateGiftCardPage(page); + } + + /** + * 申请礼品卡的微信支付权限 + * @param subMchId + * 子商户号 + * @return 微信支付商户平台确认地址 + * @throws WeixinException + */ + public String addGiftCardPayWhitelist(String subMchId) throws WeixinException { + return cardApi.addGiftCardPayWhitelist(subMchId); + } + + /** + * 绑定商户号到礼品卡小程序 + * + * @param wxaAppid + * 微信小程序ID + * @param subMchId + * 微信支付商户号 + * @return + * @throws WeixinException + */ + public ApiResult bindGiftCardPaySubMch(String wxaAppid, String subMchId) throws WeixinException { + return cardApi.bindGiftCardPaySubMch(wxaAppid, subMchId); + } + + /** + * 上传礼品卡小程序代码 + *(提供小程序APPID及货架ID,由微信平台为你小程序帐号上传一套现成的礼品卡小程序,直接用于礼品卡售卖) + * + * @param wxaAppid + * 微信小程序APPID + * @param pageId + * 礼品卡货架ID + * @return + * @throws WeixinException + */ + public ApiResult setGiftCardWxaCode(String wxaAppid, String pageId) throws WeixinException { + return cardApi.setGiftCardWxaCode(wxaAppid, pageId); + } + + /** + * 当礼品卡被使用完毕或者发生转存、绑定等操作后,开发者可以通过该接口核销用户的礼品卡,使礼品卡在列表中沉底并不再被使用。 + * 注意:需在礼品卡核销前调用,否则会报40099 已核销的错误 + * + * @param code + * 卡券Code码。 + * @param cardId + * 卡券ID,自定义code卡券必填,否则非必填。 + * @return + * @throws WeixinException + */ + public ApiResult consumeGiftCard(String code, String cardId) throws WeixinException { + return cardApi.consumeGiftCard(code, cardId); + } + + /** + * 开发者可以通过该接口查询到code对应的信息,如余额、有效期、订单号等,主要用于防止在交易完成后丢单的情况下,用于核销/余额变动时兜底处理。 + * + * @param code + * 卡券Code码 + * @param cardId + * 卡券ID,自定义code卡券必填,否则非必填。 + * @return + * @throws WeixinException + */ + public JSONObject getGiftCardInfo(String code, String cardId) throws WeixinException { + return cardApi.getGiftCardInfo(code, cardId); + } + + /** + * 查询某个订单号对应的订单详情 + * + * @param orderId + * 礼品卡订单号,商户可以通过购买成功的事件推送或者批量查询订单接口获得 + * @return + * @throws WeixinException + */ + public JSONObject getGiftCardOrderInfo(String orderId) throws WeixinException { + return cardApi.getOrderInfo(orderId); + } + + /** + * 批量查询礼品卡订单信息接口 + * + * @param beginTime + * 查询的时间起点,十位时间戳(utc+8) + * @param endTime + * 查询的时间终点,十位时间戳(utc+8) + * @param sortType + * 填"ASC" / "DESC",表示对订单创建时间进行“升 / 降”排序 + * @param offset + * 查询的订单偏移量,如填写100则表示从第100个订单开始拉取 + * @param limit + * 查询订单的数量,如offset填写100,count填写10,则表示查询第100个到第110个订单 + * @return + * @throws WeixinException + */ + public JSONObject getGiftCardOrders(long beginTime, long endTime, String sortType, int offset, int limit) throws WeixinException + { + return cardApi.getOrders(beginTime, endTime, sortType, offset, limit); + } + + /** + * 更新用户礼品卡信息 + * 当礼品卡被使用后,可以通过该接口变更某个礼品卡的余额信息。 + * + * @param cardInfo + * @return + * @throws WeixinException + */ + public JSONObject updateGiftCardUserBalance(CardInfo cardInfo) throws WeixinException { + return cardApi.updateGiftCardUserBalance(cardInfo); + } + + /** + * 对一笔礼品卡订单操作退款 + * + * @param orderId + * 订单ID + * @return + * @throws WeixinException + */ + public ApiResult giftCardOrderRefund(String orderId) throws WeixinException { + return cardApi.orderRefund(orderId); + } + /** * 打开/关闭已群发文章评论 * diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/CardApi.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/CardApi.java index 79af30b5..3b84c8c1 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/CardApi.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/CardApi.java @@ -4,19 +4,14 @@ import java.io.IOException; import java.util.List; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.TypeReference; import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.http.weixin.ApiResult; import com.foxinmy.weixin4j.http.weixin.WeixinResponse; import com.foxinmy.weixin4j.model.Token; -import com.foxinmy.weixin4j.model.card.CardCoupon; -import com.foxinmy.weixin4j.model.card.CardCoupons; -import com.foxinmy.weixin4j.model.card.CardQR; -import com.foxinmy.weixin4j.model.card.MemberInitInfo; -import com.foxinmy.weixin4j.model.card.MemberUpdateInfo; -import com.foxinmy.weixin4j.model.card.MemberUserForm; -import com.foxinmy.weixin4j.model.card.MemberUserInfo; +import com.foxinmy.weixin4j.model.card.*; import com.foxinmy.weixin4j.model.qr.QRParameter; import com.foxinmy.weixin4j.model.qr.QRResult; import com.foxinmy.weixin4j.token.TokenManager; @@ -223,6 +218,25 @@ public class CardApi extends MpApi { return CardStatus.valueOf(status); } + /** + * 查询某个card_id的创建信息、审核状态以及库存数量。 + * + * @param cardId + * @return + * @throws WeixinException + */ + public JSONObject getCardInfo(String cardId) throws WeixinException { + JSONObject requestObj = new JSONObject(); + requestObj.put("card_id", cardId); + String card_get_uri = getRequestUri("card_get_uri"); + Token token = tokenManager.getCache(); + WeixinResponse response = weixinExecutor.post( + String.format(card_get_uri, token.getAccessToken()), + requestObj.toJSONString()); + JSONObject responseJson = response.getAsJson(); + return responseJson.getJSONObject("card"); + } + /** * 支持更新所有卡券类型的部分通用字段及特殊卡券(会员卡、飞机票、电影票、会议门票)中特定字段的信息。 * @@ -330,4 +344,336 @@ public class CardApi extends MpApi { token.getAccessToken()), JSON.toJSONString(updateInfo)); return response.getAsJson(); } + + /** + * 创建一个礼品卡货架 + * + * @param page + * @return 货架ID + * @throws WeixinException + */ + public String addGiftCardPage(GiftCardPage page) throws WeixinException { + String card_gift_card_page_add = getRequestUri("card_gift_card_page_add_uri"); + JSONObject pageJson = new JSONObject(); + pageJson.put("page", page); + Token token = tokenManager.getCache(); + WeixinResponse response = weixinExecutor.post( + String.format(card_gift_card_page_add, + token.getAccessToken()), JSON.toJSONString(pageJson)); + JSONObject jsonObject = response.getAsJson(); + return jsonObject.getString("page_id"); + } + + /** + * 查询礼品卡货架信息 + * + * @param pageId + * 货架ID + * @return + * @throws WeixinException + */ + public JSONObject getGiftCardPage(String pageId) throws WeixinException { + String card_gift_card_page_get = getRequestUri("card_gift_card_page_get_uri"); + JSONObject param = new JSONObject(); + param.put("page_id", pageId); + Token token = tokenManager.getCache(); + WeixinResponse response = weixinExecutor.post( + String.format(card_gift_card_page_get, + token.getAccessToken()), JSON.toJSONString(param)); + JSONObject jsonObject = response.getAsJson(); + + return jsonObject.getJSONObject("page"); + } + + /** + * 查询当前商户下所有的礼品卡货架id + * + * @return + * @throws WeixinException + */ + public String[] getGiftCardPageIdList() throws WeixinException { + String card_gift_card_page_batchget = getRequestUri("card_gift_card_page_batchget_uri"); + JSONObject param = new JSONObject(); + Token token = tokenManager.getCache(); + WeixinResponse response = weixinExecutor.post( + String.format(card_gift_card_page_batchget, + token.getAccessToken()), JSON.toJSONString(param)); + JSONObject jsonObject = response.getAsJson(); + JSONArray idList = jsonObject.getJSONArray("page_id_list"); + if(idList==null || idList.size()==0){ + return new String[0]; + } + + return idList.toArray(new String[idList.size()]); + } + + /** + * 下架礼品卡货架 + * + * @param pageId + * 礼品卡货架ID + * @return + * @throws WeixinException + */ + public ApiResult maintainGiftCardPage(String pageId) throws WeixinException { + String card_gift_card_maintain_set = getRequestUri("card_gift_card_maintain_set_uri"); + JSONObject param = new JSONObject(); + param.put("page_id", pageId); + param.put("maintain", true); + Token token = tokenManager.getCache(); + WeixinResponse response = weixinExecutor.post( + String.format(card_gift_card_maintain_set, + token.getAccessToken()), JSON.toJSONString(param)); + return response.getAsResult(); + } + + /** + * 下架所有礼品卡货架 + * + * @return + * @throws WeixinException + */ + public ApiResult maintainAllGiftCardPage() throws WeixinException { + String card_gift_card_maintain_set = getRequestUri("card_gift_card_maintain_set_uri"); + JSONObject param = new JSONObject(); + param.put("all", true); + param.put("maintain", true); + Token token = tokenManager.getCache(); + WeixinResponse response = weixinExecutor.post( + String.format(card_gift_card_maintain_set, + token.getAccessToken()), JSON.toJSONString(param)); + return response.getAsResult(); + } + + /** + * 查询某个订单号对应的订单详情 + * + * @param orderId + * 礼品卡订单号,商户可以通过购买成功的事件推送或者批量查询订单接口获得 + * @return + * @throws WeixinException + */ + public JSONObject getOrderInfo(String orderId) throws WeixinException { + String card_gift_card_order_get = getRequestUri("card_gift_card_order_get_uri"); + JSONObject param = new JSONObject(); + param.put("order_id", orderId); + Token token = tokenManager.getCache(); + WeixinResponse response = weixinExecutor.post( + String.format(card_gift_card_order_get, + token.getAccessToken()), JSON.toJSONString(param)); + + return response.getAsJson(); + } + + /** + * 批量查询礼品卡订单信息接口 + * + * @param beginTime + * 查询的时间起点,十位时间戳(utc+8) + * @param endTime + * 查询的时间终点,十位时间戳(utc+8) + * @param sortType + * 填"ASC" / "DESC",表示对订单创建时间进行“升 / 降”排序 + * @param offset + * 查询的订单偏移量,如填写100则表示从第100个订单开始拉取 + * @param limit + * 查询订单的数量,如offset填写100,count填写10,则表示查询第100个到第110个订单 + * @return + * @throws WeixinException + */ + public JSONObject getOrders(long beginTime, long endTime, String sortType, int offset, int limit) throws WeixinException { + String card_gift_card_order_batchget_uri = getRequestUri("card_gift_card_order_batchget_uri"); + JSONObject param = new JSONObject(); + param.put("begin_time", beginTime); + param.put("end_time", endTime); + param.put("sort_type", sortType); + param.put("offset", offset); + param.put("count", limit); + Token token = tokenManager.getCache(); + WeixinResponse response = weixinExecutor.post( + String.format(card_gift_card_order_batchget_uri, + token.getAccessToken()), JSON.toJSONString(param)); + + return response.getAsJson(); + } + + /** + * 更新礼品卡货架 + * + * @param page + * @return + * @throws WeixinException + */ + public ApiResult updateGiftCardPage(GiftCardPage page) throws WeixinException { + String card_gift_card_page_update_uri = getRequestUri("card_gift_card_page_update_uri"); + JSONObject pageJson = new JSONObject(); + pageJson.put("page", page); + Token token = tokenManager.getCache(); + WeixinResponse response = weixinExecutor.post( + String.format(card_gift_card_page_update_uri, + token.getAccessToken()), JSON.toJSONString(pageJson)); + return response.getAsResult(); + } + + /** + * 申请礼品卡的微信支付权限 + * + * @param subMchId + * 微信支付子商户号,须为普通服务商模式或者直连商户号,建议为礼品卡专用商户号;商户号必须为公众号申请的商户号 + * 公众号须与商户号同主体,非同主体情况须和对接人联系申请 + * @return 商户平台确认地址,请获得后点击打开登录商户平台后台并点击确认 + * @throws WeixinException + */ + public String addGiftCardPayWhitelist(String subMchId) throws WeixinException{ + String card_gift_card_pay_whitelist_add = getRequestUri("card_gift_card_pay_whitelist_add_uri"); + JSONObject param = new JSONObject(); + param.put("sub_mch_id", subMchId); + Token token = tokenManager.getCache(); + WeixinResponse response = weixinExecutor.post( + String.format(card_gift_card_pay_whitelist_add, + token.getAccessToken()), JSON.toJSONString(param)); + JSONObject jsonObject = response.getAsJson(); + return jsonObject.getString("url"); + } + + /** + * 绑定商户号到礼品卡小程序 + * + * @param wxaAppid + * 礼品卡小程序APPID + * @param subMchId + * 微信支付商户号 + * @return + * @throws WeixinException + */ + public ApiResult bindGiftCardPaySubMch(String wxaAppid, String subMchId) throws WeixinException { + String card_gift_card_pay_submch_bind = getRequestUri("card_gift_card_pay_submch_bind_uri"); + JSONObject param = new JSONObject(); + param.put("sub_mch_id", subMchId); + param.put("wxa_appid", wxaAppid); + + Token token = tokenManager.getCache(); + WeixinResponse response = weixinExecutor.post( + String.format(card_gift_card_pay_submch_bind, + token.getAccessToken()), JSON.toJSONString(param)); + + return response.getAsResult(); + } + + /** + * 上传礼品卡小程序代码 + * (提供小程序APPID及货架ID,由微信平台为你小程序帐号上传一套现成的礼品卡小程序,直接用于礼品卡售卖) + * + * @param wxaAppid + * 微信小程序APPID + * @param pageId + * 礼品卡货架ID + * @return + * @throws WeixinException + */ + public ApiResult setGiftCardWxaCode(String wxaAppid, String pageId) throws WeixinException { + String card_gift_card_wxa_set = getRequestUri("card_gift_card_wxa_set_uri"); + JSONObject param = new JSONObject(); + param.put("wxa_appid", wxaAppid); + param.put("page_id", pageId); + + Token token = tokenManager.getCache(); + WeixinResponse response = weixinExecutor.post( + String.format(card_gift_card_wxa_set, + token.getAccessToken()), JSON.toJSONString(param)); + + return response.getAsResult(); + } + + /** + * 更新用户礼品卡信息 + * 当礼品卡被使用后,可以通过该接口变更某个礼品卡的余额信息。 + * + * @param cardInfo + * @return + * @throws WeixinException + */ + public JSONObject updateGiftCardUserBalance(CardInfo cardInfo) throws WeixinException { + String card_gift_card_wxa_set = getRequestUri("card_general_card_update_user_uri"); + + Token token = tokenManager.getCache(); + WeixinResponse response = weixinExecutor.post( + String.format(card_gift_card_wxa_set, + token.getAccessToken()), JSON.toJSONString(cardInfo)); + return response.getAsJson(); + } + + /** + * 当礼品卡被使用完毕或者发生转存、绑定等操作后,开发者可以通过该接口核销用户的礼品卡,使礼品卡在列表中沉底并不再被使用。 + * + * @param code + * 卡券Code码。 + * @param cardId + * 卡券ID,自定义code卡券必填,否则非必填。 + * @return + * @throws WeixinException + */ + public ApiResult consumeGiftCard(String code, String cardId) throws WeixinException { + String card_code_consume = getRequestUri("card_code_consume_uri"); + JSONObject param = new JSONObject(); + param.put("code", code); + if(cardId!=null && cardId.length()>0){ + param.put("card_id", cardId); + } + + Token token = tokenManager.getCache(); + WeixinResponse response = weixinExecutor.post( + String.format(card_code_consume, + token.getAccessToken()), JSON.toJSONString(param)); + + return response.getAsResult(); + } + + /** + * 开发者可以通过该接口查询到code对应的信息,如余额、有效期、订单号等,主要用于防止在交易完成后丢单的情况下,用于核销/余额变动时兜底处理。 + * 注意:需在礼品卡核销前调用,否则会报40099 已核销的错误 + * + * @param code + * 卡券Code码 + * @param cardId + * 卡券ID,自定义code卡券必填,否则非必填。 + * @return + * @throws WeixinException + */ + public JSONObject getGiftCardInfo(String code, String cardId) throws WeixinException { + String card_code_get = getRequestUri("card_code_get_uri"); + JSONObject param = new JSONObject(); + param.put("code", code); + if(!StringUtils.isEmpty(cardId)){ + param.put("card_id", cardId); + } + + Token token = tokenManager.getCache(); + WeixinResponse response = weixinExecutor.post( + String.format(card_code_get, + token.getAccessToken()), JSON.toJSONString(param)); + + return response.getAsJson(); + } + + /** + * 对一笔礼品卡订单操作退款 + * + * @param orderId + * 订单ID + * @return + * @throws WeixinException + */ + public ApiResult orderRefund(String orderId) throws WeixinException { + String card_gift_card_order_refund_uri = getRequestUri("card_gift_card_order_refund_uri"); + JSONObject param = new JSONObject(); + param.put("order_id", orderId); + + Token token = tokenManager.getCache(); + WeixinResponse response = weixinExecutor.post( + String.format(card_gift_card_order_refund_uri, + token.getAccessToken()), JSON.toJSONString(param)); + + return response.getAsResult(); + } } diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties index 98e3c622..e3682654 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties @@ -219,6 +219,34 @@ card_member_card_activate_user_form_uri={api_base_url}/card/membercard/activateu card_member_card_user_info_uri={api_base_url}/card/membercard/userinfo/get?access_token=%s #\u66f4\u65b0\u4f1a\u5458\u4fe1\u606f card_member_card_update_user_uri={api_base_url}/card/membercard/updateuser?access_token=%s +# \u521B\u5EFA\u793C\u54C1\u5361\u8D27\u67B6 +card_gift_card_page_add_uri={api_base_url}/card/giftcard/page/add?access_token=%s +# \u83B7\u53D6\u8D27\u67B6\u4FE1\u606F +card_gift_card_page_get_uri={api_base_url}/card/giftcard/page/get?access_token=%s +# \u67E5\u8BE2\u8D27\u67B6\u5217\u8868\u4FE1\u606F +card_gift_card_page_batchget_uri={api_base_url}/card/giftcard/page/batchget?access_token=%s +# \u4E0B\u67B6\u793C\u54C1\u5361\u8D27\u67B6 +card_gift_card_maintain_set_uri={api_base_url}/card/giftcard/maintain/set?access_token=%s +# \u793C\u54C1\u5361\u8D27\u67B6\u66F4\u65B0 +card_gift_card_page_update_uri={api_base_url}/card/giftcard/page/update?access_token=%s +# \u7533\u8BF7\u793C\u54C1\u5361\u5FAE\u4FE1\u652F\u4ED8\u6743\u9650 +card_gift_card_pay_whitelist_add_uri={api_base_url}/card/giftcard/pay/whitelist/add?access_token=%s +# \u7ED1\u5B9A\u5546\u6237\u53F7\u5230\u793C\u54C1\u5361\u5C0F\u7A0B\u5E8F\u63A5\u53E3 +card_gift_card_pay_submch_bind_uri={api_base_url}/card/giftcard/pay/submch/bind?access_token=%s +# \u4E0A\u4F20\u5C0F\u7A0B\u5E8F\u4EE3\u7801 +card_gift_card_wxa_set_uri={api_base_url}/card/giftcard/wxa/set?access_token=%s +# \u6838\u9500\u793C\u54C1\u5361 +card_code_consume_uri={api_base_url}/card/code/consume?access_token=%s +# \u67E5\u8BE2\u793C\u54C1\u5361 +card_code_get_uri={api_base_url}/card/code/get?access_token=%s +# \u67E5\u8BE2\u5355\u4E2A\u8BA2\u5355 +card_gift_card_order_get_uri={api_base_url}/card/giftcard/order/get?access_token=%s +# \u67E5\u8BE2\u6307\u5B9A\u5546\u6237\u67D0\u4E2A\u65F6\u95F4\u6BB5\u5185\u521B\u5EFA\u7684\u6240\u6709\u793C\u54C1\u5361\u8BA2\u5355\u8BE6\u60C5\u3002 +card_gift_card_order_batchget_uri={api_base_url}/card/giftcard/order/batchget?access_token=%s +# \u66F4\u65B0\u7528\u6237\u793C\u54C1\u5361\u4FE1\u606F\u63A5\u53E3 +card_general_card_update_user_uri={api_base_url}/card/generalcard/updateuser?access_token=%s +# \u793C\u54C1\u5361\u8BA2\u5355\u9000\u6B3E +card_gift_card_order_refund_uri={api_base_url}/card/giftcard/order/refund?access_token=%s # \u4f7f\u7528\u6388\u6743\u7801\u6362\u53d6\u516c\u4f17\u53f7\u7684\u63a5\u53e3\u8c03\u7528\u51ed\u636e\u548c\u6388\u6743\u4fe1\u606f component_query_authorization_uri={api_cgi_url}/component/api_query_auth?component_access_token=%s