| | |
| | | import com.nq.common.ServerResponse; |
| | | import com.nq.dao.UserMapper; |
| | | import com.nq.dao.UserRechargeMapper; |
| | | import com.nq.pojo.SiteSetting; |
| | | import com.nq.pojo.User; |
| | | import com.nq.pojo.UserRecharge; |
| | | import com.nq.service.IPayService; |
| | | import com.nq.service.ISiteSettingService; |
| | | import com.nq.service.IUserService; |
| | | import com.nq.utils.KeyUtils; |
| | | import com.nq.utils.PropertiesUtil; |
| | | import com.nq.utils.RechargeAmtValidator; |
| | | import com.nq.utils.UserFundUtil; |
| | | import com.nq.utils.pay.AlipayPayUtil; |
| | | import com.nq.utils.pay.CmcPayOuterRequestUtil; |
| | | import com.nq.utils.pay.CmcPayTool; |
| | | import com.nq.utils.pay.OcocnPayUtil; |
| | | import com.alipay.api.AlipayApiException; |
| | | import com.nq.vo.pay.AlipayPayVO; |
| | | import com.nq.vo.pay.FlyPayVO; |
| | | import com.nq.vo.pay.GuoPayVO; |
| | | import com.nq.vo.pay.OcocnPayVO; |
| | | |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.math.BigDecimal; |
| | |
| | | import java.security.NoSuchAlgorithmException; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | import java.util.Map; |
| | | import java.util.Random; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | |
| | |
| | | |
| | | @Autowired |
| | | UserMapper userMapper; |
| | | |
| | | @Autowired |
| | | ISiteSettingService iSiteSettingService; |
| | | |
| | | private static final String juhe1_key = "vd7omkkexkt7fvl6wm2jl9yan3g79y6i"; |
| | | |
| | |
| | | if (updateCount > 0) { |
| | | log.info("后台通知,修改订单状态成功"); |
| | | |
| | | BigDecimal total_amt = user.getUserAmt().add(userRecharge.getPayAmt()); |
| | | user.setUserAmt(total_amt); |
| | | BigDecimal total_enable = user.getEnableAmt().add(userRecharge.getPayAmt()); |
| | | user.setEnableAmt(total_enable); |
| | | UserFundUtil.creditUserBalance(user, userRecharge.getPayAmt()); |
| | | int updateUserCount = this.userMapper.updateByPrimaryKeySelective(user); |
| | | if (updateUserCount > 0) { |
| | | return ServerResponse.createBySuccessMsg("后台通知 处理成功"); |
| | |
| | | } |
| | | |
| | | @Override |
| | | public ServerResponse ococnPay(String payType, String payAmt, HttpServletRequest request) { |
| | | if (StringUtils.isBlank(payType) || StringUtils.isBlank(payAmt)) { |
| | | return ServerResponse.createByErrorMsg("参数不能为空"); |
| | | } |
| | | BigDecimal payAmtBig = new BigDecimal(payAmt); |
| | | if (payAmtBig.compareTo(BigDecimal.ZERO) <= 0) { |
| | | return ServerResponse.createByErrorMsg("支付金额必须大于0"); |
| | | } |
| | | |
| | | User user = this.iUserService.getCurrentRefreshUser(request); |
| | | if (user == null) { |
| | | return ServerResponse.createByErrorMsg("请先登录"); |
| | | } |
| | | |
| | | String ordersn = KeyUtils.getRechargeOrderSn(); |
| | | String money = payAmtBig.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString(); |
| | | String pid = PropertiesUtil.getProperty("ococn.pay.pid"); |
| | | String key = PropertiesUtil.getProperty("ococn.pay.key"); |
| | | String submitUrl = PropertiesUtil.getProperty("ococn.pay.url"); |
| | | String apiDomain = trimTrailingSlash(PropertiesUtil.getProperty("website.domain.url")); |
| | | if (StringUtils.isAnyBlank(pid, key, submitUrl, apiDomain)) { |
| | | return ServerResponse.createByErrorMsg("支付配置不完整,请联系管理员"); |
| | | } |
| | | String notifyUrl = apiDomain + "/api/pay/ococnNotify.do"; |
| | | String returnUrl = apiDomain + "/api/pay/ococnReturn.do"; |
| | | String sitename = StringUtils.defaultString(PropertiesUtil.getProperty("ococn.pay.sitename", ""), ""); |
| | | String productName = PropertiesUtil.getProperty("ococn.pay.name", "账户充值"); |
| | | |
| | | UserRecharge userRecharge = new UserRecharge(); |
| | | userRecharge.setUserId(user.getId()); |
| | | userRecharge.setNickName(user.getRealName()); |
| | | userRecharge.setAgentId(user.getAgentId()); |
| | | userRecharge.setOrderSn(ordersn); |
| | | userRecharge.setPayChannel(getOcocnChannelName(payType)); |
| | | userRecharge.setPayAmt(payAmtBig); |
| | | userRecharge.setOrderStatus(Integer.valueOf(0)); |
| | | userRecharge.setAddTime(new Date()); |
| | | |
| | | int insertCount = this.userRechargeMapper.insert(userRecharge); |
| | | if (insertCount <= 0) { |
| | | return ServerResponse.createByErrorMsg("创建支付订单失败"); |
| | | } |
| | | |
| | | String sign = OcocnPayUtil.buildSubmitSign(money, productName, notifyUrl, ordersn, pid, returnUrl, sitename, payType, key); |
| | | log.info("ococn支付 notifyUrl={} returnUrl={}", notifyUrl, returnUrl); |
| | | StringBuilder payUrlBuilder = new StringBuilder(submitUrl).append("?"); |
| | | payUrlBuilder.append("pid=").append(pid) |
| | | .append("&type=").append(payType) |
| | | .append("&out_trade_no=").append(ordersn) |
| | | .append("¬ify_url=").append(OcocnPayUtil.encode(notifyUrl)) |
| | | .append("&return_url=").append(OcocnPayUtil.encode(returnUrl)) |
| | | .append("&name=").append(OcocnPayUtil.encode(productName)) |
| | | .append("&money=").append(money); |
| | | if (StringUtils.isNotBlank(sitename)) { |
| | | payUrlBuilder.append("&sitename=").append(OcocnPayUtil.encode(sitename)); |
| | | } |
| | | payUrlBuilder.append("&sign=").append(sign).append("&sign_type=MD5"); |
| | | String payUrl = payUrlBuilder.toString(); |
| | | |
| | | OcocnPayVO ococnPayVO = new OcocnPayVO(); |
| | | ococnPayVO.setPayUrl(payUrl); |
| | | log.info("ococn支付,创建订单成功 orderSn={}", ordersn); |
| | | return ServerResponse.createBySuccess(ococnPayVO); |
| | | } |
| | | |
| | | @Override |
| | | public ServerResponse ococnNotify(HttpServletRequest request) { |
| | | Map<String, String> params = OcocnPayUtil.parseRequestParams(request); |
| | | log.info("ococn支付通知参数: {}", params); |
| | | |
| | | String outTradeNo = params.get("out_trade_no"); |
| | | String tradeNo = params.get("trade_no"); |
| | | String money = params.get("money"); |
| | | String tradeStatus = params.get("trade_status"); |
| | | String sign = params.get("sign"); |
| | | |
| | | if (StringUtils.isAnyBlank(outTradeNo, tradeNo, money, tradeStatus, sign)) { |
| | | return ServerResponse.createByErrorMsg("回调参数不完整"); |
| | | } |
| | | |
| | | String key = PropertiesUtil.getProperty("ococn.pay.key"); |
| | | if (!OcocnPayUtil.verifyNotifySign(params, key)) { |
| | | log.error("ococn支付通知签名校验失败, remoteSign={}, params={}", sign, params); |
| | | return ServerResponse.createByErrorMsg("签名校验失败"); |
| | | } |
| | | |
| | | if (!"TRADE_SUCCESS".equals(tradeStatus)) { |
| | | return ServerResponse.createByErrorMsg("支付未成功"); |
| | | } |
| | | |
| | | UserRecharge existing = this.userRechargeMapper.findUserRechargeByOrderSn(outTradeNo); |
| | | if (existing != null && existing.getOrderStatus().intValue() != 0) { |
| | | return ServerResponse.createBySuccessMsg("订单已处理"); |
| | | } |
| | | |
| | | return doSuccess(outTradeNo, money); |
| | | } |
| | | |
| | | @Override |
| | | public String ococnReturn(HttpServletRequest request) { |
| | | Map<String, String> params = OcocnPayUtil.parseRequestParams(request); |
| | | log.info("ococn支付同步跳转: {}", params); |
| | | String frontendUrl = StringUtils.defaultIfBlank( |
| | | PropertiesUtil.getProperty("ococn.pay.frontend_redirect"), |
| | | trimTrailingSlash(PropertiesUtil.getProperty("frontend.domain.url", "")) + "/#/user" |
| | | ); |
| | | return frontendUrl; |
| | | } |
| | | |
| | | private String getOcocnChannelName(String payType) { |
| | | if ("alipay".equals(payType)) { |
| | | return "支付宝-线上"; |
| | | } |
| | | if ("wxpay".equals(payType)) { |
| | | return "微信-线上"; |
| | | } |
| | | if ("qqpay".equals(payType)) { |
| | | return "QQ钱包-线上"; |
| | | } |
| | | if ("tenpay".equals(payType)) { |
| | | return "财付通-线上"; |
| | | } |
| | | return "线上支付"; |
| | | } |
| | | |
| | | private String trimTrailingSlash(String url) { |
| | | if (url == null) { |
| | | return null; |
| | | } |
| | | return url.endsWith("/") ? url.substring(0, url.length() - 1) : url; |
| | | } |
| | | |
| | | @Override |
| | | public ServerResponse alipayPagePay(String payAmt, HttpServletRequest request) { |
| | | if (StringUtils.isBlank(payAmt)) { |
| | | return ServerResponse.createByErrorMsg("参数不能为空"); |
| | | } |
| | | BigDecimal payAmtBig = new BigDecimal(payAmt); |
| | | if (payAmtBig.compareTo(BigDecimal.ZERO) <= 0) { |
| | | return ServerResponse.createByErrorMsg("支付金额必须大于0"); |
| | | } |
| | | SiteSetting siteSetting = this.iSiteSettingService.getSiteSetting(); |
| | | ServerResponse amtCheck = RechargeAmtValidator.validate(siteSetting, payAmtBig); |
| | | if (!amtCheck.isSuccess()) { |
| | | return amtCheck; |
| | | } |
| | | String configError = AlipayPayUtil.getConfigError(); |
| | | if (configError != null) { |
| | | return ServerResponse.createByErrorMsg(configError); |
| | | } |
| | | |
| | | User user = this.iUserService.getCurrentRefreshUser(request); |
| | | if (user == null) { |
| | | return ServerResponse.createByErrorMsg("请先登录"); |
| | | } |
| | | |
| | | String apiDomain = trimTrailingSlash(PropertiesUtil.getProperty("website.domain.url")); |
| | | if (StringUtils.isBlank(apiDomain)) { |
| | | return ServerResponse.createByErrorMsg("支付配置不完整,请联系管理员"); |
| | | } |
| | | |
| | | String ordersn = KeyUtils.getRechargeOrderSn(); |
| | | String money = payAmtBig.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString(); |
| | | String notifyUrl = apiDomain + "/api/pay/alipayNotify.do"; |
| | | String returnUrl = apiDomain + "/api/pay/alipayReturn.do"; |
| | | String quitUrl = PropertiesUtil.getProperty("alipay.frontend-redirect", |
| | | trimTrailingSlash(PropertiesUtil.getProperty("frontend.domain.url", "")) + "/#/rechargelist"); |
| | | String productName = PropertiesUtil.getProperty("alipay.product-name", "账户充值"); |
| | | |
| | | UserRecharge userRecharge = new UserRecharge(); |
| | | userRecharge.setUserId(user.getId()); |
| | | userRecharge.setNickName(user.getRealName()); |
| | | userRecharge.setAgentId(user.getAgentId()); |
| | | userRecharge.setOrderSn(ordersn); |
| | | userRecharge.setPayChannel("支付宝-WAP"); |
| | | userRecharge.setPayAmt(payAmtBig); |
| | | userRecharge.setOrderStatus(Integer.valueOf(0)); |
| | | userRecharge.setAddTime(new Date()); |
| | | |
| | | int insertCount = this.userRechargeMapper.insert(userRecharge); |
| | | if (insertCount <= 0) { |
| | | return ServerResponse.createByErrorMsg("创建支付订单失败"); |
| | | } |
| | | |
| | | try { |
| | | String payForm = AlipayPayUtil.buildWapPayForm(ordersn, money, productName, notifyUrl, returnUrl, quitUrl); |
| | | AlipayPayVO alipayPayVO = new AlipayPayVO(); |
| | | alipayPayVO.setPayForm(payForm); |
| | | log.info("支付宝WAP支付,创建订单成功 orderSn={}", ordersn); |
| | | return ServerResponse.createBySuccess(alipayPayVO); |
| | | } catch (AlipayApiException e) { |
| | | log.error("支付宝WAP支付下单失败 orderSn={}", ordersn, e); |
| | | String msg = e.getMessage(); |
| | | if (msg != null && (msg.contains("私钥") || msg.contains("公钥") || msg.contains("RSA2"))) { |
| | | return ServerResponse.createByErrorMsg(msg); |
| | | } |
| | | return ServerResponse.createByErrorMsg("发起支付宝支付失败,请稍后重试"); |
| | | } catch (Exception e) { |
| | | log.error("支付宝网页支付下单失败 orderSn={}", ordersn, e); |
| | | return ServerResponse.createByErrorMsg("发起支付宝支付失败,请稍后重试"); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public ServerResponse alipayNotify(HttpServletRequest request) { |
| | | Map<String, String> params = AlipayPayUtil.parseRequestParams(request); |
| | | log.info("支付宝支付通知参数: {}", params); |
| | | |
| | | String outTradeNo = params.get("out_trade_no"); |
| | | String totalAmount = params.get("total_amount"); |
| | | String tradeStatus = params.get("trade_status"); |
| | | |
| | | if (StringUtils.isAnyBlank(outTradeNo, totalAmount, tradeStatus)) { |
| | | return ServerResponse.createByErrorMsg("回调参数不完整"); |
| | | } |
| | | if (!AlipayPayUtil.verifyNotify(params)) { |
| | | log.error("支付宝支付通知签名校验失败, params={}", params); |
| | | return ServerResponse.createByErrorMsg("签名校验失败"); |
| | | } |
| | | if (!"TRADE_SUCCESS".equals(tradeStatus) && !"TRADE_FINISHED".equals(tradeStatus)) { |
| | | return ServerResponse.createByErrorMsg("支付未成功"); |
| | | } |
| | | |
| | | UserRecharge existing = this.userRechargeMapper.findUserRechargeByOrderSn(outTradeNo); |
| | | if (existing != null && existing.getOrderStatus().intValue() != 0) { |
| | | return ServerResponse.createBySuccessMsg("订单已处理"); |
| | | } |
| | | return doSuccess(outTradeNo, totalAmount); |
| | | } |
| | | |
| | | @Override |
| | | public String alipayReturn(HttpServletRequest request) { |
| | | Map<String, String> params = AlipayPayUtil.parseRequestParams(request); |
| | | log.info("支付宝支付同步跳转: {}", params); |
| | | return StringUtils.defaultIfBlank( |
| | | PropertiesUtil.getProperty("alipay.frontend-redirect"), |
| | | trimTrailingSlash(PropertiesUtil.getProperty("frontend.domain.url", "")) + "/#/rechargelist" |
| | | ); |
| | | } |
| | | |
| | | @Override |
| | | public ServerResponse juhenewpayNotify(HttpServletRequest request) throws UnsupportedEncodingException { |
| | | LinkedMap map = new LinkedMap(); |
| | | String out_trade_no = request.getParameter("out_trade_no"); |