jaxen
jaxen
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java
index 0d819c8c..06af2d9d 100644
--- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java
@@ -32,9 +32,9 @@ import com.foxinmy.weixin4j.mp.model.User;
import com.foxinmy.weixin4j.mp.msg.model.Article;
import com.foxinmy.weixin4j.mp.msg.model.BaseMsg;
import com.foxinmy.weixin4j.mp.msg.notify.BaseNotify;
+import com.foxinmy.weixin4j.mp.payment.Refund;
+import com.foxinmy.weixin4j.mp.payment.RefundResult;
import com.foxinmy.weixin4j.mp.payment.v2.Order;
-import com.foxinmy.weixin4j.mp.payment.v3.Refund;
-import com.foxinmy.weixin4j.mp.payment.v3.RefundResult;
import com.foxinmy.weixin4j.mp.response.TemplateMessage;
import com.foxinmy.weixin4j.mp.type.BillType;
import com.foxinmy.weixin4j.mp.type.IdQuery;
@@ -740,15 +740,16 @@ public class WeixinProxy {
* 用户ID
* @param transid
* 交易单号
- * @param orderNo
+ * @param outTradeNo
* 订单号
* @param status
* 成功|失败
* @param statusMsg
* status为失败时携带的信息
- * @return 调用结果
- * @throws WeixinException
+ * @return 发货处理结果
+ * @since V2 & V3
* @see com.foxinmy.weixin4j.mp.api.PayApi
+ * @throws WeixinException
*/
public JsonResult deliverNotify(String openId, String transid,
String outTradeNo, boolean status, String statusMsg)
@@ -780,6 +781,7 @@ public class WeixinProxy {
* 维权单号
* @return 调用结果
* @see com.foxinmy.weixin4j.mp.api.PayApi
+ * @since V2 & V3
* @throws WeixinException
*/
public JsonResult updateFeedback(String openId, String feedbackId)
@@ -814,6 +816,7 @@ public class WeixinProxy {
* 下载对账单的类型 ALL,返回当日所有订单信息, 默认值 SUCCESS,返回当日成功支付的订单
* REFUND,返回当日退款订单
* @return excel表格
+ * @since V2 & V3
* @see com.foxinmy.weixin4j.mp.api.PayApi
* @throws WeixinException
* @throws IOException
@@ -824,7 +827,7 @@ public class WeixinProxy {
}
/**
- * 申请退款(请求需要双向证书)
+ * 申请退款(V3请求需要双向证书)
*
* 交易时间超过 1 年的订单无法提交退款;
* 支持部分退款,部分退需要设置相同的订单号和不同的 out_refund_no。一笔退款失 败后重新提交,要采用原来的
@@ -832,7 +835,7 @@ public class WeixinProxy {
*
*
* @param ca
- * 证书文件
+ * 证书文件V2版本时无需传入
* @param idQuery
* ) 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
* transaction_id> out_trade_no
@@ -844,28 +847,36 @@ public class WeixinProxy {
* 退款总金额,单位为元,可以做部分退款
* @param opUserId
* 操作员帐号, 默认为商户号
+ * @param opUserPasswd
+ * V3版本留空,V2版本需传入值
+ *
+ * @return 退款申请结果
* @see com.foxinmy.weixin4j.mp.api.PayApi
+ * @see com.foxinmy.weixin4j.mp.payment.RefundResult
+ * @since V2 & V3
* @throws WeixinException
* @throws IOException
- * @return 退款结果
*/
public RefundResult refund(InputStream ca, IdQuery idQuery,
String outRefundNo, double totalFee, double refundFee,
- String opUserId) throws WeixinException, IOException {
- return payApi.refund(idQuery, outRefundNo, totalFee, refundFee,
- opUserId);
+ String opUserId, String opUserPasswd) throws WeixinException,
+ IOException {
+ return payApi.refund(ca, idQuery, outRefundNo, totalFee, refundFee,
+ opUserId, opUserPasswd);
}
/**
- * 使用properties中配置的ca文件
+ * 不同的退款接口选择
+ * V3支付则采用properties中配置的ca文件
+ * V2支付则需要传入opUserPasswd参数
*
- * @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#refund(InputStream, IdQuery, String, double, double, String)}
+ * @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#refund(InputStream, IdQuery, String, double, double, String,String)}
*/
public RefundResult refund(IdQuery idQuery, String outRefundNo,
- double totalFee, double refundFee, String opUserId)
- throws WeixinException, IOException {
+ double totalFee, double refundFee, String opUserId,
+ String opUserPasswd) throws WeixinException, IOException {
return payApi.refund(idQuery, outRefundNo, totalFee, refundFee,
- opUserId);
+ opUserId, opUserPasswd);
}
/**
@@ -876,8 +887,10 @@ public class WeixinProxy {
* 单号 refund_id、out_refund_no、 out_trade_no 、 transaction_id
* 四个参数必填一个,优先级为:
* refund_id>out_refund_no>transaction_id>out_trade_no
- * @see com.foxinmy.weixin4j.mp.api.PayApi
* @return 退款记录
+ * @see com.foxinmy.weixin4j.mp.api.PayApi
+ * @see com.foxinmy.weixin4j.mp.payment.Refund
+ * @since V2 & V3
* @throws WeixinException
*/
public Refund refundQuery(IdQuery idQuery) throws WeixinException {
@@ -893,6 +906,7 @@ public class WeixinProxy {
* 商户系统内部的订单号
* @return 执行结果
* @see com.foxinmy.weixin4j.mp.api.PayApi
+ * @since V3
* @throws WeixinException
*/
public XmlResult closeOrder(String outTradeNo) throws WeixinException {
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/BaseApi.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/BaseApi.java
index b7d422d2..6248698a 100644
--- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/BaseApi.java
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/BaseApi.java
@@ -1,7 +1,5 @@
package com.foxinmy.weixin4j.mp.api;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.regex.Matcher;
@@ -24,7 +22,6 @@ import com.thoughtworks.xstream.mapper.DefaultMapper;
public class BaseApi {
protected final HttpRequest request = new HttpRequest();
protected final static XStream mapXstream = XStream.get();
- protected final Charset utf8 = StandardCharsets.UTF_8;
private final static ResourceBundle weixinBundle;
static {
weixinBundle = ResourceBundle
@@ -40,7 +37,7 @@ public class BaseApi {
@SuppressWarnings("unchecked")
protected Map xml2map(String xml) {
- return mapXstream.fromXML(xml,Map.class);
+ return mapXstream.fromXML(xml, Map.class);
}
protected String getRequestUri(String key) {
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/HelperApi.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/HelperApi.java
index c30d22f2..1c74d7c0 100644
--- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/HelperApi.java
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/HelperApi.java
@@ -1,9 +1,13 @@
package com.foxinmy.weixin4j.mp.api;
import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.TypeReference;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.Response;
import com.foxinmy.weixin4j.model.Token;
+import com.foxinmy.weixin4j.model.WeixinAccount;
+import com.foxinmy.weixin4j.mp.model.SemQuery;
+import com.foxinmy.weixin4j.mp.model.SemResult;
import com.foxinmy.weixin4j.token.TokenHolder;
/**
@@ -44,4 +48,28 @@ public class HelperApi extends BaseApi {
return response.getAsJson().getString("short_url");
}
+
+ /**
+ * 语义理解
+ *
+ * @param semQuery
+ * 语义理解协议
+ * @return 语义理解结果
+ * @see com.foxinmy.weixin4j.mp.model.SemQuery
+ * @see com.foxinmy.weixin4j.mp.model.SemResult
+ * @see 语义理解
+ * @throws WeixinException
+ */
+ public SemResult semantic(SemQuery semQuery) throws WeixinException {
+ WeixinAccount weixinAccount = tokenHolder.getAccount();
+ String semantic_uri = getRequestUri("semantic_uri");
+ Token token = tokenHolder.getToken();
+ semQuery.appid(weixinAccount.getAppId());
+ Response response = request.post(
+ String.format(semantic_uri, token.getAccessToken()),
+ semQuery.toJson());
+ return response.getAsObject(new TypeReference() {
+ });
+ }
}
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/PayApi.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/PayApi.java
index 6e7486da..99e03638 100644
--- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/PayApi.java
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/PayApi.java
@@ -6,19 +6,29 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.StringReader;
+import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
+import java.nio.charset.Charset;
+import java.security.KeyStore;
+import java.security.SecureRandom;
+import java.security.cert.CertificateFactory;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManagerFactory;
+
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
+import org.apache.http.Consts;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import com.alibaba.fastjson.JSON;
@@ -33,10 +43,10 @@ import com.foxinmy.weixin4j.http.XmlResult;
import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.model.WeixinAccount;
import com.foxinmy.weixin4j.mp.payment.PayUtil;
+import com.foxinmy.weixin4j.mp.payment.Refund;
+import com.foxinmy.weixin4j.mp.payment.RefundConverter;
+import com.foxinmy.weixin4j.mp.payment.RefundResult;
import com.foxinmy.weixin4j.mp.payment.v2.Order;
-import com.foxinmy.weixin4j.mp.payment.v3.Refund;
-import com.foxinmy.weixin4j.mp.payment.v3.RefundConverter;
-import com.foxinmy.weixin4j.mp.payment.v3.RefundResult;
import com.foxinmy.weixin4j.mp.type.BillType;
import com.foxinmy.weixin4j.mp.type.IdQuery;
import com.foxinmy.weixin4j.mp.type.IdType;
@@ -77,6 +87,7 @@ public class PayApi extends BaseApi {
* @param statusMsg
* status为失败时携带的信息
* @return 发货处理结果
+ * @since V2 & V3
* @throws WeixinException
*/
public JsonResult deliverNotify(String openId, String transid,
@@ -96,8 +107,7 @@ public class PayApi extends BaseApi {
param.put("deliver_timestamp", System.currentTimeMillis() / 1000 + "");
param.put("deliver_status", status ? "1" : "0");
param.put("deliver_msg", statusMsg);
- param.put("app_signature", DigestUtils.sha1Hex(MapUtil.toJoinString(
- param, false, true, null)));
+ param.put("app_signature", PayUtil.paysignSha(param, null));
param.put("sign_method", "sha1");
Response response = request.post(
@@ -135,10 +145,9 @@ public class PayApi extends BaseApi {
obj.put("appkey", weixinAccount.getPaySignKey());
obj.put("package", sb.toString());
obj.put("timestamp", timestamp);
- String signature = DigestUtils.sha1Hex(MapUtil.toJoinString(obj, false,
- true, null));
+ String signature = PayUtil.paysignSha(obj, null);
- obj = new JSONObject();
+ obj.clear();
obj.put("appid", weixinAccount.getAppId());
obj.put("package", sb.toString());
obj.put("timestamp", timestamp);
@@ -170,6 +179,7 @@ public class PayApi extends BaseApi {
* @param feedbackId
* 维权单号
* @return 维权处理结果
+ * @since V2 & V3
* @throws WeixinException
*/
public JsonResult updateFeedback(String openId, String feedbackId)
@@ -226,46 +236,146 @@ public class PayApi extends BaseApi {
* 退款总金额,单位为元,可以做部分退款
* @param opUserId
* 操作员帐号, 默认为商户号
+ * @param opUserPasswd
+ * V3版本留空,V2版本需传入值
*
* @return 退款申请结果
- * @see com.foxinmy.weixin4j.mp.payment.v3.RefundResult
+ * @see com.foxinmy.weixin4j.mp.payment.RefundResult
+ * @since V2 & V3
* @throws WeixinException
* @throws IOException
*/
public RefundResult refund(InputStream ca, IdQuery idQuery,
String outRefundNo, double totalFee, double refundFee,
- String opUserId) throws WeixinException, IOException {
+ String opUserId, String opUserPasswd) throws WeixinException,
+ IOException {
WeixinAccount weixinAccount = tokenHolder.getAccount();
- Map map = baseMap2V3(idQuery);
- map.put("out_refund_no", outRefundNo);
- map.put("total_fee", DateUtil.formaFee2Fen(totalFee));
- map.put("refund_fee", DateUtil.formaFee2Fen(refundFee));
- if (StringUtils.isBlank(opUserId)) {
- opUserId = weixinAccount.getMchId();
+
+ int version = weixinAccount.getVersion();
+ String refund_uri = getRequestUri(String.format("refund_v%d_uri",
+ version));
+ Response response = null;
+ if (version == 2) {
+ Map map = new HashMap();
+ map.put("input_charset", Consts.UTF_8.name());
+ // 版本号
+ // 填写为 1.0 时,操作员密码为明文
+ // 填写为 1.1 时,操作员密码为 MD5(密码)值
+ map.put("service_version", "1.1");
+ map.put("partner", weixinAccount.getPartnerId());
+ map.put("out_refund_no", outRefundNo);
+ map.put("total_fee", DateUtil.formaFee2Fen(totalFee));
+ map.put("refund_fee", DateUtil.formaFee2Fen(refundFee));
+ map.put(idQuery.getType().getName(), idQuery.getId());
+ if (StringUtils.isBlank(opUserId)) {
+ opUserId = weixinAccount.getPartnerId();
+ }
+ map.put("op_user_id", opUserId);
+ map.put("op_user_passwd", DigestUtils.md5Hex(opUserPasswd));
+ // 以下几个字段可能用不到 记录下来
+ // [接收人帐号]
+ // recv_user_id
+ // 转账退款接收退款的财付通帐号。
+ // 一般无需填写,只有退银行失败,资金转入商 户号现金账号时(即状态为转入代发,查询返 回的 refund_status 是 7 或
+ // 11),填写原退款 单号并填写此字段,资金才会退到指定财付通 账号。其他情况此字段忽略
+ // ---------------------------------------------------------------------------------
+ // [接收人姓名]
+ // reccv_user_name
+ // 转账退款接收退款的姓名(需与接收退款的财 付通帐号绑定的姓名一致)
+ // ---------------------------------------------------------------------------------
+ // [通过商户订单号退款]
+ // use_spbill_no_flag
+ // 若通过接口 (https://www.tenpay.com/cgi-bin/v1.0/pay _gate.cgi)
+ // 支付的商户订单号来退款,则取值 为 1;而通过本文档支付接口的,则无需传值。
+ // ---------------------------------------------------------------------------------
+ // [退款类型]
+ // refund_type
+ // 为空或者填 1:商户号余额退款;2:现金帐号 退款;3:优先商户号退款,若商户号余额不足, 再做现金帐号退款。使用 2 或 3
+ // 时,需联系财 付通开通此功能。
+ String sign = PayUtil
+ .paysignMd5(map, weixinAccount.getPartnerKey());
+ map.put("sign", sign.toLowerCase());
+
+ SSLContext ctx = null;
+ try {
+ File file = new File(ConfigUtil.getValue("ca_file"));
+
+ String jksPwd = "";
+ File jksFile = new File(String.format("%s/tenpay_cacert.jks",
+ file.getParent()));
+ KeyStore ks = null;
+ // create jks ca
+ if (!jksFile.exists()) {
+ CertificateFactory cf = CertificateFactory
+ .getInstance(com.foxinmy.weixin4j.model.Consts.X509);
+ java.security.cert.Certificate cert = cf
+ .generateCertificate(PayUtil.class
+ .getResourceAsStream("cacert.pem"));
+ ks = KeyStore
+ .getInstance(com.foxinmy.weixin4j.model.Consts.JKS);
+ ks.load(null, null);
+ ks.setCertificateEntry("tenpay", cert);
+ ks.store(new FileOutputStream(jksFile),
+ jksPwd.toCharArray());
+ }
+ // load jks ca
+ TrustManagerFactory tmf = TrustManagerFactory
+ .getInstance(com.foxinmy.weixin4j.model.Consts.SunX509);
+ ks = KeyStore
+ .getInstance(com.foxinmy.weixin4j.model.Consts.JKS);
+ ks.load(new FileInputStream(jksFile), jksPwd.toCharArray());
+ tmf.init(ks);
+ // load pfx ca
+ KeyManagerFactory kmf = KeyManagerFactory
+ .getInstance(com.foxinmy.weixin4j.model.Consts.SunX509);
+ ks = KeyStore
+ .getInstance(com.foxinmy.weixin4j.model.Consts.PKCS12);
+ ks.load(ca, weixinAccount.getPartnerId().toCharArray());
+ kmf.init(ks, weixinAccount.getPartnerId().toCharArray());
+
+ ctx = SSLContext
+ .getInstance(com.foxinmy.weixin4j.model.Consts.TLS);
+ ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(),
+ new SecureRandom());
+ } catch (Exception e) {
+ throw new WeixinException(e.getMessage());
+ }
+ SSLHttpRequest request = new SSLHttpRequest(ctx);
+ response = request.get(refund_uri, map);
+ } else if (version == 3) {
+ Map map = baseMap2V3(idQuery);
+ map.put("out_refund_no", outRefundNo);
+ map.put("total_fee", DateUtil.formaFee2Fen(totalFee));
+ map.put("refund_fee", DateUtil.formaFee2Fen(refundFee));
+ if (StringUtils.isBlank(opUserId)) {
+ opUserId = weixinAccount.getMchId();
+ }
+ map.put("op_user_id", opUserId);
+ String sign = PayUtil
+ .paysignMd5(map, weixinAccount.getPaySignKey());
+ map.put("sign", sign);
+ String param = map2xml(map);
+ SSLHttpRequest request = new SSLHttpRequest(
+ weixinAccount.getMchId(), ca);
+ response = request.post(refund_uri, param);
}
- map.put("op_user_id", opUserId);
- String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
- map.put("sign", sign);
- String param = map2xml(map);
- String refund_uri = getRequestUri("refund_uri");
- SSLHttpRequest request = new SSLHttpRequest(weixinAccount.getMchId(),
- ca);
- Response response = request.post(refund_uri, param);
return response.getAsObject(new TypeReference() {
});
}
/**
- * 使用properties中配置的ca文件
+ * 不同的退款接口选择
+ * 默认采用properties中配置的ca文件
+ * V2支付则需要传入opUserPasswd参数
*
- * @see {@link com.foxinmy.weixin4j.mp.api.PayApi#refund(InputStream, IdQuery, String, double, double, String)}
+ * @see {@link com.foxinmy.weixin4j.mp.api.PayApi#refund(InputStream, IdQuery, String, double, double, String, String)}
*/
public RefundResult refund(IdQuery idQuery, String outRefundNo,
- double totalFee, double refundFee, String opUserId)
- throws WeixinException, IOException {
- File caFile = new File(ConfigUtil.getValue("ca_file"));
- return refund(new FileInputStream(caFile), idQuery, outRefundNo,
- totalFee, refundFee, opUserId);
+ double totalFee, double refundFee, String opUserId,
+ String opUserPasswd) throws WeixinException, IOException {
+ File ca = new File(ConfigUtil.getValue("ca_file"));
+ return refund(new FileInputStream(ca), idQuery, outRefundNo, totalFee,
+ refundFee, opUserId, opUserPasswd);
}
/**
@@ -283,8 +393,8 @@ public class PayApi extends BaseApi {
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
map.put("sign", sign);
try {
- map.put("long_url", URLEncoder.encode(url, utf8.name()));
- } catch (UnsupportedEncodingException e) {
+ map.put("long_url", URLEncoder.encode(url, Consts.UTF_8.name()));
+ } catch (UnsupportedEncodingException ignore) {
;
}
String param = map2xml(map);
@@ -302,6 +412,7 @@ public class PayApi extends BaseApi {
* @param outTradeNo
* 商户系统内部的订单号
* @return 处理结果
+ * @since V3
* @throws WeixinException
*/
public XmlResult closeOrder(String outTradeNo) throws WeixinException {
@@ -329,6 +440,7 @@ public class PayApi extends BaseApi {
* 下载对账单的类型 ALL,返回当日所有订单信息, 默认值 SUCCESS,返回当日成功支付的订单
* REFUND,返回当日退款订单
* @return excel表格
+ * @since V2 & V3
* @throws WeixinException
* @throws IOException
*/
@@ -337,7 +449,7 @@ public class PayApi extends BaseApi {
WeixinAccount weixinAccount = tokenHolder.getAccount();
if (billDate == null) {
Calendar now = Calendar.getInstance();
- now.add(Calendar.DAY_OF_MONTH, -10);
+ now.add(Calendar.DAY_OF_MONTH, -1);
billDate = now.getTime();
}
if (billType == null) {
@@ -351,17 +463,37 @@ public class PayApi extends BaseApi {
if (file.exists()) {
return file;
}
- Map map = baseMap2V3(null);
- map.put("bill_date", _billDate);
- map.put("bill_type", billType.name());
- String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
- map.put("sign", sign);
- String param = map2xml(map);
- String downloadbill_uri = getRequestUri("downloadbill_uri");
- Response response = request.post(downloadbill_uri, param);
+ int version = weixinAccount.getVersion();
+ String downloadbill_uri = getRequestUri(String.format(
+ "downloadbill_v%d_uri", version));
+ Response response = null;
+ Charset charset = Consts.UTF_8;
+ if (version == 2) {
+ Map map = new LinkedHashMap();
+ map.put("spid", weixinAccount.getPartnerId());
+ map.put("trans_time", DateUtil.fortmat2yyyy_MM_dd(billDate));
+ map.put("stamp", Long.toString(System.currentTimeMillis() / 100));
+ map.put("cft_signtype", "0");
+ map.put("mchtype", Integer.toString(billType.getVal()));
+ map.put("key", weixinAccount.getPartnerKey());
+ String sign = DigestUtils.md5Hex(MapUtil.toJoinString(map, false,
+ false));
+ map.put("sign", sign.toLowerCase());
+ response = request.get(downloadbill_uri, map);
+ charset = Charset.forName("GBK");
+ } else if (version == 3) {
+ Map map = baseMap2V3(null);
+ map.put("bill_date", _billDate);
+ map.put("bill_type", billType.name());
+ String sign = PayUtil
+ .paysignMd5(map, weixinAccount.getPaySignKey());
+ map.put("sign", sign);
+ String param = map2xml(map);
+ response = request.post(downloadbill_uri, param);
+ }
- BufferedReader reader = new BufferedReader(new StringReader(
- response.getAsString()));
+ BufferedReader reader = new BufferedReader(new InputStreamReader(
+ response.getStream(), charset));
String line = null;
List bills = new LinkedList();
while ((line = reader.readLine()) != null) {
@@ -389,17 +521,33 @@ public class PayApi extends BaseApi {
* 四个参数必填一个,优先级为:
* refund_id>out_refund_no>transaction_id>out_trade_no
* @return 退款记录
- * @see com.foxinmy.weixin4j.mp.payment.v3.Refund
+ * @see com.foxinmy.weixin4j.mp.payment.Refund
+ * @since V2 & V3
* @throws WeixinException
*/
public Refund refundQuery(IdQuery idQuery) throws WeixinException {
WeixinAccount weixinAccount = tokenHolder.getAccount();
- Map map = baseMap2V3(idQuery);
- String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
- map.put("sign", sign);
- String param = map2xml(map);
- String refundquery_uri = getRequestUri("refundquery_uri");
- Response response = request.post(refundquery_uri, param);
+ int version = weixinAccount.getVersion();
+ String refundquery_uri = getRequestUri(String.format(
+ "refundquery_v%d_uri", version));
+ Response response = null;
+ if (version == 2) {
+ Map map = new HashMap();
+ map.put("input_charset", Consts.UTF_8.name());
+ map.put("partner", weixinAccount.getPartnerId());
+ map.put(idQuery.getType().getName(), idQuery.getId());
+ String sign = PayUtil
+ .paysignMd5(map, weixinAccount.getPartnerKey());
+ map.put("sign", sign.toLowerCase());
+ response = request.get(refundquery_uri, map);
+ } else if (version == 3) {
+ Map map = baseMap2V3(idQuery);
+ String sign = PayUtil
+ .paysignMd5(map, weixinAccount.getPaySignKey());
+ map.put("sign", sign);
+ String param = map2xml(map);
+ response = request.post(refundquery_uri, param);
+ }
return new RefundConverter().fromXML(response.getAsString());
}
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties
index b343bc02..f2deb48b 100644
--- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties
@@ -5,10 +5,15 @@
# http://mp.weixin.qq.com/wiki/index.php?title=%E6%8E%A5%E5%8F%A3%E9%A2%91%E7%8E%87%E9%99%90%E5%88%B6%E8%AF%B4%E6%98%8E
# ----------------------------------------------------------------------------
-api_base_url=https://api.weixin.qq.com/cgi-bin
+api_base_url=https://api.weixin.qq.com
+api_cgi_url={api_base_url}/cgi-bin
mp_base_url=https://mp.weixin.qq.com/cgi-bin
file_base_url=http://file.api.weixin.qq.com/cgi-bin
mch_base_url=https://api.mch.weixin.qq.com
+tenpay_base_url=http://mch.tenpay.com
+tenpay_ssl_base_url=https://mch.tenpay.com
+tenpay_gw_base_url=https://gw.tenpay.com
+
# \u7f51\u9875\u6388\u6743\u83b7\u53d6\u7528\u6237\u4fe1\u606f
user_auth_uri=https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect
@@ -16,68 +21,78 @@ sns_user_token_uri=https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&se
sns_user_info_uri=https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN
# \u76f4\u63a5\u83b7\u53d6\u7528\u6237\u4fe1\u606f
-api_user_info_uri={api_base_url}/user/info?access_token=%s&openid=%s&lang=zh_CN
+api_user_info_uri={api_cgi_url}/user/info?access_token=%s&openid=%s&lang=zh_CN
# \u83b7\u53d6token
-api_token_uri={api_base_url}/token?grant_type=client_credential&appid=%s&secret=%s
+api_token_uri={api_cgi_url}/token?grant_type=client_credential&appid=%s&secret=%s
# \u83b7\u53d6\u4e8c\u7ef4\u7801
-qr_ticket_uri={api_base_url}/qrcode/create?access_token=%s
+qr_ticket_uri={api_cgi_url}/qrcode/create?access_token=%s
qr_image_uri={mp_base_url}/showqrcode?ticket=%s
# \u4e0a\u4f20\u5a92\u4f53\u6587\u4ef6
file_upload_uri={file_base_url}/media/upload?access_token=%s&type=%s
# \u4e0b\u8f7d\u5a92\u4f53\u6587\u4ef6
file_download_uri={file_base_url}/media/get?access_token=%s&media_id=%s
# \u53d1\u9001\u5ba2\u670d\u6d88\u606f
-custom_notify_uri={api_base_url}/message/custom/send?access_token=%s
+custom_notify_uri={api_cgi_url}/message/custom/send?access_token=%s
# \u521b\u5efa\u5206\u7ec4
-group_create_uri={api_base_url}/groups/create?access_token=%s
+group_create_uri={api_cgi_url}/groups/create?access_token=%s
# \u67e5\u8be2\u5206\u7ec4
-group_get_uri={api_base_url}/groups/get?access_token=%s
+group_get_uri={api_cgi_url}/groups/get?access_token=%s
# \u67e5\u8be2\u7528\u6237\u6240\u5728\u5206\u7ec4
-group_getid_uri={api_base_url}/groups/getid?access_token=%s
+group_getid_uri={api_cgi_url}/groups/getid?access_token=%s
# \u4fee\u6539\u5206\u7ec4\u540d
-group_modify_uri={api_base_url}/groups/update?access_token=%s
+group_modify_uri={api_cgi_url}/groups/update?access_token=%s
# \u79fb\u52a8\u7528\u6237\u5206\u7ec4
-group_move_uri={api_base_url}/groups/members/update?access_token=%s
+group_move_uri={api_cgi_url}/groups/members/update?access_token=%s
# \u83b7\u53d6\u5173\u6ce8\u7740
-following_uri={api_base_url}/user/get?access_token=%s&next_openid=%s
+following_uri={api_cgi_url}/user/get?access_token=%s&next_openid=%s
# \u81ea\u5b9a\u4e49\u83dc\u5355
-menu_create_uri={api_base_url}/menu/create?access_token=%s
+menu_create_uri={api_cgi_url}/menu/create?access_token=%s
# \u67e5\u8be2\u83dc\u5355
-menu_get_uri={api_base_url}/menu/get?access_token=%s
+menu_get_uri={api_cgi_url}/menu/get?access_token=%s
# \u5220\u9664\u83dc\u5355
-menu_delete_uri={api_base_url}/menu/delete?access_token=%s
+menu_delete_uri={api_cgi_url}/menu/delete?access_token=%s
# \u4e0a\u4f20\u56fe\u6587
-article_upload_uri={api_base_url}/media/uploadnews?access_token=%s
+article_upload_uri={api_cgi_url}/media/uploadnews?access_token=%s
# \u4e0a\u4f20\u89c6\u9891
video_upload_uri={file_base_url}/media/uploadvideo?access_token=%s
# \u5206\u7ec4\u7fa4\u53d1
-mass_group_uri={api_base_url}/message/mass/sendall?access_token=%s
+mass_group_uri={api_cgi_url}/message/mass/sendall?access_token=%s
# openId\u7fa4\u53d1
-mass_openid_uri={api_base_url}/message/mass/send?access_token=%s
+mass_openid_uri={api_cgi_url}/message/mass/send?access_token=%s
# \u5220\u9664\u7fa4\u53d1
-mass_delete_uri={api_base_url}/message/mass/delete?access_token=%s
+mass_delete_uri={api_cgi_url}/message/mass/delete?access_token=%s
# \u5ba2\u670d\u804a\u5929\u8bb0\u5f55
-custom_record_uri={api_base_url}/customservice/getrecord?access_token=%s
+custom_record_uri={api_cgi_url}/customservice/getrecord?access_token=%s
# \u957f\u94fe\u63a5\u8f6c\u77ed\u94fe\u63a5
-shorturl_uri={api_base_url}/shorturl?access_token=%s
+shorturl_uri={api_cgi_url}/shorturl?access_token=%s
p_shorturl_uri={mch_base_url}/tools/shorturl
# \u8bbe\u7f6e\u5907\u6ce8\u540d
-updateremark_uri={api_base_url}/user/info/updateremark?access_token=%s
+updateremark_uri={api_cgi_url}/user/info/updateremark?access_token=%s
# \u6a21\u677f\u6d88\u606f
-template_send_uri={api_base_url}/message/template/send?access_token=%s
+template_send_uri={api_cgi_url}/message/template/send?access_token=%s
+# \u8bed\u4e49\u7406\u89e3
+semantic_uri={api_base_url}/semantic/semproxy/search?access_token=%s
+
# \u8ba2\u5355\u67e5\u8be2
-orderquery_uri=https://api.weixin.qq.com/pay/orderquery?access_token=%s
+orderquery_uri={api_base_url}/pay/orderquery?access_token=%s
# \u53d1\u8d27\u901a\u77e5
-delivernotify_uri=https://api.weixin.qq.com/pay/delivernotify?access_token=%s
+delivernotify_uri={api_base_url}/pay/delivernotify?access_token=%s
# \u7ef4\u6743\u5904\u7406
-payfeedback_update_uri=https://api.weixin.qq.com/payfeedback/update?access_token=%s&openid=%s&feedbackid=%s
+payfeedback_update_uri={api_base_url}/payfeedback/update?access_token=%s&openid=%s&feedbackid=%s
+# \u5bf9\u8d26\u5355\u4e0b\u8f7d
+downloadbill_v2_uri={tenpay_base_url}/cgi-bin/mchdown_real_new.cgi
+# \u9000\u6b3e\u67e5\u8be2
+refundquery_v2_uri={tenpay_gw_base_url}/gateway/normalrefundquery.xml
+# \u9000\u6b3e\u7533\u8bf7
+refund_v2_uri={tenpay_ssl_base_url}/refundapi/gateway/refund.xml
+
# \u8ba2\u5355\u67e5\u8be2
orderquery_v3_uri={mch_base_url}/pay/orderquery
# \u5173\u95ed\u8ba2\u5355
closeorder_uri={mch_base_url}/pay/closeorder
# \u5bf9\u8d26\u5355\u4e0b\u8f7d
-downloadbill_uri={mch_base_url}/pay/downloadbill
+downloadbill_v3_uri={mch_base_url}/pay/downloadbill
# \u9000\u6b3e\u67e5\u8be2
-refundquery_uri={mch_base_url}/pay/refundquery
+refundquery_v3_uri={mch_base_url}/pay/refundquery
# \u9000\u6b3e\u7533\u8bf7
-refund_uri={mch_base_url}/secapi/pay/refund
+refund_v3_uri={mch_base_url}/secapi/pay/refund
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/Button.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/Button.java
index c02b4fe8..32fbbd98 100644
--- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/Button.java
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/Button.java
@@ -38,10 +38,10 @@ public class Button implements Serializable {
public Button(String name, String value, ButtonType buttonType) {
this.name = name;
this.type = buttonType;
- if (buttonType == ButtonType.click) {
- this.key = value;
- } else if (buttonType == ButtonType.view) {
+ if (buttonType == ButtonType.view) {
this.url = value;
+ } else {
+ this.key = value;
}
}
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/SemQuery.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/SemQuery.java
new file mode 100644
index 00000000..f02ced35
--- /dev/null
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/SemQuery.java
@@ -0,0 +1,88 @@
+package com.foxinmy.weixin4j.mp.model;
+
+import java.io.Serializable;
+
+import com.alibaba.fastjson.JSONObject;
+import com.foxinmy.weixin4j.mp.type.SemCategory;
+
+/**
+ * 语义理解参数
+ *
+ * @className SemQuery
+ * @author jy
+ * @date 2014年11月7日
+ * @since JDK 1.7
+ * @see
+ */
+public class SemQuery implements Serializable {
+
+ private static final long serialVersionUID = 679548284525912436L;
+ private JSONObject jsonObj;
+
+ // 输入文本串
+ public SemQuery(String query) {
+ jsonObj = new JSONObject();
+ jsonObj.put("query", query);
+ }
+
+ // 城市名称,与经纬度二选一传入
+ public SemQuery city(String city) {
+ jsonObj.put("city", city);
+ return this;
+ }
+
+ // 需要使用的服务类别,多个用,隔开,不能为空
+ public SemQuery category(SemCategory... categorys) {
+ String category = "";
+ if (categorys.length == 1) {
+ category = categorys[0].name();
+ } else {
+ for (int i = 0; i < categorys.length - 1; i++) {
+ category += categorys[i].name() + ",";
+ }
+ category += categorys[categorys.length - 1].name();
+ }
+ jsonObj.put("category", category);
+ return this;
+ }
+
+ // App id,开发者的唯一标识,用于区分开放者, 如果为空,则没法使用上下文理解功能。
+ public SemQuery appid(String appid) {
+ jsonObj.put("appid", appid);
+ return this;
+ }
+
+ // 用户唯一 id(并非开发者 id),用于区分该开发者下不同用户,如果为空,则没法使用上下文理解功能。appid 和 uid
+ // 同时存在的情况下,才可以使用上下文理解功能。
+ public SemQuery uid(String uid) {
+ jsonObj.put("uid", uid);
+ return this;
+ }
+
+ // 区域名称,在城市存在的情况下可省;与经纬度 二选一传入
+ public SemQuery region(String region) {
+ jsonObj.put("region", region);
+ return this;
+ }
+
+ // 纬度经度;与城市二选一传入
+ public SemQuery location(float latitude, float longitude) {
+ jsonObj.put("latitude", latitude);
+ jsonObj.put("longitude", longitude);
+ return this;
+ }
+
+ // 输入文本串
+ public static SemQuery build(String query) {
+ return new SemQuery(query);
+ }
+
+ public String toJson() {
+ return jsonObj.toJSONString();
+ }
+
+ @Override
+ public String toString() {
+ return "SemQuery " + jsonObj;
+ }
+}
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/SemResult.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/SemResult.java
new file mode 100644
index 00000000..738284d8
--- /dev/null
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/SemResult.java
@@ -0,0 +1,88 @@
+package com.foxinmy.weixin4j.mp.model;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.foxinmy.weixin4j.http.JsonResult;
+
+/**
+ * 语义理解结果
+ *
+ * @className SemResult
+ * @author jy
+ * @date 2014年11月7日
+ * @since JDK 1.7
+ * @see 语义理解
+ */
+public class SemResult extends JsonResult {
+
+ private static final long serialVersionUID = 9051214458161068387L;
+ // 用户的输入字符串
+ private String query;
+ // 服务的全局类型id,详见协议文档中垂直服务协议定义
+ private String type;
+ // 语义理解后的结构化标识,各服务不同
+ private JSONObject semantic;
+ // 部分类别的结果
+ private JSONArray result;
+ // 部分类别的结果html5展示,目前不支持
+ private String answer;
+ // 特殊回复说明
+ private String text;
+
+ public String getQuery() {
+ return query;
+ }
+
+ public void setQuery(String query) {
+ this.query = query;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public JSONObject getSemantic() {
+ return semantic;
+ }
+
+ public void setSemantic(JSONObject semantic) {
+ this.semantic = semantic;
+ }
+
+ public JSONArray getResult() {
+ return result;
+ }
+
+ public void setResult(JSONArray result) {
+ this.result = result;
+ }
+
+ public String getAnswer() {
+ return answer;
+ }
+
+ public void setAnswer(String answer) {
+ this.answer = answer;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ }
+
+ @Override
+ public String toString() {
+ return "SemResult [query=" + query + ", type=" + type + ", semantic="
+ + semantic + ", result=" + result + ", answer=" + answer
+ + ", text=" + text + ", getCode()=" + getCode()
+ + ", getDesc()=" + getDesc() + "]";
+ }
+}
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/PayAction.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/PayAction.java
index 5cd210cc..757a3574 100644
--- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/PayAction.java
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/PayAction.java
@@ -11,6 +11,7 @@ import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSONObject;
import com.foxinmy.weixin4j.exception.PayException;
import com.foxinmy.weixin4j.http.XmlResult;
+import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.model.WeixinAccount;
import com.foxinmy.weixin4j.mp.payment.v2.NativePayNotifyV2;
import com.foxinmy.weixin4j.mp.payment.v2.NativePayResponseV2;
@@ -163,7 +164,7 @@ public class PayAction {
weixinAccount.getPaySignKey());
log.info("微信签名----->sign={},vaild_sign={}", sign, valid_sign);
if (!sign.equals(valid_sign)) {
- return XStream.to(new XmlResult(XmlResult.FAIL, "签名错误"));
+ return XStream.to(new XmlResult(Consts.FAIL, "签名错误"));
}
return XStream.to(new XmlResult());
}
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/PayUtil.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/PayUtil.java
index e22369b9..165268b5 100644
--- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/PayUtil.java
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/PayUtil.java
@@ -122,9 +122,9 @@ public class PayUtil {
* @return
*/
public static String paysignSha(Object obj, String paySignKey) {
- JSONObject extra = null;
+ Map extra = null;
if (StringUtils.isNotBlank(paySignKey)) {
- extra = new JSONObject();
+ extra = new HashMap();
extra.put("appKey", paySignKey);
}
return DigestUtils.sha1Hex(MapUtil
@@ -255,7 +255,7 @@ public class PayUtil {
Map param = new HashMap();
param.put("appId", appId);
param.put("url", url);
- param.put("timeStamp", System.currentTimeMillis() / 1000 + "");
+ param.put("timeStamp", Long.toString(System.currentTimeMillis() / 1000));
param.put("nonceStr", RandomUtil.generateString(16));
param.put("accessToken", accessToken);
String sign = paysignSha(param, null);
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/Refund.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/Refund.java
similarity index 64%
rename from weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/Refund.java
rename to weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/Refund.java
index e03915e5..cd9e8853 100644
--- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/Refund.java
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/Refund.java
@@ -1,8 +1,7 @@
-package com.foxinmy.weixin4j.mp.payment.v3;
+package com.foxinmy.weixin4j.mp.payment;
import java.util.List;
-import com.foxinmy.weixin4j.mp.payment.ApiResult;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
@@ -12,7 +11,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @author jy
* @date 2014年11月1日
* @since JDK 1.7
- * @see com.foxinmy.weixin4j.mp.payment.v3.RefundDetail
+ * @see com.foxinmy.weixin4j.mp.payment.RefundDetail
*/
@XStreamAlias("xml")
public class Refund extends ApiResult {
@@ -27,6 +26,7 @@ public class Refund extends ApiResult {
private String subMchId; //
@XStreamAlias("refund_count")
private int count;// 退款笔数
+ private String partner; // 商户号V2
private List details;
public String getTransactionId() {
@@ -45,6 +45,10 @@ public class Refund extends ApiResult {
return count;
}
+ public String getPartner() {
+ return partner;
+ }
+
public List getDetails() {
return details;
}
@@ -57,12 +61,13 @@ public class Refund extends ApiResult {
public String toString() {
return "Refund [transactionId=" + transactionId + ", orderNo="
+ orderNo + ", subMchId=" + subMchId + ", count=" + count
- + ", details=" + details + ", getAppId()=" + getAppId()
- + ", getMchId()=" + getMchId() + ", getNonceStr()="
- + getNonceStr() + ", getSign()=" + getSign()
- + ", getDeviceInfo()=" + getDeviceInfo() + ", getReturnCode()="
- + getReturnCode() + ", getReturnMsg()=" + getReturnMsg()
- + ", getResultCode()=" + getResultCode() + ", getErrCode()="
- + getErrCode() + ", getErrCodeDes()=" + getErrCodeDes() + "]";
+ + ", partner=" + partner + ", details=" + details
+ + ", getAppId()=" + getAppId() + ", getMchId()=" + getMchId()
+ + ", getNonceStr()=" + getNonceStr() + ", getSign()="
+ + getSign() + ", getDeviceInfo()=" + getDeviceInfo()
+ + ", getReturnCode()=" + getReturnCode() + ", getReturnMsg()="
+ + getReturnMsg() + ", getResultCode()=" + getResultCode()
+ + ", getErrCode()=" + getErrCode() + ", getErrCodeDes()="
+ + getErrCodeDes() + "]";
}
}
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundConverter.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/RefundConverter.java
similarity index 96%
rename from weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundConverter.java
rename to weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/RefundConverter.java
index b31f9040..0630f117 100644
--- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundConverter.java
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/RefundConverter.java
@@ -1,4 +1,4 @@
-package com.foxinmy.weixin4j.mp.payment.v3;
+package com.foxinmy.weixin4j.mp.payment;
import java.lang.reflect.Field;
import java.util.HashMap;
@@ -26,8 +26,8 @@ import com.thoughtworks.xstream.mapper.Mapper;
* @author jy
* @date 2014年11月2日
* @since JDK 1.7
- * @see com.foxinmy.weixin4j.mp.payment.v3.Refund
- * @see com.foxinmy.weixin4j.mp.payment.v3.RefundDetail
+ * @see com.foxinmy.weixin4j.mp.payment.Refund
+ * @see com.foxinmy.weixin4j.mp.payment.RefundDetail
*/
public class RefundConverter {
private final static XStream xStream = XStream.get();
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundDetail.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/RefundDetail.java
similarity index 51%
rename from weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundDetail.java
rename to weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/RefundDetail.java
index 007f05b2..0c09a2e2 100644
--- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundDetail.java
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/RefundDetail.java
@@ -1,4 +1,4 @@
-package com.foxinmy.weixin4j.mp.payment.v3;
+package com.foxinmy.weixin4j.mp.payment;
import java.io.Serializable;
@@ -32,7 +32,15 @@ public class RefundDetail implements Serializable {
@XStreamAlias("coupon_refund_fee")
private int couponRefundFee; // 现金券退款金额<=退款金额,退款金额-现金券退款金额为现金
@XStreamAlias("refund_status")
- private RefundStatus refundStatus; // 退款状态
+ private String refundStatus; // 退款状态
+ @XStreamAlias("recv_user_id")
+ private String recvUserId;// 转账退款接收退款的财付通帐号
+ @XStreamAlias("reccv_user_name")
+ private String reccvUserName;// 转账退款接收退款的姓名(需与接收退款的财 付通帐号绑定的姓名一致)
+ @XStreamAlias("sign_key_index")
+ private String signKeyIndex;// 多密钥支持的密钥序号,默认 1
+ @XStreamAlias("sign_type")
+ private String signType;// 签名类型,取值:MD5、RSA,默认:MD5
public String getOutRefundNo() {
return outRefundNo;
@@ -43,8 +51,16 @@ public class RefundDetail implements Serializable {
}
public String getRefundChannel() {
- return StringUtils.isBlank(refundChannel) ? RefundChannel.BALANCE
- .name() : refundChannel;
+ if (StringUtils.isBlank(refundChannel)) {
+ return RefundChannel.BALANCE.name();
+ }
+ // V2
+ if (refundChannel.equals("0")) {
+ return RefundChannel.TENPAY.name();
+ } else if (refundChannel.equals("1")) {
+ return RefundChannel.BALANCE.name();
+ }
+ return refundChannel;
}
/**
@@ -66,7 +82,36 @@ public class RefundDetail implements Serializable {
}
public RefundStatus getRefundStatus() {
- return refundStatus;
+ // V2
+ if ("4,10,".contains(refundStatus + ",")) {
+ return RefundStatus.SUCCES;
+ } else if ("3,5,6,".contains(refundStatus + ",")) {
+ return RefundStatus.FAIL;
+ } else if ("8,9,10,".contains(refundStatus + ",")) {
+ return RefundStatus.PROCESSING;
+ } else if ("1,2,".contains(refundStatus + ",")) {
+ return RefundStatus.NOTSURE;
+ } else if ("7,".contains(refundStatus + ",")) {
+ return RefundStatus.CHANGE;
+ } else {
+ return RefundStatus.valueOf(refundStatus);
+ }
+ }
+
+ public String getRecvUserId() {
+ return recvUserId;
+ }
+
+ public String getReccvUserName() {
+ return reccvUserName;
+ }
+
+ public String getSignKeyIndex() {
+ return signKeyIndex;
+ }
+
+ public String getSignType() {
+ return signType;
}
@Override
@@ -74,6 +119,9 @@ public class RefundDetail implements Serializable {
return "RefundDetail [outRefundNo=" + outRefundNo + ", refundId="
+ refundId + ", refundChannel=" + refundChannel
+ ", refundFee=" + refundFee + ", couponRefundFee="
- + couponRefundFee + ", refundStatus=" + refundStatus + "]";
+ + couponRefundFee + ", refundStatus=" + refundStatus
+ + ", recvUserId=" + recvUserId + ", reccvUserName="
+ + reccvUserName + ", signKeyIndex=" + signKeyIndex
+ + ", signType=" + signType + "]";
}
}
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundResult.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/RefundResult.java
similarity index 67%
rename from weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundResult.java
rename to weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/RefundResult.java
index de5ed3f9..49a17458 100644
--- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundResult.java
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/RefundResult.java
@@ -1,8 +1,7 @@
-package com.foxinmy.weixin4j.mp.payment.v3;
+package com.foxinmy.weixin4j.mp.payment;
import org.apache.commons.lang3.StringUtils;
-import com.foxinmy.weixin4j.mp.payment.ApiResult;
import com.foxinmy.weixin4j.mp.type.RefundChannel;
import com.thoughtworks.xstream.annotations.XStreamAlias;
@@ -41,6 +40,14 @@ public class RefundResult extends ApiResult {
// 现金券退款金额<=退款金 额,退款金额-现金券退款金 额为现金
@XStreamAlias("coupon_refund_fee")
private int couponRefundFee;
+ @XStreamAlias("recv_user_id")
+ private String recvUserId;// 转账退款接收退款的财付通帐号
+ @XStreamAlias("reccv_user_name")
+ private String reccvUserName;// 转账退款接收退款的姓名(需与接收退款的财 付通帐号绑定的姓名一致)
+ @XStreamAlias("sign_key_index")
+ private String signKeyIndex;// 多密钥支持的密钥序号,默认 1
+ @XStreamAlias("sign_type")
+ private String signType;// 签名类型,取值:MD5、RSA,默认:MD5
public String getTransactionId() {
return transactionId;
@@ -59,8 +66,16 @@ public class RefundResult extends ApiResult {
}
public String getRefundChannel() {
- return StringUtils.isBlank(refundChannel) ? RefundChannel.BALANCE
- .name() : refundChannel;
+ if (StringUtils.isBlank(refundChannel)) {
+ return RefundChannel.BALANCE.name();
+ }
+ // V2
+ if (refundChannel.equals("0")) {
+ return RefundChannel.TENPAY.name();
+ } else if (refundChannel.equals("1")) {
+ return RefundChannel.BALANCE.name();
+ }
+ return refundChannel;
}
/**
@@ -81,14 +96,25 @@ public class RefundResult extends ApiResult {
return couponRefundFee / 100d;
}
+ public String getSignKeyIndex() {
+ return signKeyIndex;
+ }
+
+ public String getSignType() {
+ return signType;
+ }
+
@Override
public String toString() {
return "RefundResult [transactionId=" + transactionId + ", outTradeNo="
+ outTradeNo + ", outRefundNo=" + outRefundNo + ", refundId="
+ refundId + ", refundChannel=" + refundChannel
+ ", refundFee=" + refundFee + ", couponRefundFee="
- + couponRefundFee + ", getAppId()=" + getAppId()
- + ", getMchId()=" + getMchId() + ", getNonceStr()="
+ + couponRefundFee + ", recvUserId=" + recvUserId
+ + ", reccvUserName=" + reccvUserName + ", signKeyIndex="
+ + signKeyIndex + ", signType=" + signType + ", getAppId()="
+ + getAppId() + ", getMchId()=" + getMchId()
+ + ", getSubMchId()=" + getSubMchId() + ", getNonceStr()="
+ getNonceStr() + ", getSign()=" + getSign()
+ ", getDeviceInfo()=" + getDeviceInfo() + ", getReturnCode()="
+ getReturnCode() + ", getReturnMsg()=" + getReturnMsg()
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/cacert.pem b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/cacert.pem
new file mode 100644
index 00000000..e379d950
--- /dev/null
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/cacert.pem
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDezCCAuSgAwIBAgIJAI7aVO7iYwcQMA0GCSqGSIb3DQEBBAUAMIGGMQswCQYD
+VQQGEwJDTjESMBAGA1UECBMJR1VBTkdET05HMREwDwYDVQQHEwhTSEVOWkhFTjEQ
+MA4GA1UEChMHVEVOQ0VOVDEMMAoGA1UECxMDT1NTMQwwCgYDVQQDEwNDRlQxIjAg
+BgkqhkiG9w0BCQEWE3RpcHlsdW9AdGVuY2VudC5jb20wHhcNMDYwMzE0MTQyMjIz
+WhcNMTYwMzExMTQyMjIzWjCBhjELMAkGA1UEBhMCQ04xEjAQBgNVBAgTCUdVQU5H
+RE9ORzERMA8GA1UEBxMIU0hFTlpIRU4xEDAOBgNVBAoTB1RFTkNFTlQxDDAKBgNV
+BAsTA09TUzEMMAoGA1UEAxMDQ0ZUMSIwIAYJKoZIhvcNAQkBFhN0aXB5bHVvQHRl
+bmNlbnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDZF0wb1UIgAbwq
+RgnQtGRZon1LG1NLd1CiFQO41aESrJ/3hWvnzlpxepIwi9H3xUuMeoP3kOSJoT5O
+EKOVkcgkzVcPebfBgnnLToMTduuHHJ+iWWPmzFsJQB5xetJXD1lqsxlDLZk2+eiD
+FuGfPKDaW76V24YPLCQ6uzaRMiFDaQIDAQABo4HuMIHrMB0GA1UdDgQWBBTi3asX
+klhRZA2dvy0onxvowmx2YzCBuwYDVR0jBIGzMIGwgBTi3asXklhRZA2dvy0onxvo
+wmx2Y6GBjKSBiTCBhjELMAkGA1UEBhMCQ04xEjAQBgNVBAgTCUdVQU5HRE9ORzER
+MA8GA1UEBxMIU0hFTlpIRU4xEDAOBgNVBAoTB1RFTkNFTlQxDDAKBgNVBAsTA09T
+UzEMMAoGA1UEAxMDQ0ZUMSIwIAYJKoZIhvcNAQkBFhN0aXB5bHVvQHRlbmNlbnQu
+Y29tggkAjtpU7uJjBxAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQCM
+VOZNmGO9XAtEPFuA3Q42LkfcwHK9Q0CAMbMPA4pNADxBWaQvv5okE3YG1RNGLp/y
+wyxXDs62qpEHcDPQh5porQKRP3PB54pL3AFLouEcuH4j7e8f8tqokOMmtTfeSUTJ
+wYWlbwUEu53AhNBlQl1zATkGmeURsmXg5GnuNAWafg==
+-----END CERTIFICATE-----
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/NativePayResponseV3.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/NativePayResponseV3.java
index efb367b6..a323e7c4 100644
--- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/NativePayResponseV3.java
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/NativePayResponseV3.java
@@ -3,6 +3,7 @@ package com.foxinmy.weixin4j.mp.payment.v3;
import org.apache.commons.lang3.StringUtils;
import com.foxinmy.weixin4j.exception.PayException;
+import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.mp.payment.ApiResult;
import com.foxinmy.weixin4j.mp.payment.PayUtil;
import com.foxinmy.weixin4j.util.RandomUtil;
@@ -27,9 +28,11 @@ public class NativePayResponseV3 extends ApiResult {
public NativePayResponseV3(PayPackageV3 payPackage, String returnMsg,
String resultMsg) throws PayException {
super.setReturnMsg(returnMsg);
- super.setReturnCode(StringUtils.isNotBlank(returnMsg) ? FAIL : SUCCESS);
+ super.setReturnCode(StringUtils.isNotBlank(returnMsg) ? Consts.FAIL
+ : Consts.SUCCESS);
this.setErrCodeDes(resultMsg);
- this.setResultCode(StringUtils.isNotBlank(resultMsg) ? FAIL : SUCCESS);
+ this.setResultCode(StringUtils.isNotBlank(resultMsg) ? Consts.FAIL
+ : Consts.SUCCESS);
this.setMchId(payPackage.getMch_id());
this.setAppId(payPackage.getAppid());
this.setNonceStr(RandomUtil.generateString(16));
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/PayRequestV3.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/PayRequestV3.java
index 0abbde66..e185a266 100644
--- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/PayRequestV3.java
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/PayRequestV3.java
@@ -2,7 +2,7 @@ package com.foxinmy.weixin4j.mp.payment.v3;
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.exception.PayException;
-import com.foxinmy.weixin4j.http.XmlResult;
+import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.mp.payment.PayRequest;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
@@ -32,11 +32,11 @@ public class PayRequestV3 extends PayRequest {
private PrePay prePay;
public PayRequestV3(PrePay prePay) throws PayException {
- if (!prePay.getReturnCode().equalsIgnoreCase(XmlResult.SUCCESS)) {
+ if (!prePay.getReturnCode().equalsIgnoreCase(Consts.SUCCESS)) {
throw new PayException(prePay.getReturnMsg(),
prePay.getReturnCode());
}
- if (!prePay.getResultCode().equalsIgnoreCase(XmlResult.SUCCESS)) {
+ if (!prePay.getResultCode().equalsIgnoreCase(Consts.SUCCESS)) {
throw new PayException(prePay.getResultCode(),
prePay.getErrCodeDes());
}
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/spider/WeixinExecutor.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/spider/WeixinExecutor.java
index 001fe741..d4fdd685 100644
--- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/spider/WeixinExecutor.java
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/spider/WeixinExecutor.java
@@ -2,8 +2,6 @@ package com.foxinmy.weixin4j.mp.spider;
import java.io.Serializable;
import java.net.URI;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -12,6 +10,7 @@ import java.util.Map;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
+import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
@@ -59,8 +58,6 @@ public class WeixinExecutor implements Serializable {
private final Logger logger = LoggerFactory.getLogger(getClass());
- private final static Charset charset = StandardCharsets.UTF_8;
-
private final static Map accountMap = new HashMap() {
private static final long serialVersionUID = 1L;
@@ -186,13 +183,13 @@ public class WeixinExecutor implements Serializable {
if (!StringUtils.isBlank(imgcode)) {
method.addHeader("Cookie", "sig=" + sig);
}
- method.setEntity(new UrlEncodedFormEntity(parameters, charset));
+ method.setEntity(new UrlEncodedFormEntity(parameters, Consts.UTF_8));
method.addHeader("Referer", weixin.getString("base"));
HttpResponse response = client.execute(host, method);
HttpEntity entity = response.getEntity();
- Document root = Jsoup.parse(entity.getContent(), charset.name(),
- weixin.getString("base"));
+ Document root = Jsoup.parse(entity.getContent(),
+ Consts.UTF_8.name(), weixin.getString("base"));
StatusLine line = response.getStatusLine();
logger.info("step1_login--->status={},body=\n{}", line,
root.toString());
@@ -270,7 +267,8 @@ public class WeixinExecutor implements Serializable {
.getValue()).append(";base64,");
base64.append(new String(
Base64.encodeBase64(IOUtil.toByteArray(response
- .getEntity().getContent())), charset));
+ .getEntity().getContent())),
+ Consts.UTF_8));
weixin.put("verifydata", base64.toString());
List cookieList = client.getCookieStore()
.getCookies();
@@ -311,8 +309,8 @@ public class WeixinExecutor implements Serializable {
HttpResponse response = client.execute(host, method);
HttpEntity entity = response.getEntity();
- Document root = Jsoup.parse(entity.getContent(), charset.name(),
- weixin.getString("base"));
+ Document root = Jsoup.parse(entity.getContent(),
+ Consts.UTF_8.name(), weixin.getString("base"));
StatusLine line = response.getStatusLine();
logger.info("step2_setting--->status={},body=\n{}", line,
root.toString());
@@ -331,7 +329,7 @@ public class WeixinExecutor implements Serializable {
response = client.execute(host, method);
entity = response.getEntity();
- root = Jsoup.parse(entity.getContent(), charset.name(),
+ root = Jsoup.parse(entity.getContent(), Consts.UTF_8.name(),
weixin.getString("base"));
line = response.getStatusLine();
weixin.put("step", "2-1");
@@ -378,8 +376,8 @@ public class WeixinExecutor implements Serializable {
response = client.execute(host, method);
entity = response.getEntity();
- root = Jsoup.parse(entity.getContent(), charset.name(),
- weixin.getString("base"));
+ root = Jsoup.parse(entity.getContent(),
+ Consts.UTF_8.name(), weixin.getString("base"));
line = response.getStatusLine();
if (line.getStatusCode() == HttpStatus.SC_OK) {
@@ -402,11 +400,12 @@ public class WeixinExecutor implements Serializable {
System.currentTimeMillis() + ""));
post.setEntity(new UrlEncodedFormEntity(parameters,
- charset));
+ Consts.UTF_8));
response = client.execute(host, post);
entity = response.getEntity();
root = Jsoup.parse(entity.getContent(),
- charset.name(), weixin.getString("base"));
+ Consts.UTF_8.name(),
+ weixin.getString("base"));
line = response.getStatusLine();
logger.info(
"step2_bedeveloper--->status={},body=\n{}",
@@ -422,7 +421,7 @@ public class WeixinExecutor implements Serializable {
response = client.execute(host, method);
entity = response.getEntity();
root = Jsoup.parse(entity.getContent(),
- charset.name(),
+ Consts.UTF_8.name(),
weixin.getString("base"));
} else {
weixin.put("code", "-100");
@@ -495,13 +494,13 @@ public class WeixinExecutor implements Serializable {
.add(new BasicNameValuePair("callback_encrypt_mode", "0"));
parameters.add(new BasicNameValuePair("operation_seq", RandomUtil
.generateStringByNumberChar(9)));
- method.setEntity(new UrlEncodedFormEntity(parameters, charset));
+ method.setEntity(new UrlEncodedFormEntity(parameters, Consts.UTF_8));
method.addHeader("Referer", weixin.getString("developerModifyUrl"));
HttpResponse response = client.execute(host, method);
HttpEntity entity = response.getEntity();
- Document root = Jsoup.parse(entity.getContent(), charset.name(),
- weixin.getString("base"));
+ Document root = Jsoup.parse(entity.getContent(),
+ Consts.UTF_8.name(), weixin.getString("base"));
StatusLine line = response.getStatusLine();
logger.info("step3_setting--->status={},body=\n{}", line,
root.toString());
@@ -565,13 +564,13 @@ public class WeixinExecutor implements Serializable {
.currentTimeMillis() + ""));
method.setEntity(new UrlEncodedFormEntity(parameters,
- charset));
+ Consts.UTF_8));
method.setURI(URI.create(weixin.getString("start")));
response = client.execute(host, method);
entity = response.getEntity();
- root = Jsoup.parse(entity.getContent(), charset.name(),
- weixin.getString("base"));
+ root = Jsoup.parse(entity.getContent(),
+ Consts.UTF_8.name(), weixin.getString("base"));
line = response.getStatusLine();
logger.info("step3_setting--->status={},body=\n{}",
line, root.toString());
@@ -624,13 +623,14 @@ public class WeixinExecutor implements Serializable {
parameters.add(new BasicNameValuePair("lang", "zh_CN"));
parameters.add(new BasicNameValuePair("random", System
.currentTimeMillis() + ""));
- method.setEntity(new UrlEncodedFormEntity(parameters, charset));
+ method.setEntity(new UrlEncodedFormEntity(parameters,
+ Consts.UTF_8));
method.addHeader("Referer", weixin.getString("developerUrl"));
HttpResponse response = client.execute(host, method);
HttpEntity entity = response.getEntity();
Document root = Jsoup.parse(entity.getContent(),
- charset.name(), weixin.getString("base"));
+ Consts.UTF_8.name(), weixin.getString("base"));
StatusLine line = response.getStatusLine();
logger.info("step4_back--->status={},body=\n{}", line,
root.toString());
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/BillType.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/BillType.java
index 7bd7b8c6..7cfc69b6 100644
--- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/BillType.java
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/BillType.java
@@ -2,6 +2,7 @@ package com.foxinmy.weixin4j.mp.type;
/**
* 对账单类型
+ *
* @className BillType
* @author jy
* @date 2014年10月31日
@@ -9,5 +10,13 @@ package com.foxinmy.weixin4j.mp.type;
* @see
*/
public enum BillType {
- ALL, SUCCESS, REFUND
+ ALL(0), SUCCESS(1), REFUND(2);
+ private int val;
+
+ BillType(int val) {
+ this.val = val;
+ }
+ public int getVal() {
+ return val;
+ }
}
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/RefundChannel.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/RefundChannel.java
index 672bdcf0..26721d75 100644
--- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/RefundChannel.java
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/RefundChannel.java
@@ -11,5 +11,8 @@ package com.foxinmy.weixin4j.mp.type;
*/
public enum RefundChannel {
ORIGINAL, // 原路退款
- BALANCE;// 退回到余额
+ BALANCE,// 退回到余额
+
+ TENPAY, // 财付通
+ BANK; // 银行
}
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/RefundStatus.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/RefundStatus.java
index 12f3b46a..9c996b99 100644
--- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/RefundStatus.java
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/RefundStatus.java
@@ -14,7 +14,6 @@ public enum RefundStatus {
FAIL, // 退款失败
PROCESSING, // 退款处理中
NOTSURE, // 未确定,需要商户 原退款单号重新发起
- // 转入代发,退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败,资金回流到商户的现金帐号,需要商户人工干
- // 预,通过线下或者财付通转 账的方式进行退款。
- CHANGE;
+ CHANGE; // 转入代发,退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败,资金回流到商户的现金帐号,需要商户人工干预,通过线下或者财付通转
+ // 账的方式进行退款。
}
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/SemCategory.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/SemCategory.java
new file mode 100644
index 00000000..7f03212c
--- /dev/null
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/SemCategory.java
@@ -0,0 +1,61 @@
+package com.foxinmy.weixin4j.mp.type;
+
+/**
+ * 垂直服务协议
+ *
+ * @className SemCategory
+ * @author jy
+ * @date 2014年11月7日
+ * @since JDK 1.7
+ * @see
+ */
+public enum SemCategory {
+ // 生活类
+ restaurant("生活类", "餐馆", "查询餐馆的服务,例如:中关村附近的面馆"), map("生活类", "地图",
+ "查询地图服务,例如:从银科大厦到天坛公园怎么走"), nearby("生活类", "周边",
+ "查询周边的服务,例如:我想去打保龄球"), coupon("生活类", "优惠券/团购",
+ "查询优惠券/团购的服务,例如:“附 近有什么优惠券”;如果查已有类别 的优惠券,比如:“附近有什么酒店 优惠券”,那么就会优先是酒店类。"),
+ // 旅行类
+ hotel("旅行类", "酒店", "查询酒店服务,例如:查一下中关村附近有没有七天酒店"), travel("旅行类", "旅游",
+ "查询旅游服务,例如:故宫门票多少钱"), flight("旅行类", "航班", "查询航班的服务,例如:明天从北京到上海的机票"), train(
+ "旅行类", "火车", "查询火车服务,例如:查一下从北京到西安的火车"),
+ // 娱乐类
+ movie("娱乐类", "上映电影", "查询上映电影的服务,例如:最近有什么好看的电影"), music("娱乐类", "音乐",
+ "查询音乐的服务,例如:来点刘德华的歌"), video("娱乐类", "视频", "查询视频服务,例如:我想看甄嬛传"), novel(
+ "娱乐类", "小说", "查询小说的服务,例如:来点言情小说看看"),
+ // 工具类
+ weather("工具类", "天气", "查询天气的服务,例如:明天北京天气"), stock("工具类", "股票",
+ "查询股票的服务,例如:腾讯股价多少了"), remind("工具类", "提醒", "提醒服务,例如:提醒我明天上午十点开会"), telephone(
+ "工具类", "常用电影", "查询常用电话号码服务,例如:查询一下招行信用卡的电话"),
+ // 知识类
+ cookbook("知识类", "菜谱", "查询菜谱服务,例如:宫保鸡丁怎么做"), baike("知识类", "百科",
+ "查询百科服务,例如:查一下刘德华的百科资料"), news("知识类", "资讯", "查询新闻服务,例如:今天有什么新闻"),
+ // 其他类
+ tv("其他类", "电视节目预告", "查询电视节目服务,例如:湖南台今晚有什么节目"), instruction("其他类", "通用指令",
+ "通用指令服务,例如:把声音调高一点"), tv_instruction("其他类", "电视指令",
+ "电视指令服务,例如:切换到中央五台"), car_instruction("其他类", "车载指令",
+ "车载指令服务,例如:把空调设为 25 度"), app("其他类", "应用", "查询应用服务,例如:打开愤怒的小鸟"), website(
+ "其他类", "网址", "查询网址服务,例如:帮我打开腾讯网"), search("其他类", "网页搜索",
+ "网页搜索服务,例如:百度一下意大利对乌拉圭");
+ SemCategory(String main, String desc, String remark) {
+ this.main = main;
+ this.desc = desc;
+ this.remark = remark;
+ }
+
+ private String main;
+ private String desc;
+ private String remark;
+
+ public String getMain() {
+ return main;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+
+ public String getRemark() {
+ return remark;
+ }
+}
diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/resources/weixin.properties b/weixin4j-mp/weixin4j-mp-api/src/main/resources/weixin.properties
index 68a632f1..b423ddfe 100644
--- a/weixin4j-mp/weixin4j-mp-api/src/main/resources/weixin.properties
+++ b/weixin4j-mp/weixin4j-mp-api/src/main/resources/weixin.properties
@@ -15,4 +15,4 @@ media_path=/tmp/weixin/media
# \u5bf9\u8d26\u5355\u4fdd\u5b58\u8def\u5f84
bill_path=/tmp/weixin/bill
# ca\u8bc1\u4e66\u5b58\u653e\u7684\u5b8c\u6574\u8def\u5f84
-ca_file=/tmp/weixin/xxxxx.p12
\ No newline at end of file
+ca_file=/Users/jy/Downloads/1221928801.pfx
\ No newline at end of file
diff --git a/weixin4j-mp/weixin4j-mp-api/src/test/java/com/foxinmy/weixin4j/mp/test/SemanticTest.java b/weixin4j-mp/weixin4j-mp-api/src/test/java/com/foxinmy/weixin4j/mp/test/SemanticTest.java
new file mode 100644
index 00000000..913ed43f
--- /dev/null
+++ b/weixin4j-mp/weixin4j-mp-api/src/test/java/com/foxinmy/weixin4j/mp/test/SemanticTest.java
@@ -0,0 +1,27 @@
+package com.foxinmy.weixin4j.mp.test;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.foxinmy.weixin4j.exception.WeixinException;
+import com.foxinmy.weixin4j.mp.api.HelperApi;
+import com.foxinmy.weixin4j.mp.model.SemQuery;
+import com.foxinmy.weixin4j.mp.type.SemCategory;
+
+public class SemanticTest extends TokenTest {
+ private HelperApi helperApi;
+
+ @Before
+ public void init() {
+ helperApi = new HelperApi(tokenHolder);
+ }
+
+ @Test
+ public void testApi() throws WeixinException {
+ SemQuery query = SemQuery.build("附近有啥 100 元以内的保龄球馆");
+ query.city("北京").category(SemCategory.nearby);
+ query.uid("opKwyt6IhrqPmTTZshyqH5W9gIVo");
+ System.out.println(query);
+ System.out.println(helperApi.semantic(query));
+ }
+}