chengf
2025-08-29 fef2c4d637ca36cd8379b98d1e54d68a7a0536b0
service-acct/src/main/java/com/java110/acct/cmd/payment/NativeQrcodePaymentCmd.java
@@ -2,35 +2,43 @@
import com.alibaba.fastjson.JSONObject;
import com.java110.acct.payment.IPaymentBusiness;
import com.java110.acct.payment.IPaymentFactoryAdapt;
import com.java110.acct.smo.IQrCodePaymentSMO;
import com.java110.core.annotation.Java110Cmd;
import com.java110.core.context.CmdContextUtils;
import com.java110.core.context.ICmdDataFlowContext;
import com.java110.core.event.cmd.Cmd;
import com.java110.core.event.cmd.CmdEvent;
import com.java110.core.factory.CommunitySettingFactory;
import com.java110.core.factory.GenerateCodeFactory;
import com.java110.core.factory.WechatFactory;
import com.java110.core.log.LoggerFactory;
import com.java110.dto.fee.PayFeeDto;
import com.java110.dto.payment.PaymentOrderDto;
import com.java110.dto.paymentPool.PaymentPoolDto;
import com.java110.dto.paymentPoolConfig.PaymentPoolConfigDto;
import com.java110.dto.payment.*;
import com.java110.dto.wechat.SmallWeChatDto;
import com.java110.intf.acct.IPaymentKeyV1InnerServiceSMO;
import com.java110.intf.acct.IPaymentPoolConfigV1InnerServiceSMO;
import com.java110.intf.acct.IPaymentPoolV1InnerServiceSMO;
import com.java110.intf.acct.IPaymentPoolValueV1InnerServiceSMO;
import com.java110.intf.fee.IPayFeeV1InnerServiceSMO;
import com.java110.utils.cache.CommonCache;
import com.java110.utils.cache.MappingCache;
import com.java110.utils.cache.UrlCache;
import com.java110.utils.constant.MappingConstant;
import com.java110.utils.constant.WechatConstant;
import com.java110.utils.exception.CmdException;
import com.java110.utils.factory.ApplicationContextFactory;
import com.java110.utils.util.Assert;
import com.java110.utils.util.StringUtil;
import com.java110.utils.util.DateUtil;
import com.java110.utils.util.PayUtil;
import com.java110.vo.ResultVo;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;
import java.text.ParseException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
 * native qrcode 支付
@@ -43,6 +51,12 @@
    private static final Logger logger = LoggerFactory.getLogger(NativeQrcodePaymentCmd.class);
    protected static final String DEFAULT_PAYMENT_ADAPT = "wechatNativeQrcodePaymentFactory";// 默认微信通用支付
    @Autowired
    private IPaymentKeyV1InnerServiceSMO paymentKeyV1InnerServiceSMOImpl;
    @Autowired
    private IPaymentPoolValueV1InnerServiceSMO paymentPoolValueV1InnerServiceSMOImpl;
    @Autowired
    private IPaymentPoolConfigV1InnerServiceSMO paymentPoolConfigV1InnerServiceSMOImpl;
@@ -60,13 +74,53 @@
    }
    private static final String VERSION = "1.0";
    @Value("${fuiou.pay.unified-order-url}")
    public String PAY_UNIFIED_ORDER_URL;
    @Autowired
    private RestTemplate outRestTemplate;
    @Override
    public void doCmd(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) throws CmdException, ParseException {
//        if (!(reqJson.containsKey("communityId"))){
//            reqJson.put("communityId","2025062600070012");
//        }
        PaymentPoolDto paymentPoolDto = new PaymentPoolDto();
        paymentPoolDto.setCommunityId(reqJson.getString("communityId"));
        paymentPoolDto.setPage(1);
        paymentPoolDto.setRow(10);
        List<PaymentPoolDto> paymentPoolDtos = paymentPoolV1InnerServiceSMOImpl.queryPaymentPools(paymentPoolDto);
        List<PaymentPoolDto> collect = paymentPoolDtos.stream().filter(e -> e.getPaymentType().equals("FUIOU")).collect(Collectors.toList());
        PaymentPoolValueDto paymentPoolValueDto = new PaymentPoolValueDto();
        paymentPoolValueDto.setPpId(collect.get(0).getPpId());
        paymentPoolValueDto.setCommunityId(reqJson.getString("communityId"));
        List<PaymentPoolValueDto> values =  paymentPoolValueV1InnerServiceSMOImpl.queryPaymentPoolValues(paymentPoolValueDto);
        Map<String, List<PaymentPoolValueDto>> payMap = values.stream().collect(Collectors.groupingBy(PaymentPoolValueDto::getColumnKey));
        SmallWeChatDto smallWeChatDto = new SmallWeChatDto();
        if(payMap.containsKey("FUIOU_APP_ID")){
            smallWeChatDto.setAppId(payMap.get("FUIOU_APP_ID").get(0).getColumnValue());
        }else{
            smallWeChatDto.setAppId(MappingCache.getValue(WechatConstant.WECHAT_DOMAIN, "appId"));
        }
        if(payMap.containsKey("FUIOU_MCHNT_KEY")){
            smallWeChatDto.setAppSecret(payMap.get("FUIOU_MCHNT_KEY").get(0).getColumnValue());
        }else{
            smallWeChatDto.setAppSecret(MappingCache.getValue(WechatConstant.WECHAT_DOMAIN, "appSecret"));
        }
        if(payMap.containsKey("FUIOU_ORDER_PRE")){
            smallWeChatDto.setOrderPre(payMap.get("FUIOU_ORDER_PRE").get(0).getColumnValue());
        }
        if(payMap.containsKey("FUIOU_MERCHANT_ID")){
            smallWeChatDto.setMchId(payMap.get("FUIOU_MERCHANT_ID").get(0).getColumnValue());
        }else{
            smallWeChatDto.setMchId(MappingCache.getValue(MappingConstant.WECHAT_STORE_DOMAIN, "mchId"));
        }
        logger.debug(">>>>>>>>>>>>>>>>支付参数报文,{}", reqJson.toJSONString());
        String appId = context.getReqHeaders().get("app-id");
        String userId = context.getReqHeaders().get("user-id");
        reqJson.put("createUserId", userId);
        reqJson.put("storeId", CmdContextUtils.getStoreId(context));
        //1.0 查询当前支付的业务
@@ -80,138 +134,78 @@
        PaymentOrderDto paymentOrderDto = paymentBusiness.unified(context, reqJson);
        paymentOrderDto.setAppId(appId);
        paymentOrderDto.setUserId(userId);
        reqJson.put("money", paymentOrderDto.getMoney());
        logger.debug(">>>>>>>>>>>>>>>>支付业务下单返回,{}", JSONObject.toJSONString(paymentOrderDto));
        // 3.0 寻找当前支付适配器
        String payAdapt = computeAdapt(reqJson.getString("business"), reqJson);//MappingCache.getValue(WechatConstant.WECHAT_DOMAIN, WechatConstant.NATIVE_QRCODE_PAYMENT_ADAPT);
        payAdapt = StringUtil.isEmpty(payAdapt) ? DEFAULT_PAYMENT_ADAPT : payAdapt;
        if (reqJson.containsKey("payAdapt") && !StringUtil.isEmpty(reqJson.getString("payAdapt"))) {
            payAdapt = reqJson.getString("payAdapt");
        }
        IPaymentFactoryAdapt tPayAdapt = ApplicationContextFactory.getBean(payAdapt, IPaymentFactoryAdapt.class);
        // 4.0 相应支付厂家下单
        Map result = null;
        try {
            result = tPayAdapt.java110Payment(paymentOrderDto, reqJson, context);
        } catch (Exception e) {
            logger.error("支付异常", e);
            throw new CmdException(e.getLocalizedMessage());
        }
        ResponseEntity<String> responseEntity = new ResponseEntity(JSONObject.toJSONString(result), HttpStatus.OK);
        logger.debug("调用支付厂家返回,{}", responseEntity);
        context.setResponseEntity(responseEntity);
        String token = GenerateCodeFactory.getUUID();
        // redis 中 保存 请求参数
        CommonCache.setValue("nativeQrcodePayment_" + paymentOrderDto.getOrderId(), reqJson.toJSONString(), CommonCache.PAY_DEFAULT_EXPIRE_TIME);
        CommonCache.setValue("nativeQrcodePayment_" + token, reqJson.toJSONString(), CommonCache.PAY_DEFAULT_EXPIRE_TIME);
        JSONObject result = new JSONObject();
        String notifyUrl = UrlCache.getOwnerUrl() + "/app/payment/notify/wechat/"+appId+"/"+reqJson.getString("paymentPoolId");
//
//
//        List<PaymentKeyDto> paymentKeyDtos = null;
//
//        PaymentKeyDto paymentKeyDto = new  PaymentKeyDto();
//        paymentKeyDto.setPaymentType("FUIOU");
//        paymentKeyDtos = paymentKeyV1InnerServiceSMOImpl.queryPaymentKeys(paymentKeyDto);
//
        String systemName = MappingCache.getValue(WechatConstant.WECHAT_DOMAIN, WechatConstant.PAY_GOOD_NAME);
        JSONObject paramMap = new JSONObject();
        paramMap.put("version", VERSION);
        paramMap.put("mchnt_cd", smallWeChatDto.getMchId()); // 富友分配给二级商户的商户号
        paramMap.put("random_str", PayUtil.makeUUID(32));
        paramMap.put("order_amt", (int)(paymentOrderDto.getMoney()*100));
        String generatorId = GenerateCodeFactory.getGeneratorId("81");
        paramMap.put("mchnt_order_no", smallWeChatDto.getOrderPre() + generatorId);
        paramMap.put("txn_begin_ts", DateUtil.getNow(DateUtil.DATE_FORMATE_STRING_DEFAULT));
        paramMap.put("goods_des", systemName + "测试");
        paramMap.put("term_id", "abcdefgh");
        paramMap.put("term_ip", PayUtil.getLocalIp());
        paramMap.put("notify_url", notifyUrl + "?wId=" + WechatFactory.getWId(smallWeChatDto.getAppId()));
        paramMap.put("trade_type", "WXBXLET");
        paramMap.put("order_type", "WECHAT");
//        paramMap.put("sub_openid", openid);
//        paramMap.put("sub_appid", smallWeChatDto.getAppId());
        paramMap.put("sign", createSign(paramMap, smallWeChatDto.getAppSecret()));
        logger.debug("调用支付统一下单接口" + paramMap.toJSONString());
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json");
        HttpEntity httpEntity = new HttpEntity(paramMap.toJSONString(), headers);
        ResponseEntity<String> responseEntity = outRestTemplate.exchange(PAY_UNIFIED_ORDER_URL
                , HttpMethod.POST, httpEntity, String.class);
        if(JSONObject.parseObject(responseEntity.getBody()).get("result_msg").equals("SUCCESS")){
            result.put("codeUrl", JSONObject.parseObject(responseEntity.getBody()).get("qr_code"));
            ResponseEntity<String> responseEntity2 = ResultVo.createResponseEntity(result);
            logger.debug("调用支付厂家返回,{}", responseEntity2);
            context.setResponseEntity(responseEntity2);
        }else{
            result.put("codeUrl", JSONObject.parseObject(responseEntity.getBody()).get("qr_code"));
            ResponseEntity<String> responseEntity2 = ResultVo.createResponseEntity(responseEntity);
            logger.debug("调用支付厂家返回,{}", responseEntity);
            context.setResponseEntity(responseEntity2);
        }
    }
    private String createSign(JSONObject paramMap, String payPassword) {
        String str = paramMap.getString("mchnt_cd") + "|"
                + paramMap.getString("order_type") + "|"
                + paramMap.getString("order_amt") + "|"
                + paramMap.getString("mchnt_order_no") + "|"
                + paramMap.getString("txn_begin_ts") + "|"
                + paramMap.getString("goods_des") + "|"
                + paramMap.getString("term_id") + "|"
                + paramMap.getString("term_ip") + "|"
                + paramMap.getString("notify_url") + "|"
                + paramMap.getString("random_str") + "|"
                + paramMap.getString("version") + "|"
                + payPassword;
        return PayUtil.md5(str);
    }
    /**
     * 计算适配器
     *
     * @param business
     * @param reqJson
     * @return
     */
    private String computeAdapt(String business, JSONObject reqJson) {
        String communityId = reqJson.getString("communityId");
        //todo 如果是单个费用缴费
        PaymentPoolDto paymentPoolDto = ifPayFeeBusiness(business, reqJson);
        if (paymentPoolDto != null) {
            reqJson.put("paymentPoolId", paymentPoolDto.getPpId());
            return paymentPoolDto.getBeanNative();
        }
        //todo 如果是临时车
        paymentPoolDto = ifTempCarFeeBusiness(business, communityId);
        if (paymentPoolDto != null) {
            reqJson.put("paymentPoolId", paymentPoolDto.getPpId());
            return paymentPoolDto.getBeanNative();
        }
        //todo 按小区查询 支付信息
        paymentPoolDto = new PaymentPoolDto();
        paymentPoolDto.setCommunityId(communityId);
        paymentPoolDto.setPayType(PaymentPoolDto.PAY_TYPE_COMMUNITY);
        List<PaymentPoolDto> paymentPoolDtos = paymentPoolV1InnerServiceSMOImpl.queryPaymentPools(paymentPoolDto);
        if (paymentPoolDtos == null || paymentPoolDtos.isEmpty()) {
            throw new IllegalArgumentException("小区未配置支付信息");
        }
        reqJson.put("paymentPoolId", paymentPoolDtos.get(0).getPpId());
        return paymentPoolDtos.get(0).getBeanNative();
    }
    /**
     * 临时车场景处理
     *
     * @param business
     * @param communityId
     * @return
     */
    private PaymentPoolDto ifTempCarFeeBusiness(String business, String communityId) {
        if (!"tempCarFee".equals(business)) {
            return null;
        }
        //todo 按小区查询 支付信息
        PaymentPoolDto paymentPoolDto = new PaymentPoolDto();
        paymentPoolDto.setCommunityId(communityId);
        paymentPoolDto.setPayType(PaymentPoolDto.PAY_TYPE_TEMP_CAT);
        paymentPoolDto.setState("Y");
        List<PaymentPoolDto> paymentPoolDtos = paymentPoolV1InnerServiceSMOImpl.queryPaymentPools(paymentPoolDto);
        if (paymentPoolDtos == null || paymentPoolDtos.isEmpty()) {
            return null;
        }
        return paymentPoolDtos.get(0);
    }
    private PaymentPoolDto ifPayFeeBusiness(String business, JSONObject reqJson) {
        String feeId = "";
        if (!"payFee".equals(business) || !reqJson.containsKey("feeId")) {
            return null;
        }
        feeId = reqJson.getString("feeId");
        if (StringUtil.isNumber(feeId)) {
            return null;
        }
        PayFeeDto feeDto = new PayFeeDto();
        feeDto.setFeeId(feeId);
        feeDto.setCommunityId(reqJson.getString("communityId"));
        List<PayFeeDto> feeDtos = payFeeV1InnerServiceSMOImpl.queryPayFees(feeDto);
        if (feeDtos == null || feeDtos.isEmpty()) {
            return null;
        }
        PaymentPoolConfigDto paymentPoolConfigDto = new PaymentPoolConfigDto();
        paymentPoolConfigDto.setConfigId(feeDtos.get(0).getConfigId());
        paymentPoolConfigDto.setCommunityId(feeDtos.get(0).getCommunityId());
        List<PaymentPoolConfigDto> paymentPoolConfigDtos = paymentPoolConfigV1InnerServiceSMOImpl.queryPaymentPoolConfigs(paymentPoolConfigDto);
        if (paymentPoolConfigDtos == null || paymentPoolConfigDtos.isEmpty()) {
            return null;
        }
        PaymentPoolDto paymentPoolDto = new PaymentPoolDto();
        paymentPoolDto.setPpId(paymentPoolConfigDtos.get(0).getPpId());
        paymentPoolDto.setCommunityId(paymentPoolConfigDtos.get(0).getCommunityId());
        paymentPoolDto.setPayType(PaymentPoolDto.PAY_TYPE_FEE_CONFIG);
        paymentPoolDto.setState("Y");
        List<PaymentPoolDto> paymentPoolDtos = paymentPoolV1InnerServiceSMOImpl.queryPaymentPools(paymentPoolDto);
        if (paymentPoolDtos == null || paymentPoolDtos.isEmpty()) {
            return null;
        }
        return paymentPoolDtos.get(0);
    }
}