From b606905fcaf748edfc4bafb236e388f3295f2899 Mon Sep 17 00:00:00 2001
From: xuhy <3313886187@qq.com>
Date: 星期一, 07 四月 2025 09:16:46 +0800
Subject: [PATCH] Merge branch 'xizang-changyun' of https://gitee.com/xiaochen991015/xizang into dev
---
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