ab
2024-11-05 0c6faf64f2a02ae94b0d719729754f7ca29da416
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
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
package com.nova.sankuai.domain.api.yinsheng;
 
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nova.sankuai.domain.api.yinsheng.config.YinShengProperties;
import com.nova.sankuai.domain.api.yinsheng.dto.*;
import com.nova.sankuai.domain.api.yinsheng.enums.BusinessTypeEnum;
import com.nova.sankuai.domain.api.yinsheng.enums.YinShengMethodEnum;
import com.nova.sankuai.domain.api.yinsheng.response.*;
import com.nova.sankuai.domain.entity.PayRecord;
import com.nova.sankuai.infra.config.CommonException;
import com.nova.sankuai.infra.utils.MoneyUtil;
import com.nova.sankuai.service.IPayRecordService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
 
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
 
import static com.nova.sankuai.domain.api.yinsheng.enums.YinShengMethodEnum.*;
 
/**
 * 银盛快捷协议支付工具类
 *
 * @author ephemeral
 */
@Component
@RequiredArgsConstructor
public class YinShengFastProtocolUtils {
 
    @Value("${yinsheng.notify_url}")
    private String notifyUrl;
 
    private static final Logger log = LoggerFactory.getLogger("payLogger");
 
    private static final String METHOD = "method";
    private static final String PARTNER_ID = "partner_id";
    private static final String TIMESTAMP = "timestamp";
    private static final String CHARSET = "charset";
    private static final String SIGN_TYPE = "sign_type";
    private static final String SIGN = "sign";
    private static final String VERSION = "version";
    private static final String BIZ_CONTENT = "biz_content";
 
    private static final String UTF_8 = "utf-8";
    private static final String GM = "SM";
    private static final String VERSION_NUM = "3.0";
 
    private final YinShengProperties yinShengProperties;
 
    private final static String TIMEOUT_EXPRESS = "30m";
 
    public final static String STATUS_SUCCESS = "10000";
 
    // 于2022-11-17号
    private final IPayRecordService payRecordService;
 
    /**
     * 准备公共请求参数
     *
     * @param method
     * @return
     */
    private Map<String, String> prepareCommonParam(YinShengMethodEnum method) {
        Map<String, String> mapData = new HashMap<>();
        mapData.put(METHOD, method.getCode());
        mapData.put(PARTNER_ID, yinShengProperties.getPartnerId());
        mapData.put(TIMESTAMP, DateUtil.getDateNow());
        mapData.put(CHARSET, UTF_8);
        mapData.put(SIGN_TYPE, GM);
        mapData.put(VERSION, VERSION_NUM);
        log.debug("准备公共请求参数:{}", mapData);
        return mapData;
    }
 
    public Map<String, String> prepareSignParam(FastProtocolSignDTO signDTO) {
        Map<String, String> mapData = prepareCommonParam(SIGN_PROTOCOL_METHOD);
        JSONObject json = new JSONObject();
        json.put("out_trade_no", signDTO.getOutTradeNo());
        json.put("seller_id", yinShengProperties.getSellerId());  //收款方银盛支付用户号
        json.put("seller_name", yinShengProperties.getSellerName());    //收款方银盛支付客户名
        json.put("buyer_name", encryptData(signDTO.getBuyerName()));
        json.put("buyer_card_number", encryptData(signDTO.getBuyerCardNumber()));
        json.put("buyer_mobile", encryptData(signDTO.getBuyerMobile()));
        json.put("pyerIDNo", encryptData(signDTO.getPayerIDNo()));
        json.put("user_id", signDTO.getUserId());
        if (StringUtils.isNotEmpty(signDTO.getImei())) {
            json.put("imei", signDTO.getImei());
        }
        if (StringUtils.isNotEmpty(signDTO.getActionScope())) {
            json.put("actionScope", signDTO.getActionScope());
        }
        if (signDTO.getTotalAmount() != null) {
            json.put("total_amount", MoneyUtil.toYuan(signDTO.getTotalAmount()));
        }
        mapData.put(BIZ_CONTENT, json.toString());
        mapData.put(SIGN, sign(mapData));
        return mapData;
    }
 
    public Map<String, String> prepareSignQueryParam(String protocolNo) {
        Map<String, String> mapData = prepareCommonParam(QUERY_PROTOCOL_METHOD);
        JSONObject json = new JSONObject();
        json.put("protocol_no", protocolNo);
        mapData.put(BIZ_CONTENT, json.toString());
        mapData.put(SIGN, sign(mapData));
        return mapData;
    }
 
    public Map<String, String> prepareSignConfirmParam(FastProtocolSignConfirmDTO confirmDTO) {
        Map<String, String> mapData = prepareCommonParam(SIGN_CONFIRM_METHOD);
        JSONObject json = new JSONObject();
        json.put("out_trade_no", confirmDTO.getOutTradeNo());
        json.put("mobile_verify_code", confirmDTO.getMobileVerifyCode());
        if (StringUtils.isNotEmpty(confirmDTO.getCardCvn2())) {
            json.put("cardCvn2", encryptData(confirmDTO.getCardCvn2()));
        }
        if (StringUtils.isNotEmpty(confirmDTO.getCardExprDt())) {
            json.put("cardExprDt", encryptData(confirmDTO.getCardExprDt()));
        }
        mapData.put(BIZ_CONTENT, json.toString());
        mapData.put(SIGN, sign(mapData));
        return mapData;
    }
 
    public Map<String, String> prepareSmsResendParam(String paySn) {
        Map<String, String> mapData = prepareCommonParam(FAST_PROTOCOL_SMS_RESEND);
        JSONObject json = new JSONObject();
        json.put("paysn", paySn);
        mapData.put(BIZ_CONTENT, json.toString());
        mapData.put(SIGN, sign(mapData));
        return mapData;
    }
 
    public Map<String, String> prepareSmsConfirmParam(SmsConfirmDTO confirmDTO) {
        Map<String, String> mapData = prepareCommonParam(FAST_PROTOCOL_SMS_CONFIRM);
        JSONObject json = new JSONObject();
        json.put("paysn", confirmDTO.getPaySn());
        json.put("mobile_verify_code", confirmDTO.getMobileVerifyCode());
        mapData.put(BIZ_CONTENT, json.toString());
        mapData.put(SIGN, sign(mapData));
        return mapData;
    }
 
    public Map<String, String> preparePayParam(FastProtocolPayDTO payDTO) {
        Map<String, String> mapData = prepareCommonParam(FAST_PROTOCOL_PAY);
 
        mapData.put("notify_url", notifyUrl + "/api/v1/vipCardOrder/notifyByYinSheng");
 
        JSONObject json = new JSONObject();
        json.put("out_trade_no", payDTO.getOutTradeNo());//商户生成的订单号,生成规则前8位为交易日期,如20180525,范围跨度支持包含当天在内的前后一天,且只能由大小写英文字母、数字、下划线及横杠组成
        json.put("shopdate", DateUtil.getDateNowYmd());//商户日期(该参数做交易与查询时需要一致) 该日期需在当日的前后一天时间范围之内
        json.put("subject", payDTO.getSubject());//商品的标题/交易标题/订单标题/订单关键字等。该参数最长为250个汉字。
        json.put("total_amount", MoneyUtil.toYuan(payDTO.getTotalAmount()));//该笔订单的资金总额,单位为RMB-Yuan。取值范围为[0.01,100000000.00],精确到小数点后两位。Number(10,2)指10位长度,2位精度
        if (StringUtils.isNotEmpty(payDTO.getCurrency())) {
            json.put("currency", payDTO.getCurrency());//支持币种:CNY(人民币)、HKD(港币)、USD(美元)、EUR(欧元)、JPY(日元)。注:不填默认是CNY(人民币),如是非跨境商户,币种不能填HKD(港币)、USD(美元)、EUR(欧元)、JPY(日元)中的任意一种外币币种。
        } else {
            json.put("currency", "CNY");
        }
        json.put("seller_id", yinShengProperties.getSellerId());//收款方银盛支付用户号
        json.put("seller_name", yinShengProperties.getSellerName());//收款方银盛支付客户名
        json.put("timeout_express", TIMEOUT_EXPRESS);//设置未付款交易的超时时间,一旦超时,该笔交易就会自动被关闭。取值范围:1m~15d。m-分钟,h-小时,d-天。该参数数值不接受小数点,如1.5h,可转换为90m。
        if (StringUtils.isNotEmpty(payDTO.getExtendParams())) {
            json.put("extend_params", payDTO.getExtendParams());//业务扩展参数,一个json字符串,order_mode订单模式,暂时可选的值为:00 代表购物车模式;seller_list参与分账的收款方信息数组,每个元素包含seller_id收款方银盛支付用户号。实时分账业务,order_mode和seller_list均不能为空,order_mode的值必须为00。
        }
        if (StringUtils.isNotEmpty(payDTO.getExtraCommonParam())) {
            json.put("extra_common_param", payDTO.getExtraCommonParam());//公用回传参数
        }
        json.put("business_code", yinShengProperties.getBusinessCode());//业务代码
        json.put("user_id", Long.toString(payDTO.getUserId()));//唯一客户标识,商户旗下客户号。签约时的user_id
        json.put("protocol_no", payDTO.getProtocolNo());//银盛支付平台的签约流水号:商户签约确认接口(mercSignConfirm)返回的protocol_no
        if (StringUtils.isNotEmpty(payDTO.getCardCvn2())) {
            json.put("cardCvn2", payDTO.getCardCvn2());//贷记卡必传,如果签名方式为RSA,则用DES加密,密钥为商户号前8位,不足8位在商户号前补空格;如果签名方式为SM,则用SM加密
        }
        if (StringUtils.isNotEmpty(payDTO.getCardExprDt())) {
            json.put("cardExprDt", payDTO.getCardExprDt());//贷记卡必传,如果签名方式为RSA,则用DES加密,密钥为商户号前8位,不足8位在商户号前补空格,格式为MMYY; 如果签名方式为SM,则用SM加密
        }
 
        SubMerchantInfoDTO subMerchant = payDTO.getSubMerchant();
        if (subMerchant != null) {
            JSONObject subMerchantObj = new JSONObject();
            subMerchantObj.put("merName", subMerchant.getMerName());//二级商户名称,支持25个中文
            subMerchantObj.put("merShortName", subMerchant.getMerShortName());//二级商户简称,支持25个中文
            subMerchantObj.put("merAddr", subMerchant.getMerAddr());//二级商户地址,支持100个中文
            subMerchantObj.put("telephone", subMerchant.getTelephone());//固定电话/手机号码二选一
            subMerchantObj.put("merNo", subMerchant.getMerNo());//二级商户编号
            subMerchantObj.put("category", subMerchant.getCategory());//类目,按附件内容输入类目编号
            subMerchantObj.put("mrchntCertId", subMerchant
                    .getMerchantCertId());//身份证号,只支持身份证格式如果签名方式为RSA,则用DES加密,密钥为商户号前8位,不足8位在商户号前补空格; 如果签名方式为SM,则用SM加密)
            json.put("sub_merchant", subMerchantObj);
        }
        ConsigeeInfoDTO consigneeInfo = payDTO.getConsigneeInfo();
        if (consigneeInfo != null) {
            JSONObject consigneeInfoObj = new JSONObject();
            consigneeInfoObj.put("consigneeName", consigneeInfo.getConsigneeName());//收货人姓名
            consigneeInfoObj.put("consigneeAddr", consigneeInfo.getConsigneeAddr());//收货地址
            consigneeInfoObj.put("transportationInfo", consigneeInfo.getTransportationInfo());//物流配送信息(物流名称+订单号)
            consigneeInfoObj.put("commodityName", consigneeInfo.getCommodityName());//商品名称
            consigneeInfoObj.put("commodityNumber", consigneeInfo.getCommodityNumber());//商品数量,
            json.put("consignee_info", consigneeInfoObj);
        }
        if (StringUtils.isNotEmpty(payDTO.getMccs())) {
            json.put("mccs", payDTO.getMccs());//Mcc码(支持上传多个,多个用|分割)
        }
        if (StringUtils.isNotEmpty(payDTO.getMerNo())) {
            json.put("mer_no", payDTO.getMerNo());//第三方商户号
        }
        if (StringUtils.isNotEmpty(payDTO.getSubmerIp())) {
            json.put("submer_ip", payDTO.getSubmerIp());//子商户ip
        }
        mapData.put(BIZ_CONTENT, json.toString());
        mapData.put(SIGN, sign(mapData));
        return mapData;
    }
 
    private String post(Map<String, String> mapData) {
        try {
            return HttpRequest.sendPost(yinShengProperties.getApiUrl(), CommonUtil.mapToString(mapData));
        } catch (Exception e) {
            log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", yinShengProperties.getApiUrl(), CommonUtil.mapToString(mapData), e.getMessage());
            throw new CommonException(e);
        }
    }
 
    public FastProtocolResponse constructFastProtocolResponse(JSONObject jsonObj) {
        if (jsonObj == null) {
            return null;
        }
        String code = jsonObj.getString("code");
        String msg = jsonObj.getString("msg");
        String outTradeNo = jsonObj.getString("out_trade_no");
        String protocolNo = jsonObj.getString("protocol_no");
        String tradeStatus = jsonObj.getString("trade_status");
        String subMsg = jsonObj.getString("sub_msg");
        String bankType = jsonObj.getString("banktype");
 
        FastProtocolResponse response = new FastProtocolResponse();
        response.setCode(code);
        response.setMsg(msg);
        response.setOutTradeNo(outTradeNo);
        response.setTradeStatus(tradeStatus);
        response.setProtocolNo(protocolNo);
        response.setBankType(bankType);
        response.setSubMsg(subMsg);
        return response;
    }
 
    public FastProtocolQueryResponse constructFastProtocolQueryResponse(JSONObject jsonObj) {
        if (jsonObj == null) {
            return null;
        }
        String code = jsonObj.getString("code");
        String msg = jsonObj.getString("msg");
        String protocolNo = jsonObj.getString("protocol_no");
        String tradeStatus = jsonObj.getString("trade_status");
        String bankType = jsonObj.getString("banktype");
 
        FastProtocolQueryResponse response = new FastProtocolQueryResponse();
        response.setCode(code);
        response.setMsg(msg);
        response.setTradeStatus(tradeStatus);
        response.setProtocolNo(protocolNo);
        response.setBankType(bankType);
        return response;
    }
 
    public SmsResendResponse constructSmsResendResponse(JSONObject jsonObj) {
        if (jsonObj == null) {
            return null;
        }
        String code = jsonObj.getString("code");
        String msg = jsonObj.getString("msg");
        String payStatus = jsonObj.getString("pay_status");
 
        SmsResendResponse response = new SmsResendResponse();
        response.setCode(code);
        response.setMsg(msg);
        response.setPayStatus(payStatus);
        return response;
    }
 
    public FastProtocolPayResponse constructFastProtocolPayResponse(JSONObject jsonObj) {
        if (jsonObj == null) {
            return null;
        }
        String code = jsonObj.getString("code");
        String msg = jsonObj.getString("msg");
        String outTradeNo = jsonObj.getString("out_trade_no");
        String tradeNo = jsonObj.getString("trade_no");
        String tradeStatus = jsonObj.getString("trade_status");
        String totalAmount = jsonObj.getString("total_amount");
        String accountDate = jsonObj.getString("account_date");
        String needSign = jsonObj.getString("need_sign");
        String needSmsConfirm = jsonObj.getString("need_sms_confirm");
        String paySn = jsonObj.getString("paysn");
        String subMsg = jsonObj.getString("sub_msg");
        String payStatus = jsonObj.getString("pay_status");
        String merDiscountFee = jsonObj.getString("mer_discount_fee");
 
        FastProtocolPayResponse response = new FastProtocolPayResponse();
        response.setCode(code);
        response.setMsg(msg);
        response.setOutTradeNo(outTradeNo);
        response.setTradeNo(tradeNo);
        response.setTradeStatus(tradeStatus);
        response.setTotalAmount(totalAmount);
        response.setAccountDate(accountDate);
        response.setNeedSign(needSign);
        response.setNeedSmsConfirm(needSmsConfirm);
        response.setPaySn(paySn);
        response.setSubMsg(subMsg);
        response.setPayStatus(payStatus);
        response.setMerDiscountFee(merDiscountFee);
 
        JSONObject installmentResp = jsonObj.getJSONObject("installment_resp");
        if (installmentResp != null) {
            String installmentNum = installmentResp.getString("installment_num");
            String installmentFeeTotal = installmentResp.getString("installment_fee_total");
            String installmentFeePayMode = installmentResp.getString("installment_fee_pay_mode");
            String firstFee = installmentResp.getString("first_fee");
            String eachFee = installmentResp.getString("each_fee");
            String firstBackAmount = installmentResp.getString("first_back_amount");
            String realDiscountFeeRate = installmentResp.getString("real_discount_fee_rate");
 
            InstallmentResponse installmentResponse = new InstallmentResponse();
            installmentResponse.setInstallmentNum(installmentNum);
            installmentResponse.setInstallmentFeeTotal(installmentFeeTotal);
            installmentResponse.setInstallmentFeePayMode(installmentFeePayMode);
            installmentResponse.setFirstFee(firstFee);
            installmentResponse.setEachFee(eachFee);
            installmentResponse.setFirstBackAmount(firstBackAmount);
            installmentResponse.setRealDiscountFeeRate(realDiscountFeeRate);
 
            response.setInstallmentResp(installmentResponse);
        }
 
        return response;
    }
 
    private String sign(Map<String, String> mapData) {
        try {
            String signContent = CommonUtil.mapToString(mapData);
            return GMSignUtils.signMsgSM2(yinShengProperties.getPrivateKeyPath(), yinShengProperties.getPassword(), signContent);
        } catch (Exception e) {
            log.error("国密签名失败", e);
            throw new CommonException(e);
        }
    }
 
    private String encryptData(String data) {
        try {
            return GMSignUtils.encryptData(yinShengProperties.getPublicKeyPath(), data);
        } catch (Exception e) {
            log.error("参数加密失败,加密数据:{}", data, e);
            throw new CommonException(e);
        }
    }
 
    public FastProtocolResponse fastProtocolSign(FastProtocolSignDTO fastProtocolSignDTO) {
 
        try {
            Map<String, String> mapData = prepareSignParam(fastProtocolSignDTO);
            log.info("银盛快捷协议支付签约申请入参为:{}", mapData.toString());
            String result = post(mapData);
            log.info("银盛快捷协议支付签约申请响应参数为:{}", result);
            JSONObject jsonObject = JSONObject.parseObject(result);
            JSONObject signObj = jsonObject.getJSONObject(BusinessTypeEnum.SIGN.getCode());
            log.info("银盛快捷协议支付签约申请响应解密参数为:{}", signObj);
 
            FastProtocolResponse response = constructFastProtocolResponse(signObj);
 
            // 于2022-11-18新增
             payRecordImpl(mapData, signObj);
            // 完
            return response;
        } catch (Exception e) {
            log.error("银盛快捷协议支付签约申请失败", e);
        }
        return null;
    }
 
    @Autowired
    private PlatformTransactionManager transactionManager;// 引入 (平台)事务管理器,Spring 事务策略的核心。
 
    /**
     * 于2022-11-18新增:录入支付记录表
     */
    @Async
    public void payRecordImpl(Map<String, String> mapData, JSONObject signObj) {
        // 业务请求参数的集合
        String biz_content = mapData.get("biz_content");
        if (StringUtils.isBlank(biz_content)) {
            log.error("没有biz_content参数");
            return;
        }
        JSONObject jsonObject = JSONObject.parseObject(biz_content);
        String method = mapData.get("method");
        // 用户ID号
        String user_id_str = jsonObject.getString("user_id");
        Long user_id = StringUtils.isBlank(user_id_str) ? 0L : Long.parseLong(user_id_str);
 
        PayRecord payRecord = new PayRecord();
        // ys 银盛支付 st闪态支付 al支付宝支付 yp 银盛签约 sp闪态签约 yd银盛获取短信验证 ys epay.trusteeship.sign.confirm sd闪态获取短信验证码 yc银盛签约确认 sc闪态签约确认
 
        Integer payStatus = null;// 交易状态:支付、签约、短信等状态码,1成功 2失败 3 签约成功需再次确认
        String trade_status = signObj.getString("trade_status");
        String succ = "SUCCESS";// 成功;
        String failed = "FAILED"; // FAILED:签约失败
        if (StringUtils.isBlank(trade_status)) {// 若trade_status参数为空
            String code = signObj.getString("code");
            String msg = signObj.getString("msg");
            log.info("没有trade_status参数:{}  code:{}   msg:{}", user_id, code, msg);
            if ("10000".equals(code) && "Success".equals(msg)) {
                trade_status = "ysepay.trusteeship.fastPay".equals(method) ? "TRADE_SUCCESS" : succ;
            } else {
                trade_status = "ysepay.trusteeship.fastPay".equals(method) ? "TRADE_FAILED" : failed;
            }
//            return;
        }
 
        if ("ysepay.trusteeship.sign.confirm".equals(method)) {// 签约确认
            payRecord.setPayType("yc");
            if (succ.equals(trade_status)) {
                payStatus = 1;
            } else {// 失败
                payStatus = 2;
            }
        } else if ("ysepay.trusteeship.sign".equals(method)) {// 签约
            payRecord.setPayType("yp");
            if (succ.equals(trade_status)) {
                payStatus = 1;
            } else if (failed.equals(trade_status)){// 失败
                payStatus = 2;
            } else {
                payStatus = 3;
            }
        } else if ("ysepay.trusteeship.fastPay".equals(method)) {// 快捷支付
            payRecord.setPayType("ys");
            String pay_status = signObj.getString("pay_status");
            trade_status = StringUtils.isNotBlank(pay_status) ? pay_status : trade_status;
 
            switch (trade_status) {
                case "TRADE_SUCCESS":
                    payStatus = 1;
                    break;
                case "TRADE_FAILED": // 失败
                    payStatus = 2;
                    break;
                case "WAIT_BUYER_PAY": // 交易创建,等待买家付款
                    payStatus = 4;
                    break;
                case "TRADE_CLOSED": // 在指定时间段内未支付时关闭的交易;客户主动关闭订单
                    payStatus = 5;
                    break;
                case "TRADE_CANCEL": // 订单已撤销
                    payStatus = 7;
                    break;
                case "TRADE_PROCESS": // 交易正在处理中,可对该交易做查询,避免重复支付
                    payStatus = 8;
                    break;
            }
        } else {
            log.error("method参数不正确:{}", user_id);
            return;
        }
 
        if (payStatus == null) {
            log.error("交易状态参数不正确:{}", user_id);
            return;
        }
 
        payRecord.setPayStatus(payStatus);
        if (payStatus != 1) {// 交易状态不为1,成功
            String sub_msg = signObj.getString("sub_msg");
            payRecord.setPayError(sub_msg);
            payRecord.setPayErrorCode(trade_status);
        }
 
        // 订单号
        String out_trade_no = jsonObject.getString("out_trade_no");
        if (StringUtils.isBlank(out_trade_no)) {
            log.error("交易订单号不能为空:{}", user_id);
            return;
        }
        payRecord.setOutTradeNo(out_trade_no);
 
        // 交易时间
        String timestamp = mapData.get("timestamp");
        if (StringUtils.isBlank(timestamp)) {
            LocalDateTime payDate = LocalDateTime.now();
            payRecord.setPayDate(payDate);
        } else {
            DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            LocalDateTime payDate = LocalDateTime.parse(timestamp, df);
            payRecord.setPayDate(payDate);
        }
 
        // 短信验证码
        String mobileVerifyCode = jsonObject.getString("mobile_verify_code");
        payRecord.setMobileVerifyCode(mobileVerifyCode);
 
        // 若是银盛签约确认
        if ("yc".equals(payRecord.getPayType())) {
            DefaultTransactionDefinition def = new DefaultTransactionDefinition();
            TransactionStatus defStatus = transactionManager.getTransaction(def);// 获得事务状态
            // 获取获取验证码的数据
//            payRecordService.lambdaQuery().eq(PayRecord::getOutTradeNo, out_trade_no).eq(PayRecord::getPayType, "yp");
            LambdaQueryWrapper<PayRecord> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(PayRecord::getOutTradeNo, out_trade_no).eq(PayRecord::getPayType, "yp");
            PayRecord ypPayRecord = payRecordService.getOne(wrapper);
            if (ypPayRecord != null) {
                payRecord.setUserId(ypPayRecord.getUserId());
                payRecord.setId(ypPayRecord.getId());
                payRecord.setMobileVerifyCode(ypPayRecord.getMobileVerifyCode());
                payRecordService.updateById(payRecord);
            }
            transactionManager.commit(defStatus);// 手动提交事务
 
            return;
        }
 
        if (user_id_str == null) {
            log.error("没有用户ID号");
            return;
        }
        payRecord.setUserId(user_id);
 
        // 交易金额
        String total_amount = jsonObject.getString("total_amount");
        payRecord.setTotalAmount(total_amount);
 
        // 流水号
        String tradeNo = signObj.getString("trade_no");
        payRecord.setTradeNo(tradeNo);
 
        // 发起一个新事务
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);//新发起一个事务
        TransactionStatus defStatus = transactionManager.getTransaction(def);// 获得事务状态
        payRecordService.save(payRecord);
        transactionManager.commit(defStatus);// 手动提交事务
    }
 
    public FastProtocolQueryResponse fastProtocolQuery(String protocolNo) {
        try {
            Map<String, String> mapData = prepareSignQueryParam(protocolNo);
            log.info("银盛快捷协议支付签约查询请求入参为:{}", mapData.toString());
            String result = post(mapData);
            log.info("银盛快捷协议支付签约查询请求响应参数为:{}", result);
            JSONObject jsonObject = JSONObject.parseObject(result);
            JSONObject signObj = jsonObject.getJSONObject(BusinessTypeEnum.SIGN_QUERY.getCode());
            log.info("银盛快捷协议支付签约查询请求响应解密参数为:{}", signObj);
            FastProtocolQueryResponse response = constructFastProtocolQueryResponse(signObj);
            return response;
        } catch (Exception e) {
            log.error("银盛快捷协议支付签约查询请求失败", e);
        }
        return null;
    }
 
    public FastProtocolResponse fastProtocolSignConfirm(FastProtocolSignConfirmDTO confirmDTO) {
 
        try {
            Map<String, String> mapData = prepareSignConfirmParam(confirmDTO);
            log.info("银盛快捷协议支付签约确认请求入参为:{}", mapData.toString());
            String result = post(mapData);
            log.info("银盛快捷协议支付签约确认请求响应参数为:{}", result);
            JSONObject jsonObject = JSONObject.parseObject(result);
            JSONObject confirmObj = jsonObject.getJSONObject(BusinessTypeEnum.CONFIRM.getCode());
            log.info("银盛快捷协议支付签约确认请求响应解密参数为:{}", confirmObj);
            FastProtocolResponse response = constructFastProtocolResponse(confirmObj);
            payRecordImpl(mapData, confirmObj);
            return response;
        } catch (Exception e) {
            log.error("银盛快捷协议支付签约确认请求失败", e);
        }
        return null;
    }
 
    public SmsResendResponse smsResend(String paySn) {
        try {
            Map<String, String> mapData = prepareSmsResendParam(paySn);
            log.info("银盛快捷协议支付重新发送支付验证短信请求入参为:{}", mapData.toString());
            String result = post(mapData);
            log.info("银盛快捷协议支付重新发送支付验证短信请求响应参数为:{}", result);
            JSONObject jsonObject = JSONObject.parseObject(result);
            JSONObject payObj = jsonObject.getJSONObject(BusinessTypeEnum.SMS_RESEND.getCode());
            log.info("银盛快捷协议支付重新发送支付验证短信请求解密参数为:{}", payObj);
            SmsResendResponse ret = constructSmsResendResponse(payObj);
            return ret;
        } catch (Exception e) {
            log.error("银盛快捷协议支付重新发送支付验证短信请求失败", e);
        }
        return null;
    }
 
    public FastProtocolPayResponse smsConfirm(SmsConfirmDTO confirmDTO) {
 
        try {
            Map<String, String> mapData = prepareSmsConfirmParam(confirmDTO);
            log.info("银盛快捷协议支付短信确认支付请求入参为:{}", mapData.toString());
            String result = post(mapData);
            log.info("银盛快捷协议支付短信确认支付请求响应参数为:{}", result);
            JSONObject jsonObject = JSONObject.parseObject(result);
            JSONObject payObj = jsonObject.getJSONObject(BusinessTypeEnum.PAY.getCode());
            log.info("银盛快捷协议支付短信确认支付请求响应解密参数为:{}", payObj);
 
            FastProtocolPayResponse ret = constructFastProtocolPayResponse(payObj);
            // 于2022-11-18新增
             payRecordImpl(mapData, payObj);
            // 完
            return ret;
        } catch (Exception e) {
            log.error("银盛快捷协议支付短信确认支付失败", e);
        }
        return null;
    }
 
    public FastProtocolPayResponse fastProtocolPay(FastProtocolPayDTO payDTO) {
        try {
            Map<String, String> mapData = preparePayParam(payDTO);
            log.info("银盛快捷协议支付请求入参为:{}", mapData.toString());
            String result = post(mapData);
            log.info("银盛快捷协议支付请求响应参数为:{}", result);
            JSONObject jsonObject = JSONObject.parseObject(result);
            JSONObject payObj = jsonObject.getJSONObject(BusinessTypeEnum.PAY.getCode());
            log.info("银盛快捷协议支付请求响应解密参数为:{}", payObj);
 
            FastProtocolPayResponse ret = constructFastProtocolPayResponse(payObj);
            // 于2022-11-18新增
             payRecordImpl(mapData, payObj);
            // 完
            return ret;
        } catch (Exception e) {
            log.error("银盛快捷协议支付失败", e);
        }
        return null;
    }
}