package com.nuvole.hnnx.hnnxPay; import cn.hutool.core.convert.Convert; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.fasterxml.jackson.databind.node.ContainerNode; import com.nuvole.common.domain.emnu.CommonResultEmnu; import com.nuvole.common.domain.result.CommonResult; import com.nuvole.constants.PropertiesConstants; import com.nuvole.hnnx.conf.NxPayConfig; import com.nuvole.hnnx.orderQueryTask.OrderQueryTask; import com.nuvole.hnnx.orderQueryTask.OrderQueryUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; import java.util.Date; import java.util.Map; /** * @ClassName NXPayService * @Author cy * @Date 2023/10/6 * @Description * @Version 1.0 **/ @Service @Slf4j //@ConditionalOnClass(name = "com.nuvole.hnnx.conf.NxPayConfig") public class NXPayService { @Autowired(required = false) private NXHttpClientUtils nxHttpClientUtils; @Autowired private NxPayConfig nxPayConfig; @Autowired private ApplicationEventPublisher eventPublisher; public String getPlatSubMerchantId() { return nxHttpClientUtils.getPlatSubMerchantId(); } public String getKjPlatSubMerchantId() { return nxHttpClientUtils.getKjPlatSubMerchantId(); } public String getBranchId() { return nxHttpClientUtils.getBranchId(); } /** * C 扫 B 统一下单 * * @param payConfig 支付参数聚合对象 * @param orderId 商户订单号 * @param payMoney 订单总金额,只能为整数 * @param title 订单标题 * @param authCode 微信/支付宝,返回的授权码,支付中心通过授权码获取用户openId,以便进行后续下单交易。 * @param timeStamp 时间戳 * @return * @throws Exception */ public CommonResult wxScanUnifiedorder(JSONObject payConfig, String orderId, Long payMoney, String title, String goodsInfo, String authCode, String notifyUrl, String timeStamp) { log.info("【河南农信-C扫B微信支付】 统一下单开始, 订单编号=" + orderId); //验证金额 if (payMoney <= 0 && payMoney <= 0) { return new CommonResult<>(CommonResultEmnu.ERROR, "支付失败,不能0元支付!"); } // 二级商户号 String subMerchantId = payConfig.getString("subMerchantId"); //交易机构号 String branchId = payConfig.getString("branchId"); String operatorId = payConfig.getString("operatorId"); // 农信 微信支付 String onlinePayResp = null; onlinePayResp = nxHttpClientUtils.qrCodePrePay(subMerchantId, branchId, operatorId, orderId, authCode, payMoney, timeStamp, "03", 'C', notifyUrl, title); JSONObject onlinePayRespObj = JSONObject.parseObject(onlinePayResp); String respCode = onlinePayRespObj.getString("code"); if (!"000000".equals(respCode)) { log.error("河南农信-C扫B支付下单失败!错误结果码:{},错误结果描述:{}", respCode, onlinePayRespObj.getString("message")); return new CommonResult<>(CommonResultEmnu.ERROR, onlinePayRespObj.getString("message")); } JSONObject onlinePayResult = onlinePayRespObj.getJSONObject("payload"); onlinePayRespObj.put("toPayMethod", "2"); JSONObject resultMap = nxPreConvertWxParam(onlinePayResult); onlinePayRespObj.put("paymentData", resultMap); onlinePayRespObj.remove("payload"); // OrderQueryTask orderQueryTask = ApplicationContextUtil.getBean(OrderQueryTask.class); // orderQueryTask.setOrderId(orderId); // orderQueryTask.setPayService((short) 7); // orderQueryTask.setPayType((short) 1); // orderQueryTask.setOrderPayTime(new Date()); OrderQueryTask orderQueryTask = new OrderQueryTask(eventPublisher, this,nxPayConfig,orderId,(short)7,(short)1,new Date()); OrderQueryUtil.addTask(orderQueryTask); return new CommonResult(onlinePayRespObj); } public static String getFrontUrl(String orderId, Map youHuiInfo){ return HnnxConstant.NX_KJ_FRONT_URL.substring(0,56); // String frontUrl = HnnxConstant.NX_KJ_FRONT_URL.replace("${ORDERID}", orderId + ""); // if (youHuiInfo == null){ // return URLEncoder.encode(frontUrl.replace("${YOUHUIINFO}", "")); // } // return URLEncoder.encode(frontUrl.replace("${YOUHUIINFO}", JSONObject.toJSONString(youHuiInfo))); } private JSONObject nxPreConvertWxParam(JSONObject payload) { if (payload == null) { return payload; } payload.put("appId", payload.remove("AppId")); payload.put("timeStamp", payload.remove("TimeStamp")); payload.put("nonceStr", payload.remove("Charset")); payload.put("package", payload.remove("Subject")); payload.put("signType", payload.remove("SignType")); payload.put("paySign", payload.remove("Sign")); payload.put("orderNo", payload.remove("MerSeqNbr")); return payload; } /** * C 扫 B 统一下单 * * @param payConfig 支付参数聚合对象 * @param orderId 商户订单号 * @param payMoney 订单总金额,只能为整数 * @param title 订单标题 * @param authCode 微信/支付宝,返回的授权码,支付中心通过授权码获取用户openId,以便进行后续下单交易。 * @param timeStamp 时间戳 * @return * @throws Exception */ public CommonResult zfbScanUnifiedorder(JSONObject payConfig, String orderId, Long payMoney, String title, String goodsInfo, String authCode, String notifyUrl, String timeStamp) { log.info("【河南农信-C扫B支付-支付宝】 统一下单开始, 订单编号=" + orderId); //验证金额 if (payMoney <= 0 && payMoney <= 0) { return new CommonResult<>(CommonResultEmnu.ERROR, "支付失败,不能0元支付!"); } // 二级商户号 String subMerchantId = payConfig.getString("subMerchantId"); //交易机构号 String branchId = payConfig.getString("branchId"); String operatorId = payConfig.getString("operatorId"); // 农信 微信支付 String onlinePayResp = null; onlinePayResp = nxHttpClientUtils.qrCodePrePay(subMerchantId, branchId, operatorId, orderId, authCode, payMoney, timeStamp, "03", 'B', notifyUrl, title); JSONObject onlinePayRespObj = JSONObject.parseObject(onlinePayResp); String respCode = onlinePayRespObj.getString("code"); if (!"000000".equals(respCode)) { log.error("河南农信-C扫B支付支付宝下单失败!错误结果码:{},错误结果描述:{}", respCode, onlinePayRespObj.getString("message")); return new CommonResult<>(CommonResultEmnu.ERROR, onlinePayRespObj.getString("message")); } JSONObject onlinePayResult = onlinePayRespObj.getJSONObject("payload"); onlinePayResult.put("toPayMethod", "2"); JSONObject paymentData = new JSONObject(); paymentData.put("tradeNO", onlinePayResult.remove("TradeNo")); onlinePayResult.put("paymentData", paymentData); // OrderQueryTask orderQueryTask = ApplicationContextUtil.getBean(OrderQueryTask.class); // orderQueryTask.setOrderId(orderId); // orderQueryTask.setPayService((short) 7); // orderQueryTask.setPayType((short) 1); // orderQueryTask.setOrderPayTime(new Date()); OrderQueryTask orderQueryTask = new OrderQueryTask(eventPublisher, this,nxPayConfig,orderId,(short)7,(short)1,new Date()); OrderQueryUtil.addTask(orderQueryTask); return new CommonResult(onlinePayResult); } /** * 动态C 扫 B 统一下单 * * @param payConfig 支付参数聚合对象 * @param orderId 商户订单号 * @param payMoney 订单总金额,只能为整数 * @param title 订单标题 * @param authCode 微信/支付宝,返回的授权码,支付中心通过授权码获取用户openId,以便进行后续下单交易。 * @param timeStamp 时间戳 * @return * @throws Exception */ public CommonResult zfbActiveScanUnifiedorder(JSONObject payConfig, String orderId, Long payMoney, String title, String goodsInfo, String authCode, String notifyUrl, String timeStamp) { log.info("【河南农信-动态C扫B支付-支付宝】 统一下单开始, 订单编号=" + orderId); return wxAliActiveScanUnifiedorder(payConfig, orderId, payMoney, title, goodsInfo, authCode, notifyUrl, timeStamp, "03", 'B'); } /** * 动态C 扫 B 统一下单 * * @param payConfig 支付参数聚合对象 * @param orderId 商户订单号 * @param payMoney 订单总金额,只能为整数 * @param title 订单标题 * @param authCode 微信/支付宝,返回的授权码,支付中心通过授权码获取用户openId,以便进行后续下单交易。 * @param timeStamp 时间戳 * @return * @throws Exception */ public CommonResult wxActiveScanUnifiedorder(JSONObject payConfig, String orderId, Long payMoney, String title, String goodsInfo, String authCode, String notifyUrl, String timeStamp) { log.info("【河南农信-动态C扫B支付-微信】 统一下单开始, 订单编号=" + orderId); return wxAliActiveScanUnifiedorder(payConfig, orderId, payMoney, title, goodsInfo, authCode, notifyUrl, timeStamp, "03", 'C'); } /** * 支付宝、微信 动态c扫B * * @param payConfig * @param orderId * @param payMoney * @param title * @param goodsInfo * @param authCode * @param notifyUrl * @param timeStamp * @param channelNbr * @param payTypCd * @return */ private CommonResult wxAliActiveScanUnifiedorder(JSONObject payConfig, String orderId, Long payMoney, String title, String goodsInfo, String authCode, String notifyUrl, String timeStamp, String channelNbr, char payTypCd) { //验证金额 if (payMoney <= 0 && payMoney <= 0) { return new CommonResult<>(CommonResultEmnu.ERROR, "支付失败,不能0元支付!"); } // 二级商户号 String subMerchantId = payConfig.getString("subMerchantId"); //交易机构号 String branchId = payConfig.getString("branchId"); // 农信 微信支付 String onlinePayResp = null; onlinePayResp = nxHttpClientUtils.dyActiveQrCode(subMerchantId, branchId, orderId, payMoney, timeStamp, channelNbr, payTypCd, notifyUrl, title); JSONObject onlinePayRespObj = JSONObject.parseObject(onlinePayResp); String respCode = onlinePayRespObj.getString("code"); if (!"000000".equals(respCode)) { log.error("河南农信-动态C扫B支付 下单失败!错误结果码:{},错误结果描述:{}", respCode, onlinePayRespObj.getString("message")); return new CommonResult<>(CommonResultEmnu.ERROR, onlinePayRespObj.getString("message")); } JSONObject onlinePayResult = onlinePayRespObj.getJSONObject("payload"); onlinePayResult.put("paymentUrl", onlinePayResult.remove("QrCodeInfo")); onlinePayResult.put("codeUrl", onlinePayResult.get("paymentUrl")); // OrderQueryTask orderQueryTask = ApplicationContextUtil.getBean(OrderQueryTask.class); // orderQueryTask.setOrderId(orderId); // orderQueryTask.setPayService((short) 7); // orderQueryTask.setPayType((short) 1); // orderQueryTask.setOrderPayTime(new Date()); OrderQueryTask orderQueryTask = new OrderQueryTask(eventPublisher, this,nxPayConfig,orderId,(short)7,(short)1,new Date()); OrderQueryUtil.addTask(orderQueryTask); return new CommonResult(onlinePayResult); } public CommonResult offlinePayB2COrder(JSONObject payConfig, String orderNum, String timeStamp, String title, String goodsInfo, ContainerNode detail, String notifyUrl, Long money, String authPayCode, String terminalCode) { // 二级商户号 String subMerchantId = payConfig.getString("subMerchantId"); //交易机构号 String branchId = payConfig.getString("branchId"); String offlineB2CPayResp = null; try { offlineB2CPayResp = nxHttpClientUtils.coretoall(subMerchantId, branchId, orderNum, money, authPayCode, timeStamp, "03", notifyUrl, title, terminalCode); } catch (Exception e) { e.printStackTrace(); return new CommonResult<>(CommonResultEmnu.ERROR, e.getMessage()); } JSONObject offlineB2CPayRespObj = JSONObject.parseObject(offlineB2CPayResp); String respCode = offlineB2CPayRespObj.getString("code"); if (!"000000".equals(respCode)) { log.error("河南农信-付款码(B 扫 C)下单失败!错误结果码:{},错误结果描述:{}", respCode, offlineB2CPayRespObj.getString("message")); return new CommonResult<>(CommonResultEmnu.ERROR, offlineB2CPayRespObj.getString("message")); } //0 交易成功 1 交易失败 2 撤销 3 部分退货 4 全部退货 5 处理中 9 交易超时 JSONObject payloadJson = offlineB2CPayRespObj.getJSONObject("payload"); String tradeStatus = payloadJson.getString("TransStatus"); if ("0".equals(tradeStatus)) { payloadJson.put("waterNo", payloadJson.getString("TransSeqNbr")); // 支付成功 return new CommonResult<>(payloadJson); } else { int count = 4; for (int index = 0; index < count; index++) { try { Thread.sleep(10 * 1000); } catch (InterruptedException e) { e.printStackTrace(); } CommonResult tradeQueryResult = tradeQuery(payConfig, orderNum); if (!tradeQueryResult.getCode().equals(CommonResultEmnu.OK.getCode())) { return new CommonResult<>(CommonResultEmnu.ERROR, tradeQueryResult.getDescription()); } payloadJson = tradeQueryResult.getData().getJSONObject("payload"); tradeStatus = payloadJson.getString("TransStatus"); if ("0".equals(tradeStatus)) { payloadJson.put("waterNo", payloadJson.getString("TransSeqNbr")); // 支付成功 return new CommonResult<>(payloadJson); } else if ("1".equals(tradeStatus)) { return new CommonResult<>(CommonResultEmnu.ERROR, "交易失败,订单已关闭"); } else if ("2".equals(tradeStatus)) { return new CommonResult<>(CommonResultEmnu.ERROR, "交易失败,订单已被撤销"); } else if ("3,4".contains(tradeStatus)) { return new CommonResult<>(CommonResultEmnu.ERROR, "交易失败,订单已被退货"); } else if ("9".equals(tradeStatus)) { return new CommonResult<>(CommonResultEmnu.ERROR, "交易超时"); } else if ("5".equals(tradeStatus)) { log.info("交易中,继续查询"); count++; } else { return new CommonResult<>(CommonResultEmnu.ERROR, tradeQueryResult.getDescription()); } } } return new CommonResult(payloadJson); } /** * 订单交易状态查询 * * @return */ public CommonResult tradeQuery(JSONObject payConfig, String orderNum) { //交易机构号 String branchId = payConfig.getString("branchId"); String tradeQueryResp = nxHttpClientUtils.qryQrOrderStatus(orderNum, branchId); JSONObject tradeQueryRespObj = JSONObject.parseObject(tradeQueryResp); String respCode = tradeQueryRespObj.getString("code"); if (!"000000".equals(respCode)) { log.error("河南农信-订单交易状态查询失败!错误结果码:{},错误结果描述:{}", respCode, tradeQueryRespObj.getString("message")); return new CommonResult<>(CommonResultEmnu.ERROR, tradeQueryRespObj.getString("message")); } return new CommonResult(tradeQueryRespObj); } /** * 退款 * * @param orderNum 要退款的订单号 * @param merSeqDate 要退款的订单交易日期 例:20190810 * @param origTransAmt 要退款的订单的交易金额 * @param transAmt 退款金额 * @param timeStamp 当前日期 例:yyyyMMddHHmmss * @return */ public CommonResult returntrans(JSONObject payConfig, String orderNum, String merSeqDate, long origTransAmt, long transAmt, String timeStamp) { // 二级商户号 String subMerchantId = payConfig.getString("subMerchantId"); //交易机构号 String branchId = payConfig.getString("branchId"); String tradeQueryResp = nxHttpClientUtils.returntrans(subMerchantId, branchId, orderNum, merSeqDate, origTransAmt, transAmt, timeStamp); JSONObject tradeQueryRespObj = JSONObject.parseObject(tradeQueryResp); String respCode = tradeQueryRespObj.getString("code"); if (!"000000".equals(respCode)) { log.error("河南农信-退款失败!错误结果码:{},错误结果描述:{}", respCode, tradeQueryRespObj.getString("message")); return new CommonResult<>(CommonResultEmnu.ERROR, tradeQueryRespObj.getString("message")); } return new CommonResult(tradeQueryRespObj); } /*** 对账查询 * String subMerchantId, String branchId, * * @param clearDate 对账日期 YYYY-MM-DD * @param branchId 交易机构号 * @return */ public CommonResult accountqry(String clearDate, String branchId) { String tradeQueryResp = nxHttpClientUtils.accountqry(clearDate, branchId); JSONObject tradeQueryRespObj = JSONObject.parseObject(tradeQueryResp); String respCode = tradeQueryRespObj.getString("code"); if (!"000000".equals(respCode)) { log.error("河南农信-订单交易状态查询失败!错误结果码:{},错误结果描述:{}", respCode, tradeQueryRespObj.getString("message")); return new CommonResult<>(CommonResultEmnu.ERROR, tradeQueryRespObj.getString("message")); } return new CommonResult(tradeQueryRespObj); } /** * 微信小程序支付 * * @param payConfig * @param orderId * @param payMoney * @param title * @param goodsInfo * @param authCode * @param notifyUrl * @param timeStamp * @return */ public CommonResult wechatMiniPay(JSONObject payConfig, String orderId, Long payMoney, String title, String goodsInfo, String authCode, String notifyUrl, String timeStamp) { log.info("【河南农信-C扫B微信支付】 统一下单开始, 订单编号=" + orderId); //验证金额 if (payMoney <= 0 && payMoney <= 0) { return new CommonResult<>(CommonResultEmnu.ERROR, "支付失败,不能0元支付!"); } // 二级商户号 String subMerchantId = payConfig.getString("subMerchantId"); //交易机构号 String branchId = payConfig.getString("branchId"); String operatorId = payConfig.getString("operatorId"); // 农信 微信支付 String onlinePayResp = null; onlinePayResp = nxHttpClientUtils.qrCodePrePay(subMerchantId, branchId, operatorId, orderId, authCode, payMoney, timeStamp, "03", 'C', notifyUrl, title); JSONObject onlinePayRespObj = JSONObject.parseObject(onlinePayResp); String respCode = onlinePayRespObj.getString("code"); if (!"000000".equals(respCode)) { log.error("河南农信-C扫B支付下单失败!错误结果码:{},错误结果描述:{}", respCode, onlinePayRespObj.getString("message")); return new CommonResult<>(CommonResultEmnu.ERROR, onlinePayRespObj.getString("message")); } JSONObject onlinePayResult = onlinePayRespObj.getJSONObject("payload"); onlinePayRespObj.put("toPayMethod", "2"); JSONObject resultMap = nxPreConvertWxParam(onlinePayResult); onlinePayRespObj.put("paymentData", resultMap); onlinePayRespObj.remove("payload"); // OrderQueryTask orderQueryTask = ApplicationContextUtil.getBean(OrderQueryTask.class); // orderQueryTask.setOrderId(orderId); // orderQueryTask.setPayService((short) 7); // orderQueryTask.setPayType((short) 1); // orderQueryTask.setOrderPayTime(new Date()); OrderQueryTask orderQueryTask = new OrderQueryTask(eventPublisher, this,nxPayConfig,orderId,(short)7,(short)1,new Date()); OrderQueryUtil.addTask(orderQueryTask); return new CommonResult(resultMap); } /** * * @param payConfig * @param orderId * @param payMoney * @param title * @param goodsInfo * @param timeStamp yyyyMMddHHmmssSSS格式 * @return */ public CommonResult kjTrade(JSONObject payConfig, String orderId, Long payMoney, String title, String goodsInfo, String timeStamp, String frontUrl) { String kjSubMerchantId = payConfig.getString("kjSubMerchantId"); String location = null; try { location = nxHttpClientUtils.quickPayRequest(kjSubMerchantId, orderId, payMoney, timeStamp, frontUrl, PropertiesConstants.STQ_SERVER + HnnxConstant.NX_KJ_ALL_CALL_BACK, // "http://1.14.252.104:7101/service-merchant" + HnnxConstant.NX_KJ_ALL_CALL_BACK, title); } catch (Exception e) { log.error("河南农信-快捷支付 下单失败!错误结果描述:{}", e.getMessage()); return new CommonResult<>(CommonResultEmnu.ERROR, e.getMessage()); } JSONObject onlinePayResult = new JSONObject(); onlinePayResult.put("paymentUrl", location); onlinePayResult.put("codeUrl", location); onlinePayResult.put("toPayMethod", "3"); // OrderQueryTask orderQueryTask = ApplicationContextUtil.getBean(OrderQueryTask.class); // orderQueryTask.setOrderId(orderId); // orderQueryTask.setPayService((short) 7); // orderQueryTask.setPayType((short) 1); // orderQueryTask.setOrderPayTime(new Date()); OrderQueryTask orderQueryTask = new OrderQueryTask(eventPublisher, this,nxPayConfig,orderId,(short)7,(short)1,new Date()); OrderQueryUtil.addTask(orderQueryTask); return new CommonResult(onlinePayResult); } /** * 订单交易状态查询 * * @return */ public CommonResult kjTradeQuery(String orderNum, String startDate, String endDate, Integer pageSize, Integer pageNum) { String tradeQueryResp = nxHttpClientUtils.quickPayOrderQueryRequest(orderNum, startDate, endDate, Convert.toInt(pageSize, 1), Convert.toInt(pageNum, 1)); if (StringUtils.isEmpty(tradeQueryResp)) { return new CommonResult<>(CommonResultEmnu.ERROR, "未查询到数据"); } JSONObject tradeQueryRespObj = JSONObject.parseObject(tradeQueryResp); Integer totalNum = tradeQueryRespObj.getInteger("TotalNum"); if (totalNum == null || totalNum == 0) { return new CommonResult<>(CommonResultEmnu.ERROR, "未查询到数据"); } JSONArray orderList = tradeQueryRespObj.getJSONArray("OrderList"); return new CommonResult(orderList); } /** * 退款 * * @param orderNum 要退款的订单号 * @param merSeqDate 要退款的订单交易日期 例:20190810 * @param origTransAmt 要退款的订单的交易金额 * @param transAmt 退款金额 * @param timeStamp 当前日期 例:yyyyMMddHHmmss * @return */ public CommonResult kjReturntrans(JSONObject payConfig, String orderNum, String merSeqDate, long origTransAmt, long transAmt, String timeStamp) { // 二级商户号 String subMerchantId = payConfig.getString("kjSubMerchantId"); //交易机构号 String tradeQueryResp = nxHttpClientUtils.quickPayReturntrans(subMerchantId, orderNum, merSeqDate, origTransAmt, transAmt, timeStamp); JSONObject tradeQueryRespObj = JSONObject.parseObject(tradeQueryResp); String respCode = tradeQueryRespObj.getString("ReturnCode"); if (!"000000".equals(respCode)) { log.error("河南农信-退款失败!错误结果码:{},错误结果描述:{}", respCode, tradeQueryRespObj.getString("ReturnMsg")); return new CommonResult<>(CommonResultEmnu.ERROR, tradeQueryRespObj.getString("ReturnMsg")); } return new CommonResult(tradeQueryRespObj); } }