t = new SubscribeEntity<>();
+// t.setTouser(toUser);
+// t.setTemplate_id(SUBSCRIBE_MSG_ID_ORDERSEND);
+// t.setData(new ReceiveSubscriOrderSendData(params));
+// System.out.println(JacksonUtil.beanToJson(t));
+// ret = httpsRequest(url, "POST", JacksonUtil.beanToJson(t));
+// break;
+// }
+// default: {
+// break;
+// }
+// }
+// //ok: {"errcode":0,"errmsg":"ok"}
+// //err: {"errcode":43101,"errmsg":"user refuse to accept the msg hint: [V_GEdA02503942]"}
+// System.out.println("Send Subscribe Message:" + ret);
+// String errCode = pers.wei.wx.pay.util.JacksonUtil.getJsonValue(ret, "errcode");
+// System.out.println(errCode);
+// return errCode.equals("0");
+// }
+}
diff --git a/wechatutil/src/main/java/com/ccsens/wechatutil/payutil/WxPayDirectUtils.java b/wechatutil/src/main/java/com/ccsens/wechatutil/payutil/WxPayDirectUtils.java
new file mode 100644
index 00000000..c4039a1a
--- /dev/null
+++ b/wechatutil/src/main/java/com/ccsens/wechatutil/payutil/WxPayDirectUtils.java
@@ -0,0 +1,322 @@
+package com.ccsens.wechatutil.payutil;
+
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.ccsens.wechatutil.exception.PayException;
+import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
+import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
+import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
+import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
+import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
+import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.util.EntityUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.*;
+import java.math.BigInteger;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
+import java.security.PrivateKey;
+import java.security.Signature;
+import java.util.Base64;
+import java.util.UUID;
+
+/**
+ * 微信直连商户支付
+ * @author :mr.zhangsan
+ * @date :Created in 2021/6/18 23:58
+ * @version v1.0:
+ */
+@Slf4j
+public class WxPayDirectUtils {
+
+ //商户支付URL
+ private static final String URL_TRANSACTIONS
+ = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";
+ //测试小程序号appid
+ public static final String TK_APPID = "wxa26bb3e3f1d2d998";
+ //测试商户号
+ public static final String TK_MCHID = "1603930405";
+ //测试小程序秘钥secret
+ public static final String TK_SECRET = "162cc6eb70bc341bc67fea210796be21";
+ //商户私钥
+ private static PrivateKey privateKey;
+ //版本>=0.1.5可使用 AutoUpdateCertificatesVerifier 类替代默认的验签器。
+ // 它会在构造时自动下载商户对应的微信支付平台证书,并每隔一段时间(默认为1个小时)更新证书。
+ private static AutoUpdateCertificatesVerifier verifier = null;
+ //WechatPayHttpClient
+ private static HttpClient httpClient = null;
+ //测试商户证书存放路径
+ private static final String Client_Key_Path = "C:\\home\\fxxt\\cert_tk\\apiclient_key.pem";
+ //测试商户v3key
+ private static final String DIRECT_V3_Key = "5IDIy173oyjSGPZHuP0lc2V3UqFBO55M";
+ //测试证书序列号
+ private static final String DIRECT_CERT_SERIAL_NO = "368344414C13EA2ABF3A59A8CF3F31E99ACE0058";
+
+
+ /**
+ * 支付订单状态
+ */
+ public enum PayOrderStatus {
+ SUCCESS, NOTPAY, CLOSED, REVOKED, USERPAYING, PAYERROR, FAILED, UNKNOWN
+ }
+
+
+ /**
+ * 商户统一下单支付
+ *
+ * 应用ID appid string[1,32] 是 body 由微信生成的应用ID,全局唯一。请求基础下单接口时请注意APPID的应用属性,例如公众号场景下,需使用应用属性为公众号的APPID
+ * 示例值:wxd678efh567hg6787
+ * 直连商户号 mchid string[1,32] 是 body 直连商户的商户号,由微信支付生成并下发。
+ * 示例值:1230000109
+ * 商品描述 description string[1,127] 是 body 商品描述
+ * 示例值:Image形象店-深圳腾大-QQ公仔
+ * 商户订单号 out_trade_no string[6,32] 是 body 商户系统内部订单号,只能是数字、大小写字母_-*且在同一个商户号下唯一
+ * 示例值:1217752501201407033233368018
+ * 交易结束时间 time_expire string[1,64] 否 body 订单失效时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss表示时分秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35+08:00表示,北京时间2015年5月20日 13点29分35秒。
+ * 示例值:2018-06-08T10:34:56+08:00
+ * 附加数据 attach string[1,128] 否 body 附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用
+ * 示例值:自定义数据
+ * 通知地址 notify_url string[1,256] 是
+ */
+ public static JSONObject transactions(String openid, String outTradeNo, String description, String notifyUrl, int totalFee) throws Exception {
+ HttpPost httpPost = new HttpPost(URL_TRANSACTIONS);
+ httpPost.addHeader("Accept", "application/json");
+ httpPost.addHeader("Content-type", "application/json; charset=utf-8");
+
+ JSONObject params = new JSONObject();
+ JSONObject amount = new JSONObject();
+ JSONObject payer = new JSONObject();
+ payer.put("openid", openid);
+
+ amount.put("total", totalFee);
+ amount.put("currency", "CNY");
+
+ params.put("appid", TK_APPID);
+ params.put("mchid", TK_MCHID);
+ params.put("out_trade_no", outTradeNo);
+ params.put("description", description);
+ params.put("notify_url", notifyUrl);
+ params.put("amount", amount);
+ params.put("payer", payer);
+
+ httpPost.setEntity(new StringEntity(params.toJSONString(), "UTF-8"));
+ CloseableHttpResponse response = (CloseableHttpResponse) getWechatPayHttpClient().execute(httpPost);
+ String bodyAsString = EntityUtils.toString(response.getEntity());
+ JSONObject respJson = JSONObject.parseObject(bodyAsString);
+
+ Object prepayId = respJson.get("prepay_id");
+ Object code = respJson.get("code");
+
+ if (code != null) {
+ throw new Exception(respJson.get("message").toString());
+ }
+ JSONObject result = new JSONObject();
+ //根据返回的prepay_id生成发起支付需要的参数签名返回前端
+
+ result.put("appId", TK_APPID);
+ result.put("timeStamp", System.currentTimeMillis() / 1000);
+ result.put("nonceStr", createNonceStr());
+ result.put("package", "prepay_id=" + prepayId);
+ result.put("signType", "RSA");
+
+ String message = TK_APPID + "\n"
+ + result.get("timeStamp") + "\n"
+ + result.get("nonceStr") + "\n"
+ + result.get("package") + "\n";
+ String sign = wxPayReqSign(message.getBytes("utf-8"));
+ result.put("paySign", sign);
+ return result;
+ }
+
+ /**
+ * 解析支付完毕微信通知参数
+ *
+ * signature 头部签名 Wechatpay-Signature
+ * body json消息
+ * @return
+ * @throws IOException 参数名 变量 类型[长度限制] 必填 描述
+ */
+ public static JSONObject rechargeResult(HttpServletRequest request) throws Exception {
+ log.info("解析支付完毕微信通知参数");
+ //一、验证签名
+ //1.1获取平台证书
+ getVerifier();
+ //1.2检查平台证书序列号
+ String wepaySerial = request.getHeader("Wechatpay-Serial");
+ if (wepaySerial == null) {
+ throw new PayException(-9, "平台证书序列号为空");
+ }
+ log.info("获取平台证书序列号");
+ //获取平台证书序列号
+ BigInteger currentSerial = getVerifier().getValidCertificate().getSerialNumber();
+ if (StrUtil.isEmpty(wepaySerial) || !wepaySerial.equalsIgnoreCase(currentSerial.toString(16))) {
+ throw new PayException(-9, "证书序列号不一致");
+ }
+ log.info("3构造验签名串");
+ //1.3构造验签名串
+ String wepayNonce = request.getHeader("Wechatpay-Nonce");
+ String wepayTimestamp = request.getHeader("Wechatpay-Timestamp");
+ String wepayBody = null;
+ BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
+ String line = null;
+ StringBuilder body = new StringBuilder();
+ while ((line = br.readLine()) != null) {
+ body.append(line);
+ }
+ if (StrUtil.isEmpty(body.toString())) {
+ throw new PayException(-9, "body is null");
+ }
+ wepayBody = body.toString();
+
+
+ String message = wepayTimestamp + "\n"
+ + wepayNonce + "\n"
+ + body.toString() + "\n";
+ log.info("获取应答签名");
+ //1.4获取应答签名
+ String wepySignature = request.getHeader("Wechatpay-Signature");
+
+ //1.5验证签名
+ boolean rr = getVerifier().verify(wepaySerial,
+ message.getBytes(StandardCharsets.UTF_8),wepySignature);
+ if (!rr){
+ //TODO 签名验证失败抛异常
+ }
+// String sign = wxPayRespSign(message.getBytes("utf-8"));
+// if (!wepySignature.equals(sign)) {
+// throw new PayException(-9, "验证签名不一致");
+// }
+ log.info("解密数据");
+ //二、解密数据
+ JSONObject jsonObject = JSONObject.parseObject(wepayBody);
+ JSONObject resource = (JSONObject) jsonObject.get("resource");
+ AesUtil aesUtil = new AesUtil(DIRECT_V3_Key.getBytes("utf-8"));
+ //解密
+ String decryptToString = aesUtil.decryptToString(
+ resource.get("associated_data").toString().getBytes(),
+ resource.get("nonce").toString().getBytes(),
+ resource.get("ciphertext").toString());
+ JSONObject parseObject = JSONObject.parseObject(decryptToString);
+ return parseObject;
+ }
+
+ private static PayOrderStatus getPayOrderStatus(URIBuilder uriBuilder) throws URISyntaxException, IOException {
+ HttpGet httpGet = new HttpGet(uriBuilder.build());
+ httpGet.addHeader("Accept", "application/json");
+
+ CloseableHttpResponse response = (CloseableHttpResponse) getWechatPayHttpClient().execute(httpGet);
+
+ String bodyAsString = EntityUtils.toString(response.getEntity());
+
+ JSONObject jsonObject = JSONObject.parseObject(bodyAsString);
+ log.info("json:{}", jsonObject);
+ Object trade_state = jsonObject.get("trade_state");
+ if (trade_state != null) {
+ String tradeState = trade_state.toString();
+ log.info("PayOrderStatus:{}",tradeState);
+ if ("SUCCESS".equals(tradeState)) {
+ return PayOrderStatus.SUCCESS;
+ } else if ("USERPAYING".equals(tradeState)) {
+ return PayOrderStatus.USERPAYING;
+ } else {
+ return PayOrderStatus.FAILED;
+ }
+ }
+ return PayOrderStatus.UNKNOWN;
+ }
+
+ /**
+ * 商户订单号查询
+ *
+ * @param transactionId 微信订单号
+ * @return
+ * @throws IOException
+ * @throws URISyntaxException
+ */
+ public static PayOrderStatus wechatOrder(String transactionId) throws IOException, URISyntaxException {
+ URIBuilder uriBuilder = new URIBuilder("https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/" + transactionId + "?mchid=" + TK_MCHID);
+ return getPayOrderStatus(uriBuilder);
+ }
+
+ /**
+ * 根据商户证书,获取私钥
+ *
+ * @return
+ * @throws FileNotFoundException
+ */
+ public static PrivateKey getPrivateKey() throws FileNotFoundException {
+ if (privateKey == null) {
+ privateKey = PemUtil.loadPrivateKey(
+ new FileInputStream(Client_Key_Path));
+ }
+ return privateKey;
+ }
+
+ /**
+ * 依据商户证书私钥进行签名
+ *
+ * @param message
+ * @return
+ * @throws Exception
+ */
+ public static String wxPayReqSign(byte[] message) throws Exception {
+ Signature sign = Signature.getInstance("SHA256withRSA");
+ sign.initSign(getPrivateKey());
+ sign.update(message);
+
+ return Base64.getEncoder().encodeToString(sign.sign());
+ }
+
+ /**
+ * 根据微信平台证书获取httpclient
+ *
+ * @return
+ * @throws FileNotFoundException
+ * @throws UnsupportedEncodingException
+ */
+ public static HttpClient getWechatPayHttpClient() throws FileNotFoundException, UnsupportedEncodingException {
+ if (httpClient == null) {
+ //构造WechatPayHttpClientBuilder
+ WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
+ .withMerchant(TK_MCHID, DIRECT_CERT_SERIAL_NO, getPrivateKey())
+ .withValidator(new WechatPay2Validator(getVerifier()));
+
+ // 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新
+ httpClient = builder.build();
+ }
+ return httpClient;
+ }
+
+ /**
+ * 自动获取微信平台证书
+ *
+ * @throws UnsupportedEncodingException
+ */
+ public static AutoUpdateCertificatesVerifier getVerifier() throws FileNotFoundException {
+ //不需要传入微信支付证书了
+ if (verifier == null) {
+ verifier = new AutoUpdateCertificatesVerifier(
+ new WechatPay2Credentials(TK_MCHID, new PrivateKeySigner(DIRECT_CERT_SERIAL_NO, getPrivateKey())),
+ DIRECT_V3_Key.getBytes(StandardCharsets.UTF_8));
+ }
+ return verifier;
+ }
+
+
+ /**
+ * 生成随机字符串
+ *
+ * @return
+ */
+ public static String createNonceStr() {
+ return UUID.randomUUID().toString().replace("-", "");
+ }
+}
diff --git a/wechatutil/src/main/java/com/ccsens/wechatutil/payutil/WxPayProviderUtils.java b/wechatutil/src/main/java/com/ccsens/wechatutil/payutil/WxPayProviderUtils.java
new file mode 100644
index 00000000..908f21f5
--- /dev/null
+++ b/wechatutil/src/main/java/com/ccsens/wechatutil/payutil/WxPayProviderUtils.java
@@ -0,0 +1,687 @@
+package com.ccsens.wechatutil.payutil;
+
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.ccsens.util.HttpsUtil;
+import com.ccsens.wechatutil.exception.PayException;
+import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
+import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
+import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
+import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
+import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
+import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.util.EntityUtils;
+import javax.servlet.http.HttpServletRequest;
+import java.io.*;
+import java.math.BigInteger;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
+import java.security.PrivateKey;
+import java.security.Signature;
+import java.util.*;
+
+/**
+ * 微信服务商支付
+ * @author :mr.zhangsan
+ * @date :Created in 2021/5/15 22:24
+ * @version v1.0:
+ */
+@Slf4j
+public class WxPayProviderUtils {
+
+ /**
+ * 支付订单状态
+ */
+ public enum PayOrderStatus {
+ SUCCESS, NOTPAY, CLOSED, REVOKED, USERPAYING, PAYERROR, FAILED, UNKNOWN
+ }
+
+ private static final String URL_MERCHANT_PAY
+ = "https://api.mch.weixin.qq.com/v3/pay/partner/transactions/jsapi";
+ //退款url
+ private static final String URL_REFUND_PAY
+ = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds";
+ //查询退款url
+ private static final String SEL_URL_REFUND_PAY
+ = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds";
+ //付款到零钱url
+ private static final String URL_PAYTO_USER
+ = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds";
+ //商户支付URL
+ private static final String URL_TRANSACTIONS
+ = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";
+ //测试小程序APPID
+ private static final String appid = "wxf30402e727f0840a";
+ //测试小程序secret
+ private static final String secret = "70402290ac83857c7324b0ee881b544a";
+ //商户支付
+ //服务商API秘钥key
+ private static final String KEY = "5a689a2d6b8c4ff499c23d998fde0941";
+ // 服务商应用ID(公众号appid)
+ private static final String SPAPPID = "wx65d45856040e9a4a";
+ // 服务商户号
+ private static final String SPMECHID = "1610985721";
+ //子商户应用ID
+ private static final String SUBAPPID = appid;
+ // 子商户号
+ private static final String SUBMCHID = "1611259929";
+ //服务商证书序列号
+ private static final String CERT_SERIAL_NO = "1251E728C5B765190B641C9B45B2A18A4DDEC553";
+ //微信提现url
+ private static final String URL_PAY_TO_USR_WX
+ = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
+ //服务商证书存放路径
+ private static final String Client_Key_Path = "C:\\home\\fxxt\\cert_fws\\apiclient_key.pem";
+ //服务商APIv3Key
+ private static final String API_V3_Key = "gRcJ8bpi5imIm4qbbRch5iSSD77DFCKY";
+ //测试商户证书存放路径
+ public static final String PATH_WX_CRET = "C:\\home\\fxxt\\cert_zyc\\apiclient_key.pem";
+ //测试商户私钥
+ private static PrivateKey privateKey;
+ //版本>=0.1.5可使用 AutoUpdateCertificatesVerifier 类替代默认的验签器。
+ // 它会在构造时自动下载商户对应的微信支付平台证书,并每隔一段时间(默认为1个小时)更新证书。
+ private static AutoUpdateCertificatesVerifier verifier = null;
+ //WechatPayHttpClient
+ private static HttpClient httpClient = null;
+ //加密方式
+ private static final String schema = "WECHATPAY2-SHA256-RSA2048";
+
+ /**
+ * 私有构造 不允许生成实例, 只允许调用静态方法
+ */
+ private WxPayProviderUtils() {
+
+ }
+
+ /**
+ * 生成随机字符串
+ *
+ * @return
+ */
+ public static String createNonceStr() {
+ return UUID.randomUUID().toString().replace("-", "");
+ }
+
+
+ /**
+ * 依据商户证书私钥进行签名
+ *
+ * @param message
+ * @return
+ * @throws Exception
+ */
+ private static String wxPayReqSign(byte[] message) throws Exception {
+ Signature sign = Signature.getInstance("SHA256withRSA");
+ sign.initSign(getPrivateKey());
+ sign.update(message);
+
+ return Base64.getEncoder().encodeToString(sign.sign());
+ }
+
+ /**
+ * 依据微信支付平台证书(公钥)进行签名
+ *
+ * @param message
+ * @return
+ * @throws Exception
+ */
+ private static boolean wxPayRespSign(byte[] message,String signature) throws Exception {
+ Signature sign = Signature.getInstance("SHA256withRSA");
+ sign.initVerify(getVerifier().getValidCertificate());
+ sign.update(message);
+ return sign.verify(Base64.getDecoder().decode(signature));
+ }
+
+ /**
+ * 根据商户证书,获取私钥
+ *
+ * @return
+ * @throws FileNotFoundException
+ */
+ public static PrivateKey getPrivateKey() throws FileNotFoundException {
+ if (privateKey == null) {
+ privateKey = PemUtil.loadPrivateKey(
+ new FileInputStream(Client_Key_Path));
+ }
+ return privateKey;
+ }
+
+ /**
+ * 自动获取微信平台证书
+ *
+ * @throws UnsupportedEncodingException
+ */
+ public static AutoUpdateCertificatesVerifier getVerifier() throws FileNotFoundException {
+ //不需要传入微信支付证书了
+ if (verifier == null) {
+ verifier = new AutoUpdateCertificatesVerifier(
+ new WechatPay2Credentials(SPMECHID, new PrivateKeySigner(CERT_SERIAL_NO, getPrivateKey())),
+ API_V3_Key.getBytes(StandardCharsets.UTF_8));
+ }
+ return verifier;
+ }
+
+ /**
+ * 根据微信平台证书获取httpclient
+ *
+ * @return
+ * @throws FileNotFoundException
+ * @throws UnsupportedEncodingException
+ */
+ public static HttpClient getWechatPayHttpClient() throws FileNotFoundException, UnsupportedEncodingException {
+ if (httpClient == null) {
+ //构造WechatPayHttpClientBuilder
+ WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
+ .withMerchant(SPMECHID, CERT_SERIAL_NO, getPrivateKey())
+ .withValidator(new WechatPay2Validator(getVerifier()));
+
+ // 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新
+ httpClient = builder.build();
+ }
+ return httpClient;
+ }
+
+ /**
+ * 服务商统一下单支付
+ */
+ public static JSONObject merchantPreparyPay(String openid, String outTradeNo, String description, String notifyUrl, int totalFee) throws Exception {
+ HttpPost httpPost = new HttpPost(URL_MERCHANT_PAY);
+ httpPost.addHeader("Accept", "application/json");
+ httpPost.addHeader("Content-type", "application/json; charset=utf-8");
+
+ JSONObject params = new JSONObject();
+ JSONObject amount = new JSONObject();
+ JSONObject payer = new JSONObject();
+ payer.put("sub_openid", openid);
+
+ amount.put("total", totalFee);
+ amount.put("currency", "CNY");
+
+ params.put("sp_mchid", SPMECHID);
+ params.put("sub_mchid", SUBMCHID);
+ log.info("out_trade_no:{}", outTradeNo);
+ params.put("out_trade_no", outTradeNo);
+ params.put("sp_appid", SPAPPID);
+ params.put("sub_appid", SUBAPPID);
+ params.put("description", description);
+ params.put("notify_url", notifyUrl);
+ params.put("amount", amount);
+ params.put("payer", payer);
+
+ httpPost.setEntity(new StringEntity(params.toJSONString(), "UTF-8"));
+ CloseableHttpResponse response = (CloseableHttpResponse) getWechatPayHttpClient().execute(httpPost);
+ String bodyAsString = EntityUtils.toString(response.getEntity());
+ JSONObject respJson = JSONObject.parseObject(bodyAsString);
+ Object prepayId = respJson.get("prepay_id");
+ Object code = respJson.get("code");
+
+ if (code != null) {
+ throw new Exception(respJson.get("message").toString());
+ }
+ JSONObject result = new JSONObject();
+ //根据返回的prepay_id生成发起支付需要的参数签名返回前端
+
+ result.put("appId", SUBAPPID);
+ result.put("timeStamp", System.currentTimeMillis() / 1000);
+ result.put("nonceStr", createNonceStr());
+ result.put("package", "prepay_id=" + prepayId);
+ result.put("signType", "RSA");
+
+ log.info("准备签名");
+ String message = SUBAPPID + "\n"
+ + result.get("timeStamp") + "\n"
+ + result.get("nonceStr") + "\n"
+ + result.get("package") + "\n";
+ String sign = wxPayReqSign(message.getBytes(StandardCharsets.UTF_8));
+ log.info("sign:{}", sign);
+ result.put("paySign", sign);
+ return result;
+ }
+
+ /**
+ * 解析支付完毕微信通知参数
+ *
+ * signature 头部签名 Wechatpay-Signature
+ * body json消息
+ *
+ * @return
+ * @throws IOException 参数名 变量 类型[长度限制] 必填 描述
+ */
+ public JSONObject rechargeResult(HttpServletRequest request) throws Exception {
+ //一、验证签名
+ //1.1获取平台证书
+ getVerifier();
+ //1.2检查平台证书序列号
+ String wepaySerial = request.getHeader("Wechatpay-Serial");
+ if (wepaySerial == null) {
+ throw new PayException(-9, "平台证书序列号为空");
+ }
+ //获取平台证书序列号
+ BigInteger currentSerial = getVerifier().getValidCertificate().getSerialNumber();
+ log.info("currentSerial:{} " + currentSerial.toString(16));
+ log.info("wepaySerial:{} " + wepaySerial);
+ if (StrUtil.isEmpty(wepaySerial) || !wepaySerial.equalsIgnoreCase(currentSerial.toString(16))) {
+ throw new PayException(-9, "证书序列号不一致");
+ }
+ //1.3构造验签名串
+ String wepayNonce = request.getHeader("Wechatpay-Nonce");
+ String wepayTimestamp = request.getHeader("Wechatpay-Timestamp");
+ String wepayBody = null;
+ BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8));
+ String line = null;
+ StringBuilder body = new StringBuilder();
+ while ((line = br.readLine()) != null) {
+ body.append(line);
+ }
+ if (StrUtil.isEmpty(body.toString())) {
+ throw new PayException(-9, "body is null");
+ }
+ wepayBody = body.toString();
+
+ String message = wepayTimestamp + "\n"
+ + wepayNonce + "\n"
+ + body.toString() + "\n";
+ //1.4获取应答签名
+ String wepySignature = request.getHeader("Wechatpay-Signature");
+ log.info("----------------1,{}\n----{}", wepySignature, message);
+
+
+ //1.5验证签名
+ boolean rr = getVerifier().verify(wepaySerial,
+ message.getBytes(StandardCharsets.UTF_8), wepySignature);
+
+// boolean rr = wxPayRespSign(message.getBytes("utf-8"), wepySignature);
+ if (!rr) {
+ //TODO 签名验证失败抛异常
+ throw new PayException(-9, "验证签名不一致");
+ }
+ log.info("+++++++++++zzc 签名调用+++++++++++++++++++++ ");
+ //二、解密数据
+ JSONObject jsonObject = JSONObject.parseObject(wepayBody);
+ JSONObject resource = (JSONObject) jsonObject.get("resource");
+ AesUtil aesUtil = new AesUtil(API_V3_Key.getBytes("utf-8"));
+ //解密
+ String decryptToString = aesUtil.decryptToString(
+ resource.get("associated_data").toString().getBytes(),
+ resource.get("nonce").toString().getBytes(),
+ resource.get("ciphertext").toString());
+ JSONObject parseObject = JSONObject.parseObject(decryptToString);
+ return parseObject;
+ }
+
+ private static PayOrderStatus getPayOrderStatus(URIBuilder uriBuilder) throws URISyntaxException, IOException {
+ HttpGet httpGet = new HttpGet(uriBuilder.build());
+ httpGet.addHeader("Accept", "application/json");
+
+ CloseableHttpResponse response = (CloseableHttpResponse) getWechatPayHttpClient().execute(httpGet);
+
+ String bodyAsString = EntityUtils.toString(response.getEntity());
+
+ JSONObject jsonObject = JSONObject.parseObject(bodyAsString);
+ log.info("json:{}", jsonObject);
+ Object trade_state = jsonObject.get("trade_state");
+ if (trade_state != null) {
+ String tradeState = trade_state.toString();
+ if ("SUCCESS".equals(tradeState)) {
+ return PayOrderStatus.SUCCESS;
+ } else if ("USERPAYING".equals(tradeState)) {
+ return PayOrderStatus.USERPAYING;
+ } else {
+ return PayOrderStatus.FAILED;
+ }
+ }
+ return PayOrderStatus.UNKNOWN;
+ }
+
+ /**
+ * 服务商查询订单
+ *
+ * @param orderNo
+ * @throws Exception
+ */
+ public static PayOrderStatus queryOrder(String orderNo) throws IOException, URISyntaxException {
+ URIBuilder uriBuilder = new URIBuilder("https://api.mch.weixin.qq.com/v3/pay/partner/transactions/id/" + orderNo + "?sp_mchid=" + SPMECHID + "&sub_mchid=" + SUBMCHID);
+ return getPayOrderStatus(uriBuilder);
+ }
+
+ /**
+ * 商户订单号查询
+ *
+ * @param transactionId 微信订单号
+ * @return
+ * @throws IOException
+ * @throws URISyntaxException
+ */
+ public static PayOrderStatus wechatOrder(String transactionId) throws IOException, URISyntaxException {
+ URIBuilder uriBuilder = new URIBuilder("https://api.mch.weixin.qq.com/v3/pay/partner/transactions/out-trade-no/" + transactionId + "?sp_mchid=" + SPMECHID + "&sub_mchid=" + SUBMCHID);
+ return getPayOrderStatus(uriBuilder);
+ }
+
+
+ /**
+ * 服务商关闭订单
+ *
+ * @param orderNo 商户订单号
+ */
+ public static void closeOrder(String orderNo) throws IOException {
+ HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/partner/transactions/out-trade-no/" + orderNo + "/close");
+ httpPost.addHeader("Accept", "application/json");
+ httpPost.addHeader("Content-type", "application/json; charset=utf-8");
+
+ JSONObject params = new JSONObject();
+ params.put("sp_mchid", SPMECHID);
+ params.put("sub_mchid", SUBMCHID);
+
+ httpPost.setEntity(new StringEntity(params.toJSONString(), "UTF-8"));
+ getWechatPayHttpClient().execute(httpPost);
+ //接口响应204,无内容
+ }
+
+
+ /**
+ * 服务商退款
+ *
+ * @param refund 退款金额
+ * @param outTradeNo 商户订单号
+ * @param outRefundNo 商户退款单号
+ * @param notifyUrl 退款回调url
+ * @param total 原订单金额
+ * @return
+ * @throws Exception
+ */
+ public static String refunds(int refund, String outTradeNo, String outRefundNo, String notifyUrl, int total) throws Exception {
+ HttpPost httpPost = new HttpPost(URL_REFUND_PAY);
+ httpPost.addHeader("Accept", "application/json");
+ httpPost.addHeader("Content-type", "application/json; charset=utf-8");
+
+ JSONObject params = new JSONObject();
+ JSONObject amount = new JSONObject();
+
+ //金额信息
+ amount.put("refund", refund);
+ //原订单金额
+ amount.put("total", total);
+ //退款币种
+ amount.put("currency", "CNY");
+ //子商户号 否
+ params.put("sub_mchid", SUBMCHID);
+//// 微信支付订单号 (二选一)
+// params.put("transaction_id", SUBMCHID);
+ //商户订单号 (二选一)
+ params.put("out_trade_no", outTradeNo);
+ //商户退款单号
+ log.info("商户退款单号----------------------------------------out_trade_no:{}", outRefundNo);
+ params.put("out_refund_no", outRefundNo);
+ //退款结果回调url 否
+ params.put("notify_url", notifyUrl);
+ //金额信息
+ params.put("amount", amount);
+
+ httpPost.setEntity(new StringEntity(params.toJSONString(), "UTF-8"));
+ CloseableHttpResponse response = (CloseableHttpResponse) getWechatPayHttpClient().execute(httpPost);
+ String bodyAsString = EntityUtils.toString(response.getEntity());
+ JSONObject respJson = JSONObject.parseObject(bodyAsString);
+
+ log.info("respJson:{}", respJson);
+ Object result = respJson.get("status");
+ String status = result.toString();
+ if ("SUCCESS".equals(status) || "PROCESSING".equals(status)) {
+ return status;
+ } else {
+ throw new PayException("[" + respJson.get("err_code") + "]"
+ + respJson.get("err_code_des"));
+ }
+ }
+
+ /**
+ * 查询单笔退款
+ */
+ public static JSONObject selRechargeResult(String out_refund_no) throws Exception {
+ HttpGet httpGet = new HttpGet(SEL_URL_REFUND_PAY + "/" + out_refund_no + "?sub_mchid=" + SUBMCHID);
+ httpGet.addHeader("Accept", "application/json");
+ httpGet.addHeader("Content-type", "application/json; charset=utf-8");
+ httpGet.addHeader("Wechatpay-Serial", getVerifier().getValidCertificate().getSerialNumber().toString(16));
+
+ CloseableHttpResponse response = (CloseableHttpResponse) getWechatPayHttpClient().execute(httpGet);
+ String bodyAsString = EntityUtils.toString(response.getEntity());
+ return JSONObject.parseObject(bodyAsString);
+ }
+
+ /**
+ * 微信退款结果通知
+ */
+ public static JSONObject tuiKuanResult(HttpServletRequest request) throws Exception {
+ //一、验证签名
+ //1.1获取平台证书
+ getVerifier();
+ //1.2检查平台证书序列号
+ String wepaySerial = request.getHeader("Wechatpay-Serial");
+ if (wepaySerial == null) {
+ throw new PayException(-9, "平台证书序列号为空");
+ }
+ //获取平台证书序列号
+ BigInteger currentSerial = getVerifier().getValidCertificate().getSerialNumber();
+ if (StrUtil.isEmpty(wepaySerial) || !wepaySerial.equalsIgnoreCase(currentSerial.toString(16))) {
+ throw new PayException(-9, "证书序列号不一致");
+ }
+ String wepayNonce = request.getHeader("Wechatpay-Nonce");
+ String wepayTimestamp = request.getHeader("Wechatpay-Timestamp");
+ String wepayBody = null;
+ BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream(),StandardCharsets.UTF_8));
+ String line = null;
+ StringBuilder body = new StringBuilder();
+ while ((line = br.readLine()) != null) {
+ body.append(line);
+ }
+ if (StrUtil.isEmpty(body.toString())) {
+ throw new PayException(-9, "body is null");
+ }
+ wepayBody = body.toString();
+
+ String message = wepayTimestamp + "\n"
+ + wepayNonce + "\n"
+ + body.toString() + "\n";
+ //1.4获取应答签名
+ String wepySignature = request.getHeader("Wechatpay-Signature");
+
+ //1.5验证签名
+ boolean rr = getVerifier().verify(wepaySerial,
+ message.getBytes(StandardCharsets.UTF_8),wepySignature);
+ if (!rr){
+ }
+ JSONObject jsonObject = JSONObject.parseObject(wepayBody);
+ JSONObject resource = (JSONObject) jsonObject.get("resource");
+ AesUtil aesUtil = new AesUtil(API_V3_Key.getBytes("utf-8"));
+ //解密
+ String decryptToString = aesUtil.decryptToString(
+ resource.get("associated_data").toString().getBytes(),//附加数据
+ resource.get("nonce").toString().getBytes(),//随机串
+ resource.get("ciphertext").toString());//数据密文
+ JSONObject parseObject = JSONObject.parseObject(decryptToString);
+ return parseObject;
+ }
+
+
+ /**
+ * 企业付款到零钱
+ *
+ * @param partner_trade_no 商户订单号
+ * @param openid 用户openid
+ * @param total_fee 金额
+ * @param desc 付款备注
+ * @param spbill_create_ip Ip地址
+ * @return
+ * @throws Exception
+ */
+ public static Map payToUsrWx(
+ String partner_trade_no, String openid, int total_fee, String desc, String spbill_create_ip)
+ throws Exception {
+ //1.构造请求字符串
+ Map reqMap = new HashMap();
+ reqMap.put("mch_appid", SUBAPPID);
+ reqMap.put("mchid", SUBMCHID);
+ //reqMap.put("device_info",null); //不能添加空字段,Jackson会生成闭包xml 导致签名失败
+ reqMap.put("nonce_str", createNonceStr());
+ reqMap.put("partner_trade_no", partner_trade_no);
+ reqMap.put("openid", openid);
+ reqMap.put("check_name", "NO_CHECK");
+ //reqMap.put("re_user_name",null);
+ reqMap.put("amount", total_fee + "");
+ reqMap.put("desc", desc);
+ reqMap.put("spbill_create_ip", spbill_create_ip);
+ reqMap.put("sign", createSign(reqMap));
+
+ //2.发送付款请求
+ String reqrXml = JacksonUtil.mapToXml(paraFilterEmpty(reqMap), "xml");
+ String respXml = HttpsUtil.httpsRequest(URL_PAY_TO_USR_WX, "POST", reqrXml,
+ PATH_WX_CRET, SUBMCHID);
+ System.out.println("---------------PayToUsrWx Request Xml-----------------");
+ System.out.println(reqrXml);
+ System.out.println("---------------PayToUsrWx Response Xml-----------------");
+ System.out.println(respXml);
+ System.out.println("---------------PayToUsrWx end-----------------");
+
+ //3.判断成功失败
+ Map respMap = JacksonUtil.xmlToMap(new ByteArrayInputStream(respXml.getBytes(StandardCharsets.UTF_8)));
+ String return_code, result_code;
+ return_code = String.valueOf(respMap.get("return_code"));
+ result_code = String.valueOf(respMap.get("result_code"));
+
+ if (!StrUtil.isEmpty(return_code) && !StrUtil.isEmpty(result_code)) {
+ if (return_code.equals("SUCCESS") && return_code.equals(result_code)) {
+ return respMap;
+ } else {
+ throw new PayException("[" + respMap.get("err_code") + "]"
+ + respMap.get("err_code_des"));
+ }
+ } else {
+ throw new PayException(String.valueOf(respMap.get("return_msg")));
+ }
+ //return null;
+ }
+
+ /**
+ * Create Sign
+ *
+ * @param sParaTemp
+ * @return
+ */
+ private static String createSign(Map sParaTemp) throws FileNotFoundException {
+ // 除去数组中的空值和签名参数
+ Map sPara = paraFilter(sParaTemp);
+ String prestr = createLinkString(sPara); // 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
+ //MD5运算生成签名
+ String sign = sign(prestr, getPrivateKey().toString(), "utf-8").toUpperCase();
+// return sign;
+ return sign;
+ }
+
+ /**
+ * 签名字符串
+ *
+ * @param text 需要签名的字符串
+ * @param key 密钥
+ * @param input_charset 编码格式
+ * @return 签名结果
+ */
+ private static String sign(String text, String key, String input_charset) {
+ text = text + "&key=" + key;
+ return DigestUtils.md5Hex(getContentBytes(text, input_charset));
+ }
+
+ /**
+ * @param content
+ * @param charset
+ * @return
+ * @throws
+ * @throws UnsupportedEncodingException
+ */
+ private static byte[] getContentBytes(String content, String charset) {
+ if (charset == null || "".equals(charset)) {
+ return content.getBytes();
+ }
+ try {
+ return content.getBytes(charset);
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset);
+ }
+ }
+
+ /**
+ * 除去数组中的空值和签名参数
+ *
+ * @param sArray 签名参数组
+ * @return 去掉空值与签名参数后的新签名参数组
+ */
+ private static Map paraFilter(Map sArray) {
+ Map result = new HashMap();
+ if (sArray == null || sArray.size() <= 0) {
+ return result;
+ }
+ for (String key : sArray.keySet()) {
+ Object objVal = sArray.get(key);
+ if (objVal == null) {
+ continue;
+ }
+ String value = String.valueOf(objVal);
+ if (StrUtil.isEmpty(value) || key.equalsIgnoreCase("sign") || key.equalsIgnoreCase("sign_type")) {
+ continue;
+ }
+ result.put(key, value);
+ }
+ return result;
+ }
+
+ /**
+ * 把数组所有元素排序,并按照“参数=参数值”的模式用“&”字符拼接成字符串
+ *
+ * @param params 需要排序并参与字符拼接的参数组
+ * @return 拼接后字符串
+ */
+ private static String createLinkString(Map params) {
+ List keys = new ArrayList(params.keySet());
+ Collections.sort(keys);
+ String prestr = "";
+ for (int i = 0; i < keys.size(); i++) {
+ String key = keys.get(i);
+ String value = params.get(key);
+ if (i == keys.size() - 1) {// 拼接时,不包括最后一个&字符
+ prestr = prestr + key + "=" + value;
+ } else {
+ prestr = prestr + key + "=" + value + "&";
+ }
+ }
+ return prestr;
+ }
+
+
+ /**
+ * 除去数组中的空值和签名参数
+ *
+ * @param sArray 签名参数组
+ * @return 去掉空值与签名参数后的新签名参数组
+ */
+ private static Map paraFilterEmpty(Map sArray) {
+ Map result = new HashMap();
+ if (sArray == null || sArray.size() <= 0) {
+ return result;
+ }
+ for (String key : sArray.keySet()) {
+ Object objVal = sArray.get(key);
+ if (objVal == null) {
+ continue;
+ }
+ String value = String.valueOf(objVal);
+ result.put(key, value);
+ }
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/wechatutil/src/main/java/com/ccsens/wechatutil/payutil/WxTokenUtil.java b/wechatutil/src/main/java/com/ccsens/wechatutil/payutil/WxTokenUtil.java
new file mode 100644
index 00000000..bd77ea6a
--- /dev/null
+++ b/wechatutil/src/main/java/com/ccsens/wechatutil/payutil/WxTokenUtil.java
@@ -0,0 +1,64 @@
+package com.ccsens.wechatutil.payutil;
+
+import com.alibaba.fastjson.JSONObject;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.util.EntityUtils;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+/**
+ * @author :mr.zhangsan
+ * @date :Created in 2021/4/15 21:11
+ * @version v1.0:
+ */
+
+public class WxTokenUtil {
+
+ //测试APPID
+ private static final String appid = "wxf30402e727f0840a";
+ //测试secret
+ private static final String secret = "70402290ac83857c7324b0ee881b544a";
+ // 测试商户号
+ private static final String SUBMCHID = "1611259929";
+
+ /**
+ * 获取小程序全局唯一后台接口调用凭据(access_token)
+ */
+ private static final String URL_GETTOKEN_PAY
+ = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret;
+
+ public static String getToken() throws Exception{
+
+ HttpGet httpGet = new HttpGet(URL_GETTOKEN_PAY);
+ httpGet.addHeader("Accept", "application/json");
+ httpGet.addHeader("Content-type", "application/json; charset=utf-8");
+ try {
+ httpGet.addHeader("Wechatpay-Serial", WxPayProviderUtils.getVerifier().getValidCertificate().getSerialNumber().toString(16));
+ }catch (FileNotFoundException e) {
+ e.printStackTrace();
+ throw new FileNotFoundException("获取微信平台证书失败");
+ }
+ String bodyAsString = "";
+ try {
+ CloseableHttpResponse response = (CloseableHttpResponse) WxPayProviderUtils.getWechatPayHttpClient().execute(httpGet);
+ try {
+ bodyAsString = EntityUtils.toString(response.getEntity());
+ }catch (IOException e) {
+ e.printStackTrace();
+ throw new FileNotFoundException("bodyAsString转换错误");
+ }
+ }catch (IOException e) {
+ e.printStackTrace();
+ throw new FileNotFoundException("根据微信平台证书获取httpclient失败");
+ }
+ JSONObject respJson = JSONObject.parseObject(bodyAsString);
+ Object access_token = respJson.get("access_token");
+ if (access_token != null) {
+ return access_token.toString();
+ }else {
+ throw new Exception("获取WxToken失败");
+ }
+ }
+}
diff --git a/wechatutil/src/main/java/com/ccsens/wechatutil/service/IWxMessageService.java b/wechatutil/src/main/java/com/ccsens/wechatutil/service/IWxMessageService.java
index 3dc1a9f4..84d5c5ab 100644
--- a/wechatutil/src/main/java/com/ccsens/wechatutil/service/IWxMessageService.java
+++ b/wechatutil/src/main/java/com/ccsens/wechatutil/service/IWxMessageService.java
@@ -1,4 +1,12 @@
package com.ccsens.wechatutil.service;
+import com.ccsens.wechatutil.bean.dto.WxMessageDto;
+
public interface IWxMessageService {
+ /**
+ * 群机器人发送消息
+ * @param robotMessage
+ * @throws Exception
+ */
+ void sendRobotInfo(WxMessageDto.RobotMessage robotMessage)throws Exception;
}
diff --git a/wechatutil/src/main/java/com/ccsens/wechatutil/service/WxMessageService.java b/wechatutil/src/main/java/com/ccsens/wechatutil/service/WxMessageService.java
index de5ee80c..4c2c36bd 100644
--- a/wechatutil/src/main/java/com/ccsens/wechatutil/service/WxMessageService.java
+++ b/wechatutil/src/main/java/com/ccsens/wechatutil/service/WxMessageService.java
@@ -3,8 +3,8 @@ package com.ccsens.wechatutil.service;
import cn.hutool.core.collection.CollectionUtil;
import com.ccsens.util.JacksonUtil;
import com.ccsens.wechatutil.bean.dto.WxMessageDto;
+import com.ccsens.wechatutil.util.WxConstant;
import lombok.extern.slf4j.Slf4j;
-import org.json.JSONObject;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@@ -12,7 +12,11 @@ import org.springframework.transaction.annotation.Transactional;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
+import java.nio.charset.StandardCharsets;
+/**
+ * @author 逗
+ */
@Slf4j
@Service
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
@@ -23,10 +27,11 @@ public class WxMessageService implements IWxMessageService {
* @param robotMessage 机器人消息
* @throws Exception 异常
*/
+ @Override
public void sendRobotInfo(WxMessageDto.RobotMessage robotMessage)throws Exception {
WxMessageDto.WxRobotVo wxRobotVo = new WxMessageDto.WxRobotVo();
wxRobotVo.setMsgtype(robotMessage.getMsgType());
- if("text".equalsIgnoreCase(robotMessage.getMsgType())){
+ if(WxConstant.TEXT.equalsIgnoreCase(robotMessage.getMsgType())){
WxMessageDto.WxRobotText wxRobotText = new WxMessageDto.WxRobotText();
wxRobotText.setContent(robotMessage.getContent());
if(CollectionUtil.isNotEmpty(robotMessage.getMentionedList())){
@@ -36,7 +41,7 @@ public class WxMessageService implements IWxMessageService {
wxRobotText.setMentioned_mobile_list(robotMessage.getMentionedMobileList());
}
wxRobotVo.setText(wxRobotText);
- }else if("markdown".equalsIgnoreCase(robotMessage.getMsgType())){
+ }else if(WxConstant.MARKDOWN.equalsIgnoreCase(robotMessage.getMsgType())){
WxMessageDto.WxRobotMarkdown wxRobotMarkdown = new WxMessageDto.WxRobotMarkdown();
wxRobotMarkdown.setContent(robotMessage.getContent());
wxRobotVo.setMarkdown(wxRobotMarkdown);
@@ -51,8 +56,6 @@ public class WxMessageService implements IWxMessageService {
public static void sendPost(String url, String param){
PrintWriter out = null;
BufferedReader in = null;
- JSONObject jsonObject = null;
- String result = "";
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
@@ -61,18 +64,14 @@ public class WxMessageService implements IWxMessageService {
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流(设置请求编码为UTF-8)
- out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), "UTF-8"));
+ out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8));
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
// 获取请求返回数据(设置返回数据编码为UTF-8)
in = new BufferedReader(
- new InputStreamReader(conn.getInputStream(), "UTF-8"));
- String line;
- while ((line = in.readLine()) != null) {
- result += line;
- }
+ new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
} catch (IOException e) {
e.printStackTrace();
} finally {
diff --git a/wechatutil/src/main/java/com/ccsens/wechatutil/service/WxService.java b/wechatutil/src/main/java/com/ccsens/wechatutil/service/WxService.java
index 68985fe2..1b8d8c9e 100644
--- a/wechatutil/src/main/java/com/ccsens/wechatutil/service/WxService.java
+++ b/wechatutil/src/main/java/com/ccsens/wechatutil/service/WxService.java
@@ -61,8 +61,8 @@ public class WxService implements IWxService {
} catch (IOException e) {
throw new BaseException(e.getMessage());
}
- if (null != wxUser.errcode) {
- throw new BaseException(wxUser.errcode, wxUser.errmsg);
+ if (null != wxUser.getErrcode()) {
+ throw new BaseException(wxUser.getErrcode(), wxUser.getErrmsg());
}
return wxUser;
}
diff --git a/wechatutil/src/main/java/com/ccsens/wechatutil/util/WxConstant.java b/wechatutil/src/main/java/com/ccsens/wechatutil/util/WxConstant.java
index 600c7942..5c66b719 100644
--- a/wechatutil/src/main/java/com/ccsens/wechatutil/util/WxConstant.java
+++ b/wechatutil/src/main/java/com/ccsens/wechatutil/util/WxConstant.java
@@ -11,6 +11,7 @@ public class WxConstant {
/*** 默认小程序 */
public static final String ANYRING = "anyring";
+
/*** 小程序登录路径 */
public static final String MINI_PROGRAM_LOGIN = "https://api.weixin.qq.com/sns/jscode2session?appid=%1$s&secret=%2$s&js_code=%3$s&grant_type=%4$s";
/*** 公众号获取accessToken */
@@ -32,6 +33,16 @@ public class WxConstant {
/*** redis内存储AccessToken的Key */
public static final String ACCESS_TOKEN = "tall_wx_access_token_";
+ /*** 机器人消息类型--文本 */
+ public static final String TEXT = "text";
+ /*** 机器人消息类型--markdown */
+ public static final String MARKDOWN = "markdown";
+
+
+
+
+
+
/*** 小程序appId */
public static final Map APP_ID = new HashMap<>();
static {