diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java index 8935bc32..7c3db11f 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java @@ -1,18 +1,22 @@ package me.chanjar.weixin.common.util; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.thoughtworks.xstream.annotations.XStreamAlias; + import me.chanjar.weixin.common.annotation.Required; import me.chanjar.weixin.common.bean.result.WxError; import me.chanjar.weixin.common.exception.WxErrorException; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - /** *
* bean操作的一些工具类 @@ -21,6 +25,7 @@ import java.util.Map; **/ public class BeanUtils { + private static Logger log = LoggerFactory.getLogger(BeanUtils.class); /** * 检查bean里标记为@Required的field是否为空,为空则抛异常 @@ -48,41 +53,42 @@ public class BeanUtils { } if (!nullFields.isEmpty()) { - throw new WxErrorException(WxError.newBuilder().setErrorMsg("必填字段 " + nullFields + " 必须提供值").build()); + String msg = "必填字段 " + nullFields + " 必须提供值"; + log.debug(msg); + throw new WxErrorException(WxError.newBuilder().setErrorMsg(msg).build()); } } - /** - * 将bean按照@XStreamAlias标识的字符串内容生成以之为key的map对象 - * @param bean 包含@XStreamAlias的xml bean对象 - * @return map对象 - */ - public static Map
+ * JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付 + *+ * @since 2.5.0 + * @return + */ + String getTradeType(); String getToken(); @@ -112,4 +130,5 @@ public interface WxMpConfigStorage { * 是否自动刷新token */ boolean autoRefreshToken(); + } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java index e874e793..61b75fbb 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java @@ -20,6 +20,8 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { protected volatile String secret; protected volatile String partnerId; protected volatile String partnerKey; + protected volatile String notifyURL; + protected volatile String tradeType; protected volatile String token; protected volatile String accessToken; protected volatile String aesKey; @@ -267,8 +269,25 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { public void setPartnerKey(String partnerKey) { this.partnerKey = partnerKey; } + + + public String getNotifyURL() { + return notifyURL; + } - @Override + public void setNotifyURL(String notifyURL) { + this.notifyURL = notifyURL; + } + + public String getTradeType() { + return tradeType; + } + + public void setTradeType(String tradeType) { + this.tradeType = tradeType; + } + + @Override public File getTmpDirFile() { return this.tmpDirFile; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpPayService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpPayService.java index e1396afb..afe888f8 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpPayService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpPayService.java @@ -1,7 +1,6 @@ package me.chanjar.weixin.mp.api; import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.mp.bean.pay.WxPayJsSDKCallback; import me.chanjar.weixin.mp.bean.pay.request.WxEntPayRequest; import me.chanjar.weixin.mp.bean.pay.request.WxPayRefundRequest; import me.chanjar.weixin.mp.bean.pay.request.WxPaySendRedpackRequest; @@ -31,9 +30,8 @@ public interface WxMpPayService { * 接口地址:https://api.mch.weixin.qq.com/pay/orderquery * * - * @param transactionId 微信支付分配的商户号 + * @param transactionId 微信订单号 * @param outTradeNo 商户系统内部的订单号,当没提供transaction_id时需要传这个。 - * @throws WxErrorException */ WxPayOrderQueryResult queryOrder(String transactionId, String outTradeNo) throws WxErrorException; @@ -50,7 +48,6 @@ public interface WxMpPayService { * * * @param outTradeNo 商户系统内部的订单号,当没提供transaction_id时需要传这个。 - * @throws WxErrorException */ WxPayOrderCloseResult closeOrder(String outTradeNo) throws WxErrorException; @@ -60,7 +57,6 @@ public interface WxMpPayService { * 接口地址:https://api.mch.weixin.qq.com/pay/unifiedorder * * @param request 请求对象,注意一些参数如appid、mchid等不用设置,方法内会自动从配置对象中获取到(前提是对应配置中已经设置) - * @throws WxErrorException */ WxPayUnifiedOrderResult unifiedOrder(WxPayUnifiedOrderRequest request) throws WxErrorException; @@ -69,7 +65,6 @@ public interface WxMpPayService { * 详见http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN * * @param request 请求对象,注意一些参数如appid、mchid等不用设置,方法内会自动从配置对象中获取到(前提是对应配置中已经设置) - * @throws WxErrorException */ Map
- * 计算Map键值对是否和签名相符, - * 按照字段名的 ASCII 码从小到大排序(字典序)后,使用 URL 键值对的 格式(即 key1=value1&key2=value2...)拼接成字符串 - *+ * 微信公众号支付签名算法(详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3) + * + * @param xmlbean Bean需要标记有XML注解,默认使用配置中的PartnerKey进行签名 + * @return 签名字符串 + * @see #createSign(Map, String) + * @since 2.5.0 */ - boolean checkJSSDKCallbackDataSignature(Map
- * 订单支付状态回调
- * 支付结果通知(详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7)
- * /pre>
- *
- * @author ukid
- */
-public class WxPayJsSDKCallback implements Serializable {
- private static final long serialVersionUID = -4143804055690843641L;
- private String return_code;
- private String return_msg;
-
- private String appid;
- private String mch_id;
- private String device_info;
- private String nonce_str;
- private String sign;
- private String result_code;
- private String err_code;
- private String err_code_des;
- private String openid;
- private String is_subscribe;
- private String trade_type;
- private String bank_type;
- private String total_fee;
- private String fee_type;
- private String cash_fee;
- private String cash_fee_type;
- private String coupon_fee;
- private String coupon_count;
- private String coupon_batch_id_$n;
- private String coupon_id_$n;
- private String coupon_fee_$n;
- private String transaction_id;
- private String out_trade_no;
- private String attach;
- private String time_end;
-
- public String getReturn_code() {
- return this.return_code;
- }
-
- public void setReturn_code(String return_code) {
- this.return_code = return_code;
- }
-
- public String getReturn_msg() {
- return this.return_msg;
- }
-
- public void setReturn_msg(String return_msg) {
- this.return_msg = return_msg;
- }
-
- public String getAppid() {
- return this.appid;
- }
-
- public void setAppid(String appid) {
- this.appid = appid;
- }
-
- public String getMch_id() {
- return this.mch_id;
- }
-
- public void setMch_id(String mch_id) {
- this.mch_id = mch_id;
- }
-
- public String getDevice_info() {
- return this.device_info;
- }
-
- public void setDevice_info(String device_info) {
- this.device_info = device_info;
- }
-
- public String getNonce_str() {
- return this.nonce_str;
- }
-
- public void setNonce_str(String nonce_str) {
- this.nonce_str = nonce_str;
- }
-
- public String getSign() {
- return this.sign;
- }
-
- public void setSign(String sign) {
- this.sign = sign;
- }
-
- public String getResult_code() {
- return this.result_code;
- }
-
- public void setResult_code(String result_code) {
- this.result_code = result_code;
- }
-
- public String getErr_code() {
- return this.err_code;
- }
-
- public void setErr_code(String err_code) {
- this.err_code = err_code;
- }
-
- public String getErr_code_des() {
- return this.err_code_des;
- }
-
- public void setErr_code_des(String err_code_des) {
- this.err_code_des = err_code_des;
- }
-
- public String getOpenid() {
- return this.openid;
- }
-
- public void setOpenid(String openid) {
- this.openid = openid;
- }
-
- public String getIs_subscribe() {
- return this.is_subscribe;
- }
-
- public void setIs_subscribe(String is_subscribe) {
- this.is_subscribe = is_subscribe;
- }
-
- public String getTrade_type() {
- return this.trade_type;
- }
-
- public void setTrade_type(String trade_type) {
- this.trade_type = trade_type;
- }
-
- public String getBank_type() {
- return this.bank_type;
- }
-
- public void setBank_type(String bank_type) {
- this.bank_type = bank_type;
- }
-
- public String getTotal_fee() {
- return this.total_fee;
- }
-
- public void setTotal_fee(String total_fee) {
- this.total_fee = total_fee;
- }
-
- public String getFee_type() {
- return this.fee_type;
- }
-
- public void setFee_type(String fee_type) {
- this.fee_type = fee_type;
- }
-
- public String getCash_fee() {
- return this.cash_fee;
- }
-
- public void setCash_fee(String cash_fee) {
- this.cash_fee = cash_fee;
- }
-
- public String getCash_fee_type() {
- return this.cash_fee_type;
- }
-
- public void setCash_fee_type(String cash_fee_type) {
- this.cash_fee_type = cash_fee_type;
- }
-
- public String getCoupon_fee() {
- return this.coupon_fee;
- }
-
- public void setCoupon_fee(String coupon_fee) {
- this.coupon_fee = coupon_fee;
- }
-
- public String getCoupon_count() {
- return this.coupon_count;
- }
-
- public void setCoupon_count(String coupon_count) {
- this.coupon_count = coupon_count;
- }
-
- public String getCoupon_batch_id_$n() {
- return this.coupon_batch_id_$n;
- }
-
- public void setCoupon_batch_id_$n(String coupon_batch_id_$n) {
- this.coupon_batch_id_$n = coupon_batch_id_$n;
- }
-
- public String getCoupon_id_$n() {
- return this.coupon_id_$n;
- }
-
- public void setCoupon_id_$n(String coupon_id_$n) {
- this.coupon_id_$n = coupon_id_$n;
- }
-
- public String getCoupon_fee_$n() {
- return this.coupon_fee_$n;
- }
-
- public void setCoupon_fee_$n(String coupon_fee_$n) {
- this.coupon_fee_$n = coupon_fee_$n;
- }
-
- public String getTransaction_id() {
- return this.transaction_id;
- }
-
- public void setTransaction_id(String transaction_id) {
- this.transaction_id = transaction_id;
- }
-
- public String getOut_trade_no() {
- return this.out_trade_no;
- }
-
- public void setOut_trade_no(String out_trade_no) {
- this.out_trade_no = out_trade_no;
- }
-
- public String getAttach() {
- return this.attach;
- }
-
- public void setAttach(String attach) {
- this.attach = attach;
- }
-
- public String getTime_end() {
- return this.time_end;
- }
-
- public void setTime_end(String time_end) {
- this.time_end = time_end;
- }
-
- @Override
- public String toString() {
- return ToStringUtils.toSimpleString(this);
- }
-
-}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyCoupon.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyCoupon.java
new file mode 100644
index 00000000..60b3f688
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyCoupon.java
@@ -0,0 +1,64 @@
+package me.chanjar.weixin.mp.bean.pay;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+
+/**
+ * 支付异步通知代金券详细
+ */
+public class WxPayOrderNotifyCoupon implements Serializable {
+ /**
+ * @fields serialVersionUID
+ */
+ private static final long serialVersionUID = -4165343733538156097L;
+
+ @XStreamAlias("coupon_id")
+ private String couponId;
+ @XStreamAlias("coupon_type")
+ private String couponType;
+ @XStreamAlias("coupon_fee")
+ private Integer couponFee;
+
+ public String getCouponId() {
+ return couponId;
+ }
+
+ public void setCouponId(String couponId) {
+ this.couponId = couponId;
+ }
+
+ public String getCouponType() {
+ return couponType;
+ }
+
+ public void setCouponType(String couponType) {
+ this.couponType = couponType;
+ }
+
+ public Integer getCouponFee() {
+ return couponFee;
+ }
+
+ public void setCouponFee(Integer couponFee) {
+ this.couponFee = couponFee;
+ }
+
+ public Map toMap(int index) {
+ Map map = new HashMap<>();
+ map.put("coupon_id_" + index, this.getCouponId());
+ map.put("coupon_type_" + index, this.getCouponType());
+ map.put("coupon_fee_" + index, this.getCouponFee() + "");
+ return map;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResponse.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResponse.java
new file mode 100644
index 00000000..a1313ea0
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResponse.java
@@ -0,0 +1,60 @@
+package me.chanjar.weixin.mp.bean.pay;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamOmitField;
+
+import me.chanjar.weixin.common.util.xml.XStreamInitializer;
+
+@XStreamAlias("xml")
+public class WxPayOrderNotifyResponse {
+ @XStreamOmitField
+ private transient static final String FAIL = "FAIL";
+ @XStreamOmitField
+ private transient static final String SUCCESS = "SUCCESS";
+
+ @XStreamAlias("return_code")
+ private String returnCode;
+ @XStreamAlias("return_msg")
+ private String returnMsg;
+
+ public String getReturnCode() {
+ return returnCode;
+ }
+
+ public void setReturnCode(String returnCode) {
+ this.returnCode = returnCode;
+ }
+
+ public String getReturnMsg() {
+ return returnMsg;
+ }
+
+ public void setReturnMsg(String returnMsg) {
+ this.returnMsg = returnMsg;
+ }
+
+ public WxPayOrderNotifyResponse() {
+ super();
+ }
+
+ public WxPayOrderNotifyResponse(String returnCode, String returnMsg) {
+ super();
+ this.returnCode = returnCode;
+ this.returnMsg = returnMsg;
+ }
+
+ public static String fail(String msg) {
+ WxPayOrderNotifyResponse response = new WxPayOrderNotifyResponse(FAIL, msg);
+ XStream xstream = XStreamInitializer.getInstance();
+ xstream.autodetectAnnotations(true);
+ return xstream.toXML(response);
+ }
+
+ public static String success(String msg) {
+ WxPayOrderNotifyResponse response = new WxPayOrderNotifyResponse(SUCCESS, msg);
+ XStream xstream = XStreamInitializer.getInstance();
+ xstream.autodetectAnnotations(true);
+ return xstream.toXML(response);
+ }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResultConverter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResultConverter.java
new file mode 100644
index 00000000..bdd440b9
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResultConverter.java
@@ -0,0 +1,130 @@
+package me.chanjar.weixin.mp.bean.pay;
+
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Maps;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.converters.MarshallingContext;
+import com.thoughtworks.xstream.converters.UnmarshallingContext;
+import com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter;
+import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+import com.thoughtworks.xstream.mapper.Mapper;
+
+import me.chanjar.weixin.mp.bean.pay.result.WxPayOrderNotifyResult;
+
+public class WxPayOrderNotifyResultConverter extends AbstractReflectionConverter {
+
+ public WxPayOrderNotifyResultConverter(Mapper mapper, ReflectionProvider reflectionProvider) {
+ super(mapper, reflectionProvider);
+ }
+
+ @Override
+ @SuppressWarnings("rawtypes")
+ public boolean canConvert(Class type) {
+ return type.equals(WxPayOrderNotifyResult.class);
+ }
+
+ @Override
+ public void marshal(Object original, HierarchicalStreamWriter writer, MarshallingContext context) {
+ super.marshal(original, writer, context);
+ WxPayOrderNotifyResult obj = (WxPayOrderNotifyResult) original;
+ List list = obj.getCouponList();
+ if (list == null || list.size() == 0) {
+ return;
+ }
+ for (int i = 0; i < list.size(); i++) {
+ WxPayOrderNotifyCoupon coupon = list.get(i);
+ writer.startNode("coupon_id_" + i);
+ writer.setValue(coupon.getCouponId());
+ writer.endNode();
+ writer.startNode("coupon_type_" + i);
+ writer.setValue(coupon.getCouponType());
+ writer.endNode();
+ writer.startNode("coupon_fee_" + i);
+ writer.setValue(coupon.getCouponFee() + "");
+ writer.endNode();
+ }
+ }
+
+ @Override
+ protected void marshallField(MarshallingContext context, Object newObj, Field field) {
+ if (field.getName().equals("couponList")) {
+ return;
+ } else {
+ super.marshallField(context, newObj, field);
+ }
+ }
+
+ @Override
+ public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
+ WxPayOrderNotifyResult obj = new WxPayOrderNotifyResult();
+
+ List fields = new ArrayList<>(Arrays.asList(obj.getClass().getDeclaredFields()));
+ fields.addAll(Arrays.asList(obj.getClass().getSuperclass().getDeclaredFields()));
+ Map fieldMap = getFieldMap(fields);
+
+ List coupons = new ArrayList<>(10);
+ while (reader.hasMoreChildren()) {
+ reader.moveDown();
+ if (fieldMap.containsKey(reader.getNodeName())) {
+ Field field = fieldMap.get(reader.getNodeName());
+ setFieldValue(context, obj, field);
+ } else if (StringUtils.startsWith(reader.getNodeName(), "coupon_id_")) {
+ String id = (String) context.convertAnother(obj, String.class);
+ getIndex(coupons, reader.getNodeName()).setCouponId(id);
+ } else if (StringUtils.startsWith(reader.getNodeName(), "coupon_type_")) {
+ String type = (String) context.convertAnother(obj, String.class);
+ getIndex(coupons, reader.getNodeName()).setCouponType(type);
+ } else if (StringUtils.startsWith(reader.getNodeName(), "coupon_fee_")) {
+ Integer fee = (Integer) context.convertAnother(obj, Integer.class);
+ getIndex(coupons, reader.getNodeName()).setCouponFee(fee);
+ }
+ reader.moveUp();
+ }
+
+ obj.setCouponList(coupons);
+ return obj;
+ }
+
+ private void setFieldValue(UnmarshallingContext context, WxPayOrderNotifyResult obj, Field field) {
+ Object val = context.convertAnother(obj, field.getType());
+ try {
+ if (val != null) {
+ PropertyDescriptor pd = new PropertyDescriptor(field.getName(), obj.getClass());
+ pd.getWriteMethod().invoke(obj, val);
+ }
+ } catch (Exception e) {
+ }
+ }
+
+ private Map getFieldMap(List fields) {
+ Map fieldMap = Maps.uniqueIndex(fields, new Function() {
+ @Override
+ public String apply(Field field) {
+ if (field.isAnnotationPresent(XStreamAlias.class)) {
+ return field.getAnnotation(XStreamAlias.class).value();
+ }
+ return field.getName();
+ }
+ });
+ return fieldMap;
+ }
+
+ private WxPayOrderNotifyCoupon getIndex(List coupons, String nodeName) {
+ Integer index = Integer.valueOf(StringUtils.substring(nodeName, nodeName.lastIndexOf("_") + 1));
+ if (index >= coupons.size() || coupons.get(index) == null) {
+ coupons.add(index, new WxPayOrderNotifyCoupon());
+ }
+ return coupons.get(index);
+ }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxEntPayQueryRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxEntPayQueryRequest.java
index 5982d3ee..df2de905 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxEntPayQueryRequest.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxEntPayQueryRequest.java
@@ -30,7 +30,6 @@ public class WxEntPayQueryRequest extends WxPayBaseRequest {
* 微信支付分配的商户号
*
*/
- @SuppressWarnings("hiding")
@XStreamAlias("mchid")
private String mchId;
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayBaseRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayBaseRequest.java
index 341c3b2e..d6926d0e 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayBaseRequest.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayBaseRequest.java
@@ -1,5 +1,7 @@
package me.chanjar.weixin.mp.bean.pay.request;
+import java.math.BigDecimal;
+
import com.thoughtworks.xstream.annotations.XStreamAlias;
import me.chanjar.weixin.common.util.ToStringUtils;
@@ -71,6 +73,10 @@ public abstract class WxPayBaseRequest {
return this.appid;
}
+ /**
+ * 如果配置中已经设置,可以不设置值
+ * @param appid
+ */
public void setAppid(String appid) {
this.appid = appid;
}
@@ -79,6 +85,10 @@ public abstract class WxPayBaseRequest {
return this.mchId;
}
+ /**
+ * 如果配置中已经设置,可以不设置值
+ * @param mchId
+ */
public void setMchId(String mchId) {
this.mchId = mchId;
}
@@ -87,6 +97,10 @@ public abstract class WxPayBaseRequest {
return this.nonceStr;
}
+ /**
+ * 默认采用时间戳为随机字符串,可以不设置
+ * @param nonceStr
+ */
public void setNonceStr(String nonceStr) {
this.nonceStr = nonceStr;
}
@@ -98,6 +112,16 @@ public abstract class WxPayBaseRequest {
public void setSign(String sign) {
this.sign = sign;
}
+
+ /**
+ * 将单位为元转换为单位为分
+ *
+ * @param yuan
+ * @return
+ */
+ public static Integer yuanToFee(String yuan) {
+ return new BigDecimal(yuan).setScale(2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).intValue();
+ }
@Override
public String toString() {
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayUnifiedOrderRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayUnifiedOrderRequest.java
index 195e13b0..cf4c008f 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayUnifiedOrderRequest.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayUnifiedOrderRequest.java
@@ -360,6 +360,10 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest {
return this.notifyURL;
}
+ /**
+ * 如果配置中已经设置,可以不设置值
+ * @param notifyURL
+ */
public void setNotifyURL(String notifyURL) {
this.notifyURL = notifyURL;
}
@@ -368,6 +372,10 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest {
return this.tradeType;
}
+ /**
+ * 如果配置中已经设置,可以不设置值
+ * @param tradeType 交易类型
+ */
public void setTradeType(String tradeType) {
this.tradeType = tradeType;
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayBaseResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayBaseResult.java
index 64310138..b719e333 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayBaseResult.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayBaseResult.java
@@ -1,6 +1,11 @@
package me.chanjar.weixin.mp.bean.pay.result;
+import java.math.BigDecimal;
+import java.util.Map;
+
import com.thoughtworks.xstream.annotations.XStreamAlias;
+
+import me.chanjar.weixin.common.util.BeanUtils;
import me.chanjar.weixin.common.util.ToStringUtils;
/**
@@ -141,4 +146,17 @@ public abstract class WxPayBaseResult {
public void setSign(String sign) {
this.sign = sign;
}
+
+ /**
+ * 将单位分转换成单位圆
+ * @param fee
+ * @return
+ */
+ public static String feeToYuan(Integer fee) {
+ return new BigDecimal(Double.valueOf(fee) / 100).setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString();
+ }
+
+ public Map+ * 设备号 + * device_info + * 否 + * String(32) + * 013467007045764 + * 微信支付分配的终端设备号, + *+ * @fields deviceInfo + */ + @XStreamAlias("device_info") + private String deviceInfo; + + /** + *
+ * 用户标识 + * openid + * 是 + * String(128) + * wxd930ea5d5a258f4f + * 用户在商户appid下的唯一标识 + *+ * @fields openid + */ + @XStreamAlias("openid") + private String openid; + + /** + *
+ * 是否关注公众账号 + * is_subscribe + * 否 + * String(1) + * Y + * 用户是否关注公众账号,Y-关注,N-未关注,仅在公众账号类型支付有效 + *+ * @fields isSubscribe + */ + @XStreamAlias("is_subscribe") + private String isSubscribe; + + + /** + *
+ * 交易类型 + * trade_type + * 是 + * String(16) + * JSAPI JSAPI、NATIVE、APP + *+ * @fields tradeType + */ + @XStreamAlias("trade_type") + private String tradeType; + + + /** + *
+ * 付款银行 + * bank_type + * 是 + * String(16) + * CMC + * 银行类型,采用字符串类型的银行标识,银行类型见银行列表 + *+ * @fields bankType + */ + @XStreamAlias("bank_type") + private String bankType; + + + /** + *
+ * 订单金额 + * total_fee + * 是 + * Int + * 100 + * 订单总金额,单位为分 + *+ * @fields totalFee + */ + @XStreamAlias("total_fee") + private Integer totalFee; + /** + *
+ * 应结订单金额 + * settlement_total_fee + * 否 + * Int + * 100 + * 应结订单金额=订单金额-非充值代金券金额,应结订单金额<=订单金额。 + *+ * @fields settlementTotalFee + */ + @XStreamAlias("settlement_total_fee") + private Integer settlementTotalFee; + /** + *
+ * 货币种类 + * fee_type + * 否 + * String(8) + * CNY + * 货币类型,符合ISO4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型 + *+ * @fields feeType + */ + @XStreamAlias("fee_type") + private String feeType; + /** + *
+ * 现金支付金额 + * cash_fee + * 是 + * Int + * 100 + * 现金支付金额订单现金支付金额,详见支付金额 + *+ * @fields cashFee + */ + @XStreamAlias("cash_fee") + private Integer cashFee; + /** + *
+ * 现金支付货币类型 + * cash_fee_type + * 否 + * String(16) + * CNY + * 货币类型,符合ISO4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型 + *+ * @fields cashFeeType + */ + @XStreamAlias("cash_fee_type") + private String cashFeeType; + /** + *
+ * 总代金券金额 + * coupon_fee + * 否 + * Int + * 10 + * 代金券金额<=订单金额,订单金额-代金券金额=现金支付金额,详见支付金额 + *+ * @fields couponFee + */ + @XStreamAlias("coupon_fee") + private Integer couponFee; + + /** + *
+ * 代金券使用数量
+ * coupon_count
+ * 否
+ * Int
+ * 1
+ * 代金券使用数量
+ */
+ @XStreamAlias("coupon_count")
+ private Integer couponCount;
+
+ private List couponList;
+
+
+
+ /**
+ *
+ * 微信支付订单号
+ * transaction_id
+ * 是
+ * String(32)
+ * 1217752501201407033233368018
+ * 微信支付订单号
+ *
+ * @fields transactionId
+ */
+ @XStreamAlias("transaction_id")
+ private String transactionId;
+
+ /**
+ *
+ * 商户订单号
+ * out_trade_no
+ * 是
+ * String(32)
+ * 1212321211201407033568112322
+ * 商户系统的订单号,与请求一致。
+ *
+ * @fields outTradeNo
+ */
+ @XStreamAlias("out_trade_no")
+ private String outTradeNo;
+ /**
+ *
+ * 商家数据包
+ * attach
+ * 否
+ * String(128)
+ * 123456
+ * 商家数据包,原样返回
+ *
+ * @fields
+ */
+ @XStreamAlias("attach")
+ private String attach;
+ /**
+ *
+ * 支付完成时间
+ * time_end
+ * 是
+ * String(14)
+ * 20141030133525
+ * 支付完成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则
+ *
+ * @fields timeEnd
+ */
+ @XStreamAlias("time_end")
+ private String timeEnd;
+
+
+ public Integer getCouponCount() {
+ return couponCount;
+ }
+
+ public void setCouponCount(Integer couponCount) {
+ this.couponCount = couponCount;
+ }
+
+ public List getCouponList() {
+ return couponList;
+ }
+
+ public void setCouponList(List couponList) {
+ this.couponList = couponList;
+ }
+
+ public String getDeviceInfo() {
+ return deviceInfo;
+ }
+
+ public void setDeviceInfo(String deviceInfo) {
+ this.deviceInfo = deviceInfo;
+ }
+
+ public String getOpenid() {
+ return openid;
+ }
+
+ public void setOpenid(String openid) {
+ this.openid = openid;
+ }
+
+ public String getIsSubscribe() {
+ return isSubscribe;
+ }
+
+ public void setIsSubscribe(String isSubscribe) {
+ this.isSubscribe = isSubscribe;
+ }
+
+ public String getTradeType() {
+ return tradeType;
+ }
+
+ public void setTradeType(String tradeType) {
+ this.tradeType = tradeType;
+ }
+
+ public String getBankType() {
+ return bankType;
+ }
+
+ public void setBankType(String bankType) {
+ this.bankType = bankType;
+ }
+
+ public Integer getTotalFee() {
+ return totalFee;
+ }
+
+ public void setTotalFee(Integer totalFee) {
+ this.totalFee = totalFee;
+ }
+
+ public Integer getSettlementTotalFee() {
+ return settlementTotalFee;
+ }
+
+ public void setSettlementTotalFee(Integer settlementTotalFee) {
+ this.settlementTotalFee = settlementTotalFee;
+ }
+
+ public String getFeeType() {
+ return feeType;
+ }
+
+ public void setFeeType(String feeType) {
+ this.feeType = feeType;
+ }
+
+ public Integer getCashFee() {
+ return cashFee;
+ }
+
+ public void setCashFee(Integer cashFee) {
+ this.cashFee = cashFee;
+ }
+
+ public String getCashFeeType() {
+ return cashFeeType;
+ }
+
+ public void setCashFeeType(String cashFeeType) {
+ this.cashFeeType = cashFeeType;
+ }
+
+ public Integer getCouponFee() {
+ return couponFee;
+ }
+
+ public void setCouponFee(Integer couponFee) {
+ this.couponFee = couponFee;
+ }
+
+ public String getTransactionId() {
+ return transactionId;
+ }
+
+ public void setTransactionId(String transactionId) {
+ this.transactionId = transactionId;
+ }
+
+ public String getOutTradeNo() {
+ return outTradeNo;
+ }
+
+ public void setOutTradeNo(String outTradeNo) {
+ this.outTradeNo = outTradeNo;
+ }
+
+ public String getAttach() {
+ return attach;
+ }
+
+ public void setAttach(String attach) {
+ this.attach = attach;
+ }
+
+ public String getTimeEnd() {
+ return timeEnd;
+ }
+
+ public void setTimeEnd(String timeEnd) {
+ this.timeEnd = timeEnd;
+ }
+
+ @Override
+ public Map toMap(){
+ Map resultMap = BeanUtils.xmlBean2Map(this);
+ if(this.getCouponCount() != null && this.getCouponCount() > 0){
+ for (int i = 0; i < this.getCouponCount(); i++) {
+ WxPayOrderNotifyCoupon coupon = couponList.get(i);
+ resultMap.putAll(coupon.toMap(i));
+ }
+ }
+ return resultMap;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this,ToStringStyle.MULTI_LINE_STYLE);
+ }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/BaseBuilder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/BaseBuilder.java
index c5285d6f..3e40d178 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/BaseBuilder.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/BaseBuilder.java
@@ -6,7 +6,8 @@ public class BaseBuilder {
protected String msgType;
protected String toUser;
- public T toUser(String toUser) {
+ @SuppressWarnings("unchecked")
+ public T toUser(String toUser) {
this.toUser = toUser;
return (T) this;
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/outxml/BaseBuilder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/outxml/BaseBuilder.java
index e594565c..60cf675d 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/outxml/BaseBuilder.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/outxml/BaseBuilder.java
@@ -8,12 +8,14 @@ public abstract class BaseBuilder {
protected String fromUserName;
- public BuilderType toUser(String touser) {
+ @SuppressWarnings("unchecked")
+ public BuilderType toUser(String touser) {
this.toUserName = touser;
return (BuilderType) this;
}
- public BuilderType fromUser(String fromusername) {
+ @SuppressWarnings("unchecked")
+ public BuilderType fromUser(String fromusername) {
this.fromUserName = fromusername;
return (BuilderType) this;
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVoiceAndImageDownloadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVoiceAndImageDownloadRequestExecutor.java
index c40366ca..ceda65a6 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVoiceAndImageDownloadRequestExecutor.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVoiceAndImageDownloadRequestExecutor.java
@@ -23,7 +23,6 @@ import me.chanjar.weixin.common.util.json.WxGsonBuilder;
public class MaterialVoiceAndImageDownloadRequestExecutor implements RequestExecutor {
- private File tmpDirFile;
public MaterialVoiceAndImageDownloadRequestExecutor() {
super();
@@ -31,7 +30,6 @@ public class MaterialVoiceAndImageDownloadRequestExecutor implements RequestExec
public MaterialVoiceAndImageDownloadRequestExecutor(File tmpDirFile) {
super();
- this.tmpDirFile = tmpDirFile;
}
@Override