mitao
2025-04-02 45a7c01ea76ce113c2e0f940292574018c12ac59
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
package com.ruoyi.web.controller.api;
 
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.ResponseBody;
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;
 
    @Autowired
    SignatureAndVerification signatureAndVerification;
 
    @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();
        }
    }
 
 
}