From 079bfb5509b74dcf850811057e809a9db10e6c7d Mon Sep 17 00:00:00 2001 From: "java_cuibaocheng@163.com" Date: Fri, 22 Mar 2024 21:27:56 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=94=AF=E4=BB=98=E5=AE=9D?= =?UTF-8?q?=E6=94=AF=E4=BB=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/account/AccountController.java | 35 ++- .../impl/AccountRechargeServiceImpl.java | 38 ++- .../com/tenlion/operator/util/pay/ALiPay.java | 146 +++++++++++ .../operator/util/pay/AliPayProperties.java | 102 ++++++++ .../operator/util/pay/PayResultDTO.java | 77 ++++++ .../tenlion/operator/util/pay/PayUtil.java | 247 ------------------ .../tenlion/operator/util/pay/QRUtils.java | 92 +++++++ .../com/tenlion/operator/util/pay/WXPay.java | 148 +++++++++++ .../operator/util/pay/WxPayProperties.java | 144 ++++++++++ .../util/task/WxPayResultCheckTask.java | 36 ++- src/main/resources/application-lanproxy.yml | 58 ++-- .../templates/accountrecharge/pay.html | 2 +- 12 files changed, 837 insertions(+), 288 deletions(-) create mode 100644 src/main/java/cn/com/tenlion/operator/util/pay/ALiPay.java create mode 100644 src/main/java/cn/com/tenlion/operator/util/pay/AliPayProperties.java create mode 100644 src/main/java/cn/com/tenlion/operator/util/pay/PayResultDTO.java create mode 100644 src/main/java/cn/com/tenlion/operator/util/pay/QRUtils.java create mode 100644 src/main/java/cn/com/tenlion/operator/util/pay/WXPay.java create mode 100644 src/main/java/cn/com/tenlion/operator/util/pay/WxPayProperties.java diff --git a/src/main/java/cn/com/tenlion/operator/controller/api/account/AccountController.java b/src/main/java/cn/com/tenlion/operator/controller/api/account/AccountController.java index 50101f1..943dbac 100644 --- a/src/main/java/cn/com/tenlion/operator/controller/api/account/AccountController.java +++ b/src/main/java/cn/com/tenlion/operator/controller/api/account/AccountController.java @@ -7,7 +7,10 @@ import cn.com.tenlion.operator.pojo.dtos.customorg.CustomOrgDTO; import cn.com.tenlion.operator.service.accountbank.IAccountBankService; import cn.com.tenlion.operator.service.accountrecharge.IAccountRechargeService; import cn.com.tenlion.operator.util.UserUtil; +import cn.com.tenlion.operator.util.pay.ALiPay; +import cn.com.tenlion.operator.util.pay.PayResultDTO; import cn.com.tenlion.operator.util.pay.PayUtil; +import cn.com.tenlion.operator.util.pay.WXPay; import cn.com.tenlion.operator.util.socket.MessageWebSocketServer; import com.alibaba.fastjson2.JSONObject; import ink.wgink.annotation.CheckRequestBodyAnnotation; @@ -58,23 +61,30 @@ public class AccountController extends DefaultBaseController { @ApiOperation(value = "支付宝支付成功后回调", notes = "支付宝支付成功后回调") @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)}) - @PostMapping("pay-zfb") - public synchronized Object payZfb() { - JSONObject json = new JSONObject(); - json.put("code", "SUCCESS"); - json.put("message", null); - return json; + @PostMapping("pay-zfb/{rechargeId}") + public synchronized String payZfb(@PathVariable("rechargeId") String rechargeId) { + AccountRechargeDTO dto = iAccountRechargeService.get(rechargeId); + // 成功 + if (dto.getThirdParty().equals("支付宝") && !dto.getReconciliationStatus().equals("1") && !dto.getRechargeCheck().equals("-1") && !dto.getRechargeCheck().equals("2")) { + PayResultDTO payResultDTO = ALiPay.queryPay(rechargeId); + if (payResultDTO.getOrderStatus().equals("1") && payResultDTO.getMoney().equals(PayUtil.buiderMoney(dto.getRechargeMoney()))) { + iAccountRechargeService.saveConfirmOnline(dto.getAccountRechargeId(), payResultDTO.getOrderId(), payResultDTO.getOrderSuccessTime()); + // 发送socket + MessageWebSocketServer.sendAll(rechargeId, "success"); + } + } + return "success"; } @ApiOperation(value = "微信支付成功后回调", notes = "支付成功后回调接口") @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)}) - @PostMapping("pay/{rechargeId}") - public synchronized Object pay(@PathVariable("rechargeId") String rechargeId) { + @PostMapping("pay-wx/{rechargeId}") + public synchronized String pay(@PathVariable("rechargeId") String rechargeId) { AccountRechargeDTO dto = iAccountRechargeService.get(rechargeId); // 成功 if (dto.getThirdParty().equals("微信") && !dto.getReconciliationStatus().equals("1") && !dto.getRechargeCheck().equals("-1") && !dto.getRechargeCheck().equals("2")) { - AccountRechargePayResultDTO payResultDTO = PayUtil.queryOrder(rechargeId); - if (payResultDTO.getOrderStatus().equals("1") && payResultDTO.getMoney().equals(dto.getRechargeMoney())) { + PayResultDTO payResultDTO = WXPay.queryPay(rechargeId); + if (payResultDTO.getOrderStatus().equals("1") && payResultDTO.getMoney().equals(PayUtil.buiderMoney(dto.getRechargeMoney()))) { iAccountRechargeService.saveConfirmOnline(dto.getAccountRechargeId(), payResultDTO.getOrderId(), payResultDTO.getOrderSuccessTime()); // 发送socket MessageWebSocketServer.sendAll(rechargeId, "success"); @@ -82,9 +92,8 @@ public class AccountController extends DefaultBaseController { } JSONObject json = new JSONObject(); json.put("code", "SUCCESS"); - json.put("message", null); - System.out.println(rechargeId); - return json; + json.put("message", "成功"); + return json.toJSONString(); } @Autowired diff --git a/src/main/java/cn/com/tenlion/operator/service/accountrecharge/impl/AccountRechargeServiceImpl.java b/src/main/java/cn/com/tenlion/operator/service/accountrecharge/impl/AccountRechargeServiceImpl.java index 66bc5e9..9a7c766 100644 --- a/src/main/java/cn/com/tenlion/operator/service/accountrecharge/impl/AccountRechargeServiceImpl.java +++ b/src/main/java/cn/com/tenlion/operator/service/accountrecharge/impl/AccountRechargeServiceImpl.java @@ -10,8 +10,12 @@ import cn.com.tenlion.operator.service.accountbank.IAccountBankService; import cn.com.tenlion.operator.service.accountitem.IAccountItemService; import cn.com.tenlion.operator.service.remote.IRemoteWangGengInvoiceService; import cn.com.tenlion.operator.util.UserUtil; +import cn.com.tenlion.operator.util.pay.ALiPay; +import cn.com.tenlion.operator.util.pay.PayResultDTO; import cn.com.tenlion.operator.util.pay.PayUtil; +import cn.com.tenlion.operator.util.pay.WXPay; import cn.com.tenlion.projectconfig.util.ProjectConfigUtil; +import com.alipay.api.internal.util.AlipayUtils; import ink.wgink.common.base.DefaultBaseService; import ink.wgink.exceptions.SaveException; import ink.wgink.exceptions.SearchException; @@ -284,9 +288,9 @@ public class AccountRechargeServiceImpl extends DefaultBaseService implements IA accountRechargeVO.setRechargeCheck("0"); accountRechargeVO.setReconciliationStatus("0"); Integer totalMoney = PayUtil.buiderMoney(accountRechargeVO.getRechargeMoney()); - if (totalMoney < 10 || totalMoney > 200000) { // 最大2000块,最小1毛 +/* if (totalMoney < 10 || totalMoney > 200000) { // 最大2000块,最小1毛 throw new SaveException("金额输入错误"); - } + }*/ AccountRechargePayDTO payDTO = new AccountRechargePayDTO(); Map params = HashMapUtil.beanToMap(accountRechargeVO); if ("微信".equals(thirdParty)) { @@ -296,12 +300,27 @@ public class AccountRechargeServiceImpl extends DefaultBaseService implements IA params.put("accountRechargeId", accountRechargeId); params.put("rechargeFinalTime", DateUtil.getTime()); - String brcode = PayUtil.nativePay(ProjectConfigUtil.getText("RechargePayTitle"), accountRechargeId, totalMoney); + String brcode = WXPay.createPay(accountRechargeId, totalMoney, ProjectConfigUtil.getText("RechargePayTitle")); payDTO.setAccountRechargeId(accountRechargeId); payDTO.setThirdParty(thirdParty); payDTO.setThirdPartyPayUrl(brcode); } + + if ("支付宝".equals(thirdParty)) { + + String accountRechargeId = getUUID("zfb"); + params.put("rechargeType", "2"); + params.put("accountRechargeId", accountRechargeId); + params.put("rechargeFinalTime", DateUtil.getTime()); + + String brcode = ALiPay.createPay(accountRechargeId, totalMoney, ProjectConfigUtil.getText("RechargePayTitle")); + + payDTO.setAccountRechargeId(accountRechargeId); + payDTO.setThirdParty(thirdParty); + payDTO.setThirdPartyPayUrl(brcode); + } + if ("对公转账".equals(thirdParty)) { String accountRechargeId = getUUID("oto"); params.put("rechargeType", "1"); @@ -393,7 +412,18 @@ public class AccountRechargeServiceImpl extends DefaultBaseService implements IA return rechargePayResultDTO; } if (dto.getThirdParty().equals("微信")) { - AccountRechargePayResultDTO payResultDTO = PayUtil.queryOrder(accountRechargeId); + PayResultDTO payResultDTO = WXPay.queryPay(accountRechargeId); + // 成功 + if (payResultDTO.getOrderStatus().equals("1")) { + saveConfirmOnline(dto.getAccountRechargeId(), payResultDTO.getOrderId(), payResultDTO.getOrderSuccessTime()); + rechargePayResultDTO.setOrderMessage("付款金额已到账"); + }else{ + rechargePayResultDTO.setOrderMessage("到账情况稍后在账户明细查看"); + } + return rechargePayResultDTO; + } + if (dto.getThirdParty().equals("支付宝")) { + PayResultDTO payResultDTO = ALiPay.queryPay(accountRechargeId); // 成功 if (payResultDTO.getOrderStatus().equals("1")) { saveConfirmOnline(dto.getAccountRechargeId(), payResultDTO.getOrderId(), payResultDTO.getOrderSuccessTime()); diff --git a/src/main/java/cn/com/tenlion/operator/util/pay/ALiPay.java b/src/main/java/cn/com/tenlion/operator/util/pay/ALiPay.java new file mode 100644 index 0000000..896d3d4 --- /dev/null +++ b/src/main/java/cn/com/tenlion/operator/util/pay/ALiPay.java @@ -0,0 +1,146 @@ +package cn.com.tenlion.operator.util.pay; + +import com.alipay.api.AlipayClient; +import com.alipay.api.DefaultAlipayClient; +import com.alipay.api.AlipayConfig; +import com.alipay.api.domain.AlipayTradeCloseModel; +import com.alipay.api.domain.AlipayTradePrecreateModel; +import com.alipay.api.domain.AlipayTradeQueryModel; +import com.alipay.api.request.AlipayTradeCloseRequest; +import com.alipay.api.request.AlipayTradeQueryRequest; +import com.alipay.api.response.AlipayTradeCloseResponse; +import com.alipay.api.response.AlipayTradePrecreateResponse; +import com.alipay.api.request.AlipayTradePrecreateRequest; +import com.alipay.api.response.AlipayTradeQueryResponse; +import ink.wgink.exceptions.SaveException; +import ink.wgink.exceptions.SearchException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import javax.annotation.PostConstruct; +import java.awt.image.BufferedImage; +import java.text.SimpleDateFormat; + +/** + * 支付宝支付 + * 2024年3月19日15:47:30 + * 崔宝铖 + */ +@Component +public class ALiPay { + + @Autowired + private AliPayProperties aliPayProperties; + + private static AliPayProperties aliPayStaticProperties; + + @PostConstruct + public void init() { + aliPayStaticProperties = this.aliPayProperties; + } + private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + public static void closePay(String orderNo) { + AlipayConfig alipayConfig = new AlipayConfig(); + alipayConfig.setServerUrl(aliPayStaticProperties.getUrl());// 支付地址 + alipayConfig.setAppId(aliPayStaticProperties.getAppId());// 应用ID + alipayConfig.setPrivateKey(aliPayStaticProperties.getPrivateKey());// 应用私钥 + alipayConfig.setFormat("json"); + alipayConfig.setAlipayPublicKey(aliPayStaticProperties.getAliPublicKey());// 支付宝公钥 + alipayConfig.setCharset("UTF-8"); + alipayConfig.setSignType("RSA2");// 编码 + try{ + AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig); + AlipayTradeCloseRequest request = new AlipayTradeCloseRequest(); + AlipayTradeCloseModel model = new AlipayTradeCloseModel(); + model.setOutTradeNo(orderNo); + request.setBizModel(model); + AlipayTradeCloseResponse response = alipayClient.execute(request); + if (!response.isSuccess() && !response.getSubMsg().equals("交易不存在")) { + throw new SearchException(response.getSubMsg()); + } + }catch(Exception e) { + throw new SearchException(e.getMessage()); + } + } + + public static PayResultDTO queryPay(String orderNo) { + AlipayConfig alipayConfig = new AlipayConfig(); + alipayConfig.setServerUrl(aliPayStaticProperties.getUrl());// 支付地址 + alipayConfig.setAppId(aliPayStaticProperties.getAppId());// 应用ID + alipayConfig.setPrivateKey(aliPayStaticProperties.getPrivateKey());// 应用私钥 + alipayConfig.setFormat("json"); + alipayConfig.setAlipayPublicKey(aliPayStaticProperties.getAliPublicKey());// 支付宝公钥 + alipayConfig.setCharset("UTF-8"); + alipayConfig.setSignType("RSA2");// 编码 + try{ + AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig); + AlipayTradeQueryRequest request = new AlipayTradeQueryRequest(); + AlipayTradeQueryModel model = new AlipayTradeQueryModel(); + model.setOutTradeNo(orderNo); + request.setBizModel(model); + AlipayTradeQueryResponse response = alipayClient.execute(request); + PayResultDTO dto = new PayResultDTO(); + dto.setOrderStatus("0"); + dto.setOrderNo(response.getOutTradeNo()); + if (response.isSuccess()) { + dto.setOrderId(response.getTradeNo()); + dto.setOrderStatus(response.getTradeStatus().equals("TRADE_SUCCESS") || response.getTradeStatus().equals("TRADE_FINISHED") ? "1" : "0"); + dto.setOrderSuccessTime(sdf.format(response.getSendPayDate())); + dto.setMoney(PayUtil.buiderMoney(Double.parseDouble(response.getTotalAmount()))); + } + if (response == null || (!response.isSuccess() && !response.getSubMsg().equals("交易不存在"))) { + throw new SearchException(response.getSubMsg()); + } + return dto; + }catch(Exception e) { + throw new SearchException(e.getMessage()); + } + } + + /** + * 创建支付的二维码 + * @param orderNo 本地订单编号(唯一) + * @param money 支付金额, 1元为100 + * @param orderDescription 订单详细说明 + * @return + */ + public static String createPay(String orderNo, Integer money, String orderDescription) { + AlipayConfig alipayConfig = new AlipayConfig(); + alipayConfig.setServerUrl(aliPayStaticProperties.getUrl());// 支付地址 + alipayConfig.setAppId(aliPayStaticProperties.getAppId());// 应用ID + alipayConfig.setPrivateKey(aliPayStaticProperties.getPrivateKey());// 应用私钥 + alipayConfig.setFormat("json"); + alipayConfig.setAlipayPublicKey(aliPayStaticProperties.getAliPublicKey());// 支付宝公钥 + alipayConfig.setCharset("UTF-8"); + alipayConfig.setSignType("RSA2");// 编码 + try{ + if (PayUtil.buiderMoney(money) > aliPayStaticProperties.getMaxMoney() || PayUtil.buiderMoney(money) < aliPayStaticProperties.getMinMoney()) { + throw new SaveException("支付金额超出范围"); + } + AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig); + AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest(); + String notifyUrl = aliPayStaticProperties.getNotifyUrl().replaceAll("\\{orderNo}", orderNo); + request.setNotifyUrl(notifyUrl); + AlipayTradePrecreateModel model = new AlipayTradePrecreateModel(); + model.setOutTradeNo(orderNo);// 本地订单号 + model.setTotalAmount(PayUtil.buiderMoney(money) + ""); // 本次付款金额 + model.setTimeoutExpress(aliPayStaticProperties.getTimeOut() + "m");//交易超时时间 + model.setQrCodeTimeoutExpress(aliPayStaticProperties.getTimeOut() + "m");//二维码失效时间 + model.setSubject(orderDescription); // 本次订单说明 + request.setBizModel(model); + AlipayTradePrecreateResponse response = alipayClient.execute(request); + if (response.isSuccess()) { + String qrCode = response.getQrCode(); + if (qrCode.startsWith("http")) { + BufferedImage bufferedImage = QRUtils.createQrCodeImage(QRUtils.createQrCode(qrCode, 330, 330), ""); + return QRUtils.imageToBase64(bufferedImage); + } + } + throw new SaveException(response.getSubMsg()); + }catch(Exception e) { + e.printStackTrace(); + throw new SaveException("生成支付二维码失败"); + } + } + +} diff --git a/src/main/java/cn/com/tenlion/operator/util/pay/AliPayProperties.java b/src/main/java/cn/com/tenlion/operator/util/pay/AliPayProperties.java new file mode 100644 index 0000000..d3ff0ec --- /dev/null +++ b/src/main/java/cn/com/tenlion/operator/util/pay/AliPayProperties.java @@ -0,0 +1,102 @@ +package cn.com.tenlion.operator.util.pay; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +/** + * 从配置文件读取阿里支付的配置文件 + * 2024年3月21日10:20:50 + * 崔宝铖 + */ +@Configuration +@ConfigurationProperties(prefix = "pay.ali-pay") +public class AliPayProperties { + + // 应用ID + private String appId; + + // 支付宝服务器地址 + private String url; + + // 应用私钥 + private String privateKey; + + // 支付宝公钥 + private String aliPublicKey; + + // 超时时间 + private String timeOut; + + // 接收结果通知地址 + private String notifyUrl; + + // 单笔最大金额 + private Double maxMoney; + + // 单笔最小金额 + private Double minMoney; + + public String getAppId() { + return appId == null ? "" : appId.trim(); + } + + public void setAppId(String appId) { + this.appId = appId; + } + + public String getUrl() { + return url == null ? "" : url.trim(); + } + + public void setUrl(String url) { + this.url = url; + } + + public String getPrivateKey() { + return privateKey == null ? "" : privateKey.trim(); + } + + public void setPrivateKey(String privateKey) { + this.privateKey = privateKey; + } + + public String getAliPublicKey() { + return aliPublicKey == null ? "" : aliPublicKey.trim(); + } + + public void setAliPublicKey(String aliPublicKey) { + this.aliPublicKey = aliPublicKey; + } + + public String getTimeOut() { + return timeOut == null ? "5" : timeOut.trim(); + } + + public void setTimeOut(String timeOut) { + this.timeOut = timeOut; + } + + public String getNotifyUrl() { + return notifyUrl == null ? "" : notifyUrl.trim(); + } + + public void setNotifyUrl(String notifyUrl) { + this.notifyUrl = notifyUrl; + } + + public Double getMaxMoney() { + return maxMoney == null ? 2000 : maxMoney; + } + + public void setMaxMoney(Double maxMoney) { + this.maxMoney = maxMoney; + } + + public Double getMinMoney() { + return minMoney == null ? 0.1 : minMoney; + } + + public void setMinMoney(Double minMoney) { + this.minMoney = minMoney; + } +} \ No newline at end of file diff --git a/src/main/java/cn/com/tenlion/operator/util/pay/PayResultDTO.java b/src/main/java/cn/com/tenlion/operator/util/pay/PayResultDTO.java new file mode 100644 index 0000000..3251c9b --- /dev/null +++ b/src/main/java/cn/com/tenlion/operator/util/pay/PayResultDTO.java @@ -0,0 +1,77 @@ +package cn.com.tenlion.operator.util.pay; + +import io.swagger.annotations.ApiModelProperty; + +/** + * 支付结果对象 + * 2024年3月19日17:03:25 + * 崔宝铖 + */ +public class PayResultDTO { + + @ApiModelProperty(name = "orderId", value = "第三方订单ID") + private String orderId; + + @ApiModelProperty(name = "orderNo", value = "本地订单编号") + private String orderNo; + + @ApiModelProperty(name = "orderStatus", value = "支付结果,1:成功") + private String orderStatus; + + @ApiModelProperty(name = "orderSuccessTime", value = "支付成功时间") + private String orderSuccessTime; + + @ApiModelProperty(name = "orderMessage", value = "支付结果详情") + private String orderMessage; + + @ApiModelProperty(name = "money", value = "订单总金额") + private Integer money; + + public String getOrderId() { + return orderId == null ? "" : orderId.trim(); + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getOrderNo() { + return orderNo == null ? "" : orderNo.trim(); + } + + public void setOrderNo(String orderNo) { + this.orderNo = orderNo; + } + + public String getOrderStatus() { + return orderStatus == null ? "" : orderStatus.trim(); + } + + public void setOrderStatus(String orderStatus) { + this.orderStatus = orderStatus; + } + + public String getOrderSuccessTime() { + return orderSuccessTime == null ? "" : orderSuccessTime.trim(); + } + + public void setOrderSuccessTime(String orderSuccessTime) { + this.orderSuccessTime = orderSuccessTime; + } + + public String getOrderMessage() { + return orderMessage == null ? "" : orderMessage.trim(); + } + + public void setOrderMessage(String orderMessage) { + this.orderMessage = orderMessage; + } + + public Integer getMoney() { + return money == null ? 0 : money; + } + + public void setMoney(Integer money) { + this.money = money; + } +} diff --git a/src/main/java/cn/com/tenlion/operator/util/pay/PayUtil.java b/src/main/java/cn/com/tenlion/operator/util/pay/PayUtil.java index d4b104e..a505299 100644 --- a/src/main/java/cn/com/tenlion/operator/util/pay/PayUtil.java +++ b/src/main/java/cn/com/tenlion/operator/util/pay/PayUtil.java @@ -1,62 +1,10 @@ package cn.com.tenlion.operator.util.pay; -import cn.com.tenlion.operator.pojo.dtos.accountrecharge.AccountRechargePayResultDTO; -import cn.com.tenlion.projectconfig.util.ProjectConfigUtil; -import com.google.zxing.BarcodeFormat; -import com.google.zxing.EncodeHintType; -import com.google.zxing.WriterException; -import com.google.zxing.common.BitMatrix; -import com.google.zxing.qrcode.QRCodeWriter; -import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; -import com.google.zxing.client.j2se.MatrixToImageWriter; -import com.wechat.pay.java.core.Config; -import com.wechat.pay.java.core.RSAAutoCertificateConfig; -import com.wechat.pay.java.service.payments.model.Transaction; -import com.wechat.pay.java.service.payments.model.TransactionAmount; -import com.wechat.pay.java.service.payments.nativepay.NativePayService; -import com.wechat.pay.java.service.payments.nativepay.model.*; -import ink.wgink.common.base.DefaultBaseService; -import ink.wgink.exceptions.SaveException; -import ink.wgink.exceptions.SearchException; -import ink.wgink.module.file.service.v2.IFileService; -import ink.wgink.pojo.pos.FilePO; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import javax.annotation.PostConstruct; -import javax.imageio.ImageIO; -import java.awt.*; -import java.awt.image.BufferedImage; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.text.SimpleDateFormat; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; -import java.util.Base64; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; @Component public class PayUtil { - protected static final Logger LOG = LoggerFactory.getLogger(DefaultBaseService.class); - - @Autowired - private IFileService iFileService; - - private static IFileService iFileStaticService; - - @PostConstruct - public void init() throws Exception { - iFileStaticService = this.iFileService; - } - /** * 将double的金额保留2位小数 * @param num @@ -86,199 +34,4 @@ public class PayUtil { return i / 100.00; } - public static void closeOrder(String rechargeOrderId){ - // 使用自动更新平台证书的RSA配置 - Config config = - new RSAAutoCertificateConfig.Builder() - .merchantId("1609461201") // 商户号 - .privateKeyFromPath("D:\\AH\\apiclient_key.pem") // API证书地址(此处的路径自己调试一下,能找到就行) - .merchantSerialNumber("2F16A068181C2998F3EE5271416F720AF0146293") // API证书序列号 - .apiV3Key("_TSKJ_0471_TSkj_0471_tsKJ_0471__") // API密匙 - .build(); - // 构建service - NativePayService service = new NativePayService.Builder().config(config).build(); - // request.setXxx(val)设置所需参数,具体参数可见Request定义 - CloseOrderRequest request = new CloseOrderRequest(); - request.setMchid("1609461201"); - request.setOutTradeNo(rechargeOrderId); - AccountRechargePayResultDTO dto = new AccountRechargePayResultDTO(); - // 调用下单方法,得到应答 - try { - // 发送请求 - service.closeOrder(request); - }catch (Exception e){ - throw new SearchException(e.getMessage()); - } - } - - public static AccountRechargePayResultDTO queryOrder(String rechargeOrderId){ - // 使用自动更新平台证书的RSA配置 - Config config = - new RSAAutoCertificateConfig.Builder() - .merchantId("1609461201") // 商户号 - .privateKeyFromPath("D:\\AH\\apiclient_key.pem") // API证书地址(此处的路径自己调试一下,能找到就行) - .merchantSerialNumber("2F16A068181C2998F3EE5271416F720AF0146293") // API证书序列号 - .apiV3Key("_TSKJ_0471_TSkj_0471_tsKJ_0471__") // API密匙 - .build(); - // 构建service - NativePayService service = new NativePayService.Builder().config(config).build(); - // request.setXxx(val)设置所需参数,具体参数可见Request定义 - QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest(); - request.setMchid("1609461201"); - request.setOutTradeNo(rechargeOrderId); - AccountRechargePayResultDTO dto = new AccountRechargePayResultDTO(); - // 调用下单方法,得到应答 - try { - // 发送请求 - Transaction response = service.queryOrderByOutTradeNo(request); - String order = response.getTransactionId(); // 第三方订单号 - Transaction.TradeStateEnum status = response.getTradeState(); - TransactionAmount amount = response.getAmount(); - dto.setMoney(amount.getPayerTotal()); - String time = response.getSuccessTime(); - dto.setAccountRechargeId(rechargeOrderId); - dto.setOrderSuccessTime(status.name().equals("SUCCESS") ? convertToFormattedString(time) : ""); - dto.setOrderId(order); - dto.setOrderStatus(status.name().equals("SUCCESS") ? "1" : "0"); - }catch (Exception e){ - throw new SearchException(e.getMessage()); - } - return dto; - } - - /** - * 获取5分钟后超时时间 - * @return - */ - public static String getTimeExpire() { - // 当前时间 - LocalDateTime now = LocalDateTime.now(); - // 5分钟前的时间 - LocalDateTime fifteenMinutesAgo = now.plusMinutes(5); - // 获取时区信息(以北京时间为例) - ZoneId zoneId = ZoneId.of("Asia/Shanghai"); // 东八区时区 - // 将LocalDateTime转换为ZonedDateTime - ZonedDateTime zonedDateTime = fifteenMinutesAgo.atZone(zoneId); - // 创建一个符合RFC 3339的DateTimeFormatter - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX"); - // 格式化日期时间 - String formattedDateTime = zonedDateTime.format(formatter); - return formattedDateTime; - } - - /** - * 时间格式转换 - * @param inputDateTime - * @return - */ - public static String convertToFormattedString(String inputDateTime) { - // 将字符串解析为ZonedDateTime对象 - ZonedDateTime zonedDateTime = ZonedDateTime.parse(inputDateTime); - // 将ZonedDateTime对象转换为指定的格式 - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); - return zonedDateTime.format(formatter); - } - - /** - * Native支付下单,获取支付地址 - * @return 支付地址,前端用于生成支付二维码 - */ - public static String nativePay(String title, String orderId, Integer totalMoney){ - // 使用自动更新平台证书的RSA配置 - Config config = - new RSAAutoCertificateConfig.Builder() - .merchantId("1609461201") // 商户号 - .privateKeyFromPath("D:\\AH\\apiclient_key.pem") // API证书地址(此处的路径自己调试一下,能找到就行) - .merchantSerialNumber("2F16A068181C2998F3EE5271416F720AF0146293") // API证书序列号 - .apiV3Key("_TSKJ_0471_TSkj_0471_tsKJ_0471__") // API密匙 - .build(); - // 构建service - NativePayService service = new NativePayService.Builder().config(config).build(); - // request.setXxx(val)设置所需参数,具体参数可见Request定义 - PrepayRequest request = new PrepayRequest(); - Amount amount = new Amount(); - amount.setTotal(totalMoney); // 金额 - request.setAmount(amount); - request.setAppid("wxe17874894f7ff27b"); - request.setMchid("1609461201"); - request.setTimeExpire(getTimeExpire()); - request.setDescription(title);// 商品描述 - request.setNotifyUrl(ProjectConfigUtil.getText("WechatPayCallbackUrl") + "api/account/pay/" + orderId);// 支付成功的回调地址 - request.setOutTradeNo(orderId); - // 调用下单方法,得到应答 - try { - // 发送请求 - PrepayResponse response = service.prepay(request); - // 使用微信扫描 code_url 对应的二维码,即可体验Native支付 - BufferedImage bufferedImage = builderQrCodeImage(generateQRCode(response.getCodeUrl(), 330, 330)); - // 将支付地址返回 - return imageToBase64(bufferedImage); - }catch (Exception e){ - throw new SearchException(e.getMessage()); - } - } - - /** - * 将BufferdImage转为base64图片 - * @param image - * @return - * @throws IOException - */ - public static String imageToBase64(BufferedImage image) throws IOException { - // 将BufferedImage转换为字节数组 - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ImageIO.write(image, "jpg", baos); // 或者使用 "png" 或 "bmp" 等其他图片格式 - byte[] imageBytes = baos.toByteArray(); - // 将字节数组转换为Base64编码的字符串 - String encodedImage = Base64.getEncoder().encodeToString(imageBytes); - return "data:image/jpeg;base64," + encodedImage; - } - - /** - * 生成二维码 - * @param text - * @param width - * @param height - * @return - * @throws WriterException - */ - public static BufferedImage generateQRCode(String text, int width, int height) throws WriterException { - QRCodeWriter qrCodeWriter = new QRCodeWriter(); - Map hints = new HashMap<>(); - hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 设置错误纠正级别为H - BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height, hints); - return MatrixToImageWriter.toBufferedImage(bitMatrix); - - } - - /** - * 二维码设置自定义的边框 - * @param image - * @return - */ - public static BufferedImage builderQrCodeImage(BufferedImage image) { - String bufferedImage = ProjectConfigUtil.getFile("wxPayQrCodeBorderImage"); - if (StringUtils.isEmpty(bufferedImage)) { - return image; - } - try { - FilePO filePo = iFileStaticService.getPO(bufferedImage); - File file = new File(filePo.getFilePath()); - BufferedImage borderImage = ImageIO.read(new File(file.getPath())); - BufferedImage image1 = new BufferedImage(image.getWidth() + 100, image.getHeight() + 100, BufferedImage.TYPE_INT_RGB); - Graphics2D graphics = image1.createGraphics(); - //消除文字锯齿 - graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); - //消除图片锯齿 - graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - //放入二维码 - graphics.drawImage(image, 50, 50, image.getWidth(), image.getHeight(), null); - //放入边框 - graphics.drawImage(borderImage, 0, 0, image.getWidth() + 100, image.getHeight() + 100, null); - return image1; - } catch (IOException e) { - return image; - } - } - } diff --git a/src/main/java/cn/com/tenlion/operator/util/pay/QRUtils.java b/src/main/java/cn/com/tenlion/operator/util/pay/QRUtils.java new file mode 100644 index 0000000..9b5ab61 --- /dev/null +++ b/src/main/java/cn/com/tenlion/operator/util/pay/QRUtils.java @@ -0,0 +1,92 @@ +package cn.com.tenlion.operator.util.pay; + +import cn.com.tenlion.projectconfig.util.ProjectConfigUtil; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.WriterException; +import com.google.zxing.client.j2se.MatrixToImageWriter; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import ink.wgink.pojo.pos.FilePO; +import org.apache.commons.lang3.StringUtils; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; + +/** + * 二维码工具类 + * 2024年3月19日16:03:24 + * 崔宝铖 + */ +public class QRUtils { + + /** + * 将BufferdImage转为base64图片 + * @param image + * @return + * @throws IOException + */ + public static String imageToBase64(BufferedImage image) throws IOException { + // 将BufferedImage转换为字节数组 + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ImageIO.write(image, "jpg", baos); // 或者使用 "png" 或 "bmp" 等其他图片格式 + byte[] imageBytes = baos.toByteArray(); + // 将字节数组转换为Base64编码的字符串 + String encodedImage = Base64.getEncoder().encodeToString(imageBytes); + return "data:image/jpeg;base64," + encodedImage; + } + + /** + * 生成二维码 + * @param text + * @param width + * @param height + * @return + * @throws WriterException + */ + public static BufferedImage createQrCode(String text, int width, int height) throws WriterException { + QRCodeWriter qrCodeWriter = new QRCodeWriter(); + Map hints = new HashMap<>(); + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 设置错误纠正级别为H + BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height, hints); + return MatrixToImageWriter.toBufferedImage(bitMatrix); + + } + + /** + * 为二维码设置自定义的边框 + * @param image 二维码图片对象 + * @param borderFilePath 二维码边框文件 + * @return + */ + public static BufferedImage createQrCodeImage(BufferedImage image, String borderFilePath) { + if (StringUtils.isEmpty(borderFilePath)) { + return image; + } + try { + BufferedImage borderImage = ImageIO.read(new File(borderFilePath)); + BufferedImage image1 = new BufferedImage(image.getWidth() + 100, image.getHeight() + 100, BufferedImage.TYPE_INT_RGB); + Graphics2D graphics = image1.createGraphics(); + //消除文字锯齿 + graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + //消除图片锯齿 + graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + //放入二维码 + graphics.drawImage(image, 50, 50, image.getWidth(), image.getHeight(), null); + //放入边框 + graphics.drawImage(borderImage, 0, 0, image.getWidth() + 100, image.getHeight() + 100, null); + return image1; + } catch (IOException e) { + return image; + } + } + +} diff --git a/src/main/java/cn/com/tenlion/operator/util/pay/WXPay.java b/src/main/java/cn/com/tenlion/operator/util/pay/WXPay.java new file mode 100644 index 0000000..c2e8447 --- /dev/null +++ b/src/main/java/cn/com/tenlion/operator/util/pay/WXPay.java @@ -0,0 +1,148 @@ +package cn.com.tenlion.operator.util.pay; + +import cn.com.tenlion.operator.pojo.dtos.accountrecharge.AccountRechargePayResultDTO; +import com.wechat.pay.java.service.payments.model.Transaction; +import com.wechat.pay.java.service.payments.model.TransactionAmount; +import com.wechat.pay.java.service.payments.nativepay.NativePayService; +import com.wechat.pay.java.service.payments.nativepay.model.*; +import ink.wgink.exceptions.SaveException; +import ink.wgink.exceptions.SearchException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import javax.annotation.PostConstruct; +import java.awt.image.BufferedImage; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; + +/** + * 微信支付 + * 2024年3月19日17:42:14 + * 崔宝铖 + */ +@Component +public class WXPay { + + @Autowired + private WxPayProperties wxPayProperties; + + private static WxPayProperties wxPayStaticProperties; + + @PostConstruct + public void init() { + wxPayStaticProperties = this.wxPayProperties; + } + private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + public static void closePay(String orderNo) { + NativePayService service = wxPayStaticProperties.getPayUrlServices(); + CloseOrderRequest request = new CloseOrderRequest(); + request.setMchid(wxPayStaticProperties.getMchId()); + request.setOutTradeNo(orderNo); + AccountRechargePayResultDTO dto = new AccountRechargePayResultDTO(); + // 调用下单方法,得到应答 + try { + // 发送请求 + service.closeOrder(request); + }catch (Exception e){ + throw new SearchException(e.getMessage()); + } + } + + public static PayResultDTO queryPay(String orderNo) { + NativePayService service = wxPayStaticProperties.getPayUrlServices(); + QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest(); + request.setMchid(wxPayStaticProperties.getMchId()); + request.setOutTradeNo(orderNo); + PayResultDTO dto = new PayResultDTO(); + // 调用下单方法,得到应答 + try { + // 发送请求 + Transaction response = service.queryOrderByOutTradeNo(request); + String order = response.getTransactionId(); // 第三方订单号 + Transaction.TradeStateEnum status = response.getTradeState(); + TransactionAmount amount = response.getAmount(); + String time = response.getSuccessTime(); + dto.setMoney(amount.getPayerTotal()); + dto.setOrderNo(orderNo); + dto.setOrderSuccessTime(status.name().equals("SUCCESS") ? convertToFormattedString(time) : ""); + dto.setOrderId(order); + dto.setOrderStatus(status.name().equals("SUCCESS") ? "1" : "0"); + }catch (Exception e){ + throw new SearchException(e.getMessage()); + } + return dto; + } + + /** + * 创建支付的二维码 + * @param orderNo 本地订单编号(唯一) + * @param money 支付金额, 1元为100 + * @param orderDescription 订单详细说明 + * @return + */ + public static String createPay(String orderNo, Integer money, String orderDescription) { + if (PayUtil.buiderMoney(money) > wxPayStaticProperties.getMaxMoney() || PayUtil.buiderMoney(money) < wxPayStaticProperties.getMinMoney()) { + throw new SaveException("支付金额超出范围"); + } + NativePayService service = wxPayStaticProperties.getPayUrlServices(); + PrepayRequest request = new PrepayRequest(); + Amount amount = new Amount(); + amount.setTotal(money); // 金额 + request.setAmount(amount); + request.setAppid(wxPayStaticProperties.getAppId()); + request.setMchid(wxPayStaticProperties.getMchId()); + request.setTimeExpire(getTimeExpire());// 超时时间 + request.setDescription(orderDescription);// 商品描述 + String notifyUrl = wxPayStaticProperties.getNotifyUrl().replaceAll("\\{orderNo}", orderNo); + request.setNotifyUrl(notifyUrl);// 支付成功的回调地址 + request.setOutTradeNo(orderNo); + // 调用下单方法,得到应答 + try { + // 发送请求 + PrepayResponse response = service.prepay(request); + BufferedImage bufferedImage = QRUtils.createQrCodeImage(QRUtils.createQrCode(response.getCodeUrl(), 330, 330), ""); + return QRUtils.imageToBase64(bufferedImage); + }catch (Exception e){ + e.printStackTrace(); + throw new SaveException("生成支付二维码失败"); + } + } + + /** + * 获取二维码超时时间 + * @return + */ + private static String getTimeExpire() { + // 当前时间 + LocalDateTime now = LocalDateTime.now(); + // 5分钟前的时间 + LocalDateTime fifteenMinutesAgo = now.plusMinutes(Integer.valueOf(wxPayStaticProperties.getTimeOut())); + // 获取时区信息(以北京时间为例) + ZoneId zoneId = ZoneId.of("Asia/Shanghai"); // 东八区时区 + // 将LocalDateTime转换为ZonedDateTime + ZonedDateTime zonedDateTime = fifteenMinutesAgo.atZone(zoneId); + // 创建一个符合RFC 3339的DateTimeFormatter + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX"); + // 格式化日期时间 + String formattedDateTime = zonedDateTime.format(formatter); + return formattedDateTime; + } + + + /** + * 时间格式转换 + * @param inputDateTime + * @return + */ + private static String convertToFormattedString(String inputDateTime) { + // 将字符串解析为ZonedDateTime对象 + ZonedDateTime zonedDateTime = ZonedDateTime.parse(inputDateTime); + // 将ZonedDateTime对象转换为指定的格式 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + return zonedDateTime.format(formatter); + } + +} diff --git a/src/main/java/cn/com/tenlion/operator/util/pay/WxPayProperties.java b/src/main/java/cn/com/tenlion/operator/util/pay/WxPayProperties.java new file mode 100644 index 0000000..1acd995 --- /dev/null +++ b/src/main/java/cn/com/tenlion/operator/util/pay/WxPayProperties.java @@ -0,0 +1,144 @@ +package cn.com.tenlion.operator.util.pay; + +import com.wechat.pay.java.core.Config; +import com.wechat.pay.java.core.RSAAutoCertificateConfig; +import com.wechat.pay.java.service.payments.nativepay.NativePayService; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties(prefix = "pay.wx-pay") +public class WxPayProperties { + + // 商户号 + private String mchId; + + // 商户API证书序列号 + private String mchNo; + + // 私钥本地存储路径 + private String privateKeyPath; + + // API v3密钥 + private String apiV3Key; + + // 小程序APPID + private String appId; + + // 超时时间 + private String timeOut; + + // 微信服务器地址 + private String url; + + // 接收结果通知地址 + private String notifyUrl; + + // 单笔最大金额 + private Double maxMoney; + + // 单笔最小金额 + private Double minMoney; + + @Bean + // 使用自动更新平台证书的RSA配置 + public Config getConfig(){ + Config config = + new RSAAutoCertificateConfig.Builder() + .merchantId(mchId) + .privateKeyFromPath(privateKeyPath) + .merchantSerialNumber(mchNo) + .apiV3Key(apiV3Key) + .build(); + return config; + } + + @Bean + public NativePayService getPayUrlServices(){ + Config config = getConfig(); + // 构建service + NativePayService service = new NativePayService.Builder().config(config).build(); + return service; + } + + public String getMchId() { + return mchId == null ? "" : mchId.trim(); + } + + public void setMchId(String mchId) { + this.mchId = mchId; + } + + public String getMchNo() { + return mchNo == null ? "" : mchNo.trim(); + } + + public void setMchNo(String mchNo) { + this.mchNo = mchNo; + } + + public String getPrivateKeyPath() { + return privateKeyPath == null ? "" : privateKeyPath.trim(); + } + + public void setPrivateKeyPath(String privateKeyPath) { + this.privateKeyPath = privateKeyPath; + } + + public String getApiV3Key() { + return apiV3Key == null ? "" : apiV3Key.trim(); + } + + public void setApiV3Key(String apiV3Key) { + this.apiV3Key = apiV3Key; + } + + public String getAppId() { + return appId == null ? "" : appId.trim(); + } + + public void setAppId(String appId) { + this.appId = appId; + } + + public String getTimeOut() { + return timeOut == null ? "5" : timeOut.trim(); + } + + public void setTimeOut(String timeOut) { + this.timeOut = timeOut; + } + + public String getUrl() { + return url == null ? "" : url.trim(); + } + + public void setUrl(String url) { + this.url = url; + } + + public String getNotifyUrl() { + return notifyUrl == null ? "" : notifyUrl.trim(); + } + + public void setNotifyUrl(String notifyUrl) { + this.notifyUrl = notifyUrl; + } + + public Double getMaxMoney() { + return maxMoney == null ? 2000 : maxMoney; + } + + public void setMaxMoney(Double maxMoney) { + this.maxMoney = maxMoney; + } + + public Double getMinMoney() { + return minMoney == null ? 0.1 : minMoney; + } + + public void setMinMoney(Double minMoney) { + this.minMoney = minMoney; + } +} diff --git a/src/main/java/cn/com/tenlion/operator/util/task/WxPayResultCheckTask.java b/src/main/java/cn/com/tenlion/operator/util/task/WxPayResultCheckTask.java index a347c21..c9203fc 100644 --- a/src/main/java/cn/com/tenlion/operator/util/task/WxPayResultCheckTask.java +++ b/src/main/java/cn/com/tenlion/operator/util/task/WxPayResultCheckTask.java @@ -3,7 +3,10 @@ package cn.com.tenlion.operator.util.task; import cn.com.tenlion.operator.pojo.dtos.accountrecharge.AccountRechargeDTO; import cn.com.tenlion.operator.pojo.dtos.accountrecharge.AccountRechargePayResultDTO; import cn.com.tenlion.operator.service.accountrecharge.IAccountRechargeService; +import cn.com.tenlion.operator.util.pay.ALiPay; +import cn.com.tenlion.operator.util.pay.PayResultDTO; import cn.com.tenlion.operator.util.pay.PayUtil; +import cn.com.tenlion.operator.util.pay.WXPay; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @@ -24,20 +27,30 @@ public class WxPayResultCheckTask { iAccountRechargeStaticService = this.iAccountRechargeService; } - /** - * 2分钟执行一次 | 关闭超时未付款的 - */ @Scheduled(fixedRate = 60*1000*2) public void close() { // 关闭10分钟之前(未到账)的订单 List list = iAccountRechargeStaticService.getNotCloseRechargeList("微信"); for(AccountRechargeDTO dto : list) { - AccountRechargePayResultDTO payResultDTO = PayUtil.queryOrder(dto.getAccountRechargeId()); + PayResultDTO payResultDTO = WXPay.queryPay(dto.getAccountRechargeId()); // 成功 if (payResultDTO.getOrderStatus().equals("1") && payResultDTO.getMoney().equals(PayUtil.buiderMoney(dto.getRechargeMoney()))) { iAccountRechargeStaticService.saveConfirmOnline(dto.getAccountRechargeId(), payResultDTO.getOrderId(), payResultDTO.getOrderSuccessTime()); }else{ - PayUtil.closeOrder(dto.getAccountRechargeId()); + WXPay.closePay(dto.getAccountRechargeId()); + // 修改状态 + iAccountRechargeStaticService.updateClose(dto.getAccountRechargeId()); + } + } + // 关闭10分钟之前(未到账)的订单 + List list2 = iAccountRechargeStaticService.getNotCloseRechargeList("支付宝"); + for(AccountRechargeDTO dto : list2) { + PayResultDTO payResultDTO = ALiPay.queryPay(dto.getAccountRechargeId()); + // 成功 + if (payResultDTO.getOrderStatus().equals("1") && payResultDTO.getMoney().equals(PayUtil.buiderMoney(dto.getRechargeMoney()))) { + iAccountRechargeStaticService.saveConfirmOnline(dto.getAccountRechargeId(), payResultDTO.getOrderId(), payResultDTO.getOrderSuccessTime()); + }else{ + ALiPay.closePay(dto.getAccountRechargeId()); // 修改状态 iAccountRechargeStaticService.updateClose(dto.getAccountRechargeId()); } @@ -52,9 +65,18 @@ public class WxPayResultCheckTask { // 查出来近10分钟(未到账)的订单 List list = iAccountRechargeStaticService.getNotCheckRechargeList("微信"); for(AccountRechargeDTO dto : list) { - AccountRechargePayResultDTO payResultDTO = PayUtil.queryOrder(dto.getAccountRechargeId()); + PayResultDTO payResultDTO = WXPay.queryPay(dto.getAccountRechargeId()); // 成功 - if (payResultDTO.getOrderStatus().equals("1") && payResultDTO.getMoney().equals(dto.getRechargeMoney())) { + if (payResultDTO.getOrderStatus().equals("1") && payResultDTO.getMoney().equals(PayUtil.buiderMoney(dto.getRechargeMoney()))) { + iAccountRechargeStaticService.saveConfirmOnline(dto.getAccountRechargeId(), payResultDTO.getOrderId(), payResultDTO.getOrderSuccessTime()); + } + } + // 查出来近10分钟(未到账)的订单 + List list2 = iAccountRechargeStaticService.getNotCheckRechargeList("支付宝"); + for(AccountRechargeDTO dto : list2) { + PayResultDTO payResultDTO = ALiPay.queryPay(dto.getAccountRechargeId()); + // 成功 + if (payResultDTO.getOrderStatus().equals("1") && payResultDTO.getMoney().equals(PayUtil.buiderMoney(dto.getRechargeMoney()))) { iAccountRechargeStaticService.saveConfirmOnline(dto.getAccountRechargeId(), payResultDTO.getOrderId(), payResultDTO.getOrderSuccessTime()); } } diff --git a/src/main/resources/application-lanproxy.yml b/src/main/resources/application-lanproxy.yml index 7bbafc0..a16b38f 100644 --- a/src/main/resources/application-lanproxy.yml +++ b/src/main/resources/application-lanproxy.yml @@ -222,19 +222,45 @@ sms: template: verification-code: '{sign} 您的验证码为 {content}, 有效时间为120秒,若非本人操作,请忽略。' -wxpay: - # 商户号 - mchId: 1609461201 - # 商户API证书序列号 - mchSerialNo: 2F16A068181C2998F3EE5271416F720AF0146293 - # 商户私钥文件 - # 注意:apiclient_key地址 - privateKeyPath: D:\AH\apiclient_key.pem - # APIv3密钥 - apiV3Key: _TSKJ_0471_TSkj_0471_tsKJ_0471__ - # APPID 小程序id - appid: wxe17874894f7ff27b - # 微信服务器地址 - domain: https://api.mch.weixin.qq.com - # 接收结果通知地址 - notifyUrl: xxx \ No newline at end of file +pay: + wx-pay: + # 商户号 + mch-id: 1609461201 + # 商户API证书序列号 + mch-no: 2F16A068181C2998F3EE5271416F720AF0146293 + # 私钥本地存储路径 + private-key-path: D:\AH\apiclient_key.pem + # API v3密钥 + api-v3-key: _TSKJ_0471_TSkj_0471_tsKJ_0471__ + # 小程序APPID + app-id: wxe17874894f7ff27b + # 二维码超时时间/单位:分钟 + time-out: 5 + # 微信服务器网关地址 + url: https://api.mch.weixin.qq.com + # 接收结果通知地址.如果需要动态替换订单号,则以 {orderNo} 占位 + notify-url: https://lg48844529.vicp.fun/operator/api/account/pay-wx/{orderNo} + # 单笔最大金额 + max-money: 2000 + # 单笔最小金额 + min-money: 0.1 + ali-pay: + # 应用ID + # 西藏 app-id: 2021004137636507 + app-id: 2021004138650351 + # 支付宝服务器网关地址 + url: https://openapi.alipay.com/gateway.do + # 应用私钥 + # 西藏 private-key: MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCMR1SNMLAfqFnzswWftBv1TnKGgILoDNkthHienFLcEUU1eb0ws7ST8QQZGQEZaHCKSGo82Nvvhwx6+7LGwC5liiu/RGh7CZYEul8+8GwGvsTh7wf1+dEH7YtyfJV1kyUF+p9lL0qRKBbcgUSM8QMyLeCBFE+AVvIqSce8ZLTwetpHSqZFP1VnFuH+gl8c23vDLOySoXCrhqL62Wy3MRmwFtRbOJ6UXicpmU5qxeauERGOlFhQ+5AraPhuRqkvtjN0PnTRbAT1OBEClvW1XXsS+y7i8davSuJWdO4Nmm1PcfUoza1GsspuNKRscgx7znv4SEfjq48HzGf1AJ/ZdhObAgMBAAECggEADSPlZLBp3x1LB8v+O96IO+tUSQsiuA/0DBJ7pgforxqjDAZSVYyP3sfV5W/1LWceG6X65aY+u+o/ngmTzpBUCEjwHiOPUe8s8VZv85pb1CnskWltqnnzPbXfuSK4cWIONsgqRDUw2/YQZilpvXYaIYownIbFh7UdTB7LKfeZB2mm4z76h5wWT90rZtBEXvRuCJrD48xuoksgA5Lul54Jl4MVUBRMB+QyAdnRUddiEaeN47BNOrpsWFSoHQGujTZ9t229VylmRO5+p2Tq1uLrYNR8ZhKbUzhQaVrtUd2lu8TdEMcfCNWWpPTNUry9JdLVKETXoc66+C9fvyTvUo9xEQKBgQDV6UA2CadOOIjhFgya7+Bnn24aaP5wbPAFjjcFgGfQDME9yRRFTovnT5KXQZSvjHxsr+ifETPCj7RMeI0eaE4O/yist4frcvY2BoGgJDE6RmZiG9VGCI68m6y+YvXFXnnZc3lDdXXrkmMKB0uR5vrUR0yrfgEWYsIe8s3BCLSREwKBgQCn4THa1jGoBesRdsGcrQ04CtvIQY83glyjZmxaLjYeFGXxLfOjSJBojK3NfCWrA/0qLS9gN5R3dw0ES7hPPCAA2TBwHfJijfF5U5bODF3S+F9fNP4QuJkNA9PK4oX7KIf7cm8muREwpwyDsAATzr/uc/mSXKS504Wjb4Jfu6pMWQKBgED9L6P7RNhP9s4jy8qazFvPJT1i3sK7ZiTZ8z95ppCf/2nNGJqB5aFuHIRVyV2YWgkPXKZPLKGU1VtSWNV/LRADV5E55VKUR9dcHK/Rrx8cWmi+Ogqf+PW2ekIRgMfpDy4Qliv3mM7sV6ipVL1MJrKtws5rZtstP/r1G6vlAC7/AoGAd2GAnmnq7d0niEe27r9wwwWVvRZBzet6DQhszMRH36QJyjQvKVIUvwQrJBDAiJhRk4iGRBnCDiIus3tVGaNb7r6D33asQsFFkk2K1AOfRMMyrvV0JlffHo42MfRb6nqsGHcL67F3M+3WzF5/75X6josSUq5mxW5RfiNxxrohJCECgYBCeNxjadcyOhwL+BYjr8iIzqX+njguNhunrc0/xfD1WBJjK9QM9hD2TbYrdODUselc1QSM5ZlDLYjdYmEq+COr0gZhok7nHnzLV/SCIkEdT9wLLIestGFZDimcXGTmsKxXqQcGFwrwRnFEu3Xue7/36mG314giD0tIiJtK0CBpyw== + private-key: MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCWIpiransdWYJr9EXA83USVuWjX+hLhCAVHtIJqTPXPFShOW+Rv5aoXHGUsmMfs325DB0lNM/2aYS7Fyym4fzMkLYUHtJoICHafspgJraYpx19jkaSnEkiVgR/UxgDLFFKVubPIszV+zpm8J2xt8PkZHyhuaQEOtBcAGKcNRacDd9DfGZj75vPvhtvVvEFWndeuMZ6d67i2opUVL2c395vPkrjX74Q6GzZ/osfTrCD/3+JHdQXBm0bpOdx7ARJxIyR2sn+7AkPAcXdc3Kz7NoP8C84q09daqwUk6y711ZZfqUmUfAuP4vnh5vMrwcrqlRfc9/LbbH/0U3VFxjtAL2HAgMBAAECggEAMDMLMH0O6W1DIcVaX4fJngmnz7uKqDPS2PT8GX3o1sDXqqr11qTbiVGkZUif6h2Fz1LESJ2b5lAZ/LaD70++CS6sRelfQ26Nb8gk0JmdJYUBQr3ailcCY7OZ3gafPuWLc4JSt01E1a3CIio9dkC48yoPmRwwO+tl2SOGhP/GMnMDtQQ48fzJ/slqofOxyXvGPsZVi+XJz6Ht9mZPEx+jNcdgfOizCGWC6u4IlbOaC/7SP3XVqBk3NlAHk49RoRgJTuZOApU8lS32WMvM/NCRcS/qt5lGjwIFn+TjCOCpmwcqU98yEVGhyJI/xpTJk6/HEEpeCOhJFj+Z0UFjab8SAQKBgQDLGqcS7rW0Q6qNCm9BUvpotXybfoLKF6yjJPprcGe2PtelM5fFgGOurdgafOdnPvLr1lXYe2Ld0d7UioZ2uxTAUrQ3QjeR7I9fACAQHuQ6cJud89ZvGozzWrYhbK1ObZE3tg41+nDfG8qeFnPSY1L5yxreFVH0x+yOBaPhiRhskQKBgQC9PGYwutnIc+UbyS8WU2cRpcXAeAXC2pxQZ14l3gfAXETkUgehh9lKI8R5i0iHxBCvwLMXFSGGJORGQUDj/SVBjWpbuunRJKeaXyYmUnvkthdLSdg1O/KwuJHHfdd1MA4RarKe8Pz4ZqbkGguCKS0sPt39xym7ShZkG26ul3d0lwKBgQC/McHhwrFultxwlUgSWIi+FUrOHhQFJrAvjFno1hHrr9DVBXJ0S96Ky8BJfxdfTBTmCgkaF10Er9Jyhkz6bDamrbRU6JLjXavBpJ6KTmpO0T7NPIO6Z2YUmGonoOSsldxEc6+BBNdIUCM3Gq/BeBreZ2JNegiCw8leENUrNSG24QKBgQCtMu3ZJfuUcza74rw9M+K/DTncuj2TpWCyWpmaEQiJMCpByy5+0oa3S9tU331n/bTEF5wSwV1omLVx8+F/ij+iKtuwz3eX23OnX/Tb2Fza7SqO1yyTNKYgxx1uOCiOcog9uql3vdvbQqD3XzsvS56zw2qNDs+MQvgRceYw2CMWSwKBgGLOf7gdMKmr2D/H86MRI2nGoJ56/2iUu/haRmLmG0rQgc8yV+y9ax2cVm9+2ammCK0MU8bnxZJ4/vatdvCYyKXt+caKOb3JP4aDldayIdJe2wcCr0uh6HK9w317l85QCmc2S6YTYkWJWowf6h4E7UdZtIjGGdIAWfaV1Frzdo0l + # 支付宝公钥 + # 西藏 ali-public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhPuhyfS+awhnbd50xA50GC/hbjeuR4SKVPV6mkEWMGJHFYdicVL0+TKkgl3p9I4c/4OKuQjr0w1dGtyTVDAKDCYdRGpi9av0jP1bYqU0Asg8YnHcLNYYO5zc8olV2DpKd1odHx+Lq7KbO40tN2dYsU1CUBYAMBPsqc4bccomdXHSqE48fOAOu0lYVAk3+7Rlm0yZ4Ya87CVr93pfVlyYRwl0TCeOJ0HeNS/5lWoVpAqsbIUnAi1CkoKC0xLWNriibNjjb9x5KjpxrxTylI9L/FA393XpkevVLtAFVPh9mqKCac+VSw8Fo6c8IVqhJRMV1WjLAzEa8pVkIXD29gav5wIDAQAB + ali-public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0Hi1l310TLDfLnmJlpyyaj1V5JgrKyQgbtx3+QPoE/vauRKl/4pKbyIEgvvYWxB9XG5ZAewyCCh+AsXi0Et9/JBvINopBq5ki/gRn0lOmjNjsGXorz25dNPui0uX8b/0el2giH8Cs0VFHQEByISyf0ZsyK00V7yZ/kBIjvWinyPzKu3drSJQr4ukwWf1h31gXPcpn4hF7kuSAG5TRtDMeriG05WMMnWhUj/Ma3a4D8lf4NaeTa7Qvy+Ha2tTFnvwHBP6VSKllLdOa9/GzpzVRSG0UZT3vuTDup5rv8XIGI3184T6oKqFqp7uHvr9UazO06swyYcLA3gjh8CfKjr+6wIDAQAB + # 支付&二维码超时时间/单位:分钟 + time-out: 5 + # 接收结果通知地址.如果需要动态替换订单号,则以 {orderNo} 占位 + notify-url: https://lg48844529.vicp.fun/operator/api/account/pay-zfb/{orderNo} + # 单笔最大金额 + max-money: 2000 + # 单笔最小金额 + min-money: 0.1 diff --git a/src/main/resources/templates/accountrecharge/pay.html b/src/main/resources/templates/accountrecharge/pay.html index 9fbe3c4..0c88785 100644 --- a/src/main/resources/templates/accountrecharge/pay.html +++ b/src/main/resources/templates/accountrecharge/pay.html @@ -44,7 +44,7 @@
- +