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