diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/bestpay/model/TransferBatchesDetailsRequest.java b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/bestpay/model/TransferBatchesDetailsRequest.java new file mode 100644 index 0000000..1fac399 --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/bestpay/model/TransferBatchesDetailsRequest.java @@ -0,0 +1,32 @@ +package org.jeecg.common.bestpay.model; + +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Data; + +/** + * @author java996.icu + * @title: TransferBatchesDetailsRequest + * @projectName merchant + * @description: TODO + * @date 2022/10/10 15:45 + * @Version V1.0 + */ +@Data +public class TransferBatchesDetailsRequest { + + /**商家明细单号*/ + @JSONField(name = "out_detail_no") + private String outDetailNo; + /**转账金额*/ + @JSONField(name = "transfer_amount") + private Integer transferAmount; + /**转账备注*/ + @JSONField(name = "transfer_remark") + private String transferRemark; + /**用户在直连商户应用下的用户标示*/ + private String openid; + /**收款用户姓名*/ + @JSONField(name = "user_name") + private String userName; + +} diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/bestpay/model/TransferBatchesRequest.java b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/bestpay/model/TransferBatchesRequest.java index 78e1016..9997bb9 100644 --- a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/bestpay/model/TransferBatchesRequest.java +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/bestpay/model/TransferBatchesRequest.java @@ -3,6 +3,8 @@ package org.jeecg.common.bestpay.model; import com.alibaba.fastjson.annotation.JSONField; import lombok.Data; +import java.util.List; + /** * @author java996.icu * @title: TransferBatchesRequest @@ -13,36 +15,27 @@ import lombok.Data; */ @Data public class TransferBatchesRequest { - + /**直连商户的appid*/ private String appid; - /** - * 商家批次单号 - * 商户系统内部的商家批次单号,要求此参数只能由数字、大小写字母组成,在商户系统内部唯一 - */ + /**商家批次单号*/ @JSONField(name = "out_batch_no") private String outBatchNo; - /** - * 批次名称 - */ + /**批次名称*/ @JSONField(name = "batch_name") private String batchName; - /** - * 批次备注 - * 转账说明,UTF8编码,最多允许32个字符 - */ + /**批次备注*/ @JSONField(name = "batch_remark") private String batchRemark; - /** - * 转账总金额 - * 转账金额单位为“分”。转账总金额必须与批次内所有明细转账金额之和保持一致,否则无法发起转账操作 - */ + /**转账总金额*/ @JSONField(name = "total_amount") private Integer totalAmount; - /** - * 转账总笔数 - * 一个转账批次单最多发起三千笔转账。转账总笔数必须与批次内所有明细之和保持一致,否则无法发起转账操作 - */ + /**转账总笔数*/ @JSONField(name = "total_num") private Integer totalNum; + /**发起批量转账的明细列表,最多三千笔*/ + @JSONField(name = "transfer_detail_list") + private List transferDetailList; + /**转账场景id*/ + private String transferSceneId; } diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/bestpay/model/TransferBatchesResp.java b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/bestpay/model/TransferBatchesResp.java new file mode 100644 index 0000000..40ce268 --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/bestpay/model/TransferBatchesResp.java @@ -0,0 +1,27 @@ +package org.jeecg.common.bestpay.model; + +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Data; + +/** + * @author java996.icu + * @title: TransferBatchesResp + * @projectName merchant + * @description: TODO + * @date 2022/12/13 14:29 + * @Version V1.0 + */ +@Data +public class TransferBatchesResp { + + /**微信批次单号*/ + @JSONField(name = "batch_id") + private String batchId; + /**商家批次单号*/ + @JSONField(name = "out_batch_no") + private String outBatchNo; + /**批次创建时间*/ + @JSONField(name = "create_time") + private String createTime; + +} diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/bestpay/pay/WeChatPayConfig2.java b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/bestpay/pay/WeChatPayConfig2.java new file mode 100644 index 0000000..31c4129 --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/bestpay/pay/WeChatPayConfig2.java @@ -0,0 +1,166 @@ +package org.jeecg.common.bestpay.pay; + +import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder; +import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner; +import com.wechat.pay.contrib.apache.httpclient.auth.Verifier; +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.cert.CertificatesManager; +import com.wechat.pay.contrib.apache.httpclient.exception.HttpCodeException; +import com.wechat.pay.contrib.apache.httpclient.exception.NotFoundException; +import com.wechat.pay.contrib.apache.httpclient.util.PemUtil; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.impl.client.CloseableHttpClient; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.security.GeneralSecurityException; +import java.security.PrivateKey; +import java.security.cert.*; + +/** + * @author java996.icu + * @title: WeChatPayConfig2 + * @projectName chemu + * @description: TODO + * @date 2022/12/7 16:36 + * @Version V1.0 + */ +@Component +@Data +@Slf4j +@ConfigurationProperties(prefix = "wxpay") +public class WeChatPayConfig2 { + + /** + * 应用编号 + */ + private String appId; + /** + * 商户号 + */ + private String mchId; + /** + * 服务商商户号 + */ + private String slMchId; + /** + * APIv2密钥 + */ + private String apiKey; + /** + * APIv3密钥 + */ + private String apiV3Key; + /** + * 支付通知回调地址 + */ + private String notifyUrl; + /** + * 退款回调地址 + */ + private String refundNotifyUrl; + + /** + * API 证书中的 key.pem + */ + private String keyPemPath; + + /** + * 商户序列号 + */ + private String serialNo; + + /** + * 微信支付V3-url前缀 + */ + private String baseUrl; + + + /** + * 获取商户的私钥文件 + * @param keyPemPath + * @return + */ + public PrivateKey getPrivateKey(String keyPemPath){ + + InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(keyPemPath); + if(inputStream==null){ + throw new RuntimeException("私钥文件不存在"); + } + return PemUtil.loadPrivateKey(inputStream); + } + + /** + * 获取证书管理器实例 + * @return + */ + @Bean + public Verifier getVerifier() throws GeneralSecurityException, IOException, HttpCodeException, NotFoundException { + + log.info("获取证书管理器实例"); + + //获取商户私钥 + PrivateKey privateKey = getPrivateKey(keyPemPath); + + //私钥签名对象 + PrivateKeySigner privateKeySigner = new PrivateKeySigner(serialNo, privateKey); + + //身份认证对象 + WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(mchId, privateKeySigner); + + // 使用定时更新的签名验证器,不需要传入证书 + CertificatesManager certificatesManager = CertificatesManager.getInstance(); + certificatesManager.putMerchant(mchId,wechatPay2Credentials,apiV3Key.getBytes(StandardCharsets.UTF_8)); + + return certificatesManager.getVerifier(mchId); + } + + + /** + * 获取支付http请求对象 + * @param verifier + * @return + */ + @Bean(name = "wxPayClient") + public CloseableHttpClient getWxPayClient(Verifier verifier) { + + //获取商户私钥 + PrivateKey privateKey = getPrivateKey(keyPemPath); + + WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create() + .withMerchant(mchId, serialNo, privateKey) + .withValidator(new WechatPay2Validator(verifier)); + + // 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新 + return builder.build(); + } + + /** + * 获取HttpClient,无需进行应答签名验证,跳过验签的流程 + */ + @Bean(name = "wxPayNoSignClient") + public CloseableHttpClient getWxPayNoSignClient(){ + + //获取商户私钥 + PrivateKey privateKey = getPrivateKey(keyPemPath); + + //用于构造HttpClient + WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create() + //设置商户信息 + .withMerchant(mchId, serialNo, privateKey) + //无需进行签名验证、通过withValidator((response) -> true)实现 + .withValidator((response) -> true); + + // 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新 + return builder.build(); + } + + +} diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/bestpay/utils/HttpRequestUtil.java b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/bestpay/utils/HttpRequestUtil.java index 436b890..09c92c9 100644 --- a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/bestpay/utils/HttpRequestUtil.java +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/bestpay/utils/HttpRequestUtil.java @@ -4,6 +4,8 @@ import lombok.extern.slf4j.Slf4j; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; +import org.apache.http.ParseException; +import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; @@ -108,6 +110,7 @@ public class HttpRequestUtil { String requestUrl, String requestJson, String wechatPayserialNo, + String wechatPayserialNo2, String mchID4M, String privatekeypath) { CloseableHttpClient httpclient = HttpClients.createDefault(); @@ -124,7 +127,7 @@ public class HttpRequestUtil { //-------------------------核心认证 start----------------------------------------------------------------- String strToken = VechatPayV3Util.getToken("POST", "/v3/transfer/batches", - requestJson,mchID4M,wechatPayserialNo, privatekeypath); + requestJson,mchID4M,wechatPayserialNo2, privatekeypath); log.error("微信转账token "+strToken); // 添加认证信息 @@ -146,4 +149,44 @@ public class HttpRequestUtil { return null; } + + /** + * 发送HTTP_GET请求 + * + * @see 该方法会自动关闭连接,释放资源 + * @param reqURL + * 请求地址(含参数) + * @param decodeCharset + * 解码字符集,解析响应数据时用之,其为null时默认采用UTF-8解码 + * @return 远程主机响应正文 + */ + public static String sendGetRequest(String reqURL,String auth,String decodeCharset) { + long responseLength = 0; // 响应长度 + String responseContent = null; // 响应内容 + CloseableHttpClient httpclient = HttpClients.createDefault(); + + HttpGet httpGet = new HttpGet(reqURL); // 创建org.apache.http.client.methods.HttpGet + httpGet.addHeader("Authorization", auth); + httpGet.addHeader("Accept", "application/json"); + httpGet.addHeader("User-Agent", "https://zh.wikipedia.org/wiki/User_agent"); + try { + HttpResponse response = httpclient.execute(httpGet); // 执行GET请求 + HttpEntity entity = response.getEntity(); // 获取响应实体 + if (null != entity) { + responseLength = entity.getContentLength(); + responseContent = EntityUtils.toString(entity, decodeCharset == null ? "UTF-8" : decodeCharset); + EntityUtils.consume(entity); // Consume response content + } + } catch (ClientProtocolException e) { + System.out.println("该异常通常是协议错误导致,比如构造HttpGet对象时传入的协议不对(将'http'写成'htp')或者服务器端返回的内容不符合HTTP协议要求等,堆栈信息如下"); + } catch (ParseException e) { + System.out.println(e.getMessage()); + } catch (IOException e) { + System.out.println("该异常通常是网络原因引起的,如HTTP服务器未启动等,堆栈信息如下"); + } finally { + httpclient.getConnectionManager().shutdown(); // 关闭连接,释放资源 + } + return responseContent; + } + } diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/RedisKey.java b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/RedisKey.java index b7a06de..9779413 100644 --- a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/RedisKey.java +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/RedisKey.java @@ -16,5 +16,8 @@ public class RedisKey { public static final String MER_WITHDRAWAL_AUDIT = "MER_WITHDRAWAL:AUDIT"; + public static final String MER_WITHDRAWAL = "MER_WITHDRAWAL:"; + + } diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/rechargeInfoLog/controller/TbRechargeInfoLogController.java b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/rechargeInfoLog/controller/TbRechargeInfoLogController.java index 85f1d9c..9093fc9 100644 --- a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/rechargeInfoLog/controller/TbRechargeInfoLogController.java +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/rechargeInfoLog/controller/TbRechargeInfoLogController.java @@ -1,14 +1,23 @@ package org.jeecg.modules.rechargeInfoLog.controller; import java.math.BigDecimal; +import java.security.cert.X509Certificate; +import java.util.ArrayList; import java.util.Arrays; import java.util.Date; +import java.util.List; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; import org.apache.commons.lang.StringUtils; import org.jeecg.common.api.vo.Result; +import org.jeecg.common.bestpay.model.TransferBatchesRequest; +import org.jeecg.common.bestpay.utils.HttpRequestUtil; +import org.jeecg.common.bestpay.utils.MoneyUtil; import org.jeecg.common.constant.RedisKey; import org.jeecg.common.exception.JeecgBootException; import org.jeecg.common.system.query.QueryGenerator; @@ -105,8 +114,23 @@ public class TbRechargeInfoLogController extends JeecgController audit = tbRechargeInfoLogService.audit(id, status, checkInfo); return Result.OKMsg(); } - - + + + + + /** + * 提现 + * @param id + * @return + */ + @GetMapping(value = "/withdrawal") + public Result withdrawal2(@RequestParam(name="id",required=true) String id){ + Result audit = tbRechargeInfoLogService.handleWithdrawal(id); + return Result.OK(); + } + + + /** * 添加 * diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/rechargeInfoLog/service/ITbRechargeInfoLogService.java b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/rechargeInfoLog/service/ITbRechargeInfoLogService.java index a816498..6b6883f 100644 --- a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/rechargeInfoLog/service/ITbRechargeInfoLogService.java +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/rechargeInfoLog/service/ITbRechargeInfoLogService.java @@ -15,4 +15,7 @@ public interface ITbRechargeInfoLogService extends IService { Result audit(String id, boolean status, String checkInfo); + Result handleWithdrawal(String id); + + } diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/rechargeInfoLog/service/impl/TbRechargeInfoLogServiceImpl.java b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/rechargeInfoLog/service/impl/TbRechargeInfoLogServiceImpl.java index f9ca198..54f5345 100644 --- a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/rechargeInfoLog/service/impl/TbRechargeInfoLogServiceImpl.java +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/rechargeInfoLog/service/impl/TbRechargeInfoLogServiceImpl.java @@ -1,6 +1,18 @@ package org.jeecg.modules.rechargeInfoLog.service.impl; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.wechat.pay.contrib.apache.httpclient.util.RsaCryptoUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringUtils; import org.jeecg.common.api.vo.Result; +import org.jeecg.common.bestpay.model.TransferBatchesDetailsRequest; +import org.jeecg.common.bestpay.model.TransferBatchesRequest; +import org.jeecg.common.bestpay.model.TransferBatchesResp; +import org.jeecg.common.bestpay.pay.WeChatPayConfig2; +import org.jeecg.common.bestpay.utils.HttpRequestUtil; +import org.jeecg.common.bestpay.utils.MoneyUtil; import org.jeecg.common.constant.RedisKey; import org.jeecg.common.exception.JeecgBootException; import org.jeecg.common.util.RedisUtil; @@ -9,6 +21,7 @@ import org.jeecg.modules.hanHaiMember.service.IHanHaiMemberService; import org.jeecg.modules.rechargeInfoLog.entity.TbRechargeInfoLog; import org.jeecg.modules.rechargeInfoLog.mapper.TbRechargeInfoLogMapper; import org.jeecg.modules.rechargeInfoLog.service.ITbRechargeInfoLogService; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -16,14 +29,18 @@ import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.math.BigDecimal; +import java.security.cert.X509Certificate; +import java.util.ArrayList; import java.util.Date; +import java.util.List; /** * @Description: tb_recharge_info_log * @Author: jeecg-boot - * @Date: 2024-12-12 + * @Date: 2024-12-12 * @Version: V1.0 */ +@Slf4j @Service public class TbRechargeInfoLogServiceImpl extends ServiceImpl implements ITbRechargeInfoLogService { @@ -31,25 +48,36 @@ public class TbRechargeInfoLogServiceImpl extends ServiceImpl audit(String id, boolean status, String checkInfo) { Integer n = (Integer) redisUtil.get(RedisKey.MER_WITHDRAWAL_AUDIT + id); - if(n != null){ + if (n != null) { throw new JeecgBootException("请勿重复点击!"); } - redisUtil.set(RedisKey.MER_WITHDRAWAL_AUDIT + id,1,5); + redisUtil.set(RedisKey.MER_WITHDRAWAL_AUDIT + id, 1, 5); TbRechargeInfoLog rechargeInfoLog = this.getById(id); - if(rechargeInfoLog==null) { + if (rechargeInfoLog == null) { throw new JeecgBootException("未找到数据"); } Long count = this.lambdaQuery() .eq(TbRechargeInfoLog::getWithdrawalId, rechargeInfoLog.getId()) .count(); - if(count != null && count > 0){ + if (count != null && count > 0) { throw new JeecgBootException("此提现已处理过不通过,请勿重新点击"); } @@ -57,7 +85,7 @@ public class TbRechargeInfoLogServiceImpl extends ServiceImpl handleWithdrawal(String id) { + + Integer n = (Integer) redisUtil.get(RedisKey.MER_WITHDRAWAL + id); + if (n != null) { + throw new JeecgBootException("请勿重复点击,后果自负!"); + } + redisUtil.set(RedisKey.MER_WITHDRAWAL + id, 1, 5); + + TbRechargeInfoLog merRechargeInfoLog = this.getById(id); + if (merRechargeInfoLog == null) { + throw new JeecgBootException("未找到数据"); + } + HanHaiMember merMember = hanHaiMemberService.getById(merRechargeInfoLog.getMemberId()); + //微信-商家转账到零钱 + String idStr = "zx" + IdWorker.getIdStr(); + TransferBatchesRequest transferBatchesRequest = new TransferBatchesRequest(); + + transferBatchesRequest.setAppid(appId); + transferBatchesRequest.setTotalNum(1); + transferBatchesRequest.setOutBatchNo(idStr); + transferBatchesRequest.setBatchName("商家提现"); + transferBatchesRequest.setBatchRemark(merRechargeInfoLog.getInfo()); + if (StringUtils.isBlank(merRechargeInfoLog.getInfo()) || merRechargeInfoLog.getInfo().length() > 32) { + transferBatchesRequest.setBatchRemark("商家提现"); + } + transferBatchesRequest.setTotalAmount(MoneyUtil.Yuan2Fen(merRechargeInfoLog.getMoney().doubleValue())); + List transferBatchesDetailsRequests = new ArrayList<>(); + TransferBatchesDetailsRequest transferBatchesDetailsRequest = new TransferBatchesDetailsRequest(); + transferBatchesDetailsRequest.setOutDetailNo(merRechargeInfoLog.getId()); + transferBatchesDetailsRequest.setTransferAmount(MoneyUtil.Yuan2Fen(merRechargeInfoLog.getMoney().doubleValue())); + transferBatchesDetailsRequest.setTransferRemark(merRechargeInfoLog.getInfo()); + if (StringUtils.isBlank(merRechargeInfoLog.getInfo()) || merRechargeInfoLog.getInfo().length() > 32) { + transferBatchesDetailsRequest.setTransferRemark("商家提现"); + } + transferBatchesDetailsRequest.setOpenid(merMember.getAppletOpenid()); + String serialNo = null; + try { + X509Certificate certificate = weChatPayConfig2.getVerifier().getValidCertificate(); + serialNo = certificate.getSerialNumber().toString(16).toUpperCase(); + String encryptOAEP = RsaCryptoUtil.encryptOAEP(merRechargeInfoLog.getRealName(), certificate); + transferBatchesDetailsRequest.setUserName(encryptOAEP); + } catch (Exception e) { + log.info("真实姓名加密失败"); + e.printStackTrace(); + throw new JeecgBootException("真实姓名加密失败"); + } + + transferBatchesDetailsRequests.add(transferBatchesDetailsRequest); + transferBatchesRequest.setTransferDetailList(transferBatchesDetailsRequests); +// transferBatchesRequest.setTransferSceneId("1001"); + String jsonString = JSONObject.toJSONString(transferBatchesRequest); + + + String postTransBatRequest = HttpRequestUtil.postTransBatRequest(transferBatchUrl, jsonString, serialNo, wxsSerialNo, mchId, pemPath); + log.error("返回结果1:" + postTransBatRequest); + TransferBatchesResp transferBatchesResp = JSON.parseObject(postTransBatRequest, TransferBatchesResp.class); + log.error("返回结果2:" + transferBatchesResp); + if (transferBatchesResp == null || org.apache.commons.lang3.StringUtils.isBlank(transferBatchesResp.getBatchId())) { + throw new JeecgBootException("打款失败"); + } + + TbRechargeInfoLog rechargeInfoLog1 = new TbRechargeInfoLog(); + rechargeInfoLog1.setId(merRechargeInfoLog.getId()); + rechargeInfoLog1.setState(2); + rechargeInfoLog1.setOutBatchNo(transferBatchesResp.getOutBatchNo()); + rechargeInfoLog1.setBatchId(transferBatchesResp.getBatchId()); + boolean b = this.updateById(rechargeInfoLog1); + if (!b) { + throw new JeecgBootException("操作失败,请稍后重试"); + } + return Result.ok(); + } + } diff --git a/jeecg-boot-module-system/src/main/resources/application-dev.yml b/jeecg-boot-module-system/src/main/resources/application-dev.yml index fc24aff..3eb02c6 100644 --- a/jeecg-boot-module-system/src/main/resources/application-dev.yml +++ b/jeecg-boot-module-system/src/main/resources/application-dev.yml @@ -343,9 +343,10 @@ wechat: codeImg: /usr/codeImage savePath: WxCodeFile keyPemPath: apiclient_key.pem - serialNo: + serialNo: 6E4F9E70D56CC439B575B811CB4327621C81A839 apiV3Key: 0fdb77429ffdf206c151af76a663041c baseUrl: https://api.mch.weixin.qq.com/v3 + transferBatchUrl: https://api.mch.weixin.qq.com/v3/transfer/batches @@ -363,8 +364,9 @@ wxpay: # 密钥路径,resources根目录下 keyPemPath: apiclient_key.pem #商户证书序列号 - serialNo: + serialNo: 6E4F9E70D56CC439B575B811CB4327621C81A839 # 支付通知回调, pjm6m9.natappfree.cc 为内网穿透地址 - notifyUrl: + notifyUrl: http://pjm6m9.natappfree.cc/pay/payNotify # 退款通知回调, pjm6m9.natappfree.cc 为内网穿透地址 - refundNotifyUrl: + refundNotifyUrl: http://pjm6m9.natappfree.cc/pay/refundNotify + diff --git a/jeecg-boot-module-system/src/main/resources/application-prod.yml b/jeecg-boot-module-system/src/main/resources/application-prod.yml index 8769e77..5d4367e 100644 --- a/jeecg-boot-module-system/src/main/resources/application-prod.yml +++ b/jeecg-boot-module-system/src/main/resources/application-prod.yml @@ -343,10 +343,10 @@ wechat: codeImg: /usr/codeImage savePath: WxCodeFile keyPemPath: apiclient_key.pem - serialNo: + serialNo: 6E4F9E70D56CC439B575B811CB4327621C81A839 apiV3Key: 0fdb77429ffdf206c151af76a663041c baseUrl: https://api.mch.weixin.qq.com/v3 -` + transferBatchUrl: https://api.mch.weixin.qq.com/v3/transfer/batches wxpay: @@ -363,8 +363,8 @@ wxpay: # 密钥路径,resources根目录下 keyPemPath: apiclient_key.pem #商户证书序列号 - serialNo: + serialNo: 6E4F9E70D56CC439B575B811CB4327621C81A839 # 支付通知回调, pjm6m9.natappfree.cc 为内网穿透地址 - notifyUrl: + notifyUrl: http://pjm6m9.natappfree.cc/pay/payNotify # 退款通知回调, pjm6m9.natappfree.cc 为内网穿透地址 - refundNotifyUrl: + refundNotifyUrl: http://pjm6m9.natappfree.cc/pay/refundNotify diff --git a/pom.xml b/pom.xml index 0040af7..dfdbf89 100644 --- a/pom.xml +++ b/pom.xml @@ -59,6 +59,9 @@ 2.17.0 1.2.9 + + 0.4.7 + @@ -138,6 +141,13 @@ 2.23.2 + + com.github.wechatpay-apiv3 + wechatpay-apache-httpclient + ${com-github-wechatpay-apiv3.version} + + + org.glassfish.jersey.connectors jersey-apache-connector