From 1fad0578c97abbb7fc30f59eb1de0f23f08ddde1 Mon Sep 17 00:00:00 2001 From: zhangmei <645025773@qq.com> Date: 星期四, 27 三月 2025 15:21:15 +0800 Subject: [PATCH] 流水、开票营业部权限 --- ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/BankOutController.java | 386 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 379 insertions(+), 7 deletions(-) diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/BankOutController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/BankOutController.java index 8aa5914..b45ecd7 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/BankOutController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/BankOutController.java @@ -1,7 +1,24 @@ package com.ruoyi.web.controller.api; -import com.taxi591.bankapi.dto.CovertPayBackResult; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.date.DateUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.ruoyi.common.constant.AmountConstant; +import com.ruoyi.common.enums.BillTypeEnum; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.dto.TBillDto; +import com.ruoyi.system.model.TOrderBill; +import com.ruoyi.system.model.TPayOrder; +import com.ruoyi.system.service.TBillService; +import com.ruoyi.system.service.TOrderBillService; +import com.ruoyi.system.service.TPayOrderService; +import com.taxi591.bankapi.dto.*; import com.taxi591.bankapi.service.BankService; +import com.taxi591.bankapi.service.SignatureAndVerification; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.binary.Base64; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -9,25 +26,380 @@ import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; @RestController @RequestMapping("open/bank") +@Slf4j public class BankOutController { @Autowired BankService bankService; + @Autowired + TBillService tBillService; - @PostMapping(value = "payCallback") - public @ResponseBody String payCallback(HttpServletRequest request){ - CovertPayBackResult result = bankService.covertPayCallBack(request, (billRequest) -> { + @Autowired + SignatureAndVerification signatureAndVerification; - return true; - }); - return result.getBack(); + @Autowired + TOrderBillService orderBillService; + + @Autowired + TPayOrderService payOrderService; + + public static String getRequestBody(HttpServletRequest request) + throws IOException { + /** 读取httpbody内容 */ + StringBuilder httpBody = new StringBuilder(); + BufferedReader br = null; + try { + br = new BufferedReader(new InputStreamReader( + request.getInputStream())); + String line = null; + while ((line = br.readLine()) != null) { + httpBody.append(line); + } + } catch (IOException ex) { + throw ex; + } finally { + if (br != null) { + try { + br.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + } + return httpBody.toString(); } + @PostMapping(value = "payCallback") + public void payCallback(HttpServletRequest servletRequest,HttpServletResponse servletResponse){ + String request = null; + String responseJson = null; + try { + log.info("--------进入getRequest4Sale----------------------------------"); + // 接收报文 + String requestContent = getRequestBody(servletRequest).trim(); + String signatureString = requestContent.substring(0, + requestContent.indexOf("||")); + log.info("-----ChargeBillController------------截取报文的signatureString:{}", signatureString); + String requestBody = requestContent.substring(signatureString + .length() + 2); + log.info("-----ChargeBillController------------截取报文的requestBody:{}", requestBody); + //如果有双引号,则截取双引号内requestBody的内容 + Pattern p=Pattern.compile("\""); + Matcher m=p.matcher(requestBody); + while(m.find()){ + requestBody=requestBody.replace(m.group(), ""); + log.info("-----ChargeBillController------如果有双引号,则截取后的requestBody:{}", requestBody); + } + //requestBody是base64加密后的数据,需解析出来 + request = new String( + com.alibaba.fastjson.util.Base64.decodeFast(requestBody)); + log.info("-----ChargeBillController------------解析完成后的requestBody-------{}" + request); + ChargeBillRequest chargeBillRequest = JSON.parseObject(request, + new TypeReference<ChargeBillRequest>() { + }); + boolean b = signatureAndVerification.read_cer_and_verify_sign(requestBody, + signatureString); + if (!b){ + throw new ServiceException("验签失败"); + } + /** 销账报文重发次数,通过resendTimes此字段识别销账报文是否为重发的,0表示首次、1表示重发一次,2表示重发2次,最多重发3次*/ + if(chargeBillRequest!=null && "0".equals(chargeBillRequest.getMessage().getInfo().getResendTimes())){ + ChargeBillResponse chargeBillResponse = new ChargeBillResponse( + chargeBillRequest); + ChargeBillResponse.Message respMessage = chargeBillResponse + .getMessage(); + ChargeBillResponse.Message.Head respHead = chargeBillResponse + .getMessage().getHead(); + ChargeBillResponse.Message.Info respInfo = chargeBillResponse + .getMessage().getInfo(); + respHead.setTransFlag("02"); + respHead.setTimeStamp(DateUtil.format(new Date(),"yyyyMMddHHmmssSSS")); + // respHead.setChannel("MBNK"); + respHead.setChannel(chargeBillRequest.getMessage().getHead() + .getChannel()); + // respHead.setTranCode("chargeBill"); + respHead.setTransCode(chargeBillRequest.getMessage().getHead() + .getTransCode()); + respHead.setTransSeqNum(chargeBillRequest.getMessage().getHead() + .getTransSeqNum()); + //测试销账返回报文中,本来是销账成功的报文,但是不要送0000成功码 (JF190510134746710555这个流水号是在Demo的returnCode设置成null的时候产生的,流水状态为6;) + String epayCode = chargeBillRequest.getMessage().getInfo() + .getEpayCode(); + String traceNo = chargeBillRequest.getMessage().getInfo() + .getTraceNo(); + String numOpenMerchantOrder = chargeBillRequest.getMessage() + .getInfo().getNumOpenMerchantOrder(); + respInfo.setNumOpenMerchantOrder(numOpenMerchantOrder); + respInfo.setEpayCode(epayCode); + respInfo.setTraceNo(traceNo); + + try{ + tBillService.completePay(chargeBillRequest); + respHead.setReturnCode("0000"); + respHead.setReturnMessage("账单缴费成功"); + }catch (Exception e){ + respHead.setReturnCode("1111"); + respHead.setReturnMessage("账单处理失败"); + log.error("支付第一次回调出现异常,{}",request,e); + } + //第一次处理失败,不退款 + respInfo.setRefundFlag("false"); + respMessage.setInfo(respInfo); + respMessage.setHead(respHead); + chargeBillResponse.setMessage(respMessage); + responseJson = JSON.toJSONString(chargeBillResponse); + //加签名 + String signatrue = signatureAndVerification + .signWhithsha1withrsa(responseJson); + log.info("-----ChargeBillController------------responseJson打印结果是(responseJson加密前):" + responseJson); + responseJson = signatrue + "||" + + new String(Base64.encodeBase64(responseJson.getBytes("utf-8"))); + log.info("-----ChargeBillController------------responseJson打印结果是(responseJson加密后):" + responseJson); + servletResponse.setCharacterEncoding("utf-8"); + servletResponse.setContentType("text/plain"); + servletResponse.getWriter().write(responseJson); + }else{ + //销账报文重发次数,通过resendTimes此字段识别销账报文是否为重发的,0表示首次、1表示重发一次,2表示重发2次,最多重发3次 + //商户端要注意销账重复通知的情况,要进行订单唯一性处理 + + + ChargeBillResponse chargeBillResponse = new ChargeBillResponse( + chargeBillRequest); + ChargeBillResponse.Message respMessage = chargeBillResponse + .getMessage(); + ChargeBillResponse.Message.Head respHead = chargeBillResponse + .getMessage().getHead(); + ChargeBillResponse.Message.Info respInfo = chargeBillResponse + .getMessage().getInfo(); + respHead.setTransFlag("02"); + respHead.setTimeStamp(DateUtil.format(new Date(),"yyyyMMddHHmmssSSS")); + // respHead.setChannel("MBNK"); + respHead.setChannel(chargeBillRequest.getMessage().getHead() + .getChannel()); + // respHead.setTranCode("chargeBill"); + respHead.setTransCode(chargeBillRequest.getMessage().getHead() + .getTransCode()); + respHead.setTransSeqNum(chargeBillRequest.getMessage().getHead() + .getTransSeqNum()); + try{ + tBillService.completePay(chargeBillRequest); + respHead.setReturnCode("0000"); + respHead.setReturnMessage("账单缴费成功"); + }catch (Exception e){ + respHead.setReturnCode("1111"); + respHead.setReturnMessage("账单处理失败"); + log.error("支付第一次回调出现异常,{}",request,e); + } + // 再次推送未处理成功,则返回退款标志 + if (!"0000".equals(respHead.getReturnCode())) { + respInfo.setRefundFlag("true"); + } + String epayCode = chargeBillRequest.getMessage().getInfo() + .getEpayCode(); + String traceNo = chargeBillRequest.getMessage().getInfo() + .getTraceNo(); + String numOpenMerchantOrder = chargeBillRequest.getMessage() + .getInfo().getNumOpenMerchantOrder(); + respInfo.setNumOpenMerchantOrder(numOpenMerchantOrder); + respInfo.setEpayCode(epayCode); + respInfo.setTraceNo(traceNo); + + respMessage.setInfo(respInfo); + respMessage.setHead(respHead); + chargeBillResponse.setMessage(respMessage); + responseJson = JSON.toJSONString(chargeBillResponse); + //加签名 + String signatrue = signatureAndVerification + .signWhithsha1withrsa(responseJson); + log.info("-----ChargeBillController------------responseJson打印结果是(responseJson加密前):" + responseJson); + responseJson = signatrue + "||" + + new String(Base64.encodeBase64(responseJson.getBytes("utf-8"))); + log.info("-----ChargeBillController------------responseJson打印结果是(responseJson加密后):" + responseJson); + servletResponse.setCharacterEncoding("utf-8"); + servletResponse.setContentType("text/plain"); + servletResponse.getWriter().write(responseJson); + + } + + }catch (Exception e) { + log.error("处理支付回调发生异常:返回内容:{}",request,e); + } + } + + @PostMapping(value = "queryBill") + public void bills(HttpServletRequest request, HttpServletResponse httpServletResponse){ + log.info("进入QueryBillController账单查询接口--------(金额规则为0的)-------"); + + String responseJson = null; + try { + //接收报文request返回截取并返回requestBody和使用base64解析后的requestBody + Map<String, String> requestMap = signatureAndVerification.requestBodyOfBase64(request); + //使用base64解析完成后的requestBody + String requestBodyOfDecoded = requestMap.get("requestBodyOfDecoded"); + //解析前的requestBody + String requestBody = requestMap.get("requestBody"); + //获取缴费中心传送过来的签名 + String signatureString = requestMap.get("signatureString"); + + // 验签 + boolean flag = signatureAndVerification.read_cer_and_verify_sign(requestBody, + signatureString); + + log.info("【QueryBill:getBill4DirectJoinMerch】缴费中心响应的报文验签结果为:{}" , flag); + + QueryBillRequest queryBillRequest = JSON.parseObject(requestBodyOfDecoded, + new TypeReference<QueryBillRequest>() { + }); + //交易编号 + String traceNo = queryBillRequest.getMessage().getInfo() + .getTraceNo(); + //返回给缴费中心的响应 + QueryBillResponse response = new QueryBillResponse(queryBillRequest); + QueryBillResponse.Message respMessage = response.getMessage(); + QueryBillResponse.Message.Head respHead = response.getMessage() + .getHead(); + QueryBillResponse.Message.Info respInfo = response.getMessage() + .getInfo(); + //缴费账单子账单 + ArrayList<QueryBillResponse.Message.Info.Bill> respBills = new ArrayList<QueryBillResponse.Message.Info.Bill>(); +// ArrayList<QueryBillResponse.Message.Info.Bill.DescDetail> respDescDetail = +// new ArrayList<QueryBillResponse.Message.Info.Bill.DescDetail>(); + QueryBillResponse.Message.Info.Bill respBill = respInfo.new Bill(); + //缴费子商户账单 +// ArrayList<QueryBillResponse.Message.Info.Bill.SplitSubMerInfo> splitSubMerInfos = new ArrayList<QueryBillResponse.Message.Info.Bill.SplitSubMerInfo>(); + + //封装返回给缴费中心的响应 + + String epayCode = queryBillRequest.getMessage().getInfo() + .getEpayCode(); + respInfo.setEpayCode(epayCode); + String merchantId = queryBillRequest.getMessage().getInfo() + .getMerchantId(); + respInfo.setMerchantId(merchantId); + respInfo.setTraceNo(traceNo); + respInfo.setInput1(queryBillRequest.getMessage().getInfo() + .getInput1()); + respInfo.setInput2(queryBillRequest.getMessage().getInfo() + .getInput2()); + respInfo.setInput3(queryBillRequest.getMessage().getInfo() + .getInput3()); + respInfo.setInput4(queryBillRequest.getMessage().getInfo() + .getInput4()); + respInfo.setInput5(queryBillRequest.getMessage().getInfo() + .getInput5()); + String orderid= queryBillRequest.getMessage().getInfo().getInput1(); + if (StringUtils.isEmpty(orderid)){ + respHead.setReturnCode("0009"); + respHead.setReturnMessage("参数错误,input1订单号不能为空"); + }else{ + if (flag){ + + TPayOrder order = payOrderService.getById(orderid); + List<TOrderBill> orderBills = orderBillService.getByOrderNo(orderid); + List<TBillDto> bills = orderBills.stream().map(ob + -> tBillService.getDetailByBillId(ob.getBillId())).collect(Collectors.toList()); + respBill.setBillNo(orderid); + List<String> types = bills.stream().map(bill -> BillTypeEnum.getByCode(Integer.parseInt(bill.getBillType())).getName()).distinct().collect(Collectors.toList()); +// 封装详细账单信息 + respBill.setBillName("缴费:"+CollectionUtil.join(types,",")); + respBill.setOweAmt(BigDecimal.valueOf(order.getAmount()).divide(AmountConstant.b100,2, RoundingMode.HALF_DOWN).toPlainString()); + respBills.add(respBill); + respInfo.setCustName(order.getUserName()); + respInfo.setCustAddress(""); + respInfo.setCacheMem(""); + respInfo.setRemark(""); + respInfo.setCallBackText("西藏国资委"); + //respInfo.setCallBackUrl("https://abcsr.keepfx.cn/b/ejy/payResult/"); + //使用base64加密信息 +// respInfo.setCallBackUrl("aHR0cDp3d3cuYWJjaGluYS5jb20vY24v"); + //金额规则字段 + String amtRule = "0"; + respInfo.setAmtRule(amtRule); + /*QueryBillResponse.Message.Info.Bill.UnitDetail unitDetail = respBill.new UnitDetail( + "unitName", "6.66", "1");*/ + //欠费金额 + respBill.setFeeAmt("0.00"); +// +// QueryBillResponse.Message.Info.Bill.DescDetail descDtail1 = respBill.new DescDetail( +// "缴费月份:", "2020年6月份"); +// QueryBillResponse.Message.Info.Bill.DescDetail descDtail2 = respBill.new DescDetail( +// "供电局编号:", "4340152"); +// QueryBillResponse.Message.Info.Bill.DescDetail descDtail3 = respBill.new DescDetail( +// "欠费金额:", "0.00元"); +// QueryBillResponse.Message.Info.Bill.DescDetail descDtail4 = respBill.new DescDetail( +// "缴费月份:", "2020年6月份"); +// QueryBillResponse.Message.Info.Bill.DescDetail descDtail5 = respBill.new DescDetail( +// "服务时间:", "每天0:30-23:30期间均可缴费"); +// QueryBillResponse.Message.Info.Bill.DescDetail descDtail6 = respBill.new DescDetail( +// "温馨提示:", "北京电力电费代缴,咨询电话:95598 该用户为:预付费用户"); +// respDescDetail.add(descDtail1); +// respDescDetail.add(descDtail2); +// respDescDetail.add(descDtail3); +// respDescDetail.add(descDtail4); +// respDescDetail.add(descDtail5); +// respDescDetail.add(descDtail6); + +// respBill.setRcvMerchantId("103881104410001"); + +// 商户子商户详细信息 +// QueryBillResponse.Message.Info.Bill.SplitSubMerInfo splitSubMerInfo1 =respBill.new SplitSubMerInfo("10388", "0.01"); +// QueryBillResponse.Message.Info.Bill.SplitSubMerInfo splitSubMerInfo2 =respBill.new SplitSubMerInfo("1038819201", "0.02"); +// splitSubMerInfos.add(splitSubMerInfo1); +// splitSubMerInfos.add(splitSubMerInfo2); + +// respBill.setSplitSubMerInfos(splitSubMerInfos); +// respBill.setDescDetails(respDescDetail); + respInfo.setTotalBillCount(String.valueOf(respBills.size())); + respInfo.setBill(respBills); + + // 有定制电子回单附言信息的,需添加自定义定制附言信息字段 + respInfo.setMerchantRemark(""); + respHead.setReturnCode("0000"); + respHead.setReturnMessage("账单查询成功,返回成功标志"); + }else { + respHead.setReturnCode("0009"); + respHead.setReturnMessage("缴费中心传送给商户的请求报文签名验签失败!"); + } + } + + respHead.setTransFlag("02"); + respHead.setTimeStamp(DateUtil.format(new Date(),"yyyyMMddHHmmssSSS")); + + respMessage.setInfo(respInfo); + respMessage.setHead(respHead); + response.setMessage(respMessage); + responseJson = JSON.toJSONString(response); + // 加签名 + String signatrue = signatureAndVerification + .signWhithsha1withrsa(responseJson); + log.info("signatrue" + responseJson); + log.info("responseJson打印结果是(responseJson加密前):" + responseJson); + responseJson = signatrue + "||" + + new String(Base64.encodeBase64(responseJson.getBytes("utf-8"))); + log.info("responseJson打印结果是(responseJson加密后):{}", responseJson); + httpServletResponse.setCharacterEncoding("utf-8"); + httpServletResponse.setContentType("text/plain"); + httpServletResponse.getWriter().write(responseJson); + } catch (Exception e) { + e.printStackTrace(); + } + } } -- Gitblit v1.7.1