package com.xzx.gc.pay.controller; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.date.DateField; import cn.hutool.core.date.DateUtil; import cn.hutool.core.lang.Validator; import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.StrUtil; import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayClient; import com.alipay.api.DefaultAlipayClient; import com.alipay.api.request.AlipayOpenOperationOpenbizmockBizQueryRequest; import com.alipay.api.response.AlipayOpenOperationOpenbizmockBizQueryResponse; import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult; import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.service.WxPayService; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.xzx.gc.common.Result; import com.xzx.gc.common.annotations.PassToken; import com.xzx.gc.common.constant.CommonEnum; import com.xzx.gc.common.constant.Constants; import com.xzx.gc.common.constant.PayEnum; import com.xzx.gc.common.constant.SysConfigConstant; import com.xzx.gc.common.dto.CommonDto; import com.xzx.gc.common.dto.SimplePage; import com.xzx.gc.common.dto.log.OperationAppLog; import com.xzx.gc.common.exception.RestException; import com.xzx.gc.common.request.BaseController; import com.xzx.gc.common.utils.*; import com.xzx.gc.common.utils.ali.SmsUtil; import com.xzx.gc.entity.*; import com.xzx.gc.model.JsonResult; import com.xzx.gc.model.admin.MoneyModel; import com.xzx.gc.model.admin.UserAccountModel; import com.xzx.gc.model.admin.UserModel; import com.xzx.gc.model.pay.*; import com.xzx.gc.pay.config.WxPayProperties; import com.xzx.gc.pay.dto.*; import com.xzx.gc.pay.mapper.AccountMapper; import com.xzx.gc.pay.mapper.OtherUserMapper; import com.xzx.gc.pay.mapper.PayRequestMapper; import com.xzx.gc.pay.mapper.UserMapper; import com.xzx.gc.pay.service.*; import com.xzx.gc.util.pay.util.entity.TransfersDtoAdmin; import io.swagger.annotations.*; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; /** * @author:andylei * @title * @Description * @date 2019/9/1 * @修改历史 */ @Api(tags = "支付管理") @RestController @Slf4j public class PayController extends BaseController { @Autowired private PayService payService; @Autowired private BusinessUtil businessUtil; @Autowired private WxPayService wxPayService; @Autowired private PayRequestMapper payRequestMapper; @Autowired private IdUtils idUtils; @Value("${anroidAppId}") private String anroidAppId; @Autowired private WxPayProperties properties; @Autowired private PayRequestService payRequestService; @Autowired private ConfigService configService; @Autowired private WeiXinService weiXinService; @Autowired private OtherUserMapper otherUserMapper; @Autowired private UserMapper userMapper; @Autowired private AccountMapper accountMapper; @Autowired private AccountService accountService; @Autowired private MqUtil mqUtil; @Autowired private UserService userService; @Value("${wx.app.url}") String TRANS_URL; @Value("${wx.app.key}") String APP_KEY; @Value("${wx.path}") String CERT_PATH; @Value("${wx.pay.appid}") String APP_ID; @Value("${wx.mchid}") String MCH_ID; @Value("${wx.name}") String MCH_NAME; @Value("${wx.create.ip}") String CREATE_IP; /** * 支付信息录入 * @param payInfoReq */ @ApiOperation( value = "提现申请") @PostMapping("/pay/add") public Result PayInfoAdd(HttpServletRequest request,@RequestBody PayInfoReq payInfoReq) { Result result = new Result(); BigDecimal bigDecimal = Convert.toBigDecimal(payInfoReq.getMoney(),Constants.MONEY_INIT); if(bigDecimal.compareTo(BigDecimal.ZERO)==0){ result.setCode(-1); result.setMsg("提现金额必须大于0"); return result; } payInfoReq.setMoney(Convert.toStr(bigDecimal)); payInfoReq.setVersion(getVersion(request)); CommonDto commonDto = payService.PayInfoAdd(payInfoReq); result.setData(commonDto); String mobilePhone = userService.findOtherByUserId(getUserId(request),0); OperationAppLog build = OperationAppLog.builder().appPrograme(getFrontClient(request)).opreateName(mobilePhone) .methodName(Constants.PAY_MODUL_NAME).operateAction("提现申请-"+commonDto.getId()).build(); mqUtil.sendApp(build); return result; } @ApiOperation( value = "提现自动审核") @PostMapping("/pay/audit") public Result audit(HttpServletRequest request,@Validated @RequestBody CommonDto commonDto) { Result result = new Result(); // Validator.validateNotEmpty(commonDto.getId(),"支付ID不能为空"); // int code=payService.audit(commonDto); // if(code==-1){ // result.setCode(code); // result.setMsg("提现审核失败"); // } return result; } @ApiOperation( value = "查询最近的一次提现方式") @PostMapping("/pay/findPayMethod") public Result findPayMethod(HttpServletRequest request) { Result result = new Result(); String userId = getUserId(request); AccountBindInfo accountBindInfo=payService.findPayMethod(userId); result.setData(accountBindInfo); return result; } /** * 支付信息查询 * @param payInfoReq */ @ApiOperation( value = "支付详情") @PostMapping("/pay/query") public Result> queryPayInfo(HttpServletRequest request,@RequestBody PayInfoReq payInfoReq) { Result result = new Result(); String userId=getUserId(request); List list = payService.queryPayInfo(payInfoReq); if(CollUtil.isEmpty(list)){ //提现信息 list=payService.queryPayRequestInfo(payInfoReq); } result.setData(list); return result; } @ApiOperation(value = "充值") @PostMapping("/pay/new/recharge") public Result order(@Validated @RequestBody PayParamDTO payParamDTO, HttpServletRequest req) { if(CommonEnum.JSAPI.getValue().equals(payParamDTO.getTradeType())){ Validator.validateNotEmpty(payParamDTO.getOpenid(),"openid不能为空"); } payParamDTO.setNonceStr(RandomUtil.randomString(32)); payParamDTO.setOutTradeNo(idUtils.generate("ZF",0)); payParamDTO.setSpbillCreateIp(IpUtils.getIpAddr(req)); Date date = new Date(); payParamDTO.setTimeStart(DateUtil.format(date,"yyyyMMddHHmmss")); payParamDTO.setTimeExpire(DateUtil.offset(date,DateField.HOUR_OF_DAY,2).toString("yyyyMMddHHmmss")); WxPayUnifiedOrderRequest request=new WxPayUnifiedOrderRequest(); if(businessUtil.isApp(getClientType(req))){ wxPayService.getConfig().setAppId(anroidAppId); }else{ wxPayService.getConfig().setAppId(properties.getAppId()); } BeanUtils.copyProperties(payParamDTO,request); BigDecimal totalFee=BigDecimal.ZERO; if(SpringUtil.isDev()||SpringUtil.isTest()||SpringUtil.isCheck()){ totalFee=NumberUtil.mul(payParamDTO.getTotalFee(),new BigDecimal("1")); }else{ totalFee=NumberUtil.mul(payParamDTO.getTotalFee(),new BigDecimal("100")); } request.setTotalFee(totalFee.intValue()); payParamDTO.setClientType(getClientType(req)); Result result = weiXinService.pay(request, payParamDTO); if(result.getCode()==0){ String mobilePhone = userService.findOtherByUserId(getUserId(req),0); OperationAppLog build = OperationAppLog.builder().appPrograme(getFrontClient(req)).opreateName(mobilePhone) .methodName(Constants.PAY_MODUL_NAME).operateAction("充值-"+result.getData().getPayOrderId()).build(); mqUtil.sendApp(build); } return result; } @ApiOperation(value = "微信充值回调",hidden = true) @PostMapping("/pay/new/wxProPayNotify/anon") @PassToken public String payNotify(@RequestBody String xmlResult) { log.info("*************微信开始回调******************"); return weiXinService.payBack(xmlResult); } @ApiOperation(value = "微信充值修复",notes = "id:ZF支付ID") @PostMapping(Constants.ADMIN_VIEW_PREFIX+"/pay/fix") public Result payFix(@RequestBody CommonDto commonDto,HttpServletRequest request) throws WxPayException { String payOrderId=commonDto.getId(); WxPayOrderQueryResult wxPayOrderQueryResult = wxPayService.queryOrder(null, payOrderId); String returnCode = wxPayOrderQueryResult.getReturnCode(); String resultCode = wxPayOrderQueryResult.getResultCode(); if("SUCCESS".equals(returnCode)&&"SUCCESS".equals(resultCode)){ //SUCCESS—支付成功,REFUND—转入退款,NOTPAY—未支付,CLOSED—已关闭,REVOKED—已撤销(刷卡支付),USERPAYING--用户支付中,PAYERROR--支付失败(其他原因,如银行返回失败) String tradeState = wxPayOrderQueryResult.getTradeState(); log.trace("充值交易流水号:{},交易状态:{}",payOrderId,tradeState); if("SUCCESS".equals(tradeState)) { Result result = weiXinService.payFix(payOrderId); if(result.getCode()==0) { OperationAppLog build = OperationAppLog.builder().appPrograme(CommonEnum.后台.getValue()).opreateName(getAdminName(request)) .methodName(Constants.PAY_MODUL_NAME).operateAction("微信充值修复-" + payOrderId).build(); mqUtil.sendApp(build); } return result; } } return Result.error("修复失败"); } @ApiOperation(value = "额度申请") @PostMapping("/pay/new/limit/add") public Result limitAdd(HttpServletRequest request,@RequestBody CommonDto commonDto){ PayRequestInfo info=new PayRequestInfo(); info.setCreateUserId(getUserId(request)); info.setPayType(PayEnum.额度申请.getValue()); info.setStatus(PayEnum.待审核.getValue()); List select = payRequestMapper.select(info); if(CollUtil.isNotEmpty(select)){ return Result.error(-1,"正在审核中,不能重复申请"); } Result result=new Result(); String extra = commonDto.getExtra(); Validator.validateNotEmpty(extra,"透支金额不能为空"); PayRequestInfo payRequestInfo=new PayRequestInfo(); payRequestInfo.setCreateUserId(getUserId(request)); payRequestInfo.setMoney(extra); payRequestInfo.setPayType(PayEnum.额度申请.getValue()); payRequestService.add(payRequestInfo); String mobilePhone = userService.findOtherByUserId(getUserId(request),0); OperationAppLog build = OperationAppLog.builder().appPrograme(getFrontClient(request)).opreateName(mobilePhone) .methodName(Constants.PAY_MODUL_NAME).operateAction("额度申请-"+payRequestInfo.getPayOrderId()).build(); mqUtil.sendApp(build); return result; } @ApiOperation(value = "修改支付状态") @PostMapping("/pay/new/updateStatus") public Result updateStatus(HttpServletRequest request,@RequestBody PayUpdateStatusDto payUpdateStatusDto){ payService.updateStatus(payUpdateStatusDto.getPayOrderId(),payUpdateStatusDto.getStatus()); String mobilePhone = userService.findOtherByUserId(getUserId(request),0); OperationAppLog build = OperationAppLog.builder().appPrograme(getFrontClient(request)).opreateName(mobilePhone) .methodName(Constants.PAY_MODUL_NAME).operateAction("修改支付状态-"+payUpdateStatusDto.getPayOrderId()).build(); mqUtil.sendApp(build); return Result.success(""); } @ApiOperation(value = "查询充值服务费") @PostMapping("/pay/new/findFee") public Result order(@Validated @RequestBody PayFeeParamDto payFeeParamDto, HttpServletRequest request) { PayFeeDto payFeeDto=new PayFeeDto(); //查询当前用户本周内是否有成功或者在支付中的充值记录 // List forWeekByUserIdAndType = payService.findForWeekByUserIdAndType(getUserId(request), PayEnum.充值.getValue()); //需要支付服务费 List moneyFee = configService.findByGroup("MONEY_FEE"); //费率 String feeRate = moneyFee.stream().filter(x -> x.getConfigTypeCode().equals("PAY_FEE_RATE")).collect(Collectors.toList()).get(0).getConfigValue(); //最小服务费 String feeSmall = moneyFee.stream().filter(x -> x.getConfigTypeCode().equals("PAY_FEE_SMALL")).collect(Collectors.toList()).get(0).getConfigValue(); String money = payFeeParamDto.getMoney(); //服务费 BigDecimal mul = NumberUtil.mul(Convert.toBigDecimal(money),Convert.toBigDecimal(feeRate)); payFeeDto.setSmallFee(businessUtil.changeMoney(feeSmall)); BigDecimal mulRate = NumberUtil.mul(Convert.toBigDecimal(feeRate), 100); payFeeDto.setFeeRate(businessUtil.changeMoney(Convert.toStr(mulRate))+"%"); // if(CollUtil.isNotEmpty(forWeekByUserIdAndType)){ if(StrUtil.isNotBlank(feeRate)&&Convert.toBigDecimal(feeRate,BigDecimal.ZERO).compareTo(BigDecimal.ZERO)!=0){ if(mul.compareTo(Convert.toBigDecimal(feeSmall))<0){ payFeeDto.setFee(businessUtil.changeMoney(feeSmall)); }else { payFeeDto.setFee(businessUtil.changeMoney(Convert.toStr(mul))); } } // } return Result.success(payFeeDto); } @PostMapping( "/admin/front/wx/pay/wxPay.do") @ApiOperation(value = "微信提现接口", notes = "test: 仅0有正确返回") @ApiImplicitParams({ @ApiImplicitParam(paramType = "query", name = "userId", value = "用户Id", required = true, dataType = "String"), @ApiImplicitParam(paramType = "query", name = "payOrderId", value = "提现申请订单Id", required = true, dataType = "String"), @ApiImplicitParam(paramType = "query", name = "otherUserId", value = "非普通用户Id", required = true, dataType = "String") }) public JsonResult wxPay(@RequestBody TransfersDtoAdmin dto) { payService.wxPay(dto); return JsonResult.success(); } @PostMapping( "/admin/front/wx/pay/queryPayInfoDetail.json") public Map queryPayInfoDetail(String payOrderId){ return payService.queryPayInfoDetail(payOrderId); } // 回收员类别页面 @GetMapping(Constants.ADMIN_VIEW_PREFIX + "/wx/pay/queryPayInfo.do") public ModelAndView queryPayInfo(String payOrderId) { ModelAndView view = new ModelAndView("/admin/money/payInfoDetail.html"); view.addObject("payOrderId", payOrderId); return view; } /** * 更新 * @param payOrderId * @param userId * @param unpassReason * @return */ @PostMapping( "/admin/front/wx/pay/addReason.json") public int addReason(String payOrderId,String userId,String unpassReason){ return payRequestMapper.addReason(payOrderId,userId,unpassReason); } @PostMapping( "/admin/front/wx/pay/quotaList.json") public Map quotaList(MoneyModel moneyModel,String page,String limit){ moneyModel.setPayType("7"); return payRequestService.queryMoneyList(moneyModel,page,limit); } @PostMapping( "/admin/front/wx/pay/quota.json") public JsonResult quota(TransfersDtoAdmin dto) { Map result = new HashMap<>(); MoneyModel moneyModel = new MoneyModel(); moneyModel.setPayOrderId(dto.getPayOrderId()); moneyModel = payRequestMapper.queryMoney(moneyModel); // UserModel userModel = otherUserMapper.queryRecoveryById(dto.getUserId(),"2"); if(null!=userModel){ UserAccountModel userAccountModel = accountMapper.queryAccountInfo(moneyModel.getCreateUserId(), userModel.getMobilePhone()); if (userAccountModel == null) { return JsonResult.success("此用户未查询到账户信息"); }else{ accountService.updateOverdrawPriceByUserId(userAccountModel.getAccountId(),moneyModel.getMoney()); //修改申请状态 moneyModel.setStatus("2"); moneyModel.setUnpassReason("审核通过"); payRequestMapper.updateMoney(moneyModel); return JsonResult.success("完成审核"); } }else{ return JsonResult.success("查不到对应的回收员"); } } @PostMapping( "/admin/front/wx/pay/wxPayCancel.json") @ApiOperation(value="资金管理-提现申请(拒绝)", notes="test: 仅0有正确返回") @ApiImplicitParams({ @ApiImplicitParam(paramType="query", name = "payOrderId", value = "提现申请Id", required = true, dataType = "String"), @ApiImplicitParam(paramType="query", name = "userId", value = "用户Id", required = true, dataType = "String"), @ApiImplicitParam(paramType="query", name = "unpassReason", value = "未通过原因", required = true, dataType = "String") }) public JsonResult wxPayCancel(@RequestBody TransfersDtoAdmin dto,HttpServletRequest request) { Map result = new HashMap<>(); MoneyModel moneyModel = new MoneyModel(); moneyModel.setPayOrderId(dto.getPayOrderId()); moneyModel = payRequestMapper.queryMoney(moneyModel); moneyModel.setStatus("3"); moneyModel.setUnpassReason(dto.getUnpassReason()); // functionConsoleService.updateMoney(moneyModel); OperationAppLog build = OperationAppLog.builder().appPrograme(CommonEnum.后台.getValue()).opreateName(getAdminName(request)) .methodName(Constants.PAY_MODUL_NAME).operateAction("提现申请(拒绝)-"+dto.getPayOrderId()).build(); mqUtil.sendApp(build); return JsonResult.success("完成审核"); } @ApiOperation(value = "线下充值申请") @PostMapping("/pay/offline") public Result offline(@RequestBody PayOfflineDTO payOfflineDTO, HttpServletRequest req) { PayInfo payInfo=new PayInfo(); String userId=getUserId(req); List resourceUrlList = payOfflineDTO.getResourceUrlList(); String zf = idUtils.generate("ZF", 0); payInfo.setPayOrderId(zf); if (CollUtil.isNotEmpty(resourceUrlList)) { payInfo.setPayImg(CollUtil.join(resourceUrlList,",")); } payInfo.setCreateUserId(userId); payInfo.setMoney(payOfflineDTO.getMoney()); Map map=new HashMap<>(); AccountInfo byUserId = accountService.findByUserIdForbidden(userId); if(byUserId!=null){ payInfo.setAccountId(byUserId.getAccountId()); map.put("account",byUserId.getAccountName()); } payInfo.setPayType(PayEnum.充值.getValue()); payInfo.setPaySecondType(Convert.toByte(PayEnum.线下充值.getValue())); payInfo.setStatus(PayEnum.待审核中.getValue()); payInfo.setPayTime(DateUtil.now()); payService.addPay(payInfo); String phone=configService.findByCode(SysConfigConstant.PAT_AUDIT_PHONE).getConfigValue(); map.put("money",payOfflineDTO.getMoney()); //发送审核短信 String content = StrUtil.format("账号{account}提交一笔充值{money}元的申请,请尽快审核", map); String[] strings = StrUtil.splitToArray(phone, Convert.toChar(",")); for (String string : strings) { SmsUtil.sendPoint(string, content); } String mobilePhone = userService.findOtherByUserId(getUserId(req),0); OperationAppLog build = OperationAppLog.builder().appPrograme(getFrontClient(req)).opreateName(mobilePhone) .methodName(Constants.PAY_MODUL_NAME).operateAction("线下充值申请-"+payInfo.getPayOrderId()).build(); mqUtil.sendApp(build); return Result.success(); } @ApiOperation(value = "分页查询线下充值记录") @PostMapping("/pay/offlineList") public Result> offlineList(@RequestBody SimplePage simplePage, HttpServletRequest req) { PageInfo pageInfo = payService.findPageByUserIdAndSecondType(simplePage,getUserId(req), PayEnum.充值.getValue(), PayEnum.线下充值.getValue()); return Result.success(pageInfo); } @ApiOperation(value = "支付宝支付") @PostMapping("/pay/ali") @PassToken public Result aliPay(@RequestBody AliPayDTO aliPayDTO, HttpServletRequest req) throws AlipayApiException { String res=payService.aliPay(aliPayDTO); return Result.success(res); } @ApiOperation(value = "支付宝支付回调") @PostMapping("/pay/ali/notify") @PassToken public Result aliPayNotify(HttpServletRequest request) throws AlipayApiException { Map params = new HashMap(); Map requestParams = request.getParameterMap(); for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) { String name = (String) iter.next(); String[] values = (String[]) requestParams.get(name); String valueStr = ""; for (int i = 0; i < values.length; i++) { valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ","; } //乱码解决,这段代码在出现乱码时使用。 //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8"); params.put(name, valueStr); } String res=payService.aliPayNotify(params); return Result.success(res); } }