Commit 263041c0 authored by 刘帅's avatar 刘帅

1.银联支付优化

2.银联接口调用增加记录
parent d31a7e05
package com.maintain.business.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.maintain.common.core.domain.BaseEntity;
/**
* 银联支付日志记录对象 sys_pay_log
*
* @author liushuai
* @date 2025-11-10
*/
@Data
@TableName("sys_pay_log")
public class SysPayLog implements Serializable {
private static final long serialVersionUID=1L;
/**
* 主键
*/
@TableId(value = "id")
private Long id;
/**
* 结算维修单ID
*/
private Long settlementMaintainId;
/**
* 认证报文
*/
private String authorization;
/**
* 请求参数
*/
private String operParam;
/**
* 返回参数
*/
private String jsonResult;
/**
* 操作状态(0正常 1异常)
*/
private String status;
/**
* 操作时间
*/
private Date operTime;
/**
* 操作用户
*/
private Long operUser;
}
package com.maintain.business.domain.bo;
import com.maintain.common.core.validate.AddGroup;
import com.maintain.common.core.validate.EditGroup;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.*;
import java.util.Date;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.maintain.common.core.domain.BaseEntity;
/**
* 银联支付日志记录业务对象 sys_pay_log
*
* @author liushuai
* @date 2025-11-10
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class SysPayLogBo extends BaseEntity {
/**
* 主键
*/
@NotNull(message = "主键不能为空", groups = { EditGroup.class })
private Long id;
/**
* 结算维修单ID
*/
@NotNull(message = "结算维修单ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long settlementMaintainId;
/**
* 认证报文
*/
@NotBlank(message = "认证报文不能为空", groups = { AddGroup.class, EditGroup.class })
private String authorization;
/**
* 请求参数
*/
@NotBlank(message = "请求参数不能为空", groups = { AddGroup.class, EditGroup.class })
private String operParam;
/**
* 返回参数
*/
@NotBlank(message = "返回参数不能为空", groups = { AddGroup.class, EditGroup.class })
private String jsonResult;
/**
* 操作状态(0正常 1异常)
*/
@NotNull(message = "操作状态(0正常 1异常)不能为空", groups = { AddGroup.class, EditGroup.class })
private Long status;
/**
* 操作时间
*/
@NotNull(message = "操作时间不能为空", groups = { AddGroup.class, EditGroup.class })
private Date operTime;
}
package com.maintain.business.domain.vo;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.maintain.common.annotation.ExcelDictFormat;
import com.maintain.common.convert.ExcelDictConvert;
import lombok.Data;
import java.util.Date;
import java.io.Serializable;
/**
* 银联支付日志记录视图对象 sys_pay_log
*
* @author liushuai
* @date 2025-11-10
*/
@Data
@ExcelIgnoreUnannotated
public class SysPayLogVo implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@ExcelProperty(value = "主键")
private Long id;
/**
* 结算维修单ID
*/
@ExcelProperty(value = "结算维修单ID")
private Long settlementMaintainId;
/**
* 认证报文
*/
@ExcelProperty(value = "认证报文")
private String authorization;
/**
* 请求参数
*/
@ExcelProperty(value = "请求参数")
private String operParam;
/**
* 返回参数
*/
@ExcelProperty(value = "返回参数")
private String jsonResult;
/**
* 操作状态(0正常 1异常)
*/
@ExcelProperty(value = "操作状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "0=正常,1=异常")
private Long status;
/**
* 操作时间
*/
@ExcelProperty(value = "操作时间")
private Date operTime;
}
package com.maintain.business.mapper;
import com.maintain.business.domain.SysPayLog;
import com.maintain.business.domain.vo.SysPayLogVo;
import com.maintain.common.core.mapper.BaseMapperPlus;
/**
* 银联支付日志记录Mapper接口
*
* @author liushuai
* @date 2025-11-10
*/
public interface SysPayLogMapper extends BaseMapperPlus<SysPayLogMapper, SysPayLog, SysPayLogVo> {
}
package com.maintain.business.service;
import com.maintain.business.domain.bo.SysPayLogBo;
import com.maintain.business.domain.vo.SysPayLogVo;
import com.maintain.common.core.domain.PageQuery;
import com.maintain.common.core.page.TableDataInfo;
import com.maintain.common.pay.PayResult;
import java.util.List;
/**
* 银联支付日志记录Service接口
*
* @author liushuai
* @date 2025-11-10
*/
public interface ISysPayLogService {
/**
* 查询银联支付日志记录
*/
SysPayLogVo queryById(Long id);
/**
* 查询银联支付日志记录列表
*/
TableDataInfo<SysPayLogVo> queryPageList(SysPayLogBo bo, PageQuery pageQuery);
/**
* 查询银联支付日志记录列表
*/
List<SysPayLogVo> queryList(SysPayLogBo bo);
/**
* 新增银联支付日志记录
*/
PayResult insertByBo(Long id, PayResult payResult);
}
...@@ -18,6 +18,7 @@ import com.maintain.business.mapper.ErpRepairFormMapper; ...@@ -18,6 +18,7 @@ import com.maintain.business.mapper.ErpRepairFormMapper;
import com.maintain.business.mapper.ErpSettlementMaintainMapper; import com.maintain.business.mapper.ErpSettlementMaintainMapper;
import com.maintain.business.mapper.ErpSettlementMaintainRepairFormMapper; import com.maintain.business.mapper.ErpSettlementMaintainRepairFormMapper;
import com.maintain.business.service.IErpSettlementMaintainService; import com.maintain.business.service.IErpSettlementMaintainService;
import com.maintain.business.service.ISysPayLogService;
import com.maintain.common.core.domain.PageQuery; import com.maintain.common.core.domain.PageQuery;
import com.maintain.common.core.domain.entity.SysDept; import com.maintain.common.core.domain.entity.SysDept;
import com.maintain.common.core.page.TableDataInfo; import com.maintain.common.core.page.TableDataInfo;
...@@ -26,6 +27,7 @@ import com.maintain.common.enums.SettlementState; ...@@ -26,6 +27,7 @@ import com.maintain.common.enums.SettlementState;
import com.maintain.common.exception.ServiceException; import com.maintain.common.exception.ServiceException;
import com.maintain.common.helper.LoginHelper; import com.maintain.common.helper.LoginHelper;
import com.maintain.common.pay.PayResponse; import com.maintain.common.pay.PayResponse;
import com.maintain.common.pay.PayResult;
import com.maintain.common.pay.YinLianPayApi; import com.maintain.common.pay.YinLianPayApi;
import com.maintain.common.utils.StringUtils; import com.maintain.common.utils.StringUtils;
import com.maintain.common.utils.redis.RedisUtils; import com.maintain.common.utils.redis.RedisUtils;
...@@ -57,6 +59,7 @@ public class ErpSettlementMaintainServiceImpl implements IErpSettlementMaintainS ...@@ -57,6 +59,7 @@ public class ErpSettlementMaintainServiceImpl implements IErpSettlementMaintainS
private final ErpClientMapper clientMapper; private final ErpClientMapper clientMapper;
private final YinLianPayApi yinLianPayApi; private final YinLianPayApi yinLianPayApi;
private final SysDeptMapper sysDeptMapper; private final SysDeptMapper sysDeptMapper;
private final ISysPayLogService sysPayLogService;
@Value("${pay.merchantCode}") @Value("${pay.merchantCode}")
private String merchantCode; private String merchantCode;
...@@ -256,12 +259,17 @@ public class ErpSettlementMaintainServiceImpl implements IErpSettlementMaintainS ...@@ -256,12 +259,17 @@ public class ErpSettlementMaintainServiceImpl implements IErpSettlementMaintainS
if (money == 0) { if (money == 0) {
throw new ServiceException("结算单金额为0,无需支付!"); throw new ServiceException("结算单金额为0,无需支付!");
} }
PayResponse response = yinLianPayApi.pay(orderNo, money, bo.getPaymentAccount(), sysDept.getTerminalCode()); // 调用支付API
if (!response.getErrCode().equals("00")) { PayResult payResult = yinLianPayApi.pay(orderNo, money, bo.getPaymentAccount(), sysDept.getTerminalCode());
throw new ServiceException("结算单支付失败:"+ response.getErrInfo()); /* 保存支付调用记录 */
sysPayLogService.insertByBo(maintain.getId(), payResult);
PayResponse payResponse = payResult.getPayResponse();
/* 判断是否支付成功 */
if (!payResponse.getErrCode().equals("00")) {
throw new ServiceException("结算单支付失败:"+ payResponse.getErrInfo());
} }
maintain.setCollectionAccount(merchantCode); maintain.setCollectionAccount(merchantCode);
maintain.setCollectionSerialNumber(response.getOrderId()); maintain.setCollectionSerialNumber(payResponse.getOrderId());
maintain.setCollectionTime(new Date()); maintain.setCollectionTime(new Date());
maintain.setState(SettlementState.TWO.getCode()); maintain.setState(SettlementState.TWO.getCode());
maintain.setPaymentMethod(1); maintain.setPaymentMethod(1);
......
package com.maintain.business.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.maintain.business.domain.SysPayLog;
import com.maintain.business.domain.bo.SysPayLogBo;
import com.maintain.business.domain.vo.SysPayLogVo;
import com.maintain.business.mapper.SysPayLogMapper;
import com.maintain.business.service.ISysPayLogService;
import com.maintain.common.core.domain.PageQuery;
import com.maintain.common.core.page.TableDataInfo;
import com.maintain.common.helper.LoginHelper;
import com.maintain.common.pay.PayResult;
import com.maintain.common.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 银联支付日志记录Service业务层处理
*
* @author liushuai
* @date 2025-11-10
*/
@RequiredArgsConstructor
@Service
public class SysPayLogServiceImpl implements ISysPayLogService {
private final SysPayLogMapper baseMapper;
/**
* 查询银联支付日志记录
*/
@Override
public SysPayLogVo queryById(Long id){
return baseMapper.selectVoById(id);
}
/**
* 查询银联支付日志记录列表
*/
@Override
public TableDataInfo<SysPayLogVo> queryPageList(SysPayLogBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<SysPayLog> lqw = buildQueryWrapper(bo);
Page<SysPayLogVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询银联支付日志记录列表
*/
@Override
public List<SysPayLogVo> queryList(SysPayLogBo bo) {
LambdaQueryWrapper<SysPayLog> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<SysPayLog> buildQueryWrapper(SysPayLogBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<SysPayLog> lqw = Wrappers.lambdaQuery();
lqw.eq(bo.getSettlementMaintainId() != null, SysPayLog::getSettlementMaintainId, bo.getSettlementMaintainId());
lqw.eq(StringUtils.isNotBlank(bo.getAuthorization()), SysPayLog::getAuthorization, bo.getAuthorization());
lqw.eq(StringUtils.isNotBlank(bo.getOperParam()), SysPayLog::getOperParam, bo.getOperParam());
lqw.eq(StringUtils.isNotBlank(bo.getJsonResult()), SysPayLog::getJsonResult, bo.getJsonResult());
lqw.eq(bo.getStatus() != null, SysPayLog::getStatus, bo.getStatus());
lqw.eq(bo.getOperTime() != null, SysPayLog::getOperTime, bo.getOperTime());
return lqw;
}
/**
* 新增银联支付日志记录
*/
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class, timeout = 30)
public PayResult insertByBo(Long id, PayResult payResult) {
// 保存支付日志
SysPayLog sysPayLog = new SysPayLog();
sysPayLog.setSettlementMaintainId(id);
sysPayLog.setAuthorization(payResult.getAuthorization());
sysPayLog.setOperParam(payResult.getRequestParams());
sysPayLog.setJsonResult(payResult.getResponse());
sysPayLog.setStatus(payResult.getPayResponse().getErrCode());
sysPayLog.setOperTime(new Date());
sysPayLog.setOperUser(LoginHelper.getUserId());
baseMapper.insert(sysPayLog);
return payResult;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(SysPayLog entity){
//TODO 做一些数据校验,如唯一约束
}
}
package com.maintain.common.pay;
import lombok.Data;
/**
* PayResult
*
* @author Liu Shuai
* @date 2025/11/10 14:44
*/
@Data
public class PayResult {
// 请求参数
private String requestParams;
// 认证报文
private String authorization;
// 响应结果
private String response;
// 解析后的响应对象
private PayResponse payResponse;
}
...@@ -11,9 +11,10 @@ import javax.crypto.spec.SecretKeySpec; ...@@ -11,9 +11,10 @@ import javax.crypto.spec.SecretKeySpec;
import java.io.*; import java.io.*;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.util.Date;
import java.util.List;
import java.util.TimeZone;
/** /**
* 银联支付API * 银联支付API
...@@ -71,7 +72,8 @@ public class YinLianPayApi { ...@@ -71,7 +72,8 @@ public class YinLianPayApi {
* @param terminalCode 终端号 * @param terminalCode 终端号
* @return 支付结果 * @return 支付结果
*/ */
public PayResponse pay(String merchantOrderId,int transactionAmount, String payCode, String terminalCode) { public PayResult pay(String merchantOrderId,int transactionAmount, String payCode, String terminalCode) {
PayResult payResult = new PayResult();
// 组建请求报文 // 组建请求报文
PayBody reqBody = new PayBody(); PayBody reqBody = new PayBody();
reqBody.merchantCode = merchantCode; reqBody.merchantCode = merchantCode;
...@@ -90,20 +92,25 @@ public class YinLianPayApi { ...@@ -90,20 +92,25 @@ public class YinLianPayApi {
// 设备类型固定11 // 设备类型固定11
reqBody.deviceType = deviceType; reqBody.deviceType = deviceType;
String requestBody = reqBody.toString(); String requestBody = reqBody.toString();
payResult.setRequestParams(requestBody);
System.out.println("请求参数:\n" + requestBody); System.out.println("请求参数:\n" + requestBody);
// 获取认证报文,timestamp为当前日期 // 获取认证报文,timestamp为当前日期
String timestamp = getCurrentTimestamp14(); String timestamp = getCurrentTimestamp14();
String authorization; String authorization;
try { try {
authorization = getAuthorization(appid,appkey,timestamp,"nonce",reqBody.toString()); authorization = getAuthorization(appid,appkey,timestamp,"nonce",reqBody.toString());
payResult.setAuthorization(authorization);
System.out.println("认证报文:\n"+authorization); System.out.println("认证报文:\n"+authorization);
}catch (Exception e){ }catch (Exception e){
throw new RuntimeException("获取认证报文失败,请检查!"); throw new RuntimeException("获取认证报文失败,请检查!");
} }
// 发送http请求,并解析返回信息 // 发送http请求,并解析返回信息
String response = request(url,authorization,reqBody.toString()); String response = request(url,authorization,reqBody.toString());
payResult.setResponse(response);
System.out.println("响应参数:\n"+response); System.out.println("响应参数:\n"+response);
return JSONUtil.toBean(response, PayResponse.class); PayResponse payResponse = JSONUtil.toBean(response, PayResponse.class);
payResult.setPayResponse(payResponse);
return payResult;
} }
/** /**
......
...@@ -271,6 +271,7 @@ ...@@ -271,6 +271,7 @@
<el-form-item label="收款时间" prop="collectionTime"> <el-form-item label="收款时间" prop="collectionTime">
<el-date-picker clearable <el-date-picker clearable
v-model="form.collectionTime" v-model="form.collectionTime"
:disabled="isQrPay"
type="datetime" type="datetime"
value-format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择收款时间"> placeholder="请选择收款时间">
...@@ -279,12 +280,12 @@ ...@@ -279,12 +280,12 @@
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="收款账号" prop="collectionAccount"> <el-form-item label="收款账号" prop="collectionAccount">
<el-input v-model="form.collectionAccount" placeholder="请输入收款账号" /> <el-input v-model="form.collectionAccount" :disabled="isQrPay" placeholder="请输入收款账号" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="交易流水号" prop="collectionSerialNumber"> <el-form-item label="交易流水号" prop="collectionSerialNumber">
<el-input v-model="form.collectionSerialNumber" placeholder="请输入交易流水号" /> <el-input v-model="form.collectionSerialNumber" :disabled="isQrPay" placeholder="请输入交易流水号" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
...@@ -440,6 +441,7 @@ export default { ...@@ -440,6 +441,7 @@ export default {
open: false, open: false,
open1: false, open1: false,
open2: false, open2: false,
isQrPay: false,
// 查询参数 // 查询参数
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
...@@ -560,6 +562,7 @@ export default { ...@@ -560,6 +562,7 @@ export default {
paymentAccount: undefined, paymentAccount: undefined,
} }
this.open2 = true; this.open2 = true;
this.isQrPay = false;
this.title = "扫码支付"; this.title = "扫码支付";
this.$nextTick(() => { this.$nextTick(() => {
// 确保输入框存在并获取焦点 // 确保输入框存在并获取焦点
...@@ -576,6 +579,7 @@ export default { ...@@ -576,6 +579,7 @@ export default {
paySettlementMaintain(this.payForm).then(response => { paySettlementMaintain(this.payForm).then(response => {
this.$modal.msgSuccess("支付成功"); this.$modal.msgSuccess("支付成功");
this.open2 = false; this.open2 = false;
this.isQrPay = true;
getSettlementMaintain(this.form.id).then(response => { getSettlementMaintain(this.form.id).then(response => {
this.form = response.data; this.form = response.data;
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment