package com.dk.oauth.service.wxapi.basic; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.dk.common.exception.BaseBusinessException; import com.dk.common.infrastructure.constant.Constant; import com.dk.common.infrastructure.enums.ErrorCodeEnum; import com.dk.common.infrastructure.xxl.XxlJobUtils; import com.dk.common.model.response.mst.StaffResponse; import com.dk.common.response.ResponseCodeEnum; import com.dk.common.response.ResponseResultUtil; import com.dk.common.response.ResponseResultVO; import com.dk.common.util.*; import com.dk.oauth.config.WechatPayConfigInfo; import com.dk.oauth.entity.Company; import com.dk.oauth.entity.Trade; import com.dk.oauth.entity.TradeResponse; import com.dk.oauth.entity.UserLogin; import com.dk.oauth.feign.service.StaffFeign; import com.dk.oauth.mapper.CompanyMapper; import com.dk.oauth.mapper.TradeMapper; import com.dk.oauth.mapper.UserMapper; import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest; import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest; import com.github.binarywang.wxpay.bean.request.WxPayRefundV3Request; import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; import com.github.binarywang.wxpay.bean.result.WxPayRefundResult; import com.github.binarywang.wxpay.bean.result.WxPayRefundV3Result; import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult; import com.github.binarywang.wxpay.config.WxPayConfig; import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.service.WxPayService; import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; import com.xxl.job.core.context.XxlJobHelper; import com.xxl.job.core.handler.annotation.XxlJob; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ClassPathResource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 微信支付服务 * 后台管理设置的金额 从dkic_ms里取数据 金额 * 所以放到了 权限的oauth-server 的服务里240327 * * @author 姜永辉 * @since 20223-07-01 09:41:05 */ @Service("wechatPayService") @Slf4j public class WechatPayService { @Autowired private WechatPayConfigInfo wechatPayConfigInfo; @Autowired private TradeMapper tradeMapper; @Autowired private UserMapper userMapper; @Autowired private CompanyMapper companyMapper; @Autowired private XxlJobUtils xxlJobUtils; @Resource StaffFeign staffFeign; /** * 商户 下单选取旗舰版或专业版的订单 * * @param param * @return * @throws WxPayException */ public ResponseResultVO unifiedOrder(Map param) throws WxPayException { String paymentSn = param.get("paymentSn").toString(); String openId = param.get("openId").toString(); String payFee = param.get("payFee").toString(); log.info("下单选取旗舰版或专业版的订单1----------" + param.toString()); try { // 获取单据的金额 --后台管理设置的金额 从dkic_ms里取数据 金额 // 所以放到了 权限的oauth-server 的服务里 // todo。。。。。。。。。。。。 payFee = "0.01"; WxPayService wxPayService = this.getWxPayService(); WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest(); orderRequest.setBody("商品测试"); orderRequest.setOutTradeNo(paymentSn); orderRequest.setTotalFee(BaseWxPayRequest.yuanToFen(payFee.toString()));//元转成分 orderRequest.setOpenid(openId); orderRequest.setSpbillCreateIp(IpUtils.getIpAddr(ServletUtils.getRequest())); orderRequest.setNotifyUrl(wechatPayConfigInfo.getWechatNotifyUrl() + "/" + wechatPayConfigInfo.getAppId()); orderRequest.setTradeType("JSAPI"); // 生成预支付订单 WxPayUnifiedOrderResult wxPayUnifiedOrderResult = wxPayService.unifiedOrder(orderRequest); String prepay_id = wxPayUnifiedOrderResult.getPrepayId(); String timeStamp = new Date().getTime() + ""; String nonceStr = UUID.fastUUID().toString(true); String pack = "prepay_id=" + prepay_id; String signType = "MD5"; String paySign = ""; String sigmTemp = "appId=" + wxPayUnifiedOrderResult.getAppid() + "&nonceStr=" + nonceStr + "&package=" + pack + "&signType=" + signType + "&timeStamp=" + timeStamp; sigmTemp = sigmTemp + "&key=" + wechatPayConfigInfo.getMchKey(); paySign = Md5Utils.hash(sigmTemp); log.info("下单选取旗舰版或专业版的订单2----------" + prepay_id + "--" + sigmTemp + "--"); Map params = new HashMap(); params.put("appId", wxPayUnifiedOrderResult.getAppid()); params.put("timeStamp", timeStamp); params.put("nonceStr", nonceStr); params.put("pack", pack); params.put("signType", signType); params.put("paySign", paySign); log.info("下单选取旗舰版或专业版的订单3----------" + params.toString()); return ResponseResultUtil.success(params); } catch (Exception e) { log.error("unifiedOrder--微信支付失败!支付单号:{},原因:{}", paymentSn, e.getMessage()); return ResponseResultUtil.error("支付失败,请稍后重试!"); } } /** * @desc : 处理支付成功逻辑 * @author : 姜永辉 * @date : 2024/03/06 11:29 */ @Transactional( rollbackFor = {Exception.class} ) public ResponseResultVO notifyWechatPay(WxPayOrderNotifyResult info) { log.info("处理支付成功逻辑----------" + info.getOutTradeNo() + "---------" + info.toString()); UserLogin byWxid = userMapper.getByWxid(info.getOpenid()); log.info("微信用户----------" + byWxid); // 获取交易记录 TradeResponse tradeResponse = tradeMapper.selectTradeByNo(new Trade().setTradeNo(info.getOutTradeNo())); if (tradeResponse == null) { throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.NO_FIND_TRADE.getMessage()); } // 更新交易记录状态 Trade trade = new Trade(); trade.setTradeId(tradeResponse.getTradeId()); trade.setWxTradeNo(info.getTransactionId()); trade.setTradeStatus(Constant.TradeStatus.EFFECTIVE.getName()); tradeMapper.updateById(trade); // 交易类型-续费- 将该公司的 生成一个job的任务 if (Constant.TradeType.RENEW.getName().equals(trade.getTradeType())) { log.error("交易类型-续费插入任务数据-getTradeType:" + trade.getTradeType()); try { Company company = companyMapper.selectById(tradeResponse.getCpId()); // 解析license信息 String licenseStr = AESUtil.desEncrypt(company.getLicenseSocial()); log.error("交易类型-续费插入任务数据-licenseStr:" + licenseStr); if (licenseStr != null) { Map licenseMap = JSON.parseObject(licenseStr, Map.class); log.error("交易类型-续费插入任务数据-re_new:" + licenseMap.get("re_new")); if (licenseMap.get("re_new") != null) { String d = licenseMap.get("user_end_date") + ""; LocalDateTime localDateTime = LocalDateTime.parse(d, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); int id = xxlJobUtils.create(Math.toIntExact( (localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli() - System.currentTimeMillis()) / 1000 ), tradeResponse.getCpId() + "", Constant.XxlJobInfo.RENEW.getValue()); log.error("交易类型-续费插入任务数据-:" + id); } } } catch (Exception e) { log.error("交易类型-续费插入任务数据-异常:" + e.getStackTrace()); } } // 更新企业,把临时license更新到license中 log.info("交易记录----------" + trade); // 企业 Company comp = new Company(); comp.setCpId(tradeResponse.getCpId()); companyMapper.updateCompanyLicense(comp); log.info("交易记录-企业更新----------" + comp); return ResponseResultUtil.success(); } /** * @desc : 获取商户配置信息 * @author : 姜永辉 * @date : 2023-08-02 17:30 */ public WxPayService getWxPayService() { log.info("getWxPayService----------" + wechatPayConfigInfo.toString()); WxPayConfig payConfig = new WxPayConfig(); payConfig.setAppId(StringUtils.trimToNull(wechatPayConfigInfo.getAppId())); payConfig.setMchId(StringUtils.trimToNull(wechatPayConfigInfo.getMchId())); payConfig.setMchKey(StringUtils.trimToNull(wechatPayConfigInfo.getMchKey())); // payConfig.setSubAppId(null); // payConfig.setSubMchId(null); ClassPathResource classPathResource = new ClassPathResource("apiclient_cert.p12"); payConfig.setKeyPath(StringUtils.trimToNull(classPathResource.getPath())); log.info("getWxPayService=>" + classPathResource.toString()); // payConfig.setKeyPath(StringUtils.trimToNull(wechatPayConfigInfo.getKeyPath())); // 可以指定是否使用沙箱环境 payConfig.setUseSandboxEnv(false); WxPayService wxPayService = new WxPayServiceImpl(); wxPayService.setConfig(payConfig); return wxPayService; } /** * 退款 */ private Boolean refundWechat(String orderNo, String transactionId, BigDecimal amount) { try { log.info("rebackPay=>" + orderNo, transactionId, amount); WxPayService wxPayService = this.getWxPayService(); //微信支付-申请退款请求参数 WxPayRefundRequest orderRequest = new WxPayRefundRequest(); orderRequest.setOutTradeNo(transactionId); orderRequest.setOutRefundNo(orderNo); orderRequest.setRefundFee(BaseWxPayRequest.yuanToFen(amount.toString()));//元转成分 // ShopOrderInfoDto shopOrderInfoDto = new ShopOrderInfoDto(); // shopOrderInfoDto.setPaymentSn(orderInfo.getPaymentSn()); // BigDecimal sumPayFee = shopOrderInfoMapper.selectSumPayFee(shopOrderInfoDto); // orderRequest.setTotalFee(BaseWxPayRequest.yuanToFen(sumPayFee.toString())); orderRequest.setNotifyUrl(wechatPayConfigInfo.getRefundNotifyUrl() + "/" + wechatPayConfigInfo.getAppId()); //调用微信V3退款API WxPayRefundResult result = wxPayService.refund(orderRequest); log.info("微信退款结果:" + result.toString()); return true; } catch (Exception e) { log.error("微信退款结果-异常:" + e.getStackTrace()); return false; } } /** * @desc : 续费的公司提醒回调 * @author : 姜永辉 * @date : 2024-06-29 14:22 */ @Transactional(rollbackFor = {Exception.class}) @XxlJob("renew-reminder") public ResponseResultVO renewReminder() { log.info("@XxlJob(\"renewReminder\")id: {}", XxlJobHelper.getJobParam()); try { // Integer cpid = 382; Company company = companyMapper.selectById( XxlJobHelper.getJobParam()); // 解析license信息 String licenseStr = AESUtil.desEncrypt(company.getLicense()); log.error("续费的公司提醒回调-licenseStr:" + licenseStr); if (licenseStr != null) { Map licenseMap = JSON.parseObject(licenseStr, Map.class); log.error("续费的公司提醒回调-re_new:" + licenseMap.get("re_new")); if (licenseMap.get("re_new") != null) { // 续费 返回的 Map renewM = (Map) licenseMap.get("re_new"); // 生成临时license授权 Map licenseMapNew = new HashMap<>(); licenseMapNew.put("grade_code", licenseMap.get("grade_code")); licenseMapNew.put("end_date", LocalDate.parse(licenseMap.get("end_date") + "")); // 续费 返回的 licenseMapNew.put("user_end_date", LocalDate.parse(renewM.get("user_end_date") + "")); licenseMapNew.put("web_max_num", Integer.parseInt(licenseMap.get("web_max_num") + "")); // // 续费 返回的 licenseMapNew.put("wx_max_num", Integer.parseInt(renewM.get("wx_max_num") + "")); licenseMapNew.put("vip", licenseMap.get("vip")); // 续费 返回的 licenseMapNew.put("fun_package", renewM.get("fun_package")); // re_new 的值变为null // licenseMapNew.put("re_new", licenseMap.get("re_new")); // 续费和升级 Company companynew = new Company(); companynew.setCpId(company.getCpId()); companynew.setLicense(AESUtil.aesEncrypt(JSON.toJSONString(licenseMapNew))); companyMapper.updateCompanyNewLicense(companynew); // 续费 返回的 取消授权的员工id 将员工的登录标识修改 if (renewM.get("del_staff_ids") != null) { List staffids = (List) renewM.get("del_staff_ids"); // 更新员工的登录标识 ResponseResultVO responseResultVO = staffFeign.updateFeignStaffFlgCanLogin(staffids); } } } } catch (Exception e) { e.printStackTrace(); log.error("续费的公司提醒回调----异常:{}", e.getMessage()); } return null; } }