Browse Source

//会员卡 商圈相关——1

formao-live
xhxu 2 years ago
parent
commit
4687a8e54c
15 changed files with 1191 additions and 8 deletions
  1. +52
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/businesscircle/MemberCardAuthorizeNotifyResult.java
  2. +53
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/businesscircle/MemberCardAuthorizeResult.java
  3. +103
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/businesscircle/ParkingNotifyRequest.java
  4. +31
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/businesscircle/PointsCommitStatusResult.java
  5. +82
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/membercard/MemberCardActivateResult.java
  6. +93
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/membercard/MemberCardNotifyData.java
  7. +360
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/membercard/MemberCardResult.java
  8. +104
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/membercard/MemberCardRightsRequest.java
  9. +95
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/membercard/MemberCardUpdRequest.java
  10. +28
    -4
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/BusinessCircleService.java
  11. +50
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/MemberCardService.java
  12. +7
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java
  13. +6
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java
  14. +40
    -4
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BusinessCircleServiceImpl.java
  15. +87
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/MemberCardServiceImpl.java

+ 52
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/businesscircle/MemberCardAuthorizeNotifyResult.java View File

@@ -0,0 +1,52 @@
package com.github.binarywang.wxpay.bean.businesscircle;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
* 商圈授权结果通知内容
* <pre>
* 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_6_6.shtml
* </pre>
*
* @author thinsstar
*/
@NoArgsConstructor
@Data
public class MemberCardAuthorizeNotifyResult implements Serializable {

private static final long serialVersionUID = 1L;

/**
* 用户标识
* <p>
* 顾客授权时使用的小程序上的openid
* 示例值:oUpF8uMuAJ2pxb1Q9zNjWeS6o
*/
@SerializedName("openid")
private String openid;

/**
* 会员在card_id下的唯一标识,
*/
@SerializedName("code")
private String code;

/**
* 用户开会员卡时的商圈商户号
*/
@SerializedName("mchid")
private String mchid;

/**
* 用户授权类型
* REGISTERED_MODE :会员开卡(进卡包) + 未授权会员积分服务
* REGISTERED_AND_AUTHORIZATION_MODE:会员开卡(进卡包)+授权会员积分服务
*/
@SerializedName("auth_type")
private String authType;

}

+ 53
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/businesscircle/MemberCardAuthorizeResult.java View File

@@ -0,0 +1,53 @@
package com.github.binarywang.wxpay.bean.businesscircle;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
* 商圈授权结果查询内容
* <pre>
* 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_6_4.shtml
* </pre>
*
* @author thinsstar
*/
@NoArgsConstructor
@Data
public class MemberCardAuthorizeResult implements Serializable {

private static final long serialVersionUID = 1L;

/**
* 用户标识
* <p>
* 顾客授权时使用的小程序上的openid
* 示例值:oUpF8uMuAJ2pxb1Q9zNjWeS6o
*/
@SerializedName("openid")
private String openid;

/**
* 顾客授权商圈积分结果
* UNAUTHORIZED:未授权
* AUTHORIZED:已授权
* DEAUTHORIZED:已取消授权
*/
@SerializedName("authorize_state")
private String authorizeState;

/**
* 顾客成功授权商圈积分的时间,遵循rfc3339标准格式,格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE
*/
@SerializedName("authorize_time")
private String authorizeTime;

/**
* 顾客关闭授权商圈积分的时间,遵循rfc3339标准格式,格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE
*/
@SerializedName("deauthorize_time")
private String deauthorizeTime;

}

+ 103
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/businesscircle/ParkingNotifyRequest.java View File

@@ -0,0 +1,103 @@
package com.github.binarywang.wxpay.bean.businesscircle;

import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
* 商圈停车同步
* <pre>
* 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_6_5.shtml
* </pre>
*
* @author thinsstar
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ParkingNotifyRequest implements Serializable {

private static final long serialVersionUID = 1L;

/**
* <pre>
* 字段名:商圈商户ID
* 变量名:sub_mchid
* 是否必填:否
* 类型:string[1,64]
* 描述:
* 当以服务商模式管理商圈积分能力时,则要带上商圈商户ID,否则留空
* 示例值:1234567890
* </pre>
*/
@SerializedName(value = "sub_mchid")
private String subMchid;

/**
* <pre>
* 调用方商户号对应的品牌brandid,调用方商户号需为此品牌brandid的品牌主商户号或品牌服务商商户号
* </pre>
*/
@SerializedName(value = "brandid")
private String brandid;

/**
* <pre>
* 字段名:小程序appid
* 变量名:appid
* 是否必填:是
* 类型:string[1,128]
* 描述:
* 顾客授权积分时使用的小程序的appid
* 示例值:wx1234567890abcdef
* </pre>
*/
@SerializedName(value = "appid")
private String appid;

/**
* <pre>
* 字段名:用户标识
* 变量名:openid
* 是否必填:是
* 类型:string[1,64]
* 描述:
* 顾客授权时使用的小程序上的openid
* 示例值:oWmnN4xxxxxxxxxxe92NHIGf1xd8
* </pre>
*/
@SerializedName(value = "openid")
private String openid;

/**
* <pre>
* 首位需为省份的中文简称,第二位起支持大写字母、数字、中文
* </pre>
*/
@SerializedName(value = "plate_number")
private String plateNumber;

/**
* <pre>
* 停车状态,服务商模式下必传
* IN:入场,用户开车进入商圈
* OUT:离场,用户开车离开商圈
* </pre>
*/
@SerializedName(value = "state")
private String state;

/**
* <pre>
* 在场状态更新时间,按照使用rfc3339所定义的格式,格式为yyyy-MM-DDThh:mm:ss+TIMEZONE
* </pre>
*/
@SerializedName(value = "time")
private String time;

}

+ 31
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/businesscircle/PointsCommitStatusResult.java View File

@@ -0,0 +1,31 @@
package com.github.binarywang.wxpay.bean.businesscircle;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
* 商圈积分状态查询
* <pre>
* 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_6_7.shtml
* </pre>
*
* @author thinsstar
*/
@NoArgsConstructor
@Data
public class PointsCommitStatusResult implements Serializable {

private static final long serialVersionUID = 1L;

/**
* 商圈会员待积分状态
* PENDING:有积分待提交,商圈会员有待提交的积分记录,可引导会员跳转插件提交积分申请
* FINISHED:无积分可提交,商圈会员没有待提交的积分记录
*/
@SerializedName("points_commit_status")
private String pointsCommitStatus;

}

+ 82
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/membercard/MemberCardActivateResult.java View File

@@ -0,0 +1,82 @@
package com.github.binarywang.wxpay.bean.membercard;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
* 商圈支付结果通知内容
* <pre>
* 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter5_9_32.shtml
* </pre>
*
* @author thinsstar
*/
@NoArgsConstructor
@Data
public class MemberCardActivateResult implements Serializable {

private static final long serialVersionUID = 1L;

/**
* 业务细分事件类型,枚举值:
* MEMBER_CARD_ACTIVATE:激活会员卡
*
* USER_VIEW_MEMBERCARD:用户查看会员卡详情
* USER_DELETE_MEMBERCARD:用户删除会员卡
* USER_MODIFY_INFORMATION:用户修改个人信息
*/
@SerializedName("event_type")
private String eventType;

/**
* 商户创建微信会员卡模板成功后系统返回的会员卡模板id
*/
@SerializedName("card_id")
private String cardId;

/**
* 会员在card_id下的唯一标识,
*/
@SerializedName("code")
private String code;

/**
* 事件发生时间,遵循rfc3339标准格式,格式为yyyy-MM-DDTHH:mm:ss.sss+TIMEZONE
*/
@SerializedName("event_time")
private String eventTime;

/**
* 激活场景,用于区分用户新开卡激活或删卡后重新领取激活。枚举值:
* NEW_ACTIVATE 新开卡激活
* RECOVER 删卡后重新领取激活
*/
@SerializedName("activate_scene")
private String activateScene;

/**
* 用户标识
* <p>
* 顾客授权时使用的小程序上的openid
* 示例值:oUpF8uMuAJ2pxb1Q9zNjWeS6o
*/
@SerializedName("openid")
private String openid;

/**
* 微信用户在同一个微信开放平台账号下的唯一用户标识,unionid获取方式请参见《UnionID机制说明》文档。
*/
@SerializedName("unionid")
private String unionid;

/**
* 自定义场景值,商户可以用于标记投放场景,如门店/来源等。只能录入数字及中英文/半角标点
* 匹配正则表达式: ^[0-9a-zA-Z\u0000-\u00FF\u4e00-\u9fa5]+$
*/
@SerializedName("outer_str")
private String outerStr;

}

+ 93
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/membercard/MemberCardNotifyData.java View File

@@ -0,0 +1,93 @@
package com.github.binarywang.wxpay.bean.membercard;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
* 会员卡回调通知对象
* <pre>
* 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter5_9_32.shtml
* https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter5_9_33.shtml
* </pre>
*
* @author thinsstar
*/
@NoArgsConstructor
@Data
public class MemberCardNotifyData implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 通知ID
*/
@SerializedName("id")
private String id;

/**
* 通知创建时间
*/
@SerializedName("create_time")
private String createTime;

/**
* 通知类型
*/
@SerializedName("event_type")
private String eventType;

/**
* 通知数据类型
*/
@SerializedName("resource_type")
private String resourceType;

/**
* 回调摘要
* summary
*/
@SerializedName("summary")
private String summary;

/**
* 通知数据
*/
@SerializedName("resource")
private Resource resource;

@Data
public static class Resource implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 加密算法类型
*/
@SerializedName("algorithm")
private String algorithm;

/**
* 数据密文
*/
@SerializedName("ciphertext")
private String cipherText;

/**
* 附加数据
*/
@SerializedName("associated_data")
private String associatedData;

/**
* 随机串
*/
@SerializedName("nonce")
private String nonce;

/**
* 原始回调类型
*/
@SerializedName("original_type")
private String originalType;
}
}

+ 360
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/membercard/MemberCardResult.java View File

@@ -0,0 +1,360 @@
package com.github.binarywang.wxpay.bean.membercard;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.List;

/**
* 查询用户会员卡信息API
* <pre>
* 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter5_9_6.shtml
* </pre>
*
* @author thinsstar
*/
@NoArgsConstructor
@Data
public class MemberCardResult implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 商户创建微信会员卡模板成功后系统返回的会员卡模板id
*/
@SerializedName("card_id")
private String cardId;

/**
* 会员在card_id下的唯一标识,用户领取会员卡后获得的code
*/
@SerializedName("code")
private String code;

/**
* 用户在会员卡绑定品牌appid下的唯一标识,如通过手机号同步会员身份且用户未领取到卡包,无法查询该字段
*/
@SerializedName("openid")
private String openid;

/**
* 在用户会员卡上展示的会员卡编号,默认使用会员卡code作为membership_number。只能录入数字/英文/半角标点。商家可通过修改用户单张会员卡信息更新
*/
@SerializedName("membership_number")
private String membershipNumber;

/**
* 用户会员等级
*/
@SerializedName("level")
private String level;

/**
* 用户的微信昵称,如通过手机号同步会员身份且用户未领取到卡包,无法查询该字段
*/
@SerializedName("nickname")
private String nickname;

/**
* 用户的微信头像url,如通过手机号同步会员身份且用户未领取到卡包,无法查询该字段
*/
@SerializedName("head_image_url")
private String headImageUrl;

/**
* 商家给当前用户设置的会员卡背景图。仅支持通过《图片上传API》接口获取的图片URL地址。支持JPG/JPEG/PNG格式,且图片小于1M。
*/
@SerializedName("background_picture_url")
private String backgroundPictureUrl;

/**
* 用户储值的最新余额,单位分
*/
@SerializedName("balance")
private Integer balance;

/**
* 用户当前的卡状态:
* NOT_ACTIVATE:未激活
* EFFECTIVE:生效中
* EXPIRE:已过期
* UNAVAILABLE:已失效
* DELETE:已删除
* IMPORTED:已导入
*/
@SerializedName("user_card_status")
private String userCardStatus;

/**
* 用户开卡时填写的个人信息
*/
@SerializedName("user_information")
private UserInformation userInformation;

/**
* 用户当前的积分值
*/
@SerializedName("bonus_value")
private Integer bonusValue;

/**
* 用户当前的积分值
*/
@SerializedName("service_modules")
private List<ServiceModule> serviceModules;

/**
* 用户会员卡详情页会员优惠栏目中的会员专享价文案
*/
@SerializedName("member_price_word")
private String memberPriceWord;

/**
*发票栏跳转小程序的引导文案
*/
@SerializedName("fapiao_jump_word")
private String fapiaoJumpWord;

/**
*设置商家联系人员的名字、头像和联系方式
*/
@SerializedName("guide")
private List<Guide> guide;

@Data
public static class UserInformation implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 平台提供的通用开卡信息字段
* 包含性别、手机、头像、昵称、姓名等基本信息字段
*/
@SerializedName("common_field_list")
private List<CommonField> commonFieldList;

/**
* 商户自定义的开卡信息字段
*/
@SerializedName("custom_field_list")
private List<CustomField> customFieldList;

}

@Data
public static class CommonField implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 平台提供了一些通用的开卡字段供开发者选用
* USER_FORM_FLAG_MOBILE:手机号
* USER_FORM_FLAG_SEX:性别
* USER_FORM_FLAG_NAME:姓名
* USER_FORM_FLAG_BIRTHDAY:生日
* USER_FORM_FLAG_ADDRESS:地址
* USER_FORM_FLAG_EMAIL:邮箱
* USER_FORM_FLAG_CITY:城市
*/
@SerializedName("name")
private String name;

/**
* 平台提供的通用开卡信息字段,用户在开卡时填写的信息
*/
@SerializedName("value")
private String value;
}

@Data
public static class CustomField implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 商户自定义的开卡信息字段名称
*/
@SerializedName("name")
private String name;

/**
* 商户自定义的开卡信息字段值,用户在开卡时需填写。填写项目为单选时的返回
*/
@SerializedName("value")
private String value;

/**
* 商户自定义的开卡信息字段值,用户在开卡时需填写。填写项目为多选时的返回
* 特殊规则:列表最多支持10个,单个列表限制8个字符
*/
@SerializedName("value_list")
private List<String> valueList;
}

@Data
public static class ServiceModule implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 会员服务项的唯一识别ID,创建服务项后由微信支付生成的服务项ID。商户可通过服务项id查询服务项的配置信息及用途。
*/
@SerializedName("service_module_id")
private String serviceModuleId;

/**
* 用户的服务状态设置,这些设置会展示在用户的会员卡详情页。可设置状态的内容字段、按钮、消息内容等
*/
@SerializedName("state_setting")
private StateSetting stateSetting;

}

@Data
public static class StateSetting implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 状态的id。一个服务项通常包含多个状态,商户可根据服务流程选择其中的状态进行设置,模板内容展示在用户的会员卡详情页,并支持通过公众号给用户发送触达消息
*/
@SerializedName("state_id")
private String stateId;

/**
* 用户的服务内容模板设置,这些设置会展示在用户的会员卡详情页。可设置状态的内容字段、按钮等
*/
@SerializedName("content_template_data")
private ContentTemplateData contentTemplateData;

/**
* 公众号模板消息设置。部分服务项支持给用户发送触达消息,商户可通过模板id选择模板消息样式,并设置字段值。API调用成功后会通过微信公众号自动给用户发送此模板消息。不填则默认不发消息
*/
@SerializedName("message_template_setting")
private MessageTemplateSetting messageTemplateSetting;
}

@Data
public static class ContentTemplateData implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 当前服务状态下,可以设置的内容字段列表
*/
@SerializedName("field_list")
private List<Field> fieldList;

/**
* 服务状态对应的操作设置,可配置跳转文案和跳转小程序路径
* 需配置跳转文案及跳转小程序路径时必填
*/
@SerializedName("action_setting")
private ActionSetting actionSetting;

}

@Data
public static class Field implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 服务内容列表,最多包含5条内容
*/
@SerializedName("field_id")
private String fieldId;

/**
* 服务状态字段的值
*/
@SerializedName("field_value")
private String fieldValue;

}

@Data
public static class ActionSetting implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 操作名称
*/
@SerializedName("action_name")
private String actionName;

/**
* 服务状态指定跳转小程序
*/
@SerializedName("jump_miniprogram")
private JumpMiniprogram jumpMiniprogram;

}

@Data
public static class JumpMiniprogram implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 小程序的appid
*/
@SerializedName("appid")
private String appid;

/**
* 小程序的页面path
* 示例值:pages/index/index
*/
@SerializedName("path")
private String path;

}

@Data
public static class MessageTemplateSetting implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 公众号模板消息的id
*/
@SerializedName("message_template_id")
private String messageTemplateId;

/**
* 模板消息字段列表。商户在此设置模板消息每个字段需展示的内容
* 特殊规则:限制最多可提交9条
*/
@SerializedName("field_list")
private List<Field> fieldList;

}

@Data
public static class Guide implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 设置商家咨询联系人的名称
*/
@SerializedName("staff_name")
private String staffName;

/**
* 设置商家咨询联系人的头像。仅支持通过《图片上传API》接口获取的图片URL地址。
*/
@SerializedName("head_image_url")
private String headImageUrl;

/**
* 展示说明商家咨询联系人的联系方式,例如“微信号”“企业微信号”
*/
@SerializedName("contact_information_name")
private String contactInformationName;

/**
* 展示说明商家咨询联系人的联系方式信息,例如“weixin123”“135266664”
*/
@SerializedName("contact_information_value")
private String contactInformationValue;

/**
* 商家咨询联系人的联系电话
*/
@SerializedName("phone_number")
private String phoneNumber;
}
}

+ 104
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/membercard/MemberCardRightsRequest.java View File

@@ -0,0 +1,104 @@
package com.github.binarywang.wxpay.bean.membercard;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
* 设置用户会员权益信息api
* <pre>
* 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter5_9_23.shtml
* </pre>
*
* @author thinsstar
*/
@NoArgsConstructor
@Data
public class MemberCardRightsRequest implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 变更前的用户的积分值
*/
@SerializedName("before_bonus_value")
private Integer beforeBonusValue;

/**
* 变更后的用户最新积分值,该值会展示在会员卡详页上
*/
@SerializedName("bonus_value")
private Integer bonusValue;

/**
* 本次变更的积分值
*/
@SerializedName("add_bonus_value")
private Integer addBonusValue;

/**
* 商户凭据号。商户自定义,注意保持唯一性,仅供参考的格式:商户id+日期+流水号。可包含英文字母,数字,|,_,*,-等内容,不允许出现其他不合法符号。
*/
@SerializedName("out_request_no")
private String outRequestNo;

/**
* 积分变更时是否触发系统模板消息,默认为true
*/
@SerializedName("need_inform_bonus")
private Boolean needInformBonus;

/**
* 用户会员卡详情页会员优惠栏目中的会员专享价文案
*/
@SerializedName("member_price_word")
private String memberPriceWord;

/**
*发票栏跳转小程序的引导文案
*/
@SerializedName("fapiao_jump_word")
private String fapiaoJumpWord;

/**
*设置商家联系人员的名字、头像和联系方式
*/
@SerializedName("guide")
private Guide guide;

@Data
public static class Guide implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 设置商家咨询联系人的名称
*/
@SerializedName("staff_name")
private String staffName;

/**
* 设置商家咨询联系人的头像。仅支持通过《图片上传API》接口获取的图片URL地址。
*/
@SerializedName("head_image_url")
private String headImageUrl;

/**
* 展示说明商家咨询联系人的联系方式,例如“微信号”“企业微信号”
*/
@SerializedName("contact_information_name")
private String contactInformationName;

/**
* 展示说明商家咨询联系人的联系方式信息,例如“weixin123”“135266664”
*/
@SerializedName("contact_information_value")
private String contactInformationValue;

/**
* 商家咨询联系人的联系电话
*/
@SerializedName("phone_number")
private String phoneNumber;
}
}

+ 95
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/membercard/MemberCardUpdRequest.java View File

@@ -0,0 +1,95 @@
package com.github.binarywang.wxpay.bean.membercard;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.List;

/**
* 修改用户会员卡信息API
* <pre>
* 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter5_9_8.shtml
* </pre>
*
* @author thinsstar
*/
@NoArgsConstructor
@Data
public class MemberCardUpdRequest implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 在用户会员卡上展示的会员卡编号,默认使用会员卡code作为membership_number。只能录入数字/英文/半角标点。商家可通过修改用户单张会员卡信息更新
*/
@SerializedName("membership_number")
private String membershipNumber;

/**
* 商家给当前用户设置的会员卡背景图。仅支持通过《图片上传API》接口获取的图片URL地址。支持JPG/JPEG/PNG格式,且图片小于1M。
*/
@SerializedName("background_picture_url")
private String backgroundPictureUrl;

/**
* 用户会员等级
*/
@SerializedName("level")
private String level;

/**
* 商户据号。商户自定义,注意保持唯一性,仅供参考的格式:商户id+日期+流水号。可包含英文字母,数字,|,_,*,-等内容,不允许出现其他不合法符号。
*/
@SerializedName("out_request_no")
private String outRequestNo;

/**
* 用户储值变更信息
*/
@SerializedName("balance_information")
private BalanceInformation balanceInformation;

/**
* 用户储值变更信息
*/
@SerializedName("need_inform_balance")
private Boolean needInformBalance;

/**
* 用户储值变更信息
*/
@SerializedName("need_inform_level")
private Boolean needInformLevel;


@Data
public static class BalanceInformation implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 用户储值的更新前余额,单位分
*/
@SerializedName("before_balance")
private Integer beforeBalance;

/**
* 用户储值的更新后余额,单位分
*/
@SerializedName("balance")
private Integer balance;

/**
* 用户储值余额本次的变动值,单位分,等于balance减去before_balance,传入正数表示余额增加,传入负数表示余额减少
*/
@SerializedName("add_balance")
private Integer addBalance;

/**
* 商家自定义储值金额消耗记录,不超过30个字
*/
@SerializedName("balance_remark")
private String balanceRemark;

}
}

+ 28
- 4
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/BusinessCircleService.java View File

@@ -1,9 +1,6 @@
package com.github.binarywang.wxpay.service;

import com.github.binarywang.wxpay.bean.businesscircle.BusinessCircleNotifyData;
import com.github.binarywang.wxpay.bean.businesscircle.PaidResult;
import com.github.binarywang.wxpay.bean.businesscircle.PointsNotifyRequest;
import com.github.binarywang.wxpay.bean.businesscircle.RefundResult;
import com.github.binarywang.wxpay.bean.businesscircle.*;
import com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader;
import com.github.binarywang.wxpay.exception.WxPayException;

@@ -32,4 +29,31 @@ public interface BusinessCircleService {
PaidResult decryptPaidNotifyDataResource(BusinessCircleNotifyData data) throws WxPayException;

RefundResult decryptRefundNotifyDataResource(BusinessCircleNotifyData data) throws WxPayException;

MemberCardAuthorizeNotifyResult decryptMemberCardAuthorizeNotifyDataResource(BusinessCircleNotifyData data) throws WxPayException;

/**
* 授权查询
* https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_6_4.shtml
* @return
* @throws WxPayException
*/
MemberCardAuthorizeResult getAuthorizations(String openid) throws WxPayException;

/**
* 查询待积分状态
* @param brandid
* @param openid
* @return
* @throws WxPayException
*/
PointsCommitStatusResult getPointsCommitStatus(String brandid,String openid) throws WxPayException;

/**
* 停车状态同步
* https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_6_5.shtml
* @param request
* @throws WxPayException
*/
void notifyParkings(ParkingNotifyRequest request) throws WxPayException;
}

+ 50
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/MemberCardService.java View File

@@ -0,0 +1,50 @@
package com.github.binarywang.wxpay.service;

import com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader;
import com.github.binarywang.wxpay.bean.membercard.*;
import com.github.binarywang.wxpay.exception.WxPayException;

/**
* <pre>
* 会员卡相关接口
* </pre>
*
* @author thinsstar
*/
public interface MemberCardService {

MemberCardNotifyData parseNotifyData(String data, SignatureHeader header) throws WxPayException;

MemberCardActivateResult decryptActivateNotifyDataResource(MemberCardNotifyData data) throws WxPayException;

/**
* 查询会员卡信息
* https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter5_9_6.shtml
* @param card_id
* @param code
* @return
* @throws WxPayException
*/
MemberCardResult getMemberCard(String card_id,String code) throws WxPayException;

/**
* 修改用户会员卡信息API
* https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter5_9_8.shtml
* @param card_id
* @param code
* @param request
* @throws WxPayException
*/
void updMemberCard(String card_id, String code, MemberCardUpdRequest request) throws WxPayException;

/**
* 设置用户会员权益信息api
* https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter5_9_23.shtml
* @param card_id
* @param code
* @param request
* @throws WxPayException
*/
void setMemberCardRights(String card_id,String code,MemberCardRightsRequest request) throws WxPayException;

}

+ 7
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java View File

@@ -155,6 +155,13 @@ public interface WxPayService {
*/
BusinessCircleService getBusinessCircleService();

/**
* 获取会员卡服务类
*
* @return the business circle service
*/
MemberCardService getMemberCardService();

/**
* 特约商户进件服务
*


+ 6
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java View File

@@ -61,6 +61,7 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
private ProfitSharingService profitSharingService = new ProfitSharingServiceImpl(this);
private RedpackService redpackService = new RedpackServiceImpl(this);
private BusinessCircleService businessCircleService = new BusinessCircleServiceImpl(this);
private MemberCardService memberCardServiceService = new MemberCardServiceImpl(this);
private Applyment4SubService applyment4SubService = new Applyment4SubServiceImpl(this);
private MerchantMediaService merchantMediaService = new MerchantMediaServiceImpl(this);
private BankService bankService = new BankServiceImpl(this);
@@ -85,6 +86,11 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
return this.businessCircleService;
}

@Override
public MemberCardService getMemberCardService(){
return this.memberCardServiceService;
}

@Override
public RedpackService getRedpackService() {
return this.redpackService;


+ 40
- 4
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BusinessCircleServiceImpl.java View File

@@ -1,9 +1,6 @@
package com.github.binarywang.wxpay.service.impl;

import com.github.binarywang.wxpay.bean.businesscircle.BusinessCircleNotifyData;
import com.github.binarywang.wxpay.bean.businesscircle.PaidResult;
import com.github.binarywang.wxpay.bean.businesscircle.PointsNotifyRequest;
import com.github.binarywang.wxpay.bean.businesscircle.RefundResult;
import com.github.binarywang.wxpay.bean.businesscircle.*;
import com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.BusinessCircleService;
@@ -86,4 +83,43 @@ public class BusinessCircleServiceImpl implements BusinessCircleService {
throw new WxPayException("解析报文异常!", e);
}
}

@Override
public MemberCardAuthorizeNotifyResult decryptMemberCardAuthorizeNotifyDataResource(BusinessCircleNotifyData data) throws WxPayException {
BusinessCircleNotifyData.Resource resource = data.getResource();
String cipherText = resource.getCipherText();
String associatedData = resource.getAssociatedData();
String nonce = resource.getNonce();
String apiV3Key = this.payService.getConfig().getApiV3Key();
try {
return GSON.fromJson(AesUtils.decryptToString(associatedData, nonce, cipherText, apiV3Key), MemberCardAuthorizeNotifyResult.class);
} catch (GeneralSecurityException | IOException e) {
throw new WxPayException("解析报文异常!", e);
}
}

@Override
public MemberCardAuthorizeResult getAuthorizations(String openid) throws WxPayException {
String url = String.format("%s/v3/businesscircle/user-authorizations/%s?sub_mchid=%s&appid=%s",
this.payService.getPayBaseUrl(),openid,this.payService.getConfig().getSubMchId(),this.payService.getConfig().getAppId());
String response = this.payService.getV3WithWechatPaySerial(url);
return GSON.fromJson(response,MemberCardAuthorizeResult.class);
}

@Override
public PointsCommitStatusResult getPointsCommitStatus(String brandid, String openid) throws WxPayException {
String url = String.format("%s/v3/businesscircle/user/%s/points/commit_status?sub_mchid=%s&brandid=%s&appid=%s",
this.payService.getPayBaseUrl(),openid,this.payService.getConfig().getSubMchId(),brandid,this.payService.getConfig().getAppId());
String response = this.payService.getV3WithWechatPaySerial(url);
return GSON.fromJson(response,PointsCommitStatusResult.class);
}

@Override
public void notifyParkings(ParkingNotifyRequest request) throws WxPayException {
request.setAppid(this.payService.getConfig().getAppId());
request.setSubMchid(this.payService.getConfig().getSubMchId());
String url = String.format("%s/v3/businesscircle/parkings", this.payService.getPayBaseUrl());
RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
}
}

+ 87
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/MemberCardServiceImpl.java View File

@@ -0,0 +1,87 @@
package com.github.binarywang.wxpay.service.impl;

import com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader;
import com.github.binarywang.wxpay.bean.membercard.*;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.MemberCardService;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.v3.util.AesUtils;
import com.github.binarywang.wxpay.v3.util.RsaCryptoUtil;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.util.Objects;

/**
* 会员卡相关
*
* @author thinsstar
*/
@Slf4j
@RequiredArgsConstructor
public class MemberCardServiceImpl implements MemberCardService {
private static final Gson GSON = new GsonBuilder().create();
private final WxPayService payService;

/**
* 校验通知签名
*
* @param header 通知头信息
* @param data 通知数据
* @return true:校验通过 false:校验不通过
*/
private boolean verifyNotifySign(SignatureHeader header, String data) {
String beforeSign = String.format("%s%n%s%n%s%n", header.getTimeStamp(), header.getNonce(), data);
return payService.getConfig().getVerifier().verify(header.getSerialNo(),
beforeSign.getBytes(StandardCharsets.UTF_8), header.getSigned());
}

@Override
public MemberCardNotifyData parseNotifyData(String data, SignatureHeader header) throws WxPayException {
if (Objects.nonNull(header) && !this.verifyNotifySign(header, data)) {
throw new WxPayException("非法请求,头部信息验证失败");
}
return GSON.fromJson(data, MemberCardNotifyData.class);
}

@Override
public MemberCardActivateResult decryptActivateNotifyDataResource(MemberCardNotifyData data) throws WxPayException {
MemberCardNotifyData.Resource resource = data.getResource();
String cipherText = resource.getCipherText();
String associatedData = resource.getAssociatedData();
String nonce = resource.getNonce();
String apiV3Key = this.payService.getConfig().getApiV3Key();
try {
return GSON.fromJson(AesUtils.decryptToString(associatedData, nonce, cipherText, apiV3Key), MemberCardActivateResult.class);
} catch (GeneralSecurityException | IOException e) {
throw new WxPayException("解析报文异常!", e);
}
}

@Override
public MemberCardResult getMemberCard(String card_id, String code) throws WxPayException {
String url = String.format("%s/v3/marketing/membercard-open/cards/%s/codes/%s", this.payService.getPayBaseUrl(),card_id,code);
String response = this.payService.getV3WithWechatPaySerial(url);
return GSON.fromJson(response,MemberCardResult.class);
}

@Override
public void updMemberCard(String card_id, String code, MemberCardUpdRequest request) throws WxPayException {
String url = String.format("%s/v3/marketing/membercard-open/cards/%s/codes/%s", this.payService.getPayBaseUrl(),card_id,code);
RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
}

@Override
public void setMemberCardRights(String card_id, String code, MemberCardRightsRequest request) throws WxPayException {
String url = String.format("%s/v3/marketing/membercard-open/cards/%s/codes/%s/rights", this.payService.getPayBaseUrl(),card_id,code);
RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
}

}

Loading…
Cancel
Save