package com.jsowell.api.uniapp; import com.alibaba.fastjson2.JSON; import com.google.common.collect.ImmutableMap; import com.jsowell.common.UserAgentUtils; import com.jsowell.common.annotation.Anonymous; import com.jsowell.common.core.controller.BaseController; import com.jsowell.common.core.redis.RedisCache; import com.jsowell.common.enums.ykc.ReturnCodeEnum; import com.jsowell.common.enums.ykc.ScenarioEnum; import com.jsowell.common.exception.BusinessException; import com.jsowell.common.response.RestApiResponse; import com.jsowell.common.util.StringUtils; import com.jsowell.common.util.id.IdUtils; import com.jsowell.pile.domain.MemberBasicInfo; import com.jsowell.pile.dto.*; import com.jsowell.pile.service.MemberBasicInfoService; import com.jsowell.pile.service.PileMerchantInfoService; import com.jsowell.pile.service.programlogic.AbstractProgramLogic; import com.jsowell.pile.service.programlogic.ProgramLogicFactory; import com.jsowell.pile.vo.uniapp.PayModeVO; import com.jsowell.service.MemberService; import com.jsowell.service.OrderService; import com.jsowell.wxpay.response.WechatPayNotifyParameter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import java.util.List; import java.util.Map; /** * 支付相关controller */ @Anonymous @RestController @RequestMapping("/uniapp/pay") public class PayController extends BaseController { @Autowired private OrderService orderService; @Autowired private RedisCache redisCache; @Autowired private MemberBasicInfoService memberBasicInfoService; @Autowired private MemberService memberService; @Autowired private PileMerchantInfoService pileMerchantInfoService; /** * 充值余额支付/微信余额充值 * 提供给小程序使用 * http://localhost:8080/uniapp/pay/weixinPay */ // @PostMapping("/weixinPay") // public RestApiResponse weixinPay(HttpServletRequest request, @RequestBody WeixinPayDTO dto) { // logger.info("微信支付 param:{}", dto.toString()); // RestApiResponse response; // try { // if (dto != null) { // throw new BusinessException("00500005", "充值功能维护,已有余额可用,推荐使用在线支付"); // } // if (StringUtils.isBlank(dto.getCode()) || StringUtils.isBlank(dto.getAmount())) { // throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR); // } // // 鉴权 // String memberId = getMemberIdByAuthorization(request); // if (StringUtils.isBlank(memberId)) { // throw new BusinessException(ReturnCodeEnum.CODE_TOKEN_ERROR); // } // dto.setMemberId(memberId); // // String openId = memberService.getOpenIdByCode(dto.getCode()); // MemberBasicInfo memberBasicInfo = memberBasicInfoService.selectInfoByMemberId(memberId); // if (memberBasicInfo == null) { // throw new BusinessException(ReturnCodeEnum.CODE_GET_OPEN_ID_BY_CODE_ERROR); // } // String openId = memberBasicInfo.getOpenId(); // dto.setOpenId(openId); // // 充值余额 附加参数 // PaymentScenarioDTO paymentScenarioDTO = new PaymentScenarioDTO(); // paymentScenarioDTO.setType(ScenarioEnum.BALANCE.getValue()); // paymentScenarioDTO.setMemberId(memberId); // dto.setAttach(JSON.toJSONString(paymentScenarioDTO)); // dto.setDescription("会员充值余额"); // Map weixinMap = orderService.weixinPayV3(dto); // response = new RestApiResponse<>(ImmutableMap.of("weixinMap", weixinMap)); // } catch (BusinessException e) { // logger.warn("充值余额支付warn", e); // response = new RestApiResponse<>(e.getCode(), e.getMessage()); // } catch (Exception e) { // logger.warn("充值余额支付error", e); // response = new RestApiResponse<>(); // } // return response; // } /** * 7002 支付订单 * http://localhost:8080/uniapp/pay/payOrder * * @param request * @param dto * @return */ @PostMapping("/payOrder") public RestApiResponse payOrder(HttpServletRequest request, @RequestBody PayOrderDTO dto) { // logger.info("支付订单接口 param:{}", dto.toString()); RestApiResponse response; // 支付订单加锁 String lockKey = "pay_order_" + dto.getOrderCode(); String lockValue = IdUtils.fastUUID(); try { String memberId = getMemberIdByAuthorization(request); if (StringUtils.isBlank(memberId)) { throw new BusinessException(ReturnCodeEnum.CODE_TOKEN_ERROR); } if (dto.getPayAmount() == null) { throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR); } dto.setMemberId(memberId); dto.setLockValue(lockValue); // redis锁 Boolean isLock = redisCache.lock(lockKey, lockValue, 60); Map map = null; if (isLock) { String appId = request.getHeader("appId"); dto.setWechatAppId(appId); // 设置请求来源 dto.setRequestSource(UserAgentUtils.determineRequestSource(request)); map = orderService.payOrderV2(dto); } response = new RestApiResponse<>(map); } catch (BusinessException e) { logger.warn("支付订单接口 warn param:{}", dto, e); response = new RestApiResponse<>(e.getCode(), e.getMessage()); } catch (Exception e) { logger.error("支付订单接口 error param:{}", dto, e); response = new RestApiResponse<>(ReturnCodeEnum.CODE_ORDER_PAY_ERROR); } finally { // 支付订单解锁 if (lockValue.equals(redisCache.getCacheObject(lockKey).toString())) { redisCache.unLock(lockKey); } } logger.info("支付订单接口 param:{}, result:{}", JSON.toJSONString(dto), JSON.toJSONString(response)); return response; } /** * 7003 获取支付方式/查询支付方式 * http://localhost:8080/uniapp/pay/getPayMode */ @PostMapping("/getPayMode") public RestApiResponse getPayMode(HttpServletRequest request, @RequestBody GetPayModeDTO dto) { RestApiResponse response; try { dto.setMemberId(getMemberIdByAuthorization(request)); // 设置请求来源 dto.setRequestSource(UserAgentUtils.determineRequestSource(request)); List list = orderService.getPayMode(dto); response = new RestApiResponse<>(ImmutableMap.of("list", list)); } catch (BusinessException e) { logger.warn("获取支付方式 warn param:{}", dto.toString(), e); response = new RestApiResponse<>(e.getCode(), e.getMessage()); } catch (Exception e) { logger.error("获取支付方式 error param:{}", dto.toString(), e); response = new RestApiResponse<>(ReturnCodeEnum.CODE_GET_PAY_MODE); } return response; } /** * 微信支付回调接口 * http://localhost:8080/uniapp/pay/callback * https://api.jsowellcloud.com/uniapp/pay/wechatPayCallback */ @PostMapping("/wechatPayCallback") public RestApiResponse wechatPayCallback(HttpServletRequest request, @RequestBody WechatPayNotifyParameter body) { logger.info("1----------->微信支付回调开始 body:{}", JSON.toJSONString(body)); RestApiResponse response; try { // orderService.wechatPayCallback(request, body); response = new RestApiResponse<>(); } catch (BusinessException e) { logger.warn("微信支付回调接口warn", e); response = new RestApiResponse<>(e.getCode(), e.getMessage()); } catch (Exception e) { logger.error("微信支付回调接口error", e); response = new RestApiResponse<>(ReturnCodeEnum.CODE_ORDER_PAY_CALLBACK_ERROR); } return response; } /** * 微信退款回调接口 * @param request * @param body * @return */ @PostMapping("/wechatPayRefundCallback") public RestApiResponse wechatPayRefundCallback(HttpServletRequest request, @RequestBody WechatPayNotifyParameter body) { logger.info("微信退款回调接口 body:{}", JSON.toJSONString(body)); RestApiResponse response; try { orderService.wechatPayRefundCallback(request, body); response = new RestApiResponse<>(); } catch (BusinessException e) { logger.warn("微信退款回调接口warn", e); response = new RestApiResponse<>(e.getCode(), e.getMessage()); } catch (Exception e) { logger.error("微信退款回调接口error", e); response = new RestApiResponse<>(ReturnCodeEnum.CODE_ORDER_PAY_CALLBACK_ERROR); } return response; } /** * 微信退款接口/微信余额退款 * https://api.jsowellcloud.com/uniapp/pay/refund */ @PostMapping("/refund") public RestApiResponse weChatRefund(HttpServletRequest request, @RequestBody ApplyRefundDTO dto) { RestApiResponse response; try { if (dto.getRefundAmount() == null) { throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR); } String memberId = getMemberIdByAuthorization(request); if (StringUtils.isBlank(memberId)) { throw new BusinessException(ReturnCodeEnum.CODE_TOKEN_ERROR); } dto.setMemberId(memberId); dto.setRefundType("2"); orderService.weChatRefund(dto); response = new RestApiResponse<>(); } catch (BusinessException e) { logger.warn("微信退款接口 warn", e); response = new RestApiResponse<>(e.getCode(), e.getMessage()); } catch (Exception e) { logger.error("微信退款接口 error", e); response = new RestApiResponse<>(ReturnCodeEnum.CODE_WEIXIN_REFUND_ERROR); } return response; } /** * 汇付充值余额/会员充值余额/汇付余额充值 * http://localhost:8080/uniapp/pay/rechargeBalance */ @PostMapping("/rechargeBalance") public RestApiResponse rechargeBalance(HttpServletRequest request, @RequestBody WeixinPayDTO dto) { logger.info("adapay会员充值余额 param:{}", JSON.toJSONString(dto)); RestApiResponse response; try { if (StringUtils.isBlank(dto.getCode()) || StringUtils.isBlank(dto.getAmount())) { return new RestApiResponse<>(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR); } // 鉴权 String memberId = getMemberIdByAuthorization(request); if (StringUtils.isBlank(memberId)) { throw new BusinessException(ReturnCodeEnum.CODE_TOKEN_ERROR); } dto.setMemberId(memberId); // 设置appId dto.setWechatAppId(request.getHeader("appId")); // 获取openId MemberBasicInfo memberBasicInfo = memberBasicInfoService.selectInfoByMemberId(memberId); if (memberBasicInfo == null) { throw new BusinessException(ReturnCodeEnum.CODE_HANDLE_USER_INFO_ERROR); } // if (StringUtils.isBlank(openId)) { // throw new BusinessException(ReturnCodeEnum.CODE_GET_OPEN_ID_BY_CODE_ERROR); // } dto.setOpenId(memberBasicInfo.getOpenId()); // 充值余额 附加参数 // Map weixinMap = memberService.rechargeBalanceWithAdapay(dto); String mode = pileMerchantInfoService.getDelayModeByWechatAppId(dto.getWechatAppId()); // 获取处理逻辑 AbstractProgramLogic orderLogic = ProgramLogicFactory.getProgramLogic(mode); Map weixinMap = orderLogic.rechargeBalance(dto); response = new RestApiResponse<>(ImmutableMap.of("weixinMap", weixinMap)); } catch (BusinessException e) { logger.error("汇付余额充值接口 error", e); response = new RestApiResponse<>(e.getCode(), e.getMessage()); } catch (Exception e) { logger.error("汇付余额充值接口 error", e); response = new RestApiResponse<>(ReturnCodeEnum.CODE_MEMBER_RECHARGE_BALANCE_ERROR); } return response; } /** * 汇付支付退款/汇付支付余额退款/用户余额退款/汇付余额退款 * https://api.jsowellcloud.com/uniapp/pay/refundBalance */ @PostMapping("/refundBalance") public RestApiResponse refundBalance(HttpServletRequest request, @RequestBody ApplyRefundDTO dto) { RestApiResponse response; try { if (dto.getRefundAmount() == null) { throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR); } String memberId = getMemberIdByAuthorization(request); if (StringUtils.isBlank(memberId)) { throw new BusinessException(ReturnCodeEnum.CODE_TOKEN_ERROR); } dto.setMemberId(memberId); String appId = request.getHeader("appId"); dto.setWechatAppId(appId); dto.setRefundType("2"); // orderService.adapayRefund(dto); String mode = pileMerchantInfoService.getDelayModeByWechatAppId(dto.getWechatAppId()); // 获取处理逻辑 AbstractProgramLogic orderLogic = ProgramLogicFactory.getProgramLogic(mode); orderLogic.refundBalance(dto); response = new RestApiResponse<>(); } catch (BusinessException e) { logger.warn("汇付支付退款接口 warn", e); response = new RestApiResponse<>(e.getCode(), e.getMessage()); } catch (Exception e) { logger.error("汇付支付退款接口 error", e); response = new RestApiResponse<>(ReturnCodeEnum.CODE_WEIXIN_REFUND_ERROR); } return response; } /** * 汇付支付回调 * ... */ @PostMapping("/adapayCallback") public void adapayCallback(HttpServletRequest request) { try { orderService.adapayCallback(request); // String type = request.getParameter("type"); logger.info("1汇付回调type:{}", request.getParameter("type")); } catch (Exception e) { logger.error("1汇付支付回调失败 error", e); } } /** * 支付占桩订单/占桩订单支付 * https://api.jsowellcloud.com/uniapp/pay/payOccupyPileOrder */ @PostMapping("/payOccupyPileOrder") public RestApiResponse payOccupyPileOrder(HttpServletRequest request, @RequestBody PayOrderDTO dto) { logger.info("支付占桩订单 param:{}", dto.toString()); RestApiResponse response; // 支付订单加锁 String lockKey = "pay_occupy_order_" + dto.getOrderCode(); String lockValue = IdUtils.fastUUID(); try { String memberId = getMemberIdByAuthorization(request); if (StringUtils.isBlank(memberId)) { throw new BusinessException(ReturnCodeEnum.CODE_TOKEN_ERROR); } if (dto.getPayAmount() == null) { throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR); } dto.setMemberId(memberId); dto.setLockValue(lockValue); // redis锁 Boolean isLock = redisCache.lock(lockKey, lockValue, 60); Map map = null; if (isLock) { String appId = request.getHeader("appId"); dto.setWechatAppId(appId); //设置请求来源 dto.setRequestSource(UserAgentUtils.determineRequestSource(request)); map = orderService.payOccupyPileOrder(dto); } response = new RestApiResponse<>(map); } catch (BusinessException e) { logger.warn("支付占桩订单 warn param:{}", dto.toString(), e); response = new RestApiResponse<>(e.getCode(), e.getMessage()); } catch (Exception e) { logger.error("支付占桩订单 error param:{}", dto.toString(), e); response = new RestApiResponse<>(ReturnCodeEnum.CODE_ORDER_PAY_ERROR); } finally { // 支付订单解锁 if (lockValue.equals(redisCache.getCacheObject(lockKey).toString())) { redisCache.unLock(lockKey); } } logger.info("支付占桩订单 result:{}", JSON.toJSONString(response)); return response; } }