增加支付宝支付

This commit is contained in:
java_cuibaocheng@163.com 2024-03-22 21:27:56 +08:00
parent 92f431caa8
commit 079bfb5509
12 changed files with 837 additions and 288 deletions

View File

@ -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

View File

@ -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<String, Object> 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());

View File

@ -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("生成支付二维码失败");
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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<EncodeHintType, ErrorCorrectionLevel> 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;
}
}
}

View File

@ -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<EncodeHintType, ErrorCorrectionLevel> 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;
}
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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<AccountRechargeDTO> 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<AccountRechargeDTO> 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<AccountRechargeDTO> 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<AccountRechargeDTO> 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());
}
}

View File

@ -222,19 +222,45 @@ sms:
template:
verification-code: '{sign} 您的验证码为 {content}, 有效时间为120秒若非本人操作请忽略。'
wxpay:
pay:
wx-pay:
# 商户号
mchId: 1609461201
mch-id: 1609461201
# 商户API证书序列号
mchSerialNo: 2F16A068181C2998F3EE5271416F720AF0146293
# 商户私钥文件
# 注意apiclient_key地址
privateKeyPath: D:\AH\apiclient_key.pem
mch-no: 2F16A068181C2998F3EE5271416F720AF0146293
# 私钥本地存储路径
private-key-path: D:\AH\apiclient_key.pem
# API v3密钥
apiV3Key: _TSKJ_0471_TSkj_0471_tsKJ_0471__
# APPID 小程序id
appid: wxe17874894f7ff27b
# 微信服务器地址
domain: https://api.mch.weixin.qq.com
# 接收结果通知地址
notifyUrl: xxx
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

View File

@ -44,7 +44,7 @@
<label class="layui-form-label">付款方式<span style="color: red">*</span></label>
<div class="layui-input-block">
<input type="radio" name="thirdParty" lay-skin="primary" lay-verify="required" value="微信" lay-filter="thirdParty" title="微信">
<input type="radio" name="thirdParty" value="支付宝" disabled lay-filter="thirdParty" title="支付宝">
<input type="radio" name="thirdParty" value="支付宝" lay-filter="thirdParty" title="支付宝">
<input type="radio" name="thirdParty" value="银联" disabled lay-filter="thirdParty" title="银联">
<input type="radio" name="thirdParty" value="对公转账" lay-filter="thirdParty" title="对公转账">
</div>