From bbc10565b89295917eb7b4e0793912fa96254502 Mon Sep 17 00:00:00 2001
From: egan
Date: Sat, 2 Jul 2022 21:31:23 +0800
Subject: [PATCH] =?UTF-8?q?=E5=8F=91=E7=BA=A2=E5=8C=85=E4=BF=AE=E5=A4=8Dwx?=
=?UTF-8?q?appid=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../com/egzosn/pay/wx/api/WxPayService.java | 142 ++++++++++--------
.../egzosn/pay/wx/api/WxRedPackService.java | 20 +++
.../com/egzosn/pay/wx/bean/RedpackOrder.java | 63 ++++++--
3 files changed, 151 insertions(+), 74 deletions(-)
diff --git a/pay-java-wx/src/main/java/com/egzosn/pay/wx/api/WxPayService.java b/pay-java-wx/src/main/java/com/egzosn/pay/wx/api/WxPayService.java
index 2f2e7f3..f5eaf7b 100644
--- a/pay-java-wx/src/main/java/com/egzosn/pay/wx/api/WxPayService.java
+++ b/pay-java-wx/src/main/java/com/egzosn/pay/wx/api/WxPayService.java
@@ -12,6 +12,7 @@ import java.security.GeneralSecurityException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
+import java.util.Objects;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.zip.GZIPInputStream;
@@ -44,7 +45,6 @@ import com.egzosn.pay.common.bean.BillType;
import com.egzosn.pay.common.bean.MethodType;
import com.egzosn.pay.common.bean.NoticeParams;
import com.egzosn.pay.common.bean.NoticeRequest;
-import com.egzosn.pay.common.bean.Order;
import com.egzosn.pay.common.bean.OrderParaStructure;
import com.egzosn.pay.common.bean.PayMessage;
import com.egzosn.pay.common.bean.PayOrder;
@@ -155,27 +155,23 @@ public class WxPayService extends BasePayService implements
* @param noticeParams 回调回来的参数集
* @return 签名校验 true通过
*/
+ @Override
public boolean verify(NoticeParams noticeParams) {
final Map params = noticeParams.getBody();
//如果为退款不需要校验, 直接返回,
- if (params.containsKey(REQ_INFO)){
+ if (params.containsKey(REQ_INFO)) {
return true;
}
- if (null == params.get(SIGN) || !(SUCCESS.equals(params.get(RETURN_CODE)) && SUCCESS.equals(params.get(RESULT_CODE)))) {
+ if (Objects.isNull(params.get(SIGN)) || !(SUCCESS.equals(params.get(RETURN_CODE)) && SUCCESS.equals(params.get(RESULT_CODE)))) {
if (LOG.isErrorEnabled()) {
LOG.error(String.format("微信支付异常:return_code=%s,参数集=%s", params.get(RETURN_CODE), params));
}
return false;
}
- try {
- return signVerify(params, (String) params.get(SIGN));
- }
- catch (PayErrorException e) {
- LOG.error("", e);
- }
- return false;
+ return signVerify(params, (String) params.get(SIGN));
+
}
@@ -186,7 +182,7 @@ public class WxPayService extends BasePayService implements
* @param sign 比对的签名结果
* @return 生成的签名结果
*/
- public boolean signVerify(Map params, String sign) {
+ private boolean signVerify(Map params, String sign) {
return signVerify(params, sign, payConfigStorage.isTest());
}
@@ -207,7 +203,7 @@ public class WxPayService extends BasePayService implements
*/
private Map getPublicParameters() {
- Map parameters = new TreeMap();
+ Map parameters = new TreeMap<>();
parameters.put(APPID, payConfigStorage.getAppId());
parameters.put(MCH_ID, payConfigStorage.getMchId());
//判断如果是服务商模式信息则加入
@@ -298,7 +294,7 @@ public class WxPayService extends BasePayService implements
return result;
}
- Map params = new TreeMap();
+ Map params = new TreeMap<>();
if (WxTransactionType.JSAPI == order.getTransactionType()) {
params.put("signType", payConfigStorage.getSignType());
@@ -653,6 +649,7 @@ public class WxPayService extends BasePayService implements
* RECHARGE_REFUND,返回当日充值退款订单
* @return 返回支付方下载对账单的结果
*/
+ @Override
public Map downloadBill(Date billDate, String billType) {
return downloadBill(billDate, WxPayBillType.valueOf(billType));
}
@@ -668,6 +665,7 @@ public class WxPayService extends BasePayService implements
* RECHARGE_REFUND,返回当日充值退款订单
* @return 返回支付方下载对账单的结果, 如果【账单类型】为gzip的话则返回值中key为data值为gzip的输入流
*/
+ @Override
public Map downloadBill(Date billDate, BillType billType) {
//获取公共参数
Map parameters = getPublicParameters();
@@ -710,24 +708,19 @@ public class WxPayService extends BasePayService implements
//设置签名
setSign(parameters);
InputStream inputStream = requestTemplate.postForObject(getReqUrl(WxTransactionType.DOWNLOADBILL), XML.getMap2Xml(parameters), InputStream.class);
- try {
- //解压流
- inputStream = uncompress(inputStream);
- writeToLocal(path + DateUtils.formatDate(new Date(), DateUtils.YYYYMM) + "/" + DateUtils.formatDate(new Date(), DateUtils.YYYYMMDDHHMMSS) + ".txt", inputStream);
- Map ret = new HashMap(3);
+ //解压流
+ try (InputStream fileIs = uncompress(inputStream);) {
+ writeToLocal(path + DateUtils.formatDate(new Date(), DateUtils.YYYYMM) + "/" + DateUtils.formatDate(new Date(), DateUtils.YYYYMMDDHHMMSS) + ".txt", fileIs);
+ Map ret = new HashMap<>(3);
ret.put(RETURN_CODE, SUCCESS);
ret.put(RETURN_MSG_CODE, "ok");
ret.put("data", path);
return ret;
}
- catch (Exception e) {
- e.printStackTrace();
- Map ret = new HashMap(3);
- ret.put(RETURN_CODE, FAIL);
- ret.put(RETURN_MSG_CODE, "fail");
- ret.put("data", e.getMessage());
- return ret;
+ catch (IOException e) {
+ throw new PayErrorException(new WxPayError(FAIL, e.getMessage()), e);
}
+
}
/**
@@ -739,15 +732,15 @@ public class WxPayService extends BasePayService implements
*/
@Deprecated
public static InputStream uncompress(InputStream input) throws IOException {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- GZIPInputStream ungzip = new GZIPInputStream(input);
- byte[] buffer = new byte[1024];
- int n;
- while ((n = ungzip.read(buffer)) >= 0) {
- out.write(buffer, 0, n);
+ try (GZIPInputStream ungZip = new GZIPInputStream(input); ByteArrayOutputStream out = new ByteArrayOutputStream()) {
+ byte[] buffer = new byte[1024];
+ int n;
+ while ((n = ungZip.read(buffer)) >= 0) {
+ out.write(buffer, 0, n);
+ }
+ return new ByteArrayInputStream(out.toByteArray());
}
- InputStream is = new ByteArrayInputStream(out.toByteArray());
- return is;
+
}
/**
@@ -758,12 +751,11 @@ public class WxPayService extends BasePayService implements
* @throws IOException IOException
*/
@Deprecated
- private void writeToLocal(String destination, InputStream inputStream)
- throws IOException {
+ private void writeToLocal(String destination, InputStream inputStream) throws IOException {
// 判断字节大小
if (inputStream.available() != 0) {
- System.out.println("结果大小:" + inputStream.available());
+ LOG.debug("结果大小:{}", inputStream.available());
File file = new File(destination);
if (!file.getParentFile().exists()) {
boolean result = file.getParentFile().mkdirs();
@@ -771,17 +763,17 @@ public class WxPayService extends BasePayService implements
LOG.warn("创建失败");
}
}
- OutputStream out = new FileOutputStream(file);
- int size = 0;
- int len = 0;
- byte[] buf = new byte[1024];
- while ((size = inputStream.read(buf)) != -1) {
- len += size;
- out.write(buf, 0, size);
+ try (OutputStream out = new FileOutputStream(file)) {
+ int size = 0;
+ int len = 0;
+ byte[] buf = new byte[1024];
+ while ((size = inputStream.read(buf)) != -1) {
+ len += size;
+ out.write(buf, 0, size);
+ }
+ LOG.debug("最终写入字节数大小:{}", len);
}
- LOG.info("最终写入字节数大小:" + len);
- inputStream.close();
- out.close();
+
}
}
@@ -813,7 +805,7 @@ public class WxPayService extends BasePayService implements
* @param transactionType 交易类型
* @return 返回支付方对应接口的结果
*/
- public Map secondaryInterface(Object transactionIdOrBillDate, String outTradeNoBillType, TransactionType transactionType) {
+ private Map secondaryInterface(Object transactionIdOrBillDate, String outTradeNoBillType, TransactionType transactionType) {
if (transactionType == WxTransactionType.REFUND) {
throw new PayErrorException(new PayException(FAILURE, "通用接口不支持:" + transactionType));
@@ -844,18 +836,11 @@ public class WxPayService extends BasePayService implements
*
* @param order 转账订单
*
- *
- * 注意事项:
- * ◆ 当返回错误码为“SYSTEMERROR”时,请不要更换商户订单号,一定要使用原商户订单号重试,否则可能造成重复支付等资金风险。
- * ◆ XML具有可扩展性,因此返回参数可能会有新增,而且顺序可能不完全遵循此文档规范,如果在解析回包的时候发生错误,请商户务必不要换单重试,请商户联系客服确认付款情况。如果有新回包字段,会更新到此API文档中。
- * ◆ 因为错误代码字段err_code的值后续可能会增加,所以商户如果遇到回包返回新的错误码,请商户务必不要换单重试,请商户联系客服确认付款情况。如果有新的错误码,会更新到此API文档中。
- * ◆ 错误代码描述字段err_code_des只供人工定位问题时做参考,系统实现时请不要依赖这个字段来做自动化处理。
- *
- * @return 对应的转账结果
+ * @return 对应的转账结果
*/
@Override
public Map transfer(TransferOrder order) {
- Map parameters = new TreeMap();
+ Map parameters = new TreeMap<>();
parameters.put("partner_trade_no", order.getOutNo());
@@ -889,7 +874,7 @@ public class WxPayService extends BasePayService implements
* 商户企业付款到银行卡
*
*/
- public Map transfers(Map parameters, TransferOrder order) {
+ private Map transfers(Map parameters, TransferOrder order) {
//转账到余额, 申请商户号的appid或商户号绑定的appid
parameters.put("mch_appid", payConfigStorage.getAppId());
parameters.put("openid", order.getPayeeAccount());
@@ -911,7 +896,7 @@ public class WxPayService extends BasePayService implements
* @param order 转账订单
* @return 包装后参数信息
*/
- public Map payBank(Map parameters, TransferOrder order) {
+ private Map payBank(Map parameters, TransferOrder order) {
parameters.put("enc_bank_no", keyPublic(order.getPayeeAccount()));
parameters.put("enc_true_name", keyPublic(order.getPayeeName()));
@@ -952,7 +937,7 @@ public class WxPayService extends BasePayService implements
}
- public String keyPublic(String content) {
+ private String keyPublic(String content) {
try {
return RSA2.encrypt(content, payConfigStorage.getKeyPublic(), CIPHER_ALGORITHM, payConfigStorage.getInputCharset());
}
@@ -981,7 +966,19 @@ public class WxPayService extends BasePayService implements
*/
@Override
public Map sendredpack(RedpackOrder redpackOrder) {
- Map parameters = new TreeMap();
+ return sendRedPack(redpackOrder);
+ }
+
+ /**
+ * 微信发红包
+ *
+ * @param redpackOrder 红包实体
+ * @return 返回发红包实体后的结果
+ * @author faymanwang 1057438332@qq.com
+ */
+ @Override
+ public Map sendRedPack(RedpackOrder redpackOrder) {
+ Map parameters = new TreeMap<>();
redPackParam(redpackOrder, parameters);
final TransferType transferType = redpackOrder.getTransferType();
if (WxSendredpackType.SENDGROUPREDPACK == transferType) {
@@ -998,7 +995,7 @@ public class WxPayService extends BasePayService implements
if (WxSendredpackType.SENDMINIPROGRAMHB != transferType || FAIL.equals(resp.getString(RESULT_CODE))) {
return resp;
}
- Map params = new TreeMap();
+ Map params = new TreeMap<>();
params.put("appId", payConfigStorage.getAppId());
params.put("timeStamp", System.currentTimeMillis() / 1000 + "");
params.put("nonceStr", parameters.get(NONCE_STR));
@@ -1021,8 +1018,22 @@ public class WxPayService extends BasePayService implements
*/
@Override
public Map gethbinfo(String mchBillno) {
+ return getHbInfo(mchBillno);
+ }
+
+ /**
+ * 查询红包记录
+ * 用于商户对已发放的红包进行查询红包的具体信息,可支持普通红包和裂变包
+ * 查询红包记录API只支持查询30天内的红包订单,30天之前的红包订单请登录商户平台查询。
+ *
+ * @param mchBillNo 商户发放红包的商户订单号
+ * @return 返回查询结果
+ * @author faymanwang 1057438332@qq.com
+ */
+ @Override
+ public Map getHbInfo(String mchBillNo) {
Map parameters = this.getPublicParameters();
- parameters.put("mch_billno", mchBillno);
+ parameters.put("mch_billno", mchBillNo);
parameters.put("bill_type", "MCHT");
parameters.put(SIGN, createSign(SignTextUtils.parameterText(parameters, "&", SIGN), payConfigStorage.getInputCharset()));
return requestTemplate.postForObject(getReqUrl(WxSendredpackType.GETHBINFO), XML.getMap2Xml(parameters), JSONObject.class);
@@ -1037,10 +1048,13 @@ public class WxPayService extends BasePayService implements
private void redPackParam(RedpackOrder redpackOrder, Map parameters) {
parameters.put(NONCE_STR, SignTextUtils.randomStr());
parameters.put(MCH_ID, payConfigStorage.getPid());
- parameters.put("wxappid", payConfigStorage.getAppId());
+ if (StringUtils.isEmpty(redpackOrder.getWxAppId())) {
+ throw new PayErrorException(new WxPayError(FAIL, "RedpackOrder#getWxAppId()公众账号appid 必填"));
+ }
+ parameters.put("wxappid", redpackOrder.getWxAppId());
parameters.put("send_name", redpackOrder.getSendName());
parameters.put("re_openid", redpackOrder.getReOpenid());
- parameters.put("mch_billno", redpackOrder.getMchBillno());
+ parameters.put("mch_billno", redpackOrder.getMchBillNo());
parameters.put("total_amount", Util.conversionCentAmount(redpackOrder.getTotalAmount()));
parameters.put("total_num", 1);
parameters.put("wishing", redpackOrder.getWishing());
diff --git a/pay-java-wx/src/main/java/com/egzosn/pay/wx/api/WxRedPackService.java b/pay-java-wx/src/main/java/com/egzosn/pay/wx/api/WxRedPackService.java
index 341f3a8..a18cff5 100644
--- a/pay-java-wx/src/main/java/com/egzosn/pay/wx/api/WxRedPackService.java
+++ b/pay-java-wx/src/main/java/com/egzosn/pay/wx/api/WxRedPackService.java
@@ -18,8 +18,17 @@ public interface WxRedPackService {
*
* @param redpackOrder 红包实体
* @return 返回发红包实体后的结果
+ * @see #sendRedPack(RedpackOrder)
*/
+ @Deprecated
Map sendredpack(RedpackOrder redpackOrder);
+ /**
+ * 微信发红包
+ *
+ * @param redpackOrder 红包实体
+ * @return 返回发红包实体后的结果
+ */
+ Map sendRedPack(RedpackOrder redpackOrder);
/**
* 查询红包记录
@@ -28,6 +37,17 @@ public interface WxRedPackService {
*
* @param mchBillno 商户发放红包的商户订单号
* @return 返回查询结果
+ * @see #getHbInfo(String)
*/
+ @Deprecated
Map gethbinfo(String mchBillno);
+ /**
+ * 查询红包记录
+ * 用于商户对已发放的红包进行查询红包的具体信息,可支持普通红包和裂变包
+ * 查询红包记录API只支持查询30天内的红包订单,30天之前的红包订单请登录商户平台查询。
+ *
+ * @param mchBillNo 商户发放红包的商户订单号
+ * @return 返回查询结果
+ */
+ Map getHbInfo(String mchBillNo);
}
diff --git a/pay-java-wx/src/main/java/com/egzosn/pay/wx/bean/RedpackOrder.java b/pay-java-wx/src/main/java/com/egzosn/pay/wx/bean/RedpackOrder.java
index 8354f3c..2587431 100644
--- a/pay-java-wx/src/main/java/com/egzosn/pay/wx/bean/RedpackOrder.java
+++ b/pay-java-wx/src/main/java/com/egzosn/pay/wx/bean/RedpackOrder.java
@@ -1,32 +1,57 @@
package com.egzosn.pay.wx.bean;
-import com.egzosn.pay.common.bean.TransferOrder;
-
import java.math.BigDecimal;
+import com.egzosn.pay.common.bean.TransferOrder;
+
/**
- * 发红包订单
+ * 发红包订单
+ *
* @author 保网 faymanwang 1057438332@qq.com
* 2020/5/15 12:40
*/
public class RedpackOrder extends TransferOrder {
-
+ /**
+ * 微信为发放红包商户分配的公众账号ID,接口传入的appid应该为公众号的appid或小程序的appid(在mp.weixin.qq.com申请的)或APP的appid(在open.weixin.qq.com申请的)。
+ * 校验规则:
+ * 1、该appid需要与接口传入中的re_openid有对应关系;
+ * 2、该appid需要与发放红包商户号有绑定关系,若未绑定,可参考该指引完成绑定(商家商户号与AppID账号关联管理)
+ */
+ private String wxAppId;
+ /**
+ * 商户订单号(每个订单号必须唯一。取值范围:0~9,a~z,A~Z)
+ * 接口根据商户订单号支持重入,如出现超时可再调用。
+ */
+ private String mchBillNo;
/**
* 商户订单号(每个订单号必须唯一。取值范围:0~9,a~z,A~Z)
* 接口根据商户订单号支持重入,如出现超时可再调用
+ *
* @return 商户订单号
*/
+ @Deprecated
public String getMchBillno() {
- return getOutNo();
+ return getMchBillNo();
}
+ @Deprecated
public void setMchBillno(String mchBillno) {
- setOutNo(mchBillno);
+ setMchBillNo(mchBillno);
+ }
+
+ public String getMchBillNo() {
+ return mchBillNo;
+ }
+
+ public void setMchBillNo(String mchBillNo) {
+ setOutNo(mchBillNo);
+ this.mchBillNo = mchBillNo;
}
/**
* 商户名称:红包发送者名称
+ *
* @return 红包发送者名称
*/
public String getSendName() {
@@ -34,11 +59,12 @@ public class RedpackOrder extends TransferOrder {
}
public void setSendName(String sendName) {
- super.setPayerName(sendName);
+ super.setPayerName(sendName);
}
/**
* 用户openid
+ *
* @return 用户openid
*/
public String getReOpenid() {
@@ -46,11 +72,12 @@ public class RedpackOrder extends TransferOrder {
}
public void setReOpenid(String reOpenid) {
- super.setPayeeAccount(reOpenid);
+ super.setPayeeAccount(reOpenid);
}
/**
* 付款金额 每个红包金额必须在默认额度内(默认大于1元,小于200元,可在产品设置中自行申请调高额度)
+ *
* @return 付款金额
*/
public BigDecimal getTotalAmount() {
@@ -60,22 +87,26 @@ public class RedpackOrder extends TransferOrder {
public void setTotalAmount(BigDecimal totalAmount) {
super.setAmount(totalAmount);
}
+
/**
* 红包发放总人数
* 普通红包:1
* 裂变:必须介于(包括)3到20之间
+ *
* @return 红包发放总人数
*/
public int getTotalNum() {
Object totalNum = getAttr("total_num");
- return null == totalNum ? 1 : (Integer)totalNum;
+ return null == totalNum ? 1 : (Integer) totalNum;
}
public void setTotalNum(int totalNum) {
addAttr("total_num", totalNum);
}
+
/**
* 红包祝福语
+ *
* @return 红包祝福语
*/
public String getWishing() {
@@ -90,6 +121,7 @@ public class RedpackOrder extends TransferOrder {
/**
* 活动名称
+ *
* @return 活动名称
*/
public String getActName() {
@@ -103,6 +135,7 @@ public class RedpackOrder extends TransferOrder {
public String getSceneId() {
return (String) getAttr("scene_id");
}
+
/**
* 发放红包使用场景,红包金额大于200或者小于1元时必传
* PRODUCT_1:商品促销
@@ -113,7 +146,8 @@ public class RedpackOrder extends TransferOrder {
* PRODUCT_6:保险回馈
* PRODUCT_7:彩票派奖
* PRODUCT_8:税务刮奖
- * @param sceneId 红包使用场景
+ *
+ * @param sceneId 红包使用场景
*/
public void setSceneId(String sceneId) {
addAttr("scene_id", sceneId);
@@ -123,4 +157,13 @@ public class RedpackOrder extends TransferOrder {
public void setTransferType(WxSendredpackType transferType) {
super.setTransferType(transferType);
}
+
+ public String getWxAppId() {
+ return wxAppId;
+ }
+
+ public void setWxAppId(String wxAppId) {
+ addAttr("wxappid", wxAppId);
+ this.wxAppId = wxAppId;
+ }
}