| @@ -32,7 +32,6 @@ public class BeanUtils { | |||||
| * 检查bean里标记为@Required的field是否为空,为空则抛异常 | * 检查bean里标记为@Required的field是否为空,为空则抛异常 | ||||
| * | * | ||||
| * @param bean 要检查的bean对象 | * @param bean 要检查的bean对象 | ||||
| * @throws WxErrorException | |||||
| */ | */ | ||||
| public static void checkRequiredFields(Object bean) throws WxErrorException { | public static void checkRequiredFields(Object bean) throws WxErrorException { | ||||
| List<String> requiredFields = Lists.newArrayList(); | List<String> requiredFields = Lists.newArrayList(); | ||||
| @@ -68,39 +67,4 @@ public class BeanUtils { | |||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * 将bean按照@XStreamAlias标识的字符串内容生成以之为key的map对象 | |||||
| * | |||||
| * @param bean 包含@XStreamAlias的xml bean对象 | |||||
| * @return map对象 | |||||
| */ | |||||
| public static Map<String, String> xmlBean2Map(Object bean) { | |||||
| Map<String, String> result = Maps.newHashMap(); | |||||
| List<Field> fields = new ArrayList<>(Arrays.asList(bean.getClass().getDeclaredFields())); | |||||
| fields.addAll(Arrays.asList(bean.getClass().getSuperclass().getDeclaredFields())); | |||||
| for (Field field : fields) { | |||||
| try { | |||||
| boolean isAccessible = field.isAccessible(); | |||||
| field.setAccessible(true); | |||||
| if (field.get(bean) == null) { | |||||
| field.setAccessible(isAccessible); | |||||
| continue; | |||||
| } | |||||
| if (field.isAnnotationPresent(XStreamAlias.class)) { | |||||
| result.put(field.getAnnotation(XStreamAlias.class).value(), field.get(bean).toString()); | |||||
| } else if (!Modifier.isStatic(field.getModifiers())) { | |||||
| //忽略掉静态成员变量 | |||||
| result.put(field.getName(), field.get(bean).toString()); | |||||
| } | |||||
| field.setAccessible(isAccessible); | |||||
| } catch (SecurityException | IllegalArgumentException | IllegalAccessException e) { | |||||
| log.error(e.getMessage(), e); | |||||
| } | |||||
| } | |||||
| return result; | |||||
| } | |||||
| } | } | ||||
| @@ -34,6 +34,12 @@ | |||||
| <artifactId>commons-lang3</artifactId> | <artifactId>commons-lang3</artifactId> | ||||
| </dependency> | </dependency> | ||||
| <dependency> | |||||
| <groupId>commons-beanutils</groupId> | |||||
| <artifactId>commons-beanutils</artifactId> | |||||
| <version>1.9.3</version> | |||||
| </dependency> | |||||
| <dependency> | <dependency> | ||||
| <groupId>ch.qos.logback</groupId> | <groupId>ch.qos.logback</groupId> | ||||
| <artifactId>logback-classic</artifactId> | <artifactId>logback-classic</artifactId> | ||||
| @@ -0,0 +1,48 @@ | |||||
| package com.github.binarywang.wxpay.bean.entpay; | |||||
| import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest; | |||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
| import lombok.*; | |||||
| import me.chanjar.weixin.common.annotation.Required; | |||||
| import me.chanjar.weixin.common.util.ToStringUtils; | |||||
| /** | |||||
| * <pre> | |||||
| * 企业付款请求对象 | |||||
| * Created by Binary Wang on 2016/10/19. | |||||
| * </pre> | |||||
| * | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| */ | |||||
| @Data | |||||
| @EqualsAndHashCode(callSuper = true) | |||||
| @Builder(builderMethodName = "newBuilder") | |||||
| @NoArgsConstructor | |||||
| @AllArgsConstructor | |||||
| @XStreamAlias("xml") | |||||
| public class EntPayQueryRequest extends BaseWxPayRequest { | |||||
| /** | |||||
| * <pre> | |||||
| * 字段名:商户订单号. | |||||
| * 变量名:partner_trade_no | |||||
| * 是否必填:是 | |||||
| * 示例值:10000098201411111234567890 | |||||
| * 类型:String | |||||
| * 描述商户订单号 | |||||
| * </pre> | |||||
| */ | |||||
| @Required | |||||
| @XStreamAlias("partner_trade_no") | |||||
| private String partnerTradeNo; | |||||
| @Override | |||||
| protected void checkConstraints() { | |||||
| //do nothing | |||||
| } | |||||
| @Override | |||||
| public String toString() { | |||||
| return ToStringUtils.toSimpleString(this); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,77 @@ | |||||
| package com.github.binarywang.wxpay.bean.entpay; | |||||
| import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; | |||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
| import lombok.Data; | |||||
| import lombok.EqualsAndHashCode; | |||||
| import lombok.NoArgsConstructor; | |||||
| /** | |||||
| * <pre> | |||||
| * 企业付款查询返回结果. | |||||
| * Created by Binary Wang on 2016/10/19. | |||||
| * </pre> | |||||
| * | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| */ | |||||
| @Data | |||||
| @EqualsAndHashCode(callSuper = true) | |||||
| @NoArgsConstructor | |||||
| @XStreamAlias("xml") | |||||
| public class EntPayQueryResult extends BaseWxPayResult { | |||||
| /** | |||||
| * 商户订单号 | |||||
| */ | |||||
| @XStreamAlias("partner_trade_no") | |||||
| private String partnerTradeNo; | |||||
| /** | |||||
| * 付款单号 | |||||
| */ | |||||
| @XStreamAlias("detail_id") | |||||
| private String detailId; | |||||
| /** | |||||
| * 转账状态 | |||||
| */ | |||||
| @XStreamAlias("status") | |||||
| private String status; | |||||
| /** | |||||
| * 失败原因 | |||||
| */ | |||||
| @XStreamAlias("reason") | |||||
| private String reason; | |||||
| /** | |||||
| * 收款用户openid | |||||
| */ | |||||
| @XStreamAlias("openid") | |||||
| private String openid; | |||||
| /** | |||||
| * 收款用户姓名 | |||||
| */ | |||||
| @XStreamAlias("transfer_name") | |||||
| private String transferName; | |||||
| /** | |||||
| * 付款金额 | |||||
| */ | |||||
| @XStreamAlias("payment_amount") | |||||
| private Integer paymentAmount; | |||||
| /** | |||||
| * 转账时间 | |||||
| */ | |||||
| @XStreamAlias("transfer_time") | |||||
| private String transferTime; | |||||
| /** | |||||
| * 付款描述 | |||||
| */ | |||||
| @XStreamAlias("desc") | |||||
| private String desc; | |||||
| } | |||||
| @@ -0,0 +1,194 @@ | |||||
| package com.github.binarywang.wxpay.bean.entpay; | |||||
| import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest; | |||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
| import lombok.*; | |||||
| import me.chanjar.weixin.common.annotation.Required; | |||||
| import me.chanjar.weixin.common.util.ToStringUtils; | |||||
| /** | |||||
| * <pre> | |||||
| * 企业付款请求对象. | |||||
| * Created by Binary Wang on 2016/10/02. | |||||
| * </pre> | |||||
| * | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| */ | |||||
| @Data | |||||
| @EqualsAndHashCode(callSuper = true) | |||||
| @Builder(builderMethodName = "newBuilder") | |||||
| @NoArgsConstructor | |||||
| @AllArgsConstructor | |||||
| @XStreamAlias("xml") | |||||
| public class EntPayRequest extends BaseWxPayRequest { | |||||
| /** | |||||
| * <pre> | |||||
| * 字段名:公众账号appid | |||||
| * 变量名:mch_appid | |||||
| * 是否必填:是 | |||||
| * 示例值:wx8888888888888888 | |||||
| * 类型:String | |||||
| * 描述:微信分配的公众账号ID(企业号corpid即为此appId) | |||||
| * </pre> | |||||
| */ | |||||
| @XStreamAlias("mch_appid") | |||||
| private String mchAppid; | |||||
| /** | |||||
| * <pre> | |||||
| * 字段名:商户号 | |||||
| * 变量名:mchid | |||||
| * 是否必填:是 | |||||
| * 示例值:1900000109 | |||||
| * 类型:String(32) | |||||
| * 描述:微信支付分配的商户号 | |||||
| * </pre> | |||||
| */ | |||||
| @XStreamAlias("mchid") | |||||
| private String mchId; | |||||
| /** | |||||
| * <pre> | |||||
| * 字段名:设备号 | |||||
| * 变量名:device_info | |||||
| * 是否必填:否 | |||||
| * 示例值:13467007045764 | |||||
| * 类型:String(32) | |||||
| * 描述:微信支付分配的终端设备号 | |||||
| * </pre> | |||||
| */ | |||||
| @XStreamAlias("device_info") | |||||
| private String deviceInfo; | |||||
| /** | |||||
| * <pre> | |||||
| * 字段名:商户订单号 | |||||
| * 变量名:partner_trade_no | |||||
| * 是否必填:是 | |||||
| * 示例值:10000098201411111234567890 | |||||
| * 类型:String | |||||
| * 描述:商户订单号 | |||||
| * </pre> | |||||
| */ | |||||
| @Required | |||||
| @XStreamAlias("partner_trade_no") | |||||
| private String partnerTradeNo; | |||||
| /** | |||||
| * <pre> | |||||
| * 字段名:需保持唯一性 用户openid | |||||
| * 变量名:openid | |||||
| * 是否必填:是 | |||||
| * 示例值:oxTWIuGaIt6gTKsQRLau2M0yL16E | |||||
| * 类型:String | |||||
| * 描述:商户appid下,某用户的openid | |||||
| * </pre> | |||||
| */ | |||||
| @Required | |||||
| @XStreamAlias("openid") | |||||
| private String openid; | |||||
| /** | |||||
| * <pre> | |||||
| * 字段名:校验用户姓名选项 | |||||
| * 变量名:check_name | |||||
| * 是否必填:是 | |||||
| * 示例值:OPTION_CHECK | |||||
| * 类型:String | |||||
| * 描述:NO_CHECK:不校验真实姓名 | |||||
| * FORCE_CHECK:强校验真实姓名(未实名认证的用户会校验失败,无法转账) | |||||
| * OPTION_CHECK:针对已实名认证的用户才校验真实姓名(未实名认证用户不校验,可以转账成功) | |||||
| * </pre> | |||||
| */ | |||||
| @Required | |||||
| @XStreamAlias("check_name") | |||||
| private String checkName; | |||||
| /** | |||||
| * <pre> | |||||
| * 字段名:收款用户姓名 | |||||
| * 变量名:re_user_name | |||||
| * 是否必填:可选 | |||||
| * 示例值:马花花 | |||||
| * 类型:String | |||||
| * 描述:收款用户真实姓名。 | |||||
| * 如果check_name设置为FORCE_CHECK或OPTION_CHECK, 则必填用户真实姓名 | |||||
| * </pre> | |||||
| */ | |||||
| @XStreamAlias("re_user_name") | |||||
| private String reUserName; | |||||
| /** | |||||
| * <pre> | |||||
| * 字段名:金额 | |||||
| * 变量名:amount | |||||
| * 是否必填:是 | |||||
| * 示例值:10099 | |||||
| * 类型:int | |||||
| * 描述:企业付款金额, 单位为分 | |||||
| * </pre> | |||||
| */ | |||||
| @Required | |||||
| @XStreamAlias("amount") | |||||
| private Integer amount; | |||||
| /** | |||||
| * <pre> | |||||
| * 字段名:企业付款描述信息 | |||||
| * 变量名:desc | |||||
| * 是否必填:是 | |||||
| * 示例值:理赔 | |||||
| * 类型:String | |||||
| * 描述:企业付款操作说明信息。必填。 | |||||
| * </pre> | |||||
| */ | |||||
| @Required | |||||
| @XStreamAlias("desc") | |||||
| private String description; | |||||
| /** | |||||
| * <pre> | |||||
| * 字段名:Ip地址 | |||||
| * 变量名:spbill_create_ip | |||||
| * 是否必填:是 | |||||
| * 示例值:192.168.0.1 | |||||
| * 类型:String(32) | |||||
| * 描述:调用接口的机器Ip地址 | |||||
| * </pre> | |||||
| */ | |||||
| @Required | |||||
| @XStreamAlias("spbill_create_ip") | |||||
| private String spbillCreateIp; | |||||
| @Override | |||||
| protected void checkConstraints() { | |||||
| } | |||||
| @Override | |||||
| public String getAppid() { | |||||
| return this.mchAppid; | |||||
| } | |||||
| @Override | |||||
| public void setAppid(String appid) { | |||||
| this.mchAppid = appid; | |||||
| } | |||||
| @Override | |||||
| public String getMchId() { | |||||
| return this.mchId; | |||||
| } | |||||
| @Override | |||||
| public void setMchId(String mchId) { | |||||
| this.mchId = mchId; | |||||
| } | |||||
| @Override | |||||
| public String toString() { | |||||
| return ToStringUtils.toSimpleString(this); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,54 @@ | |||||
| package com.github.binarywang.wxpay.bean.entpay; | |||||
| import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; | |||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
| import lombok.Data; | |||||
| import lombok.EqualsAndHashCode; | |||||
| import lombok.NoArgsConstructor; | |||||
| /** | |||||
| * <pre> | |||||
| * 企业付款返回结果 | |||||
| * Created by Binary Wang on 2016/10/02. | |||||
| * </pre> | |||||
| * | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| */ | |||||
| @Data | |||||
| @EqualsAndHashCode(callSuper = true) | |||||
| @NoArgsConstructor | |||||
| @XStreamAlias("xml") | |||||
| public class EntPayResult extends BaseWxPayResult { | |||||
| /** | |||||
| * 商户appid | |||||
| */ | |||||
| @XStreamAlias("mch_appid") | |||||
| private String mchAppid; | |||||
| /** | |||||
| * 设备号 | |||||
| */ | |||||
| @XStreamAlias("device_info") | |||||
| private String deviceInfo; | |||||
| //############以下字段在return_code 和result_code都为SUCCESS的时候有返回############## | |||||
| /** | |||||
| * 商户订单号 | |||||
| */ | |||||
| @XStreamAlias("partner_trade_no") | |||||
| private String partnerTradeNo; | |||||
| /** | |||||
| * 微信订单号 | |||||
| */ | |||||
| @XStreamAlias("payment_no") | |||||
| private String paymentNo; | |||||
| /** | |||||
| * 微信支付成功时间 | |||||
| */ | |||||
| @XStreamAlias("payment_time") | |||||
| private String paymentTime; | |||||
| } | |||||
| @@ -2,12 +2,12 @@ package com.github.binarywang.wxpay.bean.notify; | |||||
| import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; | import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; | ||||
| import com.github.binarywang.wxpay.converter.WxPayOrderNotifyResultConverter; | import com.github.binarywang.wxpay.converter.WxPayOrderNotifyResultConverter; | ||||
| import com.github.binarywang.wxpay.util.SignUtils; | |||||
| import com.thoughtworks.xstream.XStream; | import com.thoughtworks.xstream.XStream; | ||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
| import lombok.Data; | import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
| import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
| import me.chanjar.weixin.common.util.BeanUtils; | |||||
| import me.chanjar.weixin.common.util.ToStringUtils; | import me.chanjar.weixin.common.util.ToStringUtils; | ||||
| import me.chanjar.weixin.common.util.xml.XStreamInitializer; | import me.chanjar.weixin.common.util.xml.XStreamInitializer; | ||||
| @@ -270,7 +270,7 @@ public class WxPayOrderNotifyResult extends BaseWxPayResult implements Serializa | |||||
| @Override | @Override | ||||
| public Map<String, String> toMap() { | public Map<String, String> toMap() { | ||||
| Map<String, String> resultMap = BeanUtils.xmlBean2Map(this); | |||||
| Map<String, String> resultMap = SignUtils.xmlBean2Map(this); | |||||
| if (this.getCouponCount() != null && this.getCouponCount() > 0) { | if (this.getCouponCount() != null && this.getCouponCount() > 0) { | ||||
| for (int i = 0; i < this.getCouponCount(); i++) { | for (int i = 0; i < this.getCouponCount(); i++) { | ||||
| WxPayOrderNotifyCoupon coupon = couponList.get(i); | WxPayOrderNotifyCoupon coupon = couponList.get(i); | ||||
| @@ -1,54 +1,15 @@ | |||||
| package com.github.binarywang.wxpay.bean.request; | package com.github.binarywang.wxpay.bean.request; | ||||
| import com.github.binarywang.wxpay.bean.entpay.EntPayQueryRequest; | |||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
| import lombok.*; | import lombok.*; | ||||
| import me.chanjar.weixin.common.annotation.Required; | import me.chanjar.weixin.common.annotation.Required; | ||||
| import me.chanjar.weixin.common.util.ToStringUtils; | import me.chanjar.weixin.common.util.ToStringUtils; | ||||
| /** | /** | ||||
| * <pre> | |||||
| * 企业付款请求对象 | |||||
| * 注释中各行每个字段描述对应如下: | |||||
| * <li>字段名 | |||||
| * <li>变量名 | |||||
| * <li>是否必填 | |||||
| * <li>类型 | |||||
| * <li>示例值 | |||||
| * <li>描述 | |||||
| * </pre> | |||||
| * Created by Binary Wang on 2016/10/19. | |||||
| * | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| * 请使用 {@link EntPayQueryRequest} | |||||
| */ | */ | ||||
| @Data | |||||
| @EqualsAndHashCode(callSuper = true) | |||||
| @Builder(builderMethodName = "newBuilder") | |||||
| @NoArgsConstructor | |||||
| @AllArgsConstructor | |||||
| @XStreamAlias("xml") | @XStreamAlias("xml") | ||||
| public class WxEntPayQueryRequest extends BaseWxPayRequest { | |||||
| /** | |||||
| * <pre> | |||||
| * 商户订单号 | |||||
| * partner_trade_no | |||||
| * 是 | |||||
| * 10000098201411111234567890 | |||||
| * String | |||||
| * 商户订单号 | |||||
| * </pre> | |||||
| */ | |||||
| @Required | |||||
| @XStreamAlias("partner_trade_no") | |||||
| private String partnerTradeNo; | |||||
| @Override | |||||
| protected void checkConstraints() { | |||||
| //do nothing | |||||
| } | |||||
| @Override | |||||
| public String toString() { | |||||
| return ToStringUtils.toSimpleString(this); | |||||
| } | |||||
| @Deprecated | |||||
| public class WxEntPayQueryRequest extends EntPayQueryRequest { | |||||
| } | } | ||||
| @@ -1,5 +1,7 @@ | |||||
| package com.github.binarywang.wxpay.bean.request; | package com.github.binarywang.wxpay.bean.request; | ||||
| import com.github.binarywang.wxpay.bean.entpay.EntPayQueryRequest; | |||||
| import com.github.binarywang.wxpay.bean.entpay.EntPayRequest; | |||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
| import lombok.*; | import lombok.*; | ||||
| import me.chanjar.weixin.common.annotation.Required; | import me.chanjar.weixin.common.annotation.Required; | ||||
| @@ -8,186 +10,140 @@ import me.chanjar.weixin.common.util.ToStringUtils; | |||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| * 企业付款请求对象 | * 企业付款请求对象 | ||||
| * 请使用 {@link EntPayRequest} | |||||
| * </pre> | * </pre> | ||||
| * Created by Binary Wang on 2016/10/02. | |||||
| * | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| */ | */ | ||||
| @Data | |||||
| @EqualsAndHashCode(callSuper = true) | |||||
| @Builder(builderMethodName = "newBuilder") | |||||
| @NoArgsConstructor | |||||
| @AllArgsConstructor | |||||
| @XStreamAlias("xml") | @XStreamAlias("xml") | ||||
| public class WxEntPayRequest extends BaseWxPayRequest { | |||||
| /** | |||||
| * <pre> | |||||
| * 字段名:公众账号appid | |||||
| * 变量名:mch_appid | |||||
| * 是否必填:是 | |||||
| * 示例值:wx8888888888888888 | |||||
| * 类型:String | |||||
| * 描述:微信分配的公众账号ID(企业号corpid即为此appId) | |||||
| * </pre> | |||||
| */ | |||||
| @XStreamAlias("mch_appid") | |||||
| private String mchAppid; | |||||
| /** | |||||
| * <pre> | |||||
| * 字段名:商户号 | |||||
| * 变量名:mchid | |||||
| * 是否必填:是 | |||||
| * 示例值:1900000109 | |||||
| * 类型:String(32) | |||||
| * 描述:微信支付分配的商户号 | |||||
| * </pre> | |||||
| */ | |||||
| @XStreamAlias("mchid") | |||||
| private String mchId; | |||||
| /** | |||||
| * <pre> | |||||
| * 字段名:设备号 | |||||
| * 变量名:device_info | |||||
| * 是否必填:否 | |||||
| * 示例值:13467007045764 | |||||
| * 类型:String(32) | |||||
| * 描述:微信支付分配的终端设备号 | |||||
| * </pre> | |||||
| */ | |||||
| @XStreamAlias("device_info") | |||||
| private String deviceInfo; | |||||
| /** | |||||
| * <pre> | |||||
| * 字段名:商户订单号 | |||||
| * 变量名:partner_trade_no | |||||
| * 是否必填:是 | |||||
| * 示例值:10000098201411111234567890 | |||||
| * 类型:String | |||||
| * 描述:商户订单号 | |||||
| * </pre> | |||||
| */ | |||||
| @Required | |||||
| @XStreamAlias("partner_trade_no") | |||||
| private String partnerTradeNo; | |||||
| /** | |||||
| * <pre> | |||||
| * 字段名:需保持唯一性 用户openid | |||||
| * 变量名:openid | |||||
| * 是否必填:是 | |||||
| * 示例值:oxTWIuGaIt6gTKsQRLau2M0yL16E | |||||
| * 类型:String | |||||
| * 描述:商户appid下,某用户的openid | |||||
| * </pre> | |||||
| */ | |||||
| @Required | |||||
| @XStreamAlias("openid") | |||||
| private String openid; | |||||
| /** | |||||
| * <pre> | |||||
| * 字段名:校验用户姓名选项 | |||||
| * 变量名:check_name | |||||
| * 是否必填:是 | |||||
| * 示例值:OPTION_CHECK | |||||
| * 类型:String | |||||
| * 描述:NO_CHECK:不校验真实姓名 | |||||
| * FORCE_CHECK:强校验真实姓名(未实名认证的用户会校验失败,无法转账) | |||||
| * OPTION_CHECK:针对已实名认证的用户才校验真实姓名(未实名认证用户不校验,可以转账成功) | |||||
| * </pre> | |||||
| */ | |||||
| @Required | |||||
| @XStreamAlias("check_name") | |||||
| private String checkName; | |||||
| /** | |||||
| * <pre> | |||||
| * 字段名:收款用户姓名 | |||||
| * 变量名:re_user_name | |||||
| * 是否必填:可选 | |||||
| * 示例值:马花花 | |||||
| * 类型:String | |||||
| * 描述:收款用户真实姓名。 | |||||
| * 如果check_name设置为FORCE_CHECK或OPTION_CHECK, 则必填用户真实姓名 | |||||
| * </pre> | |||||
| */ | |||||
| @XStreamAlias("re_user_name") | |||||
| private String reUserName; | |||||
| /** | |||||
| * <pre> | |||||
| * 字段名:金额 | |||||
| * 变量名:amount | |||||
| * 是否必填:是 | |||||
| * 示例值:10099 | |||||
| * 类型:int | |||||
| * 描述:企业付款金额, 单位为分 | |||||
| * </pre> | |||||
| */ | |||||
| @Required | |||||
| @XStreamAlias("amount") | |||||
| private Integer amount; | |||||
| /** | |||||
| * <pre> | |||||
| * 字段名:企业付款描述信息 | |||||
| * 变量名:desc | |||||
| * 是否必填:是 | |||||
| * 示例值:理赔 | |||||
| * 类型:String | |||||
| * 描述:企业付款操作说明信息。必填。 | |||||
| * </pre> | |||||
| */ | |||||
| @Required | |||||
| @XStreamAlias("desc") | |||||
| private String description; | |||||
| /** | |||||
| * <pre> | |||||
| * 字段名:Ip地址 | |||||
| * 变量名:spbill_create_ip | |||||
| * 是否必填:是 | |||||
| * 示例值:192.168.0.1 | |||||
| * 类型:String(32) | |||||
| * 描述:调用接口的机器Ip地址 | |||||
| * </pre> | |||||
| */ | |||||
| @Required | |||||
| @XStreamAlias("spbill_create_ip") | |||||
| private String spbillCreateIp; | |||||
| @Override | |||||
| protected void checkConstraints() { | |||||
| @Deprecated | |||||
| public class WxEntPayRequest extends EntPayRequest { | |||||
| private WxEntPayRequest(Builder builder) { | |||||
| setAppid(builder.appid); | |||||
| setMchId(builder.mchId); | |||||
| setSubAppId(builder.subAppId); | |||||
| setSubMchId(builder.subMchId); | |||||
| setNonceStr(builder.nonceStr); | |||||
| setSign(builder.sign); | |||||
| setSignType(builder.signType); | |||||
| setMchAppid(builder.mchAppid); | |||||
| setMchId(builder.mchId); | |||||
| setDeviceInfo(builder.deviceInfo); | |||||
| setPartnerTradeNo(builder.partnerTradeNo); | |||||
| setOpenid(builder.openid); | |||||
| setCheckName(builder.checkName); | |||||
| setReUserName(builder.reUserName); | |||||
| setAmount(builder.amount); | |||||
| setDescription(builder.description); | |||||
| setSpbillCreateIp(builder.spbillCreateIp); | |||||
| } | } | ||||
| @Override | |||||
| public String getAppid() { | |||||
| return this.mchAppid; | |||||
| public static Builder builder() { | |||||
| return new Builder(); | |||||
| } | } | ||||
| @Override | |||||
| public void setAppid(String appid) { | |||||
| this.mchAppid = appid; | |||||
| public static final class Builder { | |||||
| private String appid; | |||||
| private String mchId; | |||||
| private String deviceInfo; | |||||
| private String partnerTradeNo; | |||||
| private String openid; | |||||
| private String checkName; | |||||
| private String reUserName; | |||||
| private Integer amount; | |||||
| private String description; | |||||
| private String spbillCreateIp; | |||||
| private String subAppId; | |||||
| private String subMchId; | |||||
| private String nonceStr; | |||||
| private String sign; | |||||
| private String signType; | |||||
| private String mchAppid; | |||||
| private Builder() { | |||||
| } | |||||
| public Builder appid(String appid) { | |||||
| this.appid = appid; | |||||
| return this; | |||||
| } | |||||
| public Builder mchId(String mchId) { | |||||
| this.mchId = mchId; | |||||
| return this; | |||||
| } | |||||
| public Builder deviceInfo(String deviceInfo) { | |||||
| this.deviceInfo = deviceInfo; | |||||
| return this; | |||||
| } | |||||
| public Builder partnerTradeNo(String partnerTradeNo) { | |||||
| this.partnerTradeNo = partnerTradeNo; | |||||
| return this; | |||||
| } | |||||
| public Builder openid(String openid) { | |||||
| this.openid = openid; | |||||
| return this; | |||||
| } | |||||
| public Builder checkName(String checkName) { | |||||
| this.checkName = checkName; | |||||
| return this; | |||||
| } | |||||
| public Builder reUserName(String reUserName) { | |||||
| this.reUserName = reUserName; | |||||
| return this; | |||||
| } | |||||
| public Builder amount(Integer amount) { | |||||
| this.amount = amount; | |||||
| return this; | |||||
| } | |||||
| public Builder description(String description) { | |||||
| this.description = description; | |||||
| return this; | |||||
| } | |||||
| public Builder spbillCreateIp(String spbillCreateIp) { | |||||
| this.spbillCreateIp = spbillCreateIp; | |||||
| return this; | |||||
| } | |||||
| public WxEntPayRequest build() { | |||||
| return new WxEntPayRequest(this); | |||||
| } | |||||
| public Builder subAppId(String subAppId) { | |||||
| this.subAppId = subAppId; | |||||
| return this; | |||||
| } | |||||
| public Builder subMchId(String subMchId) { | |||||
| this.subMchId = subMchId; | |||||
| return this; | |||||
| } | |||||
| public Builder nonceStr(String nonceStr) { | |||||
| this.nonceStr = nonceStr; | |||||
| return this; | |||||
| } | |||||
| public Builder sign(String sign) { | |||||
| this.sign = sign; | |||||
| return this; | |||||
| } | |||||
| public Builder signType(String signType) { | |||||
| this.signType = signType; | |||||
| return this; | |||||
| } | |||||
| public Builder mchAppid(String mchAppid) { | |||||
| this.mchAppid = mchAppid; | |||||
| return this; | |||||
| } | |||||
| } | } | ||||
| @Override | |||||
| public String getMchId() { | |||||
| return this.mchId; | |||||
| } | |||||
| @Override | |||||
| public void setMchId(String mchId) { | |||||
| this.mchId = mchId; | |||||
| } | |||||
| @Override | |||||
| public String toString() { | |||||
| return ToStringUtils.toSimpleString(this); | |||||
| } | |||||
| } | } | ||||
| @@ -1,6 +1,7 @@ | |||||
| package com.github.binarywang.wxpay.bean.result; | package com.github.binarywang.wxpay.bean.result; | ||||
| import com.github.binarywang.wxpay.exception.WxPayException; | import com.github.binarywang.wxpay.exception.WxPayException; | ||||
| import com.github.binarywang.wxpay.service.WxPayService; | |||||
| import com.github.binarywang.wxpay.service.impl.BaseWxPayServiceImpl; | import com.github.binarywang.wxpay.service.impl.BaseWxPayServiceImpl; | ||||
| import com.github.binarywang.wxpay.util.SignUtils; | import com.github.binarywang.wxpay.util.SignUtils; | ||||
| import com.google.common.base.Joiner; | import com.google.common.base.Joiner; | ||||
| @@ -219,7 +220,7 @@ public abstract class BaseWxPayResult { | |||||
| * @param signType 签名类型 | * @param signType 签名类型 | ||||
| * @param checkSuccess 是否同时检查结果是否成功 | * @param checkSuccess 是否同时检查结果是否成功 | ||||
| */ | */ | ||||
| public void checkResult(BaseWxPayServiceImpl wxPayService, String signType, boolean checkSuccess) throws WxPayException { | |||||
| public void checkResult(WxPayService wxPayService, String signType, boolean checkSuccess) throws WxPayException { | |||||
| //校验返回结果签名 | //校验返回结果签名 | ||||
| Map<String, String> map = toMap(); | Map<String, String> map = toMap(); | ||||
| if (getSign() != null && !SignUtils.checkSign(map, signType, wxPayService.getConfig().getMchKey())) { | if (getSign() != null && !SignUtils.checkSign(map, signType, wxPayService.getConfig().getMchKey())) { | ||||
| @@ -1,74 +1,27 @@ | |||||
| package com.github.binarywang.wxpay.bean.result; | package com.github.binarywang.wxpay.bean.result; | ||||
| import com.github.binarywang.wxpay.bean.entpay.EntPayQueryResult; | |||||
| import com.github.binarywang.wxpay.bean.entpay.EntPayResult; | |||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
| import lombok.Data; | import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
| import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
| import org.apache.commons.beanutils.BeanUtils; | |||||
| /** | /** | ||||
| * 企业付款查询返回结果 | * 企业付款查询返回结果 | ||||
| * Created by Binary Wang on 2016/10/19. | |||||
| * | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| * 请使用{@link EntPayQueryResult} | |||||
| */ | */ | ||||
| @Data | |||||
| @EqualsAndHashCode(callSuper = true) | |||||
| @NoArgsConstructor | |||||
| @XStreamAlias("xml") | @XStreamAlias("xml") | ||||
| public class WxEntPayQueryResult extends BaseWxPayResult { | |||||
| /** | |||||
| * 商户订单号 | |||||
| */ | |||||
| @XStreamAlias("partner_trade_no") | |||||
| private String partnerTradeNo; | |||||
| /** | |||||
| * 付款单号 | |||||
| */ | |||||
| @XStreamAlias("detail_id") | |||||
| private String detailId; | |||||
| /** | |||||
| * 转账状态 | |||||
| */ | |||||
| @XStreamAlias("status") | |||||
| private String status; | |||||
| /** | |||||
| * 失败原因 | |||||
| */ | |||||
| @XStreamAlias("reason") | |||||
| private String reason; | |||||
| /** | |||||
| * 收款用户openid | |||||
| */ | |||||
| @XStreamAlias("openid") | |||||
| private String openid; | |||||
| /** | |||||
| * 收款用户姓名 | |||||
| */ | |||||
| @XStreamAlias("transfer_name") | |||||
| private String transferName; | |||||
| /** | |||||
| * 付款金额 | |||||
| */ | |||||
| @XStreamAlias("payment_amount") | |||||
| private Integer paymentAmount; | |||||
| /** | |||||
| * 转账时间 | |||||
| */ | |||||
| @XStreamAlias("transfer_time") | |||||
| private String transferTime; | |||||
| /** | |||||
| * 付款描述 | |||||
| */ | |||||
| @XStreamAlias("desc") | |||||
| private String desc; | |||||
| @Deprecated | |||||
| public class WxEntPayQueryResult extends EntPayQueryResult { | |||||
| public static WxEntPayQueryResult createFrom(EntPayQueryResult entPayQueryResult) { | |||||
| WxEntPayQueryResult result = new WxEntPayQueryResult(); | |||||
| try { | |||||
| BeanUtils.copyProperties(result, entPayQueryResult); | |||||
| } catch (Exception e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| return result; | |||||
| } | |||||
| } | } | ||||
| @@ -1,51 +1,25 @@ | |||||
| package com.github.binarywang.wxpay.bean.result; | package com.github.binarywang.wxpay.bean.result; | ||||
| import com.github.binarywang.wxpay.bean.entpay.EntPayResult; | |||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
| import lombok.Data; | |||||
| import lombok.EqualsAndHashCode; | |||||
| import lombok.NoArgsConstructor; | |||||
| import org.apache.commons.beanutils.BeanUtils; | |||||
| import java.lang.reflect.InvocationTargetException; | |||||
| /** | /** | ||||
| * 企业付款返回结果 | * 企业付款返回结果 | ||||
| * Created by Binary Wang on 2016/10/02. | |||||
| * | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| * 请使用{@link EntPayResult} | |||||
| */ | */ | ||||
| @Data | |||||
| @EqualsAndHashCode(callSuper = true) | |||||
| @NoArgsConstructor | |||||
| @XStreamAlias("xml") | @XStreamAlias("xml") | ||||
| public class WxEntPayResult extends BaseWxPayResult { | |||||
| /** | |||||
| * 商户appid | |||||
| */ | |||||
| @XStreamAlias("mch_appid") | |||||
| private String mchAppid; | |||||
| /** | |||||
| * 设备号 | |||||
| */ | |||||
| @XStreamAlias("device_info") | |||||
| private String deviceInfo; | |||||
| //############以下字段在return_code 和result_code都为SUCCESS的时候有返回############## | |||||
| /** | |||||
| * 商户订单号 | |||||
| */ | |||||
| @XStreamAlias("partner_trade_no") | |||||
| private String partnerTradeNo; | |||||
| /** | |||||
| * 微信订单号 | |||||
| */ | |||||
| @XStreamAlias("payment_no") | |||||
| private String paymentNo; | |||||
| /** | |||||
| * 微信支付成功时间 | |||||
| */ | |||||
| @XStreamAlias("payment_time") | |||||
| private String paymentTime; | |||||
| @Deprecated | |||||
| public class WxEntPayResult extends EntPayResult { | |||||
| public static WxEntPayResult createFrom(EntPayResult entPayResult) { | |||||
| WxEntPayResult result = new WxEntPayResult(); | |||||
| try { | |||||
| BeanUtils.copyProperties(result, entPayResult); | |||||
| } catch (Exception e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| return result; | |||||
| } | |||||
| } | } | ||||
| @@ -0,0 +1,45 @@ | |||||
| package com.github.binarywang.wxpay.service; | |||||
| import com.github.binarywang.wxpay.bean.entpay.EntPayQueryResult; | |||||
| import com.github.binarywang.wxpay.bean.entpay.EntPayRequest; | |||||
| import com.github.binarywang.wxpay.bean.entpay.EntPayResult; | |||||
| import com.github.binarywang.wxpay.bean.request.WxEntPayRequest; | |||||
| import com.github.binarywang.wxpay.bean.result.WxEntPayQueryResult; | |||||
| import com.github.binarywang.wxpay.bean.result.WxEntPayResult; | |||||
| import com.github.binarywang.wxpay.exception.WxPayException; | |||||
| /** | |||||
| * <pre> | |||||
| * 企业付款相关服务类 | |||||
| * Created by BinaryWang on 2017/12/19. | |||||
| * </pre> | |||||
| * | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| */ | |||||
| public interface EntPaySerivce { | |||||
| /** | |||||
| * <pre> | |||||
| * 企业付款业务是基于微信支付商户平台的资金管理能力,为了协助商户方便地实现企业向个人付款,针对部分有开发能力的商户,提供通过API完成企业付款的功能。 | |||||
| * 比如目前的保险行业向客户退保、给付、理赔。 | |||||
| * 企业付款将使用商户的可用余额,需确保可用余额充足。查看可用余额、充值、提现请登录商户平台“资金管理”https://pay.weixin.qq.com/进行操作。 | |||||
| * 注意:与商户微信支付收款资金并非同一账户,需要单独充值。 | |||||
| * 文档详见:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2 | |||||
| * 接口链接:https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers | |||||
| * </pre> | |||||
| * | |||||
| * @param request 请求对象 | |||||
| */ | |||||
| EntPayResult entPay(EntPayRequest request) throws WxPayException; | |||||
| /** | |||||
| * <pre> | |||||
| * 查询企业付款API | |||||
| * 用于商户的企业付款操作进行结果查询,返回付款操作详细结果。 | |||||
| * 文档详见:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_3 | |||||
| * 接口链接:https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo | |||||
| * </pre> | |||||
| * | |||||
| * @param partnerTradeNo 商户订单号 | |||||
| */ | |||||
| EntPayQueryResult queryEntPay(String partnerTradeNo) throws WxPayException; | |||||
| } | |||||
| @@ -2,6 +2,9 @@ package com.github.binarywang.wxpay.service; | |||||
| import com.github.binarywang.wxpay.bean.WxPayApiData; | import com.github.binarywang.wxpay.bean.WxPayApiData; | ||||
| import com.github.binarywang.wxpay.bean.coupon.*; | import com.github.binarywang.wxpay.bean.coupon.*; | ||||
| import com.github.binarywang.wxpay.bean.entpay.EntPayQueryResult; | |||||
| import com.github.binarywang.wxpay.bean.entpay.EntPayRequest; | |||||
| import com.github.binarywang.wxpay.bean.entpay.EntPayResult; | |||||
| import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; | import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; | ||||
| import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult; | import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult; | ||||
| import com.github.binarywang.wxpay.bean.request.*; | import com.github.binarywang.wxpay.bean.request.*; | ||||
| @@ -15,7 +18,7 @@ import java.util.Map; | |||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| * 微信支付相关接口 | |||||
| * 微信支付相关接口. | |||||
| * Created by Binary Wang on 2016/7/28. | * Created by Binary Wang on 2016/7/28. | ||||
| * </pre> | * </pre> | ||||
| * | * | ||||
| @@ -23,6 +26,41 @@ import java.util.Map; | |||||
| */ | */ | ||||
| public interface WxPayService { | public interface WxPayService { | ||||
| /** | |||||
| * 获取微信支付请求url前缀,沙箱环境可能不一样 | |||||
| */ | |||||
| String getPayBaseUrl(); | |||||
| /** | |||||
| * 发送post请求,得到响应字节数组 | |||||
| * | |||||
| * @param url 请求地址 | |||||
| * @param requestStr 请求信息 | |||||
| * @param useKey 是否使用证书 | |||||
| * @return 返回请求结果字节数组 | |||||
| */ | |||||
| byte[] postForBytes(String url, String requestStr, boolean useKey) throws WxPayException; | |||||
| /** | |||||
| * 发送post请求,得到响应字符串 | |||||
| * | |||||
| * @param url 请求地址 | |||||
| * @param requestStr 请求信息 | |||||
| * @param useKey 是否使用证书 | |||||
| * @return 返回请求结果字符串 | |||||
| */ | |||||
| String post(String url, String requestStr, boolean useKey) throws WxPayException; | |||||
| /** | |||||
| * 获取企业付款服务类 | |||||
| */ | |||||
| EntPaySerivce getEntPaySerivce(); | |||||
| /** | |||||
| * 设置企业付款服务类,允许开发者自定义实现类 | |||||
| */ | |||||
| void setEntPaySerivce(EntPaySerivce entPaySerivce); | |||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| * 查询订单(详见https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2) | * 查询订单(详见https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2) | ||||
| @@ -173,29 +211,15 @@ public interface WxPayService { | |||||
| WxPayRedpackQueryResult queryRedpack(String mchBillNo) throws WxPayException; | WxPayRedpackQueryResult queryRedpack(String mchBillNo) throws WxPayException; | ||||
| /** | /** | ||||
| * <pre> | |||||
| * 企业付款业务是基于微信支付商户平台的资金管理能力,为了协助商户方便地实现企业向个人付款,针对部分有开发能力的商户,提供通过API完成企业付款的功能。 | |||||
| * 比如目前的保险行业向客户退保、给付、理赔。 | |||||
| * 企业付款将使用商户的可用余额,需确保可用余额充足。查看可用余额、充值、提现请登录商户平台“资金管理”https://pay.weixin.qq.com/进行操作。 | |||||
| * 注意:与商户微信支付收款资金并非同一账户,需要单独充值。 | |||||
| * 文档详见:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2 | |||||
| * 接口链接:https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers | |||||
| * </pre> | |||||
| * | |||||
| * @param request 请求对象 | |||||
| * 请使用this.getEntPayService().entPay()方法{@link EntPaySerivce#entPay(EntPayRequest)} | |||||
| */ | */ | ||||
| @Deprecated | |||||
| WxEntPayResult entPay(WxEntPayRequest request) throws WxPayException; | WxEntPayResult entPay(WxEntPayRequest request) throws WxPayException; | ||||
| /** | /** | ||||
| * <pre> | |||||
| * 查询企业付款API | |||||
| * 用于商户的企业付款操作进行结果查询,返回付款操作详细结果。 | |||||
| * 文档详见:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_3 | |||||
| * 接口链接:https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo | |||||
| * </pre> | |||||
| * | |||||
| * @param partnerTradeNo 商户订单号 | |||||
| * 请使用this.getEntPayService().queryEntPay()方法 {@link EntPaySerivce#queryEntPay(String)} | |||||
| */ | */ | ||||
| @Deprecated | |||||
| WxEntPayQueryResult queryEntPay(String partnerTradeNo) throws WxPayException; | WxEntPayQueryResult queryEntPay(String partnerTradeNo) throws WxPayException; | ||||
| /** | /** | ||||
| @@ -3,6 +3,8 @@ package com.github.binarywang.wxpay.service.impl; | |||||
| import com.github.binarywang.utils.qrcode.QrcodeUtils; | import com.github.binarywang.utils.qrcode.QrcodeUtils; | ||||
| import com.github.binarywang.wxpay.bean.WxPayApiData; | import com.github.binarywang.wxpay.bean.WxPayApiData; | ||||
| import com.github.binarywang.wxpay.bean.coupon.*; | import com.github.binarywang.wxpay.bean.coupon.*; | ||||
| import com.github.binarywang.wxpay.bean.entpay.EntPayQueryResult; | |||||
| import com.github.binarywang.wxpay.bean.entpay.EntPayResult; | |||||
| import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; | import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; | ||||
| import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult; | import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult; | ||||
| import com.github.binarywang.wxpay.bean.order.WxPayAppOrderResult; | import com.github.binarywang.wxpay.bean.order.WxPayAppOrderResult; | ||||
| @@ -15,6 +17,7 @@ import com.github.binarywang.wxpay.constant.WxPayConstants.BillType; | |||||
| import com.github.binarywang.wxpay.constant.WxPayConstants.SignType; | import com.github.binarywang.wxpay.constant.WxPayConstants.SignType; | ||||
| import com.github.binarywang.wxpay.constant.WxPayConstants.TradeType; | import com.github.binarywang.wxpay.constant.WxPayConstants.TradeType; | ||||
| import com.github.binarywang.wxpay.exception.WxPayException; | import com.github.binarywang.wxpay.exception.WxPayException; | ||||
| import com.github.binarywang.wxpay.service.EntPaySerivce; | |||||
| import com.github.binarywang.wxpay.service.WxPayService; | import com.github.binarywang.wxpay.service.WxPayService; | ||||
| import com.github.binarywang.wxpay.util.SignUtils; | import com.github.binarywang.wxpay.util.SignUtils; | ||||
| import com.google.common.base.Joiner; | import com.google.common.base.Joiner; | ||||
| @@ -49,8 +52,20 @@ public abstract class BaseWxPayServiceImpl implements WxPayService { | |||||
| protected final Logger log = LoggerFactory.getLogger(this.getClass()); | protected final Logger log = LoggerFactory.getLogger(this.getClass()); | ||||
| protected static ThreadLocal<WxPayApiData> wxApiData = new ThreadLocal<>(); | protected static ThreadLocal<WxPayApiData> wxApiData = new ThreadLocal<>(); | ||||
| private EntPaySerivce entPaySerivce = new EntPayServiceImpl(this); | |||||
| protected WxPayConfig config; | protected WxPayConfig config; | ||||
| @Override | |||||
| public EntPaySerivce getEntPaySerivce() { | |||||
| return entPaySerivce; | |||||
| } | |||||
| @Override | |||||
| public void setEntPaySerivce(EntPaySerivce entPaySerivce) { | |||||
| this.entPaySerivce = entPaySerivce; | |||||
| } | |||||
| @Override | @Override | ||||
| public WxPayConfig getConfig() { | public WxPayConfig getConfig() { | ||||
| return this.config; | return this.config; | ||||
| @@ -61,7 +76,8 @@ public abstract class BaseWxPayServiceImpl implements WxPayService { | |||||
| this.config = config; | this.config = config; | ||||
| } | } | ||||
| private String getPayBaseUrl() { | |||||
| @Override | |||||
| public String getPayBaseUrl() { | |||||
| if (this.getConfig().useSandbox()) { | if (this.getConfig().useSandbox()) { | ||||
| return PAY_BASE_URL + "/sandboxnew"; | return PAY_BASE_URL + "/sandboxnew"; | ||||
| } | } | ||||
| @@ -69,26 +85,6 @@ public abstract class BaseWxPayServiceImpl implements WxPayService { | |||||
| return PAY_BASE_URL; | return PAY_BASE_URL; | ||||
| } | } | ||||
| /** | |||||
| * 发送post请求,得到响应字节数组 | |||||
| * | |||||
| * @param url 请求地址 | |||||
| * @param requestStr 请求信息 | |||||
| * @param useKey 是否使用证书 | |||||
| * @return 返回请求结果字节数组 | |||||
| */ | |||||
| protected abstract byte[] postForBytes(String url, String requestStr, boolean useKey) throws WxPayException; | |||||
| /** | |||||
| * 发送post请求,得到响应字符串 | |||||
| * | |||||
| * @param url 请求地址 | |||||
| * @param requestStr 请求信息 | |||||
| * @param useKey 是否使用证书 | |||||
| * @return 返回请求结果字符串 | |||||
| */ | |||||
| protected abstract String post(String url, String requestStr, boolean useKey) throws WxPayException; | |||||
| @Override | @Override | ||||
| public WxPayRefundResult refund(WxPayRefundRequest request) throws WxPayException { | public WxPayRefundResult refund(WxPayRefundRequest request) throws WxPayException { | ||||
| request.checkAndSign(this.getConfig(), false); | request.checkAndSign(this.getConfig(), false); | ||||
| @@ -352,27 +348,15 @@ public abstract class BaseWxPayServiceImpl implements WxPayService { | |||||
| } | } | ||||
| @Override | @Override | ||||
| @Deprecated | |||||
| public WxEntPayResult entPay(WxEntPayRequest request) throws WxPayException { | public WxEntPayResult entPay(WxEntPayRequest request) throws WxPayException { | ||||
| request.checkAndSign(this.getConfig(), false); | |||||
| String url = this.getPayBaseUrl() + "/mmpaymkttransfers/promotion/transfers"; | |||||
| String responseContent = this.post(url, request.toXML(), true); | |||||
| WxEntPayResult result = BaseWxPayResult.fromXML(responseContent, WxEntPayResult.class); | |||||
| result.checkResult(this, request.getSignType(), true); | |||||
| return result; | |||||
| return WxEntPayResult.createFrom(this.getEntPaySerivce().entPay(request)); | |||||
| } | } | ||||
| @Override | @Override | ||||
| @Deprecated | |||||
| public WxEntPayQueryResult queryEntPay(String partnerTradeNo) throws WxPayException { | public WxEntPayQueryResult queryEntPay(String partnerTradeNo) throws WxPayException { | ||||
| WxEntPayQueryRequest request = new WxEntPayQueryRequest(); | |||||
| request.setPartnerTradeNo(partnerTradeNo); | |||||
| request.checkAndSign(this.getConfig(), false); | |||||
| String url = this.getPayBaseUrl() + "/mmpaymkttransfers/gettransferinfo"; | |||||
| String responseContent = this.post(url, request.toXML(), true); | |||||
| WxEntPayQueryResult result = BaseWxPayResult.fromXML(responseContent, WxEntPayQueryResult.class); | |||||
| result.checkResult(this, request.getSignType(), true); | |||||
| return result; | |||||
| return WxEntPayQueryResult.createFrom(this.getEntPaySerivce().queryEntPay(partnerTradeNo)); | |||||
| } | } | ||||
| @Override | @Override | ||||
| @@ -0,0 +1,50 @@ | |||||
| package com.github.binarywang.wxpay.service.impl; | |||||
| import com.github.binarywang.wxpay.bean.entpay.EntPayQueryRequest; | |||||
| import com.github.binarywang.wxpay.bean.entpay.EntPayQueryResult; | |||||
| import com.github.binarywang.wxpay.bean.entpay.EntPayRequest; | |||||
| import com.github.binarywang.wxpay.bean.entpay.EntPayResult; | |||||
| import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; | |||||
| import com.github.binarywang.wxpay.exception.WxPayException; | |||||
| import com.github.binarywang.wxpay.service.EntPaySerivce; | |||||
| import com.github.binarywang.wxpay.service.WxPayService; | |||||
| /** | |||||
| * <pre> | |||||
| * Created by BinaryWang on 2017/12/19. | |||||
| * </pre> | |||||
| * | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| */ | |||||
| public class EntPayServiceImpl implements EntPaySerivce { | |||||
| private WxPayService payService; | |||||
| public EntPayServiceImpl(WxPayService payService) { | |||||
| this.payService = payService; | |||||
| } | |||||
| @Override | |||||
| public EntPayResult entPay(EntPayRequest request) throws WxPayException { | |||||
| request.checkAndSign(this.payService.getConfig(), false); | |||||
| String url = this.payService.getPayBaseUrl() + "/mmpaymkttransfers/promotion/transfers"; | |||||
| String responseContent = this.payService.post(url, request.toXML(), true); | |||||
| EntPayResult result = BaseWxPayResult.fromXML(responseContent, EntPayResult.class); | |||||
| result.checkResult(this.payService, request.getSignType(), true); | |||||
| return result; | |||||
| } | |||||
| @Override | |||||
| public EntPayQueryResult queryEntPay(String partnerTradeNo) throws WxPayException { | |||||
| EntPayQueryRequest request = new EntPayQueryRequest(); | |||||
| request.setPartnerTradeNo(partnerTradeNo); | |||||
| request.checkAndSign(this.payService.getConfig(), false); | |||||
| String url = this.payService.getPayBaseUrl() + "/mmpaymkttransfers/gettransferinfo"; | |||||
| String responseContent = this.payService.post(url, request.toXML(), true); | |||||
| EntPayQueryResult result = BaseWxPayResult.fromXML(responseContent, EntPayQueryResult.class); | |||||
| result.checkResult(this.payService, request.getSignType(), true); | |||||
| return result; | |||||
| } | |||||
| } | |||||
| @@ -32,9 +32,8 @@ import java.nio.charset.StandardCharsets; | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||
| */ | */ | ||||
| public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl { | public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl { | ||||
| @Override | @Override | ||||
| protected byte[] postForBytes(String url, String requestStr, boolean useKey) throws WxPayException { | |||||
| public byte[] postForBytes(String url, String requestStr, boolean useKey) throws WxPayException { | |||||
| try { | try { | ||||
| HttpClientBuilder httpClientBuilder = createHttpClientBuilder(useKey); | HttpClientBuilder httpClientBuilder = createHttpClientBuilder(useKey); | ||||
| HttpPost httpPost = this.createHttpPost(url, requestStr); | HttpPost httpPost = this.createHttpPost(url, requestStr); | ||||
| @@ -57,7 +56,7 @@ public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl { | |||||
| } | } | ||||
| @Override | @Override | ||||
| protected String post(String url, String requestStr, boolean useKey) throws WxPayException { | |||||
| public String post(String url, String requestStr, boolean useKey) throws WxPayException { | |||||
| try { | try { | ||||
| HttpClientBuilder httpClientBuilder = this.createHttpClientBuilder(useKey); | HttpClientBuilder httpClientBuilder = this.createHttpClientBuilder(useKey); | ||||
| HttpPost httpPost = this.createHttpPost(url, requestStr); | HttpPost httpPost = this.createHttpPost(url, requestStr); | ||||
| @@ -22,9 +22,8 @@ import java.nio.charset.StandardCharsets; | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||
| */ | */ | ||||
| public class WxPayServiceJoddHttpImpl extends BaseWxPayServiceImpl { | public class WxPayServiceJoddHttpImpl extends BaseWxPayServiceImpl { | ||||
| @Override | @Override | ||||
| protected byte[] postForBytes(String url, String requestStr, boolean useKey) throws WxPayException { | |||||
| public byte[] postForBytes(String url, String requestStr, boolean useKey) throws WxPayException { | |||||
| try { | try { | ||||
| HttpRequest request = this.buildHttpRequest(url, requestStr, useKey); | HttpRequest request = this.buildHttpRequest(url, requestStr, useKey); | ||||
| byte[] responseBytes = request.send().bodyBytes(); | byte[] responseBytes = request.send().bodyBytes(); | ||||
| @@ -40,7 +39,7 @@ public class WxPayServiceJoddHttpImpl extends BaseWxPayServiceImpl { | |||||
| } | } | ||||
| @Override | @Override | ||||
| protected String post(String url, String requestStr, boolean useKey) throws WxPayException { | |||||
| public String post(String url, String requestStr, boolean useKey) throws WxPayException { | |||||
| try { | try { | ||||
| HttpRequest request = this.buildHttpRequest(url, requestStr, useKey); | HttpRequest request = this.buildHttpRequest(url, requestStr, useKey); | ||||
| String responseString = this.getResponseString(request.send()); | String responseString = this.getResponseString(request.send()); | ||||
| @@ -1,7 +1,11 @@ | |||||
| package com.github.binarywang.wxpay.util; | package com.github.binarywang.wxpay.util; | ||||
| import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest; | |||||
| import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; | |||||
| import com.github.binarywang.wxpay.constant.WxPayConstants.SignType; | import com.github.binarywang.wxpay.constant.WxPayConstants.SignType; | ||||
| import com.google.common.collect.Lists; | import com.google.common.collect.Lists; | ||||
| import com.google.common.collect.Maps; | |||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
| import me.chanjar.weixin.common.util.BeanUtils; | import me.chanjar.weixin.common.util.BeanUtils; | ||||
| import org.apache.commons.codec.binary.Hex; | import org.apache.commons.codec.binary.Hex; | ||||
| import org.apache.commons.codec.digest.DigestUtils; | import org.apache.commons.codec.digest.DigestUtils; | ||||
| @@ -11,11 +15,11 @@ import org.slf4j.LoggerFactory; | |||||
| import javax.crypto.Mac; | import javax.crypto.Mac; | ||||
| import javax.crypto.spec.SecretKeySpec; | import javax.crypto.spec.SecretKeySpec; | ||||
| import java.lang.reflect.Field; | |||||
| import java.lang.reflect.Modifier; | |||||
| import java.security.InvalidKeyException; | import java.security.InvalidKeyException; | ||||
| import java.security.NoSuchAlgorithmException; | import java.security.NoSuchAlgorithmException; | ||||
| import java.util.Map; | |||||
| import java.util.SortedMap; | |||||
| import java.util.TreeMap; | |||||
| import java.util.*; | |||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| @@ -33,7 +37,7 @@ public class SignUtils { | |||||
| */ | */ | ||||
| @Deprecated | @Deprecated | ||||
| public static String createSign(Object xmlBean, String signKey) { | public static String createSign(Object xmlBean, String signKey) { | ||||
| return createSign(BeanUtils.xmlBean2Map(xmlBean), signKey); | |||||
| return createSign(xmlBean2Map(xmlBean), signKey); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -54,7 +58,7 @@ public class SignUtils { | |||||
| * @return 签名字符串 | * @return 签名字符串 | ||||
| */ | */ | ||||
| public static String createSign(Object xmlBean, String signType, String signKey, boolean isIgnoreSignType) { | public static String createSign(Object xmlBean, String signType, String signKey, boolean isIgnoreSignType) { | ||||
| return createSign(BeanUtils.xmlBean2Map(xmlBean), signType, signKey, isIgnoreSignType); | |||||
| return createSign(xmlBean2Map(xmlBean), signType, signKey, isIgnoreSignType); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -116,7 +120,7 @@ public class SignUtils { | |||||
| * @return true - 签名校验成功,false - 签名校验失败 | * @return true - 签名校验成功,false - 签名校验失败 | ||||
| */ | */ | ||||
| public static boolean checkSign(Object xmlBean, String signType, String signKey) { | public static boolean checkSign(Object xmlBean, String signType, String signKey) { | ||||
| return checkSign(BeanUtils.xmlBean2Map(xmlBean), signType, signKey); | |||||
| return checkSign(xmlBean2Map(xmlBean), signType, signKey); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -131,4 +135,48 @@ public class SignUtils { | |||||
| String sign = createSign(params, signType, signKey, false); | String sign = createSign(params, signType, signKey, false); | ||||
| return sign.equals(params.get("sign")); | return sign.equals(params.get("sign")); | ||||
| } | } | ||||
| /** | |||||
| * 将bean按照@XStreamAlias标识的字符串内容生成以之为key的map对象 | |||||
| * | |||||
| * @param bean 包含@XStreamAlias的xml bean对象 | |||||
| * @return map对象 | |||||
| */ | |||||
| public static Map<String, String> xmlBean2Map(Object bean) { | |||||
| Map<String, String> result = Maps.newHashMap(); | |||||
| List<Field> fields = new ArrayList<>(Arrays.asList(bean.getClass().getDeclaredFields())); | |||||
| fields.addAll(Arrays.asList(bean.getClass().getSuperclass().getDeclaredFields())); | |||||
| if(bean.getClass().getSuperclass().getSuperclass() == BaseWxPayRequest.class){ | |||||
| fields.addAll(Arrays.asList(BaseWxPayRequest.class.getDeclaredFields())); | |||||
| } | |||||
| if(bean.getClass().getSuperclass().getSuperclass() == BaseWxPayResult.class){ | |||||
| fields.addAll(Arrays.asList(BaseWxPayResult.class.getDeclaredFields())); | |||||
| } | |||||
| for (Field field : fields) { | |||||
| try { | |||||
| boolean isAccessible = field.isAccessible(); | |||||
| field.setAccessible(true); | |||||
| if (field.get(bean) == null) { | |||||
| field.setAccessible(isAccessible); | |||||
| continue; | |||||
| } | |||||
| if (field.isAnnotationPresent(XStreamAlias.class)) { | |||||
| result.put(field.getAnnotation(XStreamAlias.class).value(), field.get(bean).toString()); | |||||
| } else if (!Modifier.isStatic(field.getModifiers())) { | |||||
| //忽略掉静态成员变量 | |||||
| result.put(field.getName(), field.get(bean).toString()); | |||||
| } | |||||
| field.setAccessible(isAccessible); | |||||
| } catch (SecurityException | IllegalArgumentException | IllegalAccessException e) { | |||||
| log.error(e.getMessage(), e); | |||||
| } | |||||
| } | |||||
| return result; | |||||
| } | |||||
| } | } | ||||
| @@ -245,31 +245,6 @@ public class BaseWxPayServiceImplTest { | |||||
| this.logger.info(redpackResult.toString()); | this.logger.info(redpackResult.toString()); | ||||
| } | } | ||||
| /** | |||||
| * Test method for {@link WxPayService#entPay(WxEntPayRequest)}. | |||||
| */ | |||||
| @Test | |||||
| public void testEntPay() throws WxPayException { | |||||
| WxEntPayRequest request = WxEntPayRequest.newBuilder() | |||||
| .partnerTradeNo("Eb6Aep7uVTdbkJqrP4") | |||||
| .openid("ojOQA0y9o-Eb6Aep7uVTdbkJqrP4") | |||||
| .amount(1) | |||||
| .spbillCreateIp("10.10.10.10") | |||||
| .checkName(CheckNameOption.NO_CHECK) | |||||
| .description("描述信息") | |||||
| .build(); | |||||
| this.logger.info(this.payService.entPay(request).toString()); | |||||
| } | |||||
| /** | |||||
| * Test method for {@link WxPayService#queryEntPay(String)}. | |||||
| */ | |||||
| @Test | |||||
| public void testQueryEntPay() throws WxPayException { | |||||
| this.logger.info(this.payService.queryEntPay("11212121").toString()); | |||||
| } | |||||
| @Test | @Test | ||||
| public void testCreateScanPayQrcodeMode1() throws Exception { | public void testCreateScanPayQrcodeMode1() throws Exception { | ||||
| String productId = "abc"; | String productId = "abc"; | ||||
| @@ -0,0 +1,66 @@ | |||||
| package com.github.binarywang.wxpay.service.impl; | |||||
| import com.github.binarywang.wxpay.bean.entpay.EntPayRequest; | |||||
| import com.github.binarywang.wxpay.bean.request.WxEntPayRequest; | |||||
| import com.github.binarywang.wxpay.constant.WxPayConstants; | |||||
| import com.github.binarywang.wxpay.exception.WxPayException; | |||||
| import com.github.binarywang.wxpay.service.WxPayService; | |||||
| import com.github.binarywang.wxpay.testbase.ApiTestModule; | |||||
| import com.google.inject.Inject; | |||||
| import org.slf4j.Logger; | |||||
| import org.slf4j.LoggerFactory; | |||||
| import org.testng.annotations.Guice; | |||||
| import org.testng.annotations.Test; | |||||
| /** | |||||
| * <pre> | |||||
| * 企业付款测试类 | |||||
| * Created by BinaryWang on 2017/12/19. | |||||
| * </pre> | |||||
| * | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| */ | |||||
| @Test | |||||
| @Guice(modules = ApiTestModule.class) | |||||
| public class EntPayServiceImplTest { | |||||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||||
| @Inject | |||||
| private WxPayService payService; | |||||
| @Test | |||||
| public void testEntPay_old() throws WxPayException { | |||||
| this.logger.info(this.payService.entPay(WxEntPayRequest.builder() | |||||
| .partnerTradeNo("Eb6Aep7uVTdbkJqrP4") | |||||
| .openid("ojOQA0y9o-Eb6Aep7uVTdbkJqrP4") | |||||
| .amount(1) | |||||
| .spbillCreateIp("10.10.10.10") | |||||
| .checkName(WxPayConstants.CheckNameOption.NO_CHECK) | |||||
| .description("描述信息") | |||||
| .build()).toString()); | |||||
| } | |||||
| @Test | |||||
| public void testEntPay() throws WxPayException { | |||||
| EntPayRequest request = EntPayRequest.newBuilder() | |||||
| .partnerTradeNo("Eb6Aep7uVTdbkJqrP4") | |||||
| .openid("ojOQA0y9o-Eb6Aep7uVTdbkJqrP4") | |||||
| .amount(1) | |||||
| .spbillCreateIp("10.10.10.10") | |||||
| .checkName(WxPayConstants.CheckNameOption.NO_CHECK) | |||||
| .description("描述信息") | |||||
| .build(); | |||||
| this.logger.info(this.payService.getEntPaySerivce().entPay(request).toString()); | |||||
| } | |||||
| @Test | |||||
| public void testQueryEntPay_old() throws WxPayException { | |||||
| this.logger.info(this.payService.queryEntPay("11212121").toString()); | |||||
| } | |||||
| @Test | |||||
| public void testQueryEntPay() throws WxPayException { | |||||
| this.logger.info(this.payService.getEntPaySerivce().queryEntPay("11212121").toString()); | |||||
| } | |||||
| } | |||||