From 3cb61867769d091f7e20ade8701b6593b82141ad Mon Sep 17 00:00:00 2001 From: 无关风月 <443237572@qq.com> Date: 星期四, 26 九月 2024 14:40:10 +0800 Subject: [PATCH] 玩湃微信商户分账 --- cloud-server-management/src/main/webapp/static/modular/system/operator/operator_add.js | 5 cloud-server-other/src/main/java/com/dsh/other/util/PayMoneyUtil.java | 89 ++ cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/Operator_wx.html | 7 cloud-server-course/src/main/java/com/dsh/course/controller/CoursePackagePaymentController.java | 3 cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetition/TCompetition_edit.html | 2 cloud-server-course/src/main/java/com/dsh/course/util/PayMoneyUtil.java | 77 ++ cloud-server-other/src/main/java/com/dsh/other/controller/SiteController.java | 58 ++ cloud-server-course/src/main/java/com/dsh/course/feignclient/activity/CouponClient.java | 8 cloud-server-course/src/main/java/com/dsh/course/service/TCoursePackageService.java | 2 cloud-server-account/src/main/java/com/dsh/account/service/impl/TStudentServiceImpl.java | 2 cloud-server-course/src/main/java/com/dsh/course/service/TCoursePackagePaymentService.java | 2 cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/OperatorController.java | 13 cloud-server-course/src/main/java/com/dsh/course/util/httpClinet/HttpClientUtil.java | 55 ++ cloud-server-account/src/main/java/com/dsh/account/util/httpClinet/HttpClientUtil.java | 35 + cloud-server-competition/src/main/java/com/dsh/competition/util/httpClinet/HttpClientUtil.java | 42 + cloud-server-management/src/main/webapp/WEB-INF/view/system/operatorUser/OperatorUser.html | 2 cloud-server-competition/src/main/java/com/dsh/competition/util/PayMoneyUtil.java | 85 ++ cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackageServiceImpl.java | 56 +- cloud-server-management/src/main/webapp/static/modular/system/tCompetition/tCompetition_info.js | 14 cloud-server-account/src/main/java/com/dsh/account/controller/UseBenefitsController.java | 1 cloud-server-other/src/main/java/com/dsh/other/entity/TGameRecord.java | 10 cloud-server-activity/src/main/java/com/dsh/activity/controller/CouponController.java | 11 cloud-server-management/src/main/resources/mapper/TOperatorUserMapper.xml | 14 cloud-server-course/src/main/java/com/dsh/course/feignclient/other/StoreClient.java | 9 cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/Operator.html | 2 cloud-server-competition/src/main/java/com/dsh/competition/service/impl/CompetitionServiceImpl.java | 26 - cloud-server-competition/src/main/java/com/dsh/competition/feignclient/other/StoreClient.java | 9 cloud-server-other/src/main/java/com/dsh/other/controller/GameController.java | 92 ++- cloud-server-account/src/main/java/com/dsh/account/util/PayMoneyUtil.java | 89 +++ cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TCompetitionController.java | 44 + cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetition/TCompetition_add.html | 23 cloud-server-account/src/main/java/com/dsh/account/service/impl/TAppUserServiceImpl.java | 274 +++++++--- cloud-server-other/src/main/java/com/dsh/other/service/impl/SiteServiceImpl.java | 43 - cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackagePaymentServiceImpl.java | 127 +++- cloud-server-course/src/main/java/com/dsh/course/model/vo/request/ClasspaymentRequest.java | 6 cloud-server-competition/src/main/java/com/dsh/competition/service/impl/PaymentCompetitionServiceImpl.java | 6 cloud-server-other/src/main/java/com/dsh/other/util/HttpClientUtil.java | 34 + cloud-server-account/src/main/java/com/dsh/account/feignclient/other/StoreClient.java | 9 cloud-server-account/src/main/java/com/dsh/account/service/TAppUserService.java | 2 cloud-server-competition/src/main/java/com/dsh/competition/controller/CompetitionController.java | 31 + 40 files changed, 1,043 insertions(+), 376 deletions(-) diff --git a/cloud-server-account/src/main/java/com/dsh/account/controller/UseBenefitsController.java b/cloud-server-account/src/main/java/com/dsh/account/controller/UseBenefitsController.java index 88665d2..499eada 100644 --- a/cloud-server-account/src/main/java/com/dsh/account/controller/UseBenefitsController.java +++ b/cloud-server-account/src/main/java/com/dsh/account/controller/UseBenefitsController.java @@ -428,6 +428,7 @@ @PostMapping("/base/coupon/weChatPaymentCouponCallback") public void weChatPaymentCouponCallback(HttpServletRequest request, HttpServletResponse response){ try { + System.err.println("进入回调"); Map<String, String> map = payMoneyUtil.weixinpayCallback(request); if(null != map){ String code = map.get("out_trade_no"); diff --git a/cloud-server-account/src/main/java/com/dsh/account/feignclient/other/StoreClient.java b/cloud-server-account/src/main/java/com/dsh/account/feignclient/other/StoreClient.java index 376aca4..ab30047 100644 --- a/cloud-server-account/src/main/java/com/dsh/account/feignclient/other/StoreClient.java +++ b/cloud-server-account/src/main/java/com/dsh/account/feignclient/other/StoreClient.java @@ -4,6 +4,7 @@ import com.dsh.account.feignclient.course.model.QueryStoreList; import com.dsh.account.feignclient.other.model.*; import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -16,8 +17,8 @@ * 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 * @return */ - @PostMapping("/base/getProportionByOperatorId") - String getProportionByOperatorId(Integer id); + @PostMapping("/base/getProportionByOperatorId/{id}") + String getProportionByOperatorId(@PathVariable("id") Integer id); /** * 根据运营商id获取对应运营商支付宝商户号 * @return @@ -25,8 +26,8 @@ @PostMapping("/base/getSMIDByOperatorId") String getSMIDByOperatorId(Integer id); // 根据运营商id获取微信商户号 - @PostMapping("/base/getmerchantNumberByOperatorId") - String getmerchantNumberByOperatorId(Integer id); + @PostMapping("/base/getmerchantNumberByOperatorId/{id}") + String getmerchantNumberByOperatorId(@PathVariable("id")Integer id); @PostMapping("/store/queryByStoreId") OperatorUser queryByStoreId(Integer storeId); diff --git a/cloud-server-account/src/main/java/com/dsh/account/service/TAppUserService.java b/cloud-server-account/src/main/java/com/dsh/account/service/TAppUserService.java index 339e7b0..9664571 100644 --- a/cloud-server-account/src/main/java/com/dsh/account/service/TAppUserService.java +++ b/cloud-server-account/src/main/java/com/dsh/account/service/TAppUserService.java @@ -157,7 +157,7 @@ * @param orderNumber * @return */ - ResultUtil paymentCouponCallback(String code, String orderNumber); + ResultUtil paymentCouponCallback(String code, String orderNumber) throws Exception; diff --git a/cloud-server-account/src/main/java/com/dsh/account/service/impl/TAppUserServiceImpl.java b/cloud-server-account/src/main/java/com/dsh/account/service/impl/TAppUserServiceImpl.java index d964181..0e39c85 100644 --- a/cloud-server-account/src/main/java/com/dsh/account/service/impl/TAppUserServiceImpl.java +++ b/cloud-server-account/src/main/java/com/dsh/account/service/impl/TAppUserServiceImpl.java @@ -130,6 +130,7 @@ @Resource private UserConponClient ucponClient; + @Resource private CoursePackageClient cpageClient; @@ -1363,11 +1364,9 @@ } //查询该用户是否超出限领数量 Integer usercounts = userConponClient.queryCounts1(queryIds); - if (usercounts == coupon.getPickUpQuantity()) { return new ResultUtil<>(0, "限领数量已达最大"); } - SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); String code = sdf.format(new Date()) + UUIDUtil.getNumberRandom(5); //生成支付订单 @@ -1423,7 +1422,7 @@ } } } - System.out.println(exchangeType); + System.out.println("兑换积分商品"+exchangeType); try { SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); String code = sdf.format(new Date()) + UUIDUtil.getNumberRandom(5); @@ -1540,6 +1539,7 @@ return ResultUtil.success(returnModel); } + System.err.println("兑换方式"+exchangeType); switch (exchangeType.getExchangeType()) { // 积分 case 1: @@ -1636,6 +1636,8 @@ return WechatPayment(merchandise.getType(), merchandise.getCash().multiply(new BigDecimal(exchangeType.getStuIds().size())), code,merchandise.getId()); } else if (merchandise.getType() == 1){ return WechatPayment(merchandise.getType(), merchandise.getCash().multiply(new BigDecimal(goodsNums)), code,merchandise.getId()); + }else if(merchandise.getType() == 3){ + return WechatPayment(merchandise.getType(), merchandise.getCash().multiply(new BigDecimal(goodsNums)), code,merchandise.getId()); } } catch (Exception e) { return ResultUtil.runErr(); @@ -1702,6 +1704,7 @@ if (coupon.getPublisherType()!=null&&coupon.getPublisherType()!=2){ temp = "1"; } + System.err.println("购买优惠券"); ResultUtil weixinpay = payMoneyUtil.weixinpay(body+"-"+temp, "", code, cash.toString(), "/base/coupon/weChatPaymentCouponCallback", "APP", ""); if (weixinpay.getCode() == 200) { @@ -1758,38 +1761,6 @@ TAppUser user = appUserService.getById(userCouponPayment1.getUserId()); user.setIntegral(user.getIntegral() - userCouponPayment1.getIntegral().intValue()); appUserService.updateById(user); - } - // 休眠两分钟后再调用分账接口 避免提示订单正在处理中 - Thread.sleep(120000); - if (coupon!=null){ - if (coupon.getPublisherType()!=null&&coupon.getPublisherType()!=2){ - if (coupon.getPublisherType() == 3){ - // 门店 向上查询运营商 - Store store = storeClient.queryStoreById(coupon.getCityManagerId()); - if (store.getOperatorId()==null || store.getOperatorId()==0){ - // 平台不分账 - break; - }else{ - // 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 - String proportionByOperatorId = storeClient.getProportionByOperatorId(store.getOperatorId()); - String[] split = proportionByOperatorId.split(","); - String s1 = split[0]; - if (!s1.equals("未设置")){ - BigDecimal bigDecimal = new BigDecimal(s1); - // 分账比例 - BigDecimal bigDecimal1 = bigDecimal.divide(new BigDecimal(100)).setScale(2); - // 微信商户号 - String s2 = storeClient.getmerchantNumberByOperatorId(store.getOperatorId()); - BigDecimal bigDecimal2 = new BigDecimal(cash); - ResultUtil fenzhang = payMoneyUtil.fenzhang(userCouponPayment1.getOrderNumber(), bigDecimal2.multiply(bigDecimal1), s2); - if (!fenzhang.getCode().equals(500)){ - System.err.println("分账失败 原因是:"+fenzhang.getMsg()); - } - - } - } - } - } } break; } @@ -1902,7 +1873,8 @@ * @return */ @Override - public ResultUtil paymentCouponCallback(String code, String orderNumber) { + public ResultUtil paymentCouponCallback(String code, String orderNumber) throws Exception { + System.err.println("进入回调"); UserCouponPayment userCouponPayment1 = userCouponPaymentClient.getUserCouponPayment(code); if (userCouponPayment1.getStatus() == 2) { return ResultUtil.success(); @@ -1927,8 +1899,70 @@ vo.setRemark("兑换优惠券"); vo.setType(2); userIntegralChangesService.saveUserIntegralChanges(vo); - } + Coupon coupon = ucponClient.queryCouponById(userCouponPayment1.getCouponId()); + // 创建一个两分钟后执行的线程 + new Thread(() -> { + try { + Thread.sleep(120000); + if (coupon!=null){ + if (coupon.getPublisherType()!=null&&coupon.getPublisherType()!=2){ + if (coupon.getPublisherType() == 1){ + System.err.println("进入分账逻辑"); + // 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 + String proportionByOperatorId = storeClient.getProportionByOperatorId(coupon.getCityManagerId()); + System.err.println("分账比例:"+proportionByOperatorId); + String[] split = proportionByOperatorId.split(","); + String s1 = split[0]; + if (!s1.equals("未设置")){ + BigDecimal bigDecimal = new BigDecimal(s1); + // 分账比例 + BigDecimal bigDecimal1 = bigDecimal.divide(new BigDecimal(100)).setScale(2); + // 微信商户号 + String s2 = storeClient.getmerchantNumberByOperatorId(coupon.getCityManagerId()); + System.err.println("商户号"+s2); + System.err.println("分账比例"+bigDecimal1); + System.err.println("分账金额"+coupon.getCash().multiply(bigDecimal1)); + ResultUtil fenzhang = payMoneyUtil.fenzhang(userCouponPayment1.getOrderNumber(), coupon.getCash().multiply(bigDecimal1), s2,""); + if (!fenzhang.getCode().equals(200)){ + System.err.println("分账失败 原因是:"+fenzhang.getMsg()); + } + + } + } else if (coupon.getPublisherType() == 3){ + // 门店 向上查询运营商 + Store store = storeClient.queryStoreById(coupon.getCityManagerId()); + if (store.getOperatorId()==null || store.getOperatorId()==0){ + // 平台不分账 + }else{ + // 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 + String proportionByOperatorId = storeClient.getProportionByOperatorId(store.getOperatorId()); + String[] split = proportionByOperatorId.split(","); + String s1 = split[0]; + if (!s1.equals("未设置")){ + BigDecimal bigDecimal = new BigDecimal(s1); + // 分账比例 + BigDecimal bigDecimal1 = bigDecimal.divide(new BigDecimal(100)).setScale(2); + // 微信商户号 + String s2 = storeClient.getmerchantNumberByOperatorId(store.getOperatorId()); + ResultUtil fenzhang = payMoneyUtil.fenzhang(userCouponPayment1.getOrderNumber(), coupon.getCash().multiply(bigDecimal1), s2,"购买优惠券分账"); + if (!fenzhang.getCode().equals(200)){ + System.err.println("分账失败 原因是:"+fenzhang.getMsg()); + }else{ + System.err.println("分账成功"); + return; + } + + } + } + } + } + } + }catch (Exception e){ + e.printStackTrace(); + } + }).start(); + return ResultUtil.success(); } @@ -2125,7 +2159,10 @@ private ResultUtil WechatPayment(Integer type, BigDecimal cash, String code,Integer id) throws Exception { String name = (type == 1 ? "购买实体商品" : type == 2 ? "报名运动营": type == 3 ? "购买门票" : "购买优惠券"); + System.err.println("微信支付:"+name); + PointsMerchandise pointsMerchandise = mcClient.selectPointsMerchandiseById(id); + System.err.println("查询积分商品"+pointsMerchandise); // 分账表示 0否1是 String temp = "0"; switch (type){ @@ -2155,8 +2192,10 @@ // 查询门票指定的门店 属于平台还是运营商 break; } + System.err.println("支付"); ResultUtil weixinpay = payMoneyUtil.weixinpay(name+"-"+temp, "", code, cash.toString(), "/base/pointMer/exchangeGoodPaymentWeChatCallback", "APP", ""); + System.err.println("提交支付"+weixinpay); if (weixinpay.getCode() == 200) { new Thread(new Runnable() { @Override @@ -2222,59 +2261,6 @@ paymentClient.addCoursePackageOrderStudent(addCoursePackageOrderStudent); } } - // 休眠两分钟后再调用分账接口 避免提示订单正在处理中 - Thread.sleep(120000); - // 分账表示 0否1是 - String temp = "0"; - // 运营商id - Integer operatorId = 0; - switch (type){ - case 1: - temp = "0"; - break; - case 2: - // 判断课包属于平台还是运营商 - CoursePackage coursePackage = cpageClient.queryCoursePackageById(pointsMerchandise.getCoursePackageId()); - Store store = storeClient.queryStoreById(coursePackage.getStoreId()); - if (store.getOperatorId() ==null || store.getOperatorId() == 0){ - // 平台课包 不分账 - }else{ - temp = "1"; - operatorId = store.getOperatorId(); - } - break; - case 3: - List<Integer> integers = mcsClient.queryPointMerStoreIds(pointsMerchandise.getId()); - if (!integers.isEmpty()){ - Store store1 = storeClient.queryStoreById(integers.get(0)); - if (store1.getOperatorId() ==null || store1.getOperatorId() == 0){ - // 平台门票 不分账 - }else{ - temp = "1"; - operatorId = store1.getOperatorId(); - } - } - // 查询门票指定的门店 属于平台还是运营商 - break; - } - if (operatorId != 0) { - // 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 - String proportionByOperatorId = storeClient.getProportionByOperatorId(operatorId); - String[] split = proportionByOperatorId.split(","); - String s1 = split[0]; - if (!s1.equals("未设置")){ - BigDecimal bigDecimal = new BigDecimal(s1); - // 分账比例 - BigDecimal bigDecimal1 = bigDecimal.divide(new BigDecimal(100)).setScale(2); - // 微信商户号 - String s2 = storeClient.getmerchantNumberByOperatorId(operatorId); - - ResultUtil fenzhang = payMoneyUtil.fenzhang(transaction_id, cash.multiply(bigDecimal1), s2); - if (!fenzhang.getCode().equals(500)){ - System.err.println("分账失败 原因是:"+fenzhang.getMsg()); - } - } - } break; } if ("USERPAYING".equals(s) || "NOTPAY".equals(s)) { @@ -2293,7 +2279,9 @@ @Override public ResultUtil exchangeAddPaymentCallback(String code, String orderNumber) { + System.err.println("进入回调"+code); UserPointsMerchandise userPointsMerchandise = mcClient.queryUserPointMerchaseByCode(code).get(0); + System.err.println("商品"+userPointsMerchandise); if (userPointsMerchandise.getPayStatus() == 2) { return ResultUtil.success(); } @@ -2328,7 +2316,113 @@ paymentClient.addCoursePackageOrderStudent(addCoursePackageOrderStudent); } } + // 创建一个2分钟后执行的线程 + new Thread(() -> { + try { + // 休眠两分钟后再调用分账接口 避免提示订单正在处理中 + Thread.sleep(1000 * 60 * 2); + // 分账表示 0否1是 + String temp = "0"; + // 运营商id + Integer operatorId = 0; + System.err.println("商品"+pointsMerchandise); + switch (pointsMerchandise.getType()){ + case 1: + temp = "0"; + break; + case 2: + // 判断课包属于平台还是运营商 + CoursePackage coursePackage = cpageClient.queryCoursePackageById(pointsMerchandise.getCoursePackageId()); + Store store = storeClient.queryStoreById(coursePackage.getStoreId()); + if (store.getOperatorId() ==null || store.getOperatorId() == 0){ + // 平台课包 不分账 + }else{ + temp = "1"; + operatorId = store.getOperatorId(); + } + break; + case 3: + List<Integer> integers = mcsClient.queryPointMerStoreIds(pointsMerchandise.getId()); + System.err.println("门店ids"+integers); + if (!integers.isEmpty()){ + Store store1 = storeClient.queryStoreById(integers.get(0)); + if (store1.getOperatorId() ==null || store1.getOperatorId() == 0){ + // 平台门票 不分账 + }else{ + temp = "1"; + operatorId = store1.getOperatorId(); + } + } + // 查询门票指定的门店 属于平台还是运营商 + break; + } + System.err.println("运营商id"+operatorId); + if (operatorId != 0) { + //课程 + if(pointsMerchandise.getType() == 2){ + //课程 + CoursePackageOrder coursePackageOrder1 = paymentClient.getCoursePackageOrderByCode(code); + if(null != coursePackageOrder1){ + coursePackageOrder1.setPayStatus(2); + coursePackageOrder1.setOrderNumber(orderNumber); + coursePackageOrder1.setAppUserId(null); + paymentClient.updateCoursePackageOrder(coursePackageOrder1); + GetCoursePackagePaymentConfig getCoursePackagePaymentConfig = new GetCoursePackagePaymentConfig(); + getCoursePackagePaymentConfig.setCoursePackageId(coursePackageOrder1.getCoursePackageId()); + getCoursePackagePaymentConfig.setClassHours(coursePackageOrder1.getClassHours()); + CoursePackagePaymentConfig coursePackagePaymentConfig = paymentClient.getCoursePackagePaymentConfig(getCoursePackagePaymentConfig); + + AddCoursePackageOrderStudent addCoursePackageOrderStudent = new AddCoursePackageOrderStudent(); + addCoursePackageOrderStudent.setCoursePackageOrderId(coursePackageOrder1.getId()); + addCoursePackageOrderStudent.setCoursePackagePaymentConfig(coursePackagePaymentConfig); + paymentClient.addCoursePackageOrderStudent(addCoursePackageOrderStudent); + // 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 + String proportionByOperatorId = storeClient.getProportionByOperatorId(operatorId); + String[] split = proportionByOperatorId.split(","); + String s1 = split[0]; + if (!s1.equals("未设置")){ + BigDecimal bigDecimal = new BigDecimal(s1); + // 分账比例 + BigDecimal bigDecimal1 = bigDecimal.divide(new BigDecimal(100)).setScale(2); + // 微信商户号 + String s2 = storeClient.getmerchantNumberByOperatorId(operatorId); + + ResultUtil fenzhang = payMoneyUtil.fenzhang(orderNumber, coursePackageOrder1.getCashPayment().multiply(bigDecimal1), s2,"运动营商品"); + if (!fenzhang.getCode().equals(200)){ + System.err.println("分账失败 原因是:"+fenzhang.getMsg()); + } + } + } + }else{ + System.err.println("门票"); + // 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 + String proportionByOperatorId = storeClient.getProportionByOperatorId(operatorId); + System.err.println("分账比例"+proportionByOperatorId); + String[] split = proportionByOperatorId.split(","); + String s1 = split[0]; + if (!s1.equals("未设置")){ + BigDecimal bigDecimal = new BigDecimal(s1); + // 分账比例 + BigDecimal bigDecimal1 = bigDecimal.divide(new BigDecimal(100)).setScale(2); + // 微信商户号 + String s2 = storeClient.getmerchantNumberByOperatorId(operatorId); + System.err.println("微信商户号"+s2); + + ResultUtil fenzhang = payMoneyUtil.fenzhang(orderNumber, pointsMerchandise.getCash().multiply(bigDecimal1), s2,"门票"); + if (!fenzhang.getCode().equals(200)){ + System.err.println("分账失败 原因是:"+fenzhang.getMsg()); + } + } + } + + } + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (Exception e) { + throw new RuntimeException(e); + } + }).start(); return ResultUtil.success(); } diff --git a/cloud-server-account/src/main/java/com/dsh/account/service/impl/TStudentServiceImpl.java b/cloud-server-account/src/main/java/com/dsh/account/service/impl/TStudentServiceImpl.java index 8b8a57b..9dacfdf 100644 --- a/cloud-server-account/src/main/java/com/dsh/account/service/impl/TStudentServiceImpl.java +++ b/cloud-server-account/src/main/java/com/dsh/account/service/impl/TStudentServiceImpl.java @@ -491,7 +491,7 @@ // 微信商户号 String s2 = storeClient.getmerchantNumberByOperatorId(store.getOperatorId()); - ResultUtil fenzhang = payMoneyUtil.fenzhang(transaction_id, amount.multiply(bigDecimal1), s2); + ResultUtil fenzhang = payMoneyUtil.fenzhang(transaction_id, amount.multiply(bigDecimal1), s2,"课包续费分账"); if (!fenzhang.getCode().equals(500)){ System.err.println("分账失败 原因是:"+fenzhang.getMsg()); } diff --git a/cloud-server-account/src/main/java/com/dsh/account/util/PayMoneyUtil.java b/cloud-server-account/src/main/java/com/dsh/account/util/PayMoneyUtil.java index 7802c17..e6f6192 100644 --- a/cloud-server-account/src/main/java/com/dsh/account/util/PayMoneyUtil.java +++ b/cloud-server-account/src/main/java/com/dsh/account/util/PayMoneyUtil.java @@ -2,6 +2,7 @@ import cn.hutool.core.util.RandomUtil; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayClient; @@ -39,10 +40,7 @@ import org.springframework.util.StringUtils; import javax.annotation.Resource; -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; +import javax.crypto.*; import javax.crypto.spec.SecretKeySpec; import javax.servlet.http.HttpServletRequest; import java.io.*; @@ -55,6 +53,8 @@ import java.security.NoSuchProviderException; import java.security.Security; import java.util.*; + +import static com.dsh.account.util.akeylogin.Md5Util.byteArrayToHexString; /** * 第三方支付工具类 @@ -90,29 +90,45 @@ private String certPath = "/usr/playpai/cert/weixin/apiclient_cert.p12";//微信证书 - +// public static void main(String[] args) { +// Map<String, Object> body = new HashMap<>(); +// body.put("type", "MERCHANT_ID"); +// body.put("account", "1231232121"); +// body.put("amount", "asda"); +// body.put("description", "订单分账"); +// JSONObject jsonObject = new JSONObject(body); +// JSONArray objects = new JSONArray(); +// objects.add(jsonObject); +// System.err.println(objects); +// System.err.println(objects.toJSONString()); +// } /** * 发起分账 * @param order 微信订单号 * @return */ - public ResultUtil fenzhang(String order,BigDecimal amount,String merchantNumber) throws Exception { + public ResultUtil fenzhang(String order,BigDecimal amount,String merchantNumber,String description) throws Exception { Map<String, Object> map = new HashMap<>(); map.put("mch_id", mchId); map.put("appid", appid); String nonce_str = UUIDUtil.getRandomCode(16); + String out_order_no = UUIDUtil.getRandomCode(16); + map.put("out_order_no", out_order_no); map.put("nonce_str", nonce_str); + map.put("transaction_id", order); // 将这个字符串使用json格式拼接起来 Map<String, Object> body = new HashMap<>(); body.put("type", "MERCHANT_ID"); body.put("account", merchantNumber); - body.put("amount", amount); - body.put("description", "订单分账"); + int i = amount.multiply(new BigDecimal("100")).intValue(); + body.put("amount", i); + body.put("description", description); JSONObject jsonObject = new JSONObject(body); - String jsonString = jsonObject.toString(); - map.put("receiver",jsonString); - String s = this.weixinSignature(map); + JSONArray objects = new JSONArray(); + objects.add(jsonObject); + map.put("receivers",objects.toJSONString()); + String s = this.weixinSignature1(map); map.put("sign", s); String url = "https://api.mch.weixin.qq.com/secapi/pay/profitsharing"; //设置请求头 @@ -132,7 +148,7 @@ Map<String, String> map1 = null; String body1 = null; try { - body1 = HttpClientUtil.pushHttpsRequsetXml(url, xmlString.toString(), new HashMap<>(), mchId, certPath, "PKCS12"); + body1 = HttpClientUtil.pushHttpsRequsetXml1(url, xmlString.toString(), new HashMap<>(), mchId, certPath, "PKCS12"); } catch (Exception e) { e.printStackTrace(); } @@ -1454,7 +1470,54 @@ } return null; } - + private String weixinSignature1(Map<String, Object> map) { + try { + Set<Map.Entry<String, Object>> entries = map.entrySet(); + List<Map.Entry<String, Object>> infoIds = new ArrayList<Map.Entry<String, Object>>(entries); + // 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序) + Collections.sort(infoIds, new Comparator<Map.Entry<String, Object>>() { + public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) { + return (o1.getKey()).toString().compareTo(o2.getKey()); + } + }); + // 构造签名键值对的格式 + StringBuilder sb = new StringBuilder(); + for (Map.Entry<String, Object> item : infoIds) { + if (item.getKey() != null || item.getKey() != "") { + String key = item.getKey(); + Object val = item.getValue(); + if (!(val == "" || val == null)) { + sb.append(key + "=" + val + "&"); + } + } + } + sb.append("key=" + key); + String sign = sha256_HMAC(sb.toString(), key).toUpperCase(); + return sign; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + /** + * sha256_HMAC加密 + * @param message 消息 + * @param secret 秘钥 + * @return 加密后字符串 + */ + public String sha256_HMAC(String message, String secret) { + String hash = ""; + try { + Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); + SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256"); + sha256_HMAC.init(secret_key); + byte[] bytes = sha256_HMAC.doFinal(message.getBytes()); + hash = byteArrayToHexString(bytes); + } catch (Exception e) { + System.out.println("Error HmacSHA256 ===========" + e.getMessage()); + } + return hash; + } /** * 微信退款成功后的解密 diff --git a/cloud-server-account/src/main/java/com/dsh/account/util/httpClinet/HttpClientUtil.java b/cloud-server-account/src/main/java/com/dsh/account/util/httpClinet/HttpClientUtil.java index c66d006..098ebbe 100644 --- a/cloud-server-account/src/main/java/com/dsh/account/util/httpClinet/HttpClientUtil.java +++ b/cloud-server-account/src/main/java/com/dsh/account/util/httpClinet/HttpClientUtil.java @@ -219,7 +219,39 @@ httpCline.close(); return content; } - + public static String pushHttpsRequsetXml1(String url, String xml, Map<String, String> header, String certPassword, String certPath, String certType) throws Exception { + HttpPost httpPost = new HttpPost(url); + for (String key : header.keySet()) { + httpPost.setHeader(key, header.get(key)); + } + httpPost.setHeader("Content-Type", "application/xml"); + httpPost.setEntity(new StringEntity(xml, "UTF-8")); + CloseableHttpClient httpCline = initCert1(certPassword, certPath, certType); + CloseableHttpResponse httpResponse = httpCline.execute(httpPost); + String content = null; + if (httpResponse.getStatusLine().getStatusCode() == 200) { + content = EntityUtils.toString(httpResponse.getEntity(), "UTF-8"); + } else { + content = "返回状态码:" + httpResponse.getStatusLine() + "。" + EntityUtils.toString(httpResponse.getEntity()); + } + close(httpResponse); + httpCline.close(); + return content; + } + private static CloseableHttpClient initCert1(String key, String certPath, String certType) throws Exception { + KeyStore keyStore = KeyStore.getInstance(certType); + InputStream inputStream = new FileInputStream(new File(certPath)); + try { + keyStore.load(inputStream, key.toCharArray()); + } finally { + inputStream.close(); + } + SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, key.toCharArray()).build(); + SSLConnectionSocketFactory sslsf = + new SSLConnectionSocketFactory(sslcontext, null, null, + SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); + return HttpClients.custom().setSSLSocketFactory(sslsf).build(); + } /** * 初始化https对象(带证书) @@ -245,6 +277,7 @@ } + /** * 关闭资源 */ diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/controller/CouponController.java b/cloud-server-activity/src/main/java/com/dsh/activity/controller/CouponController.java index 219f9f3..39b6df5 100644 --- a/cloud-server-activity/src/main/java/com/dsh/activity/controller/CouponController.java +++ b/cloud-server-activity/src/main/java/com/dsh/activity/controller/CouponController.java @@ -189,6 +189,17 @@ return null; } } + @ResponseBody + @PostMapping("/coupon/queryUserCouponById") + public Integer queryUserCouponById(@RequestBody Long id) { + try { + Integer couponId = userCouponService.getById(id).getCouponId(); + return couponId; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } @Autowired diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/controller/CompetitionController.java b/cloud-server-competition/src/main/java/com/dsh/competition/controller/CompetitionController.java index db27a44..70acfbd 100644 --- a/cloud-server-competition/src/main/java/com/dsh/competition/controller/CompetitionController.java +++ b/cloud-server-competition/src/main/java/com/dsh/competition/controller/CompetitionController.java @@ -460,7 +460,34 @@ Competition competition = cttService.getById(paymentCompetition.getCompetitionId()); competition.setApplicantsNumber(competition.getApplicantsNumber() + 1); cttService.updateById(competition); + if (competition.getOperatorId()!=null && competition.getOperatorId()!=0){ + // 休眠两分钟后再调用分账接口 避免提示订单正在处理中 + Thread.sleep(120000); + // 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 + String proportionByOperatorId = storeClient.getProportionByOperatorId(competition.getOperatorId()); + String[] split = proportionByOperatorId.split(","); + String s1 = split[0]; + if (!s1.equals("未设置")){ + BigDecimal bigDecimal = new BigDecimal(s1); + // 分账比例 + BigDecimal bigDecimal1 = bigDecimal.divide(new BigDecimal(100)).setScale(2); + // 微信商户号 + String s2 = storeClient.getmerchantNumberByOperatorId(competition.getOperatorId()); + String nonce_str = UUIDUtil.getRandomCode(16); + paymentCompetition.setFenzhangOrderNo(nonce_str); + BigDecimal bigDecimal2 = new BigDecimal(paymentCompetition.getAmount()); + ResultUtil fenzhang = payMoneyUtil.fenzhang(transaction_id, bigDecimal2.multiply(bigDecimal1), s2,nonce_str,"报名赛事分账"); + if (!fenzhang.getCode().equals(200)){ + System.err.println("分账失败 原因是:"+fenzhang.getData()+"-"+fenzhang.getMsg()); + }else{ + paymentCompetition.setFenzhangNo(fenzhang.getData().toString()); + paymentCompetition.setFenzhangAmount(bigDecimal2.multiply(bigDecimal1)); + paymentCompetitionService.updateById(paymentCompetition); + } + } + } } + PrintWriter out = response.getWriter(); out.write(result); @@ -812,10 +839,10 @@ // 微信商户号 String s2 =storeClient.getmerchantNumberByOperatorId(competition.getOperatorId()); ResultUtil resultUtil = payMoneyUtil.fenzhangRefund(paymentCompetition.getFenzhangNo(), paymentCompetition.getFenzhangAmount(), s2, randomCode, randomCode1); - if (!resultUtil.getCode().equals(500)){ + if (!resultUtil.getCode().equals(200)){ System.err.println("分账回退失败 原因是:"+resultUtil.getMsg()); }else{ - paymentCompetition.setFenzhangRefundNo(resultUtil.getMsg()); + paymentCompetition.setFenzhangRefundNo(resultUtil.getData().toString()); paymentCompetitionService.updateById(paymentCompetition); } diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/feignclient/other/StoreClient.java b/cloud-server-competition/src/main/java/com/dsh/competition/feignclient/other/StoreClient.java index 8fe6d08..0b66da1 100644 --- a/cloud-server-competition/src/main/java/com/dsh/competition/feignclient/other/StoreClient.java +++ b/cloud-server-competition/src/main/java/com/dsh/competition/feignclient/other/StoreClient.java @@ -3,6 +3,7 @@ import com.dsh.competition.entity.OperatorUser; import com.dsh.competition.feignclient.other.model.Store; import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import java.util.List; @@ -17,8 +18,8 @@ * 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 * @return */ - @PostMapping("/base/getProportionByOperatorId") - String getProportionByOperatorId(Integer id); + @PostMapping("/base/getProportionByOperatorId/{id}") + String getProportionByOperatorId(@PathVariable("id") Integer id); /** * 根据运营商id获取对应运营商商户号 * @return @@ -26,8 +27,8 @@ @PostMapping("/base/getSMIDByOperatorId") String getSMIDByOperatorId(Integer id); // 根据运营商id获取微信商户号 - @PostMapping("/base/getmerchantNumberByOperatorId") - String getmerchantNumberByOperatorId(Integer id); + @PostMapping("/base/getmerchantNumberByOperatorId/{id}") + String getmerchantNumberByOperatorId(@PathVariable("id")Integer id); /** * 根据名称模糊搜索门店 * diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/CompetitionServiceImpl.java b/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/CompetitionServiceImpl.java index 413b0f5..54ef1fc 100644 --- a/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/CompetitionServiceImpl.java +++ b/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/CompetitionServiceImpl.java @@ -420,31 +420,7 @@ Competition competition = cttService.getById(paymentCompetition.getCompetitionId()); competition.setApplicantsNumber(competition.getApplicantsNumber() + 1); cttService.updateById(competition); - if (operatorId!=null && operatorId!=0){ - // 休眠两分钟后再调用分账接口 避免提示订单正在处理中 - Thread.sleep(120000); - // 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 - String proportionByOperatorId = storeClient.getProportionByOperatorId(operatorId); - String[] split = proportionByOperatorId.split(","); - String s1 = split[0]; - if (!s1.equals("未设置")){ - BigDecimal bigDecimal = new BigDecimal(s1); - // 分账比例 - BigDecimal bigDecimal1 = bigDecimal.divide(new BigDecimal(100)).setScale(2); - // 微信商户号 - String s2 = storeClient.getmerchantNumberByOperatorId(operatorId); - String nonce_str = UUIDUtil.getRandomCode(16); - paymentCompetition.setFenzhangOrderNo(nonce_str); - ResultUtil fenzhang = payMoneyUtil.fenzhang(transaction_id, money.multiply(bigDecimal1), s2,nonce_str); - if (!fenzhang.getCode().equals(500)){ - System.err.println("分账失败 原因是:"+fenzhang.getMsg()); - }else{ - paymentCompetition.setFenzhangNo(fenzhang.getMsg()); - paymentCompetition.setFenzhangAmount(money.multiply(bigDecimal1)); - paymentCompetitionService.updateById(paymentCompetition); - } - } - } + break; } if ("USERPAYING".equals(s) || "NOTPAY".equals(s)) { diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/PaymentCompetitionServiceImpl.java b/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/PaymentCompetitionServiceImpl.java index 1b12afa..81b6967 100644 --- a/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/PaymentCompetitionServiceImpl.java +++ b/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/PaymentCompetitionServiceImpl.java @@ -258,10 +258,10 @@ // 微信商户号 String s2 =storeClient.getmerchantNumberByOperatorId(competition.getOperatorId()); ResultUtil resultUtil = payMoneyUtil.fenzhangRefund(paymentCompetition.getFenzhangNo(), paymentCompetition.getFenzhangAmount(), s2, randomCode, randomCode1); - if (!resultUtil.getCode().equals(500)){ - System.err.println("分账回退失败 原因是:"+resultUtil.getMsg()); + if (!resultUtil.getCode().equals(200)){ + System.err.println("分账回退失败 原因是:"+resultUtil.getData().toString()); }else{ - paymentCompetition.setFenzhangRefundNo(resultUtil.getMsg()); + paymentCompetition.setFenzhangRefundNo(resultUtil.getData().toString()); paymentCompetitionMapper.updateById(paymentCompetition); } diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/util/PayMoneyUtil.java b/cloud-server-competition/src/main/java/com/dsh/competition/util/PayMoneyUtil.java index ec1574d..4ed40c1 100644 --- a/cloud-server-competition/src/main/java/com/dsh/competition/util/PayMoneyUtil.java +++ b/cloud-server-competition/src/main/java/com/dsh/competition/util/PayMoneyUtil.java @@ -1,6 +1,7 @@ package com.dsh.competition.util; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayClient; @@ -21,10 +22,7 @@ import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; +import javax.crypto.*; import javax.crypto.spec.SecretKeySpec; import javax.servlet.http.HttpServletRequest; import java.io.*; @@ -36,6 +34,8 @@ import java.security.NoSuchProviderException; import java.security.Security; import java.util.*; + +import static com.dsh.competition.util.akeylogin.Md5Util.byteArrayToHexString; /** * 第三方支付工具类 @@ -510,22 +510,27 @@ * @param order 微信订单号 * @return */ - public ResultUtil fenzhang(String order,BigDecimal amount,String merchantNumber,String nonceStr ) throws Exception { + public ResultUtil fenzhang(String order,BigDecimal amount,String merchantNumber,String nonceStr,String description) throws Exception { Map<String, Object> map = new HashMap<>(); map.put("mch_id", mchId); map.put("appid", appid); map.put("nonce_str", nonceStr); map.put("transaction_id", order); + String out_order_no = UUIDUtil.getRandomCode(16); + map.put("out_order_no", out_order_no); // 将这个字符串使用json格式拼接起来 Map<String, Object> body = new HashMap<>(); + // 将这个字符串使用json格式拼接起来 body.put("type", "MERCHANT_ID"); body.put("account", merchantNumber); - body.put("amount", amount); - body.put("description", "订单分账"); + int i = amount.multiply(new BigDecimal("100")).intValue(); + body.put("amount", i); + body.put("description", description); JSONObject jsonObject = new JSONObject(body); - String jsonString = jsonObject.toString(); - map.put("receiver",jsonString); - String s = this.weixinSignature(map); + JSONArray objects = new JSONArray(); + objects.add(jsonObject); + map.put("receivers",objects.toJSONString()); + String s = this.weixinSignature1(map); map.put("sign", s); String url = "https://api.mch.weixin.qq.com/secapi/pay/profitsharing"; //设置请求头 @@ -545,7 +550,7 @@ Map<String, String> map1 = null; String body1 = null; try { - body1 = HttpClientUtil.pushHttpsRequsetXml(url, xmlString.toString(), new HashMap<>(), mchId, certPath, "PKCS12"); + body1 = HttpClientUtil.pushHttpsRequsetXml1(url, xmlString.toString(), new HashMap<>(), mchId, certPath, "PKCS12"); } catch (Exception e) { e.printStackTrace(); } @@ -832,9 +837,10 @@ map.put("out_return_no", fenzhangRefundNo); map.put("return_account_type", "MERCHANT_ID"); map.put("return_account", merchantNumber); - map.put("return_amount", amount); - map.put("description", "用户退款"); - String s = this.weixinSignature(map); + BigDecimal multiply = amount.multiply(new BigDecimal("100")); + map.put("return_amount", multiply.intValue()); + map.put("description", "用户报名赛事退款"); + String s = this.weixinSignature1(map); map.put("sign", s); String url = "https://api.mch.weixin.qq.com/secapi/pay/profitsharingreturn"; //设置请求头 @@ -854,7 +860,7 @@ Map<String, String> map1 = null; String body1 = null; try { - body1 = HttpClientUtil.pushHttpsRequsetXml(url, xmlString.toString(), new HashMap<>(), mchId, certPath, "PKCS12"); + body1 = HttpClientUtil.pushHttpsRequsetXml1(url, xmlString.toString(), new HashMap<>(), mchId, certPath, "PKCS12"); } catch (Exception e) { e.printStackTrace(); } @@ -1278,7 +1284,54 @@ return sb.toString(); } - + private String weixinSignature1(Map<String, Object> map) { + try { + Set<Map.Entry<String, Object>> entries = map.entrySet(); + List<Map.Entry<String, Object>> infoIds = new ArrayList<Map.Entry<String, Object>>(entries); + // 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序) + Collections.sort(infoIds, new Comparator<Map.Entry<String, Object>>() { + public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) { + return (o1.getKey()).toString().compareTo(o2.getKey()); + } + }); + // 构造签名键值对的格式 + StringBuilder sb = new StringBuilder(); + for (Map.Entry<String, Object> item : infoIds) { + if (item.getKey() != null || item.getKey() != "") { + String key = item.getKey(); + Object val = item.getValue(); + if (!(val == "" || val == null)) { + sb.append(key + "=" + val + "&"); + } + } + } + sb.append("key=" + key); + String sign = sha256_HMAC(sb.toString(), key).toUpperCase(); + return sign; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + /** + * sha256_HMAC加密 + * @param message 消息 + * @param secret 秘钥 + * @return 加密后字符串 + */ + public String sha256_HMAC(String message, String secret) { + String hash = ""; + try { + Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); + SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256"); + sha256_HMAC.init(secret_key); + byte[] bytes = sha256_HMAC.doFinal(message.getBytes()); + hash = byteArrayToHexString(bytes); + } catch (Exception e) { + System.out.println("Error HmacSHA256 ===========" + e.getMessage()); + } + return hash; + } /** * 微信下单的签名算法 * diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/util/httpClinet/HttpClientUtil.java b/cloud-server-competition/src/main/java/com/dsh/competition/util/httpClinet/HttpClientUtil.java index 97b9b6a..f797a93 100644 --- a/cloud-server-competition/src/main/java/com/dsh/competition/util/httpClinet/HttpClientUtil.java +++ b/cloud-server-competition/src/main/java/com/dsh/competition/util/httpClinet/HttpClientUtil.java @@ -218,7 +218,25 @@ httpCline.close(); return content; } - + public static String pushHttpsRequsetXml1(String url, String xml, Map<String, String> header, String certPassword, String certPath, String certType) throws Exception { + HttpPost httpPost = new HttpPost(url); + for (String key : header.keySet()) { + httpPost.setHeader(key, header.get(key)); + } + httpPost.setHeader("Content-Type", "application/xml"); + httpPost.setEntity(new StringEntity(xml, "UTF-8")); + CloseableHttpClient httpCline = initCert1(certPassword, certPath, certType); + CloseableHttpResponse httpResponse = httpCline.execute(httpPost); + String content = null; + if (httpResponse.getStatusLine().getStatusCode() == 200) { + content = EntityUtils.toString(httpResponse.getEntity(), "UTF-8"); + } else { + content = "返回状态码:" + httpResponse.getStatusLine() + "。" + EntityUtils.toString(httpResponse.getEntity()); + } + close(httpResponse); + httpCline.close(); + return content; + } /** * 初始化https对象(带证书) @@ -242,6 +260,28 @@ SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); return HttpClients.custom().setSSLSocketFactory(sslsf).build(); } + /** + * 初始化https对象(带证书) + * + * @param key 证书密码 + * @param certPath 证书路径 + * @param certType 证书类型 + * @throws Exception + */ + private static CloseableHttpClient initCert1(String key, String certPath, String certType) throws Exception { + KeyStore keyStore = KeyStore.getInstance(certType); + InputStream inputStream = new FileInputStream(new File(certPath)); + try { + keyStore.load(inputStream, key.toCharArray()); + } finally { + inputStream.close(); + } + SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, key.toCharArray()).build(); + SSLConnectionSocketFactory sslsf = + new SSLConnectionSocketFactory(sslcontext, null, null, + SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); + return HttpClients.custom().setSSLSocketFactory(sslsf).build(); + } /** diff --git a/cloud-server-course/src/main/java/com/dsh/course/controller/CoursePackagePaymentController.java b/cloud-server-course/src/main/java/com/dsh/course/controller/CoursePackagePaymentController.java index effc10e..d18b5ab 100644 --- a/cloud-server-course/src/main/java/com/dsh/course/controller/CoursePackagePaymentController.java +++ b/cloud-server-course/src/main/java/com/dsh/course/controller/CoursePackagePaymentController.java @@ -1173,10 +1173,11 @@ public ResultUtil continuationOperation(ClasspaymentRequest request) { try { Integer userId = tokenUtil.getUserIdFormRedis(); + System.err.println("续课参数"+request); if (null == userId) { return ResultUtil.tokenErr(); } - Integer couponId = request.getConponId(); + Long couponId = request.getConponId(); if (couponId == null || couponId == 0) { request.setConponId(null); } diff --git a/cloud-server-course/src/main/java/com/dsh/course/feignclient/activity/CouponClient.java b/cloud-server-course/src/main/java/com/dsh/course/feignclient/activity/CouponClient.java index a724d7c..4b535a7 100644 --- a/cloud-server-course/src/main/java/com/dsh/course/feignclient/activity/CouponClient.java +++ b/cloud-server-course/src/main/java/com/dsh/course/feignclient/activity/CouponClient.java @@ -24,6 +24,14 @@ */ @PostMapping("/coupon/queryCouponById") Coupon queryCouponById(Integer id); + /** + * 根据领取优惠券记录id获取优惠券 + * + * @param id + * @return + */ + @PostMapping("/coupon/queryUserCouponById") + Integer queryUserCouponById(Long id); @PostMapping("/base/userConpon/queryCouponRules") Map<String, Object> getCouponRules(@RequestBody Integer couponId); diff --git a/cloud-server-course/src/main/java/com/dsh/course/feignclient/other/StoreClient.java b/cloud-server-course/src/main/java/com/dsh/course/feignclient/other/StoreClient.java index fb0e5d4..ff8a9cc 100644 --- a/cloud-server-course/src/main/java/com/dsh/course/feignclient/other/StoreClient.java +++ b/cloud-server-course/src/main/java/com/dsh/course/feignclient/other/StoreClient.java @@ -4,6 +4,7 @@ import com.dsh.course.feignclient.other.model.GetDistanceVo; import com.dsh.course.feignclient.other.model.Store; import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -19,8 +20,8 @@ * 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 * @return */ - @PostMapping("/base/getProportionByOperatorId") - String getProportionByOperatorId(Integer id); + @PostMapping("/base/getProportionByOperatorId/{id}") + String getProportionByOperatorId(@PathVariable("id")Integer id); /** * 根据运营商id获取对应运营商商户号 @@ -29,8 +30,8 @@ @PostMapping("/base/getSMIDByOperatorId") String getSMIDByOperatorId(Integer id); // 根据运营商id获取微信商户号 - @PostMapping("/base/getmerchantNumberByOperatorId") - String getmerchantNumberByOperatorId(Integer id); + @PostMapping("/base/getmerchantNumberByOperatorId/{id}") + String getmerchantNumberByOperatorId(@PathVariable("id") Integer id); /** * 根据名称模糊搜索门店 * diff --git a/cloud-server-course/src/main/java/com/dsh/course/model/vo/request/ClasspaymentRequest.java b/cloud-server-course/src/main/java/com/dsh/course/model/vo/request/ClasspaymentRequest.java index 9f2495d..977b4eb 100644 --- a/cloud-server-course/src/main/java/com/dsh/course/model/vo/request/ClasspaymentRequest.java +++ b/cloud-server-course/src/main/java/com/dsh/course/model/vo/request/ClasspaymentRequest.java @@ -20,13 +20,17 @@ private Integer useConpon; @ApiModelProperty(value = "优惠券Id") - private Integer conponId; + private Long conponId; @ApiModelProperty(value = "支付记录id") private Long coursePayId; @ApiModelProperty(value = "课时数") private Integer courseHoursNum; + @ApiModelProperty(value = "支付价格") + private Double cash; + @ApiModelProperty(value = "玩湃币支付价格") + private Integer playPaiCoin; } diff --git a/cloud-server-course/src/main/java/com/dsh/course/service/TCoursePackagePaymentService.java b/cloud-server-course/src/main/java/com/dsh/course/service/TCoursePackagePaymentService.java index 7f5910b..4f1b620 100644 --- a/cloud-server-course/src/main/java/com/dsh/course/service/TCoursePackagePaymentService.java +++ b/cloud-server-course/src/main/java/com/dsh/course/service/TCoursePackagePaymentService.java @@ -95,7 +95,7 @@ */ List<RecordAppoint> obtainStuClassDetails(Integer stuId, Integer appUserId, Integer pageNum); - ResultUtil insertVipPaymentCallback(String code, String orderNumber); + ResultUtil insertVipPaymentCallback(String code, String orderNumber) throws Exception; List<BillingRequest> queryAmountDatas(Integer appUserId, String monthStart, String monthEnd); diff --git a/cloud-server-course/src/main/java/com/dsh/course/service/TCoursePackageService.java b/cloud-server-course/src/main/java/com/dsh/course/service/TCoursePackageService.java index 779d552..4b76d7b 100644 --- a/cloud-server-course/src/main/java/com/dsh/course/service/TCoursePackageService.java +++ b/cloud-server-course/src/main/java/com/dsh/course/service/TCoursePackageService.java @@ -109,7 +109,7 @@ * @param trade_no * @return */ - ResultUtil paymentCourseCallback(String code, String trade_no, String attach) throws AlipayApiException; + ResultUtil paymentCourseCallback(String code, String trade_no, String attach) throws Exception; diff --git a/cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackagePaymentServiceImpl.java b/cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackagePaymentServiceImpl.java index 52544e2..121df37 100644 --- a/cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackagePaymentServiceImpl.java +++ b/cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackagePaymentServiceImpl.java @@ -798,11 +798,13 @@ @Override public ResultUtil ContinuationOrpaymentCourse(Integer userId, ClasspaymentRequest request) { + System.err.println("请求参数"+request); AppUser appUser = appuClient.queryAppUser(userId); CoursePackageOrder coursePackageOrder = coursePackageOrderService.getById(request.getCoursePayId()); + System.err.println("上次支付记录"+coursePackageOrder); String code = ""; - BigDecimal money = coursePackageOrder.getCashPayment(); - Integer wpGold = coursePackageOrder.getPlayPaiCoin(); + BigDecimal money = BigDecimal.valueOf(request.getCash()); + Integer wpGold = request.getPlayPaiCoin(); if (coursePackageOrder.getPayStatus() == 1) { code = coursePackageOrder.getCode(); coursePackageOrder.setPayType(request.getPayType()); @@ -815,11 +817,13 @@ CoursePackagePaymentConfig paymentConfig = cpConfigMapper.selectOne(new QueryWrapper<CoursePackagePaymentConfig>() .eq("coursePackageId", request.getLessonId()) .eq("classHours", request.getCourseHoursNum())); + System.err.println("价格配置"+paymentConfig); TCoursePackageDiscount coursePackageDiscount = tcpdMapper.selectOne(new QueryWrapper<TCoursePackageDiscount>() .eq("coursePackageId", request.getLessonId()) .eq("type", 2) .eq("auditStatus", 1) .eq("coursePackagePaymentConfigId", paymentConfig.getCoursePackageId())); + System.err.println("折扣"+coursePackageDiscount); if (ToolUtil.isNotEmpty(coursePackageDiscount)) { String content = coursePackageDiscount.getContent(); JSONObject jsonObject = JSON.parseObject(content); @@ -837,7 +841,7 @@ newPayment.setAppUserId(appUser.getId()); newPayment.setStudentIds(request.getStuId().toString()); newPayment.setCoursePackageId(request.getLessonId()); - newPayment.setClassHours(coursePackageOrder.getClassHours()); + newPayment.setClassHours(request.getCourseHoursNum()); newPayment.setOriginalPrice(coursePackageOrder.getOriginalPrice()); if (request.getUseConpon() == 1) { newPayment.setUserCouponId(Long.valueOf(request.getUseConpon())); @@ -848,27 +852,37 @@ newPayment.setPayType(request.getPayType()); newPayment.setState(1); newPayment.setInsertTime(new Date()); + if (request.getCash()!=null && request.getCash()!=0){ + newPayment.setCashPayment(BigDecimal.valueOf(request.getCash())); + } + newPayment.setPlayPaiCoin(request.getPlayPaiCoin()); newPayment.setOrderType(1); + newPayment.setUserCouponId(request.getConponId()); coursePackageOrderService.save(newPayment); code = newPayment.getCode(); } + System.err.println("选择"); switch (request.getPayType()) { case 1: if (request.getUseConpon() == 1) { - Coupon coupon = client.queryCouponById(request.getConponId()); - if (coupon.getType() == 1) { - Map<String, Object> couponRules = client.getCouponRules(coupon.getId()); - Double conditionalAmount = (Double) couponRules.get("conditionalAmount"); - Double deductionAmount = (Double) couponRules.get("deductionAmount"); - if (money.compareTo(BigDecimal.valueOf(conditionalAmount)) >= 0) { - money = BigDecimal.valueOf(deductionAmount); - } - } - if (coupon.getType() == 2) { - Map<String, Object> couponRules = client.getCouponRules(coupon.getId()); - Object amount = couponRules.get("deductionAmount"); - money = BigDecimal.valueOf((Double) amount); - } + Integer coupon1 = client.queryUserCouponById(request.getConponId()); + System.err.println("优惠券id"+coupon1); + Coupon coupon = client.queryCouponById(coupon1); + System.err.println("优惠券信息"+coupon); +// if (coupon.getType() == 1) { +// Map<String, Object> couponRules = client.getCouponRules(coupon.getId()); +// Double conditionalAmount = (Double) couponRules.get("conditionalAmount"); +// Double deductionAmount = (Double) couponRules.get("deductionAmount"); +// if (money.compareTo(BigDecimal.valueOf(conditionalAmount)) >= 0) { +// money = BigDecimal.valueOf(deductionAmount); +// } +// } +// if (coupon.getType() == 2) { +// Map<String, Object> couponRules = client.getCouponRules(coupon.getId()); +// System.err.println("优惠券规则"+couponRules); +// Object amount = couponRules.get("conditionalAmount"); +// money = BigDecimal.valueOf((Double) amount); +// } } try { return WeChatPayment(code, money,request.getLessonId()); @@ -877,7 +891,8 @@ } case 2: if (request.getUseConpon() == 1) { - Coupon coupon = client.queryCouponById(request.getConponId()); + Integer coupon1 = client.queryUserCouponById(request.getConponId()); + Coupon coupon = client.queryCouponById(coupon1); if (coupon.getType() == 1) { Map<String, Object> couponRules = client.getCouponRules(coupon.getId()); Double conditionalAmount = (Double) couponRules.get("conditionalAmount"); @@ -892,8 +907,10 @@ money = BigDecimal.valueOf((Double) amount); } } + return AlipayPayment(code, money); case 3: + System.err.println("选择"); PlaypaiGoldPayment(appUser, code, wpGold); break; default: @@ -903,9 +920,14 @@ } public ResultUtil WeChatPayment(String code, BigDecimal request,Integer coursePackageId) throws Exception { + System.err.println("code-------------"+code); + System.err.println("request---------------"+request); + System.err.println("coursePackageId-------------"+coursePackageId); TCoursePackage byId = coursePackageService.getById(coursePackageId); + System.err.println("课包"+coursePackageId); Integer storeId = byId.getStoreId(); Store store = storeClient.queryStoreById(storeId); + System.err.println("门店查询"+store); // 是否分账 0否1是 int isFenZhang= 1; String merchantNumber = ""; @@ -913,6 +935,7 @@ // 平台 isFenZhang = 0; } + System.err.println("拉起支付"); ResultUtil weixinpay = payMoneyUtil.weixinpay("课包续费"+"-"+isFenZhang, "", code, request.toString(), "/base/coursePackage/wechatRegisteredCoursesCallback", "APP", ""); if (weixinpay.getCode() == 200) { @@ -964,27 +987,7 @@ .eq("classHours", coursePackageOrder1.getClassHours()) ); coursePackageService.addCoursePackageOrderStudent(coursePackageOrder1.getId(), coursePackagePaymentConfig); - if (store.getOperatorId()!=null && store.getOperatorId()!=0){ - // 休眠两分钟后再调用分账接口 避免提示订单正在处理中 - Thread.sleep(120000); - // 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 - String proportionByOperatorId = storeClient.getProportionByOperatorId(store.getOperatorId()); - String[] split = proportionByOperatorId.split(","); - String s1 = split[0]; - if (!s1.equals("未设置")){ - BigDecimal bigDecimal = new BigDecimal(s1); - // 分账比例 - BigDecimal bigDecimal1 = bigDecimal.divide(new BigDecimal(100)).setScale(2); - // 微信商户号 - String s2 = storeClient.getmerchantNumberByOperatorId(store.getOperatorId()); - String nonce_str = UUIDUtil.getRandomCode(16); - ResultUtil fenzhang = payMoneyUtil.fenzhang(transaction_id, request.multiply(bigDecimal1), s2,nonce_str); - if (!fenzhang.getCode().equals(500)){ - System.err.println("分账失败 原因是:"+fenzhang.getMsg()); - } - } - } break; } if ("USERPAYING".equals(s) || "NOTPAY".equals(s)) { @@ -1155,17 +1158,31 @@ } public ResultUtil PlaypaiGoldPayment(AppUser appUser, String code, Integer wpGold) { - TCoursePackagePayment packagePayment = this.baseMapper.selectOne(new QueryWrapper<TCoursePackagePayment>() + System.err.println("进入玩湃支付"); + CoursePackageOrder packagePayment = coursePackageOrderService.getOne(new QueryWrapper<CoursePackageOrder>() .eq("code", code)); + System.err.println("支付"+packagePayment); + System.err.println("用户信息"+appUser); + System.err.println("code"+code); + System.err.println("wpGold"+wpGold); if (appUser.getPlayPaiCoins() < wpGold) { return ResultUtil.error("玩湃币不足!"); } packagePayment.setPayStatus(2); packagePayment.setPayUserId(appUser.getId()); packagePayment.setPlayPaiCoin(wpGold); - this.baseMapper.updateById(packagePayment); + System.err.println("扣去玩湃币"); + try { + System.err.println("修改"); + boolean b = coursePackageOrderService.updateById(packagePayment); + }catch (Exception e){ + System.err.println("报错"+e.getCause()); + System.err.println("报错"+e.getMessage()); + e.printStackTrace(); + } appUser.setPlayPaiCoins(ToolUtil.isNotEmpty(appUser.getPlayPaiCoins()) ? appUser.getPlayPaiCoins() - wpGold : wpGold); + appuClient.updateAppUser(appUser); return ResultUtil.success(); } @@ -1316,7 +1333,7 @@ } @Override - public ResultUtil insertVipPaymentCallback(String code, String orderNumber) { + public ResultUtil insertVipPaymentCallback(String code, String orderNumber) throws Exception { CoursePackageOrder coursePackageOrder1 = coursePackageOrderService.getOne(new QueryWrapper<CoursePackageOrder>() .eq("code", code).eq("state", 1)); if (coursePackageOrder1.getPayStatus() == 2) { @@ -1332,10 +1349,30 @@ .eq("classHours", coursePackageOrder1.getClassHours()) ); coursePackageService.addCoursePackageOrderStudent(coursePackageOrder1.getId(), coursePackagePaymentConfig); - try { - coursePackageService.moneyOut(orderNumber,orderNumber,code); - } catch (AlipayApiException e) { - e.printStackTrace(); + TCoursePackage byId = coursePackageService.getById(coursePackageOrder1.getCoursePackageId()); + Integer storeId = byId.getStoreId(); + Store store = storeClient.queryStoreById(storeId); + + if (store.getOperatorId()!=null && store.getOperatorId()!=0){ + // 休眠两分钟后再调用分账接口 避免提示订单正在处理中 + Thread.sleep(120000); + // 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 + String proportionByOperatorId = storeClient.getProportionByOperatorId(store.getOperatorId()); + String[] split = proportionByOperatorId.split(","); + String s1 = split[0]; + if (!s1.equals("未设置")){ + BigDecimal bigDecimal = new BigDecimal(s1); + // 分账比例 + BigDecimal bigDecimal1 = bigDecimal.divide(new BigDecimal(100)).setScale(2); + // 微信商户号 + String s2 = storeClient.getmerchantNumberByOperatorId(store.getOperatorId()); + String nonce_str = UUIDUtil.getRandomCode(16); + + ResultUtil fenzhang = payMoneyUtil.fenzhang(orderNumber, coursePackageOrder1.getCashPayment().multiply(bigDecimal1), s2,nonce_str); + if (!fenzhang.getCode().equals(200)){ + System.err.println("分账失败 原因是:"+fenzhang.getData()); + } + } } return ResultUtil.success(); } diff --git a/cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackageServiceImpl.java b/cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackageServiceImpl.java index 6a4790d..2404704 100644 --- a/cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackageServiceImpl.java +++ b/cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackageServiceImpl.java @@ -997,31 +997,7 @@ coursePackageOrderService.updateById(coursePackageOrder1); //修改课时有效期 addCoursePackageOrderStudent(coursePackageOrder1.getId(), coursePackagePaymentConfig); - if (store.getOperatorId()!=null && store.getOperatorId()!=0){ - // 休眠两分钟后再调用分账接口 避免提示订单正在处理中 - Thread.sleep(120000); - // 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 - String proportionByOperatorId = storeClient.getProportionByOperatorId(store.getOperatorId()); - String[] split = proportionByOperatorId.split(","); - String s1 = split[0]; - if (!s1.equals("未设置")){ - BigDecimal bigDecimal = new BigDecimal(s1); - // 分账比例 - BigDecimal bigDecimal1 = bigDecimal.divide(new BigDecimal(100)).setScale(2); - // 微信商户号 - String s2 = storeClient.getmerchantNumberByOperatorId(store.getOperatorId()); - BigDecimal bigDecimal2 = new BigDecimal(paymentPrice); - String nonce_str = UUIDUtil.getRandomCode(16); - ResultUtil fenzhang = payMoneyUtil.fenzhang(transaction_id, bigDecimal2.multiply(bigDecimal1), s2,nonce_str); - if (!fenzhang.getCode().equals(500)){ - System.err.println("分账失败 原因是:"+fenzhang.getMsg()); - }else{ - coursePackageOrder1.setFenzhangNo(fenzhang.getMsg()); - coursePackageOrder1.setFenzhangOrderNo(nonce_str); - coursePackageOrderService.updateById(coursePackageOrder1); - } - } - } + @@ -1363,7 +1339,7 @@ * @return */ @Override - public ResultUtil paymentCourseCallback(String code, String trade_no, String attach) throws AlipayApiException { + public ResultUtil paymentCourseCallback(String code, String trade_no, String attach) throws Exception { CoursePackageOrder coursePackageOrder1 = coursePackageOrderService.getOne(new QueryWrapper<CoursePackageOrder>() .eq("code", code).eq("state", 1)); if (coursePackageOrder1.getPayStatus() == 2) { @@ -1376,7 +1352,33 @@ CoursePackagePaymentConfig coursePackagePaymentConfig = coursePackagePaymentConfigService.getById(attach); addCoursePackageOrderStudent(coursePackageOrder1.getId(), coursePackagePaymentConfig); - moneyOut(trade_no,trade_no,code); + TCoursePackage byId = coursePackageService.getById(coursePackageOrder1.getCoursePackageId()); + Store store = storeClient.queryStoreById(byId.getStoreId()); +// moneyOut(trade_no,trade_no,code); + if (store.getOperatorId()!=null && store.getOperatorId()!=0){ + // 休眠两分钟后再调用分账接口 避免提示订单正在处理中 + Thread.sleep(120000); + // 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 + String proportionByOperatorId = storeClient.getProportionByOperatorId(store.getOperatorId()); + String[] split = proportionByOperatorId.split(","); + String s1 = split[0]; + if (!s1.equals("未设置")){ + BigDecimal bigDecimal = new BigDecimal(s1); + // 分账比例 + BigDecimal bigDecimal1 = bigDecimal.divide(new BigDecimal(100)).setScale(2); + // 微信商户号 + String s2 = storeClient.getmerchantNumberByOperatorId(store.getOperatorId()); + String nonce_str = UUIDUtil.getRandomCode(16); + ResultUtil fenzhang = payMoneyUtil.fenzhang(trade_no, coursePackageOrder1.getCashPayment().multiply(bigDecimal1), s2,nonce_str); + if (!fenzhang.getCode().equals(200)){ + System.err.println("分账失败 原因是:"+fenzhang.getData().toString()); + }else{ + coursePackageOrder1.setFenzhangNo(fenzhang.getData().toString()); + coursePackageOrder1.setFenzhangOrderNo(nonce_str); + coursePackageOrderService.updateById(coursePackageOrder1); + } + } + } return ResultUtil.success(); } diff --git a/cloud-server-course/src/main/java/com/dsh/course/util/PayMoneyUtil.java b/cloud-server-course/src/main/java/com/dsh/course/util/PayMoneyUtil.java index 8756908..a8021ef 100644 --- a/cloud-server-course/src/main/java/com/dsh/course/util/PayMoneyUtil.java +++ b/cloud-server-course/src/main/java/com/dsh/course/util/PayMoneyUtil.java @@ -1,6 +1,7 @@ package com.dsh.course.util; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayClient; @@ -22,10 +23,7 @@ import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; +import javax.crypto.*; import javax.crypto.spec.SecretKeySpec; import javax.servlet.http.HttpServletRequest; import java.io.*; @@ -38,6 +36,8 @@ import java.security.NoSuchProviderException; import java.security.Security; import java.util.*; + +import static com.dsh.course.util.akeylogin.Md5Util.byteArrayToHexString; /** * 第三方支付工具类 @@ -495,6 +495,8 @@ return ResultUtil.error(map1.get("return_msg"), new JSONObject()); } } + + /** * 发起分账 * @param order 微信订单号 @@ -506,16 +508,20 @@ map.put("appid", appid); map.put("nonce_str", nonceStr); map.put("transaction_id", order); + String out_order_no = UUIDUtil.getRandomCode(16); + map.put("out_order_no", out_order_no); // 将这个字符串使用json格式拼接起来 Map<String, Object> body = new HashMap<>(); body.put("type", "MERCHANT_ID"); body.put("account", merchantNumber); - body.put("amount", amount); - body.put("description", "订单分账"); + int i = amount.multiply(new BigDecimal("100")).intValue(); + body.put("amount", i); + body.put("description", "购买课包分账"); JSONObject jsonObject = new JSONObject(body); - String jsonString = jsonObject.toString(); - map.put("receiver",jsonString); - String s = this.weixinSignature(map); + JSONArray objects = new JSONArray(); + objects.add(jsonObject); + map.put("receivers",objects.toJSONString()); + String s = this.weixinSignature1(map); map.put("sign", s); String url = "https://api.mch.weixin.qq.com/secapi/pay/profitsharing"; //设置请求头 @@ -535,7 +541,7 @@ Map<String, String> map1 = null; String body1 = null; try { - body1 = HttpClientUtil.pushHttpsRequsetXml(url, xmlString.toString(), new HashMap<>(), mchId, certPath, "PKCS12"); + body1 = HttpClientUtil.pushHttpsRequsetXml1(url, xmlString.toString(), new HashMap<>(), mchId, certPath, "PKCS12"); } catch (Exception e) { e.printStackTrace(); } @@ -554,7 +560,7 @@ if ("SUCCESS".equals(return_code)) { String result_code = map1.get("result_code"); if ("SUCCESS".equals(result_code)) { - return ResultUtil.success(); + return ResultUtil.success(map1.get("order_id")); } else { // System.err.println(map1.get("err_code_des")); return ResultUtil.error(map1.get("err_code_des")); @@ -1237,7 +1243,54 @@ } return null; } - + private String weixinSignature1(Map<String, Object> map) { + try { + Set<Map.Entry<String, Object>> entries = map.entrySet(); + List<Map.Entry<String, Object>> infoIds = new ArrayList<Map.Entry<String, Object>>(entries); + // 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序) + Collections.sort(infoIds, new Comparator<Map.Entry<String, Object>>() { + public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) { + return (o1.getKey()).toString().compareTo(o2.getKey()); + } + }); + // 构造签名键值对的格式 + StringBuilder sb = new StringBuilder(); + for (Map.Entry<String, Object> item : infoIds) { + if (item.getKey() != null || item.getKey() != "") { + String key = item.getKey(); + Object val = item.getValue(); + if (!(val == "" || val == null)) { + sb.append(key + "=" + val + "&"); + } + } + } + sb.append("key=" + key); + String sign = sha256_HMAC(sb.toString(), key).toUpperCase(); + return sign; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + /** + * sha256_HMAC加密 + * @param message 消息 + * @param secret 秘钥 + * @return 加密后字符串 + */ + public String sha256_HMAC(String message, String secret) { + String hash = ""; + try { + Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); + SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256"); + sha256_HMAC.init(secret_key); + byte[] bytes = sha256_HMAC.doFinal(message.getBytes()); + hash = byteArrayToHexString(bytes); + } catch (Exception e) { + System.out.println("Error HmacSHA256 ===========" + e.getMessage()); + } + return hash; + } /** * 微信下单的签名算法 diff --git a/cloud-server-course/src/main/java/com/dsh/course/util/httpClinet/HttpClientUtil.java b/cloud-server-course/src/main/java/com/dsh/course/util/httpClinet/HttpClientUtil.java index d4b0bfe..0e969e4 100644 --- a/cloud-server-course/src/main/java/com/dsh/course/util/httpClinet/HttpClientUtil.java +++ b/cloud-server-course/src/main/java/com/dsh/course/util/httpClinet/HttpClientUtil.java @@ -242,6 +242,61 @@ SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); return HttpClients.custom().setSSLSocketFactory(sslsf).build(); } + /** + * 请求https发送XML请求 + * + * @param url 接口路径 + * @param xml 内容 + * @param header 请求头 + * @param certPassword 证书密码 + * @param certPath 证书路径 + * @param certType 证书类型 + * @return + * @throws Exception + */ + public static String pushHttpsRequsetXml1(String url, String xml, Map<String, String> header, String certPassword, String certPath, String certType) throws Exception { + HttpPost httpPost = new HttpPost(url); + for (String key : header.keySet()) { + httpPost.setHeader(key, header.get(key)); + } + httpPost.setHeader("Content-Type", "application/xml"); + httpPost.setEntity(new StringEntity(xml, "UTF-8")); + CloseableHttpClient httpCline = initCert1(certPassword, certPath, certType); + CloseableHttpResponse httpResponse = httpCline.execute(httpPost); + String content = null; + if (httpResponse.getStatusLine().getStatusCode() == 200) { + content = EntityUtils.toString(httpResponse.getEntity(), "UTF-8"); + } else { + content = "返回状态码:" + httpResponse.getStatusLine() + "。" + EntityUtils.toString(httpResponse.getEntity()); + } + close(httpResponse); + httpCline.close(); + return content; + } + + + /** + * 初始化https对象(带证书) + * + * @param key 证书密码 + * @param certPath 证书路径 + * @param certType 证书类型 + * @throws Exception + */ + private static CloseableHttpClient initCert1(String key, String certPath, String certType) throws Exception { + KeyStore keyStore = KeyStore.getInstance(certType); + InputStream inputStream = new FileInputStream(new File(certPath)); + try { + keyStore.load(inputStream, key.toCharArray()); + } finally { + inputStream.close(); + } + SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, key.toCharArray()).build(); + SSLConnectionSocketFactory sslsf = + new SSLConnectionSocketFactory(sslcontext, null, null, + SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); + return HttpClients.custom().setSSLSocketFactory(sslsf).build(); + } /** diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/OperatorController.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/OperatorController.java index a5d0e85..2173819 100644 --- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/OperatorController.java +++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/OperatorController.java @@ -132,6 +132,11 @@ model.addAttribute("id",id); model.addAttribute("merchantNumber",operatorService.getById(id).getMerchantNumber()); model.addAttribute("name",operatorService.getById(id).getMerchantName()); + OperatorUser one = operatorUserService.lambdaQuery() + .eq(OperatorUser::getOperatorId, id).one(); + if (one!=null){ + model.addAttribute("wechatProportion",one.getWechatProportion()); + } return PREFIX + "Operator_wx.html"; } /** @@ -192,11 +197,17 @@ */ @RequestMapping(value = "/merchantNumberWx") @ResponseBody - public Object listAll(Integer id, String merchantNumber,String name) throws Exception { + public Object listAll(Integer id, String merchantNumber,String name,String wechatProportion) throws Exception { TOperator byId = operatorService.getById(id); byId.setMerchantNumber(merchantNumber); byId.setMerchantName(name); operatorService.updateById(byId); + OperatorUser one = operatorUserService.lambdaQuery() + .eq(OperatorUser::getOperatorId, id).one(); + if (one!=null){ + one.setWechatProportion(wechatProportion); + operatorUserService.updateById(one); + } ResultUtil resultUtil = payMoneyUtil.addReceiver(merchantNumber, name); if (resultUtil.getCode() == 500){ return ResultUtil.error(resultUtil.getMsg()); diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TCompetitionController.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TCompetitionController.java index d79ad0d..8d60d0d 100644 --- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TCompetitionController.java +++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TCompetitionController.java @@ -139,7 +139,6 @@ @RequestMapping("/tCompetition_add") public String tCompetitionAdd(Model model) { List<TCity> list = cityService.list(new LambdaQueryWrapper<TCity>().eq(TCity::getParentId, 0)); - model.addAttribute("list",list); List<TOperator> list1 = tOperatorService.list(); model.addAttribute("yysList",list1); @@ -152,13 +151,12 @@ // 查询这个运营商管理的省 TOperator id = tOperatorService.getOne(new QueryWrapper<TOperator>().eq("id", UserExt.getUser().getObjectId())); if (id.getType()==1){ - // 全国 - List<TCity> list3 = cityService.list(new LambdaQueryWrapper<TCity>().eq(TCity::getParentId, 0)); - model.addAttribute("province",list3); + }else{ // 找到他管理的省 List<TOperatorCity> list4 = operatorCityService.list(new QueryWrapper<TOperatorCity>().eq("operatorId", UserExt.getUser().getObjectId()).eq("pid", 0)); - model.addAttribute("province",list4); + List<Integer> collect = list4.stream().map(TOperatorCity::getCode).collect(Collectors.toList()); + list = cityService.list(new LambdaQueryWrapper<TCity>().in(TCity::getCode, collect)); } model.addAttribute("operator",objectId); // 查询当前运营商管理了哪些门店 @@ -172,6 +170,8 @@ if (UserExt.getUser().getObjectType()==3) model.addAttribute("operator",byId.getOperatorId()); List<TOperator> list2 = tOperatorService.list(); model.addAttribute("yysList",list2); + model.addAttribute("list",list); + return PREFIX + "TCompetition_add.html"; } @@ -206,10 +206,39 @@ model.addAttribute("storeIds",integers); List<TCity> list = cityService.list(new LambdaQueryWrapper<TCity>().eq(TCity::getParentId, 0)); + TCity one = cityService.getOne(new LambdaQueryWrapper<TCity>().eq(TCity::getCode, competition.getProvinceCode())); List<TCity> list1 = cityService.list(new LambdaQueryWrapper<TCity>().eq(TCity::getParentId,one.getId())); List<TStore> list2 = storeService.list(new LambdaQueryWrapper<TStore>().eq(TStore::getCityCode,competition.getCityCode())); + if (UserExt.getUser().getObjectType()==2){ + // 查询这个运营商管理的省 + TOperator id1 = tOperatorService.getOne(new QueryWrapper<TOperator>().eq("id", UserExt.getUser().getObjectId())); + if (id1.getType()==1){ + + }else{ + // 找到他管理的省 + List<TOperatorCity> list4 = operatorCityService.list(new QueryWrapper<TOperatorCity>().eq("operatorId", UserExt.getUser().getObjectId()).eq("pid", 0)); + List<Integer> collect = list4.stream().map(TOperatorCity::getCode).collect(Collectors.toList()); + list = cityService.list(new LambdaQueryWrapper<TCity>().in(TCity::getCode, collect)); + // 找到他管理的市 + TOperatorCity one1 = operatorCityService.lambdaQuery().eq(TOperatorCity::getCode, competition.getProvinceCode()) + .eq(TOperatorCity::getOperatorId, UserExt.getUser().getObjectId()).one(); + + List<TOperatorCity> list3 = operatorCityService.lambdaQuery().eq(TOperatorCity::getPid, one1.getId()) + .eq(TOperatorCity::getOperatorId, UserExt.getUser().getObjectId()).list(); + if (list3.isEmpty()){ + // 管理整个市区 + }else{ + List<Integer> collect1 = list3.stream().map(TOperatorCity::getCode).collect(Collectors.toList()); + list1 = cityService.list(new LambdaQueryWrapper<TCity>().eq(TCity::getParentId,one.getId()) + .in(TCity::getCode, collect1)); + } + + } + list2 = storeService.list(new LambdaQueryWrapper<TStore>().eq(TStore::getCityCode,competition.getCityCode()) + .eq(TStore::getOperatorId,UserExt.getUser().getObjectId())); + } model.addAttribute("list",list); model.addAttribute("list1",list1); model.addAttribute("list2",list2); @@ -437,6 +466,11 @@ @ResponseBody public Object oneChangeNext(Integer oneId) { try { + if (UserExt.getUser().getObjectType() == 2){ + return storeService.list(new LambdaQueryWrapper<TStore>().eq(TStore::getCityCode, oneId) + .eq(TStore::getOperatorId, UserExt.getUser().getObjectId())); + + } return storeService.list(new LambdaQueryWrapper<TStore>().eq(TStore::getCityCode, oneId)); }catch (Exception e){ e.printStackTrace(); diff --git a/cloud-server-management/src/main/resources/mapper/TOperatorUserMapper.xml b/cloud-server-management/src/main/resources/mapper/TOperatorUserMapper.xml index ce5f4a2..79aa256 100644 --- a/cloud-server-management/src/main/resources/mapper/TOperatorUserMapper.xml +++ b/cloud-server-management/src/main/resources/mapper/TOperatorUserMapper.xml @@ -20,20 +20,6 @@ t1.name AS operatorName, t2.name AS userName, t2.phone, - t3.wechat AS platform, - t3.wechatProportion AS proportion, - t3.wechatNum AS number, - t3.wechatAudit AS audit, - t3.wechatType AS type - FROM t_operator_user t3 - LEFT JOIN t_operator t1 ON t3.operatorId = t1.id - LEFT JOIN sys_user t2 ON t1.userId = t2.id AND t2.objectType = 2 - UNION ALL - SELECT t3.id, - t1.id AS operatorId, - t1.name AS operatorName, - t2.name AS userName, - t2.phone, t3.alipay AS platform, t3.alipayProportion AS proportion, t3.alipayNum AS number, diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/Operator.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/Operator.html index 5a01801..8958336 100644 --- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/Operator.html +++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/Operator.html @@ -40,7 +40,9 @@ <#button name="冻结" icon="fa-remove" clickFun="TSite.offShelf()" space="true"/> <#button name="解冻" icon="fa-check" clickFun="TSite.onShelf()" space="true"/> <#button name="重置密码" icon="fa-search" clickFun="TSite.reload()" space="true"/> + @if(shiro.hasPermission("/operator/merchantNumberWx")){ <#button name="绑定微信商户号" icon="fa-search" clickFun="TSite.bindWx()" space="true"/> + @} </div> <#table id="TSiteTable"/> </div> diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/Operator_wx.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/Operator_wx.html index fd8e561..ab77e4d 100644 --- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/Operator_wx.html +++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/Operator_wx.html @@ -58,6 +58,13 @@ <div class="col-sm-9"> <input style="width: 300px" class="form-control" id="name" value="${name}" placeholder="请输入" type="text"> </div> + <div class="form-group" > + + <label class="col-sm-3 control-label">*微信分账比例(%):</label> + <div class="col-sm-9"> + <input style="width: 300px" class="form-control" id="wechatProportion" value="${wechatProportion}" placeholder="请输入" type="number"> + </div> + </div> </div> </div> </div> diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/operatorUser/OperatorUser.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/operatorUser/OperatorUser.html index f34b0b5..2bc8448 100644 --- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/operatorUser/OperatorUser.html +++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/operatorUser/OperatorUser.html @@ -24,7 +24,7 @@ </div> <select style="width: 300px" class="form-control" id="platform" name = "platform"> <option value="">全部</option> - <option value="1">微信</option> + <option value="2">支付宝</option> </select> </div> diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetition/TCompetition_add.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetition/TCompetition_add.html index 258661a..025eb76 100644 --- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetition/TCompetition_add.html +++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetition/TCompetition_add.html @@ -46,6 +46,7 @@ <div class="ibox-content"> <input hidden id="operator" value="${operator}"> + <input hidden id="type" value="${type}"> <div class="form-horizontal" id="carInfoForm"> @if(type==1){ @@ -106,7 +107,27 @@ </div> </div> </div> - + @} + @if(type==2){ + <div class="form-group" > + <label class="col-sm-3 control-label">所在省:</label> + <div class="col-sm-9"> + <select class="form-control" id="pCode1" name="pCode" onchange="TCarInfoDlg.oneChange9(this)"> + <option value="">选择省</option> + @for(i in list){ + <option value="${i.code}" >${i.name}</option> + @} + </select> + </div> + </div> + <div class="form-group" > + <label class="col-sm-3 control-label">举办市:</label> + <div class="col-sm-9"> + <select class="form-control" id="cCode1" name="cCode" onchange="TCarInfoDlg.oneChangeNext(this)"> + <option value="">选择市</option> + </select> + </div> + </div> @} @if(type==1){ <div class="form-group" id="shop"> diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetition/TCompetition_edit.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetition/TCompetition_edit.html index c55380a..dfcb68d 100644 --- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetition/TCompetition_edit.html +++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetition/TCompetition_edit.html @@ -55,6 +55,8 @@ <input hidden id="type" value="${item.status}"> @if(objectType==1){ <#label id="types" name="当前状态" type="text" /> + @} + @if(objectType!=3){ <div class="form-group" id="provinceCode"> <label class="col-sm-3 control-label">举办省:</label> <div class="col-sm-9"> diff --git a/cloud-server-management/src/main/webapp/static/modular/system/operator/operator_add.js b/cloud-server-management/src/main/webapp/static/modular/system/operator/operator_add.js index 5090314..ded86b3 100644 --- a/cloud-server-management/src/main/webapp/static/modular/system/operator/operator_add.js +++ b/cloud-server-management/src/main/webapp/static/modular/system/operator/operator_add.js @@ -135,6 +135,10 @@ Feng.error("请填写微信商户全称") return; } + if($("#wechatProportion").val() == "" || $("#wechatProportion").val() == null){ + Feng.error("请填写微信分账比例") + return; + } //提交信息 var ajax = new $ax(Feng.ctxPath + "/operator/merchantNumberWx", function(data){ console.log(data) @@ -151,6 +155,7 @@ ajax.set("id",$("#id").val()); ajax.set("merchantNumber",$("#merchantNumber").val()); ajax.set("name",$("#name").val()); + ajax.set("wechatProportion",$("#wechatProportion").val()); ajax.start(); }; TSite.oneChange = function (e) { diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tCompetition/tCompetition_info.js b/cloud-server-management/src/main/webapp/static/modular/system/tCompetition/tCompetition_info.js index bc9e345..4030ebb 100644 --- a/cloud-server-management/src/main/webapp/static/modular/system/tCompetition/tCompetition_info.js +++ b/cloud-server-management/src/main/webapp/static/modular/system/tCompetition/tCompetition_info.js @@ -249,7 +249,19 @@ } } } - + console.log("当前登陆人"+$("#type").val()) + if ($("#type").val()==2){ + pCode = $("#pCode1").val(); + if($("#pCode1").val()==""){ + Feng.info("请选择省"); + return; + } + cCode = $("#cCode1").val(); + if($("#cCode1").val()==""){ + Feng.info("请选择市"); + return; + } + } var shopId = $("#shopId").val(); if(shopId==""){ diff --git a/cloud-server-other/src/main/java/com/dsh/other/controller/GameController.java b/cloud-server-other/src/main/java/com/dsh/other/controller/GameController.java index bf1a715..b5c911a 100644 --- a/cloud-server-other/src/main/java/com/dsh/other/controller/GameController.java +++ b/cloud-server-other/src/main/java/com/dsh/other/controller/GameController.java @@ -198,10 +198,12 @@ return ResultUtil.tokenErr(); } Site byId = siteService.getById(spaceId); + Store byId1 = storeService.getById(byId.getStoreId()); + // 是否分账 0否1是 int isFenZhang= 1; String merchantNumber = ""; - if (byId.getOperatorId()==null || byId.getOperatorId()==0){ + if (byId1.getOperatorId()==null || byId1.getOperatorId()==0){ // 平台 isFenZhang = 0; } @@ -221,14 +223,17 @@ tGameRecord.setUserId(uid); tGameRecord.setNumber(code); tGameRecord.setTime(new Date()); + tGameRecord.setSiteId(spaceId); gameRecordService.save(tGameRecord); + System.err.println("启动游戏支付"); if (type == 1) { tGameRecord.setMoney(config.getCash()); gameRecordService.updateById(tGameRecord); String params = uid + "_" + gameId + "_" + spaceId + "_" + sutuId+"_"+code+"_"+configId + "_" + gameType; ResultUtil weixinpay = payMoneyUtil.weixinpay("游戏支付-"+isFenZhang, params, code, config.getCash().toString(), "/base/game/wechatPaymentGameCallback", "APP", ""); + System.err.println("启动游戏支付"); if (weixinpay.getCode() == 200) { new Thread(new Runnable() { @Override @@ -271,41 +276,7 @@ } gameRecordService.updateBatchById(list); Integer integer = startGame(uid, gameType, gameId, spaceId, sutuId); - if (byId.getOperatorId()!=null && byId.getOperatorId()!=0){ - // 休眠两分钟后再调用分账接口 避免提示订单正在处理中 - Thread.sleep(120000); - // 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 - OperatorUser operatorId = operatorUserService.getOne( - new QueryWrapper<OperatorUser>().eq("operatorId",byId.getOperatorId()) - ); - if (operatorId.getWechatProportion() == null){ - operatorId.setWechatProportion("0"); - } - if (operatorId.getAlipayProportion() == null){ - operatorId.setAlipayProportion("0"); - } - String proportion= operatorId.getWechatProportion()+","+operatorId.getAlipayProportion(); - String[] split = proportion.split(","); - String s1 = split[0]; - if (!s1.equals("未设置")){ - BigDecimal bigDecimal = new BigDecimal(s1); - // 分账比例 - BigDecimal bigDecimal1 = bigDecimal.divide(new BigDecimal(100)).setScale(2); - // 微信商户号 - String s2 =siteService.getmerchantNumberByOperatorId(byId.getOperatorId()); - String nonce_str = UUIDUtil.getRandomCode(16); - ResultUtil fenzhang = payMoneyUtil.fenzhang(transaction_id, config.getCash().multiply(bigDecimal1), s2,nonce_str); - if (!fenzhang.getCode().equals(500)){ - System.err.println("分账失败 原因是:"+fenzhang.getMsg()); - }else{ - tGameRecord.setFenzhangNo(fenzhang.getMsg()); - tGameRecord.setFenzhangOrderNo(nonce_str); - tGameRecord.setFenzhangAmount(config.getCash().multiply(bigDecimal1)); - gameRecordService.updateById(tGameRecord); - } - } - } break; } @@ -507,11 +478,15 @@ } + @Resource + private StoreService storeService; @ResponseBody @PostMapping("/base/game/wechatPaymentGameCallback") - public void wechatPaymentGameCallback(HttpServletRequest request, HttpServletResponse response){ + public void wechatPaymentGameCallback(HttpServletRequest request, HttpServletResponse response) throws Exception { + System.err.println("进入游戏回调"); Map<String, String> map = payMoneyUtil.weixinpayCallback(request); + System.err.println("回调参数"+map); if(null != map){ String out_trade_no = map.get("out_trade_no"); String transaction_id = map.get("transaction_id"); @@ -537,6 +512,51 @@ gameRecordService.updateBatchById(list); String[] s = attach.split("_"); Integer integer = startGame(Integer.valueOf(s[0]), Integer.valueOf(s[6]), Integer.valueOf(s[1]), Integer.valueOf(s[2]), Integer.valueOf(s[3])); + TGameRecord one = gameRecordService.getOne(new QueryWrapper<TGameRecord>().eq("number", out_trade_no).eq("payType", 1)); + System.err.println("游戏支付记录"+one); + if (one!=null){ + Integer gameId = one.getGameId(); + Site byId1 = siteService.getById(one.getSiteId()); + Store byId = storeService.getById(byId1.getStoreId()); + if (byId!=null){ + if (byId.getOperatorId()!=null && byId.getOperatorId()!=0){ + // 休眠两分钟后再调用分账接口 避免提示订单正在处理中 + Thread.sleep(120000); + // 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 + OperatorUser operatorId = operatorUserService.getOne( + new QueryWrapper<OperatorUser>().eq("operatorId",byId.getOperatorId()) + ); + if (operatorId.getWechatProportion() == null){ + operatorId.setWechatProportion("0"); + } + if (operatorId.getAlipayProportion() == null){ + operatorId.setAlipayProportion("0"); + } + String proportion= operatorId.getWechatProportion()+","+operatorId.getAlipayProportion(); + String[] split = proportion.split(","); + String s1 = split[0]; + if (!s1.equals("未设置")){ + BigDecimal bigDecimal = new BigDecimal(s1); + // 分账比例 + BigDecimal bigDecimal1 = bigDecimal.divide(new BigDecimal(100)).setScale(2); + // 微信商户号 + String s2 =siteService.getmerchantNumberByOperatorId(byId.getOperatorId()); + String nonce_str = UUIDUtil.getRandomCode(16); + + ResultUtil fenzhang = payMoneyUtil.fenzhang(transaction_id, one.getMoney().multiply(bigDecimal1), s2,nonce_str,"玩游戏分账"); + if (!fenzhang.getCode().equals(200)){ + System.err.println("分账失败 原因是:"+fenzhang.getMsg()); + }else{ + one.setFenzhangNo(fenzhang.getData().toString()); + one.setFenzhangOrderNo(nonce_str); + one.setFenzhangAmount(one.getMoney().multiply(bigDecimal1)); + gameRecordService.updateById(one); + } + } + } + } + + } PrintWriter out = null; try { diff --git a/cloud-server-other/src/main/java/com/dsh/other/controller/SiteController.java b/cloud-server-other/src/main/java/com/dsh/other/controller/SiteController.java index 3092149..1eb56f6 100644 --- a/cloud-server-other/src/main/java/com/dsh/other/controller/SiteController.java +++ b/cloud-server-other/src/main/java/com/dsh/other/controller/SiteController.java @@ -35,6 +35,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.PrintWriter; +import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.*; import java.util.stream.Collectors; @@ -93,6 +94,7 @@ + /** * 通过运营商id查询运营商对应的支付宝商户号 */ @@ -104,17 +106,17 @@ /** * 通过运营商id查询运营商对应的微信商户号 */ - @RequestMapping("/base/getmerchantNumberByOperatorId") + @RequestMapping("/base/getmerchantNumberByOperatorId/{id}") @ResponseBody - public String getmerchantNumberByOperatorId(Integer id) { + public String getmerchantNumberByOperatorId(@PathVariable("id")Integer id) { return siteService.getmerchantNumberByOperatorId(id); } /** * 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 */ - @RequestMapping("/base/getProportionByOperatorId") + @RequestMapping("/base/getProportionByOperatorId/{id}") @ResponseBody - public String getProportionByOperatorId(Integer id) { + public String getProportionByOperatorId(@PathVariable("id")Integer id) { OperatorUser operatorId = operatorUserService.getOne( new QueryWrapper<OperatorUser>().eq("operatorId",id) ); @@ -124,6 +126,7 @@ if (operatorId.getAlipayProportion() == null){ operatorId.setAlipayProportion("0"); } + System.err.println("查询分账比例"+operatorId); return operatorId.getWechatProportion()+","+operatorId.getAlipayProportion(); } /** @@ -350,6 +353,7 @@ @PostMapping("/base/site/weChatPaymentSiteCallback") public void weChatPaymentSiteCallback(HttpServletRequest request, HttpServletResponse response) { try { + System.err.println("预约场地回调"); Map<String, String> map = payMoneyUtil.weixinpayCallback(request); if (null != map) { String code = map.get("out_trade_no"); @@ -361,12 +365,49 @@ siteBooking.setStatus(1); siteBooking.setPayOrderNo(transaction_id); siteBookingService.updateById(siteBooking); - + Store byId = service.getById(siteBooking.getStoreId()); + if (byId.getOperatorId()!=null && byId.getOperatorId()!=0){ + System.err.println("预约场地分账"); + // 休眠两分钟后再调用分账接口 避免提示订单正在处理中 + Thread.sleep(120000); + // 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 + OperatorUser operatorId = operatorUserService.getOne( + new QueryWrapper<OperatorUser>().eq("operatorId",byId.getOperatorId()) + ); + if (operatorId.getWechatProportion() == null){ + operatorId.setWechatProportion("0"); + } + if (operatorId.getAlipayProportion() == null){ + operatorId.setAlipayProportion("0"); + } + String proportion= operatorId.getWechatProportion()+","+operatorId.getAlipayProportion(); + String[] split = proportion.split(","); + String s1 = split[0]; + if (!s1.equals("未设置")){ + BigDecimal bigDecimal = new BigDecimal(s1); + // 分账比例 + BigDecimal bigDecimal1 = bigDecimal.divide(new BigDecimal(100)).setScale(2); + // 微信商户号 + String s2 =siteService.getmerchantNumberByOperatorId(byId.getOperatorId()); + String nonce_str = UUIDUtil.getRandomCode(16); + BigDecimal bigDecimal2 = new BigDecimal(siteBooking.getPayMoney()); + ResultUtil fenzhang = payMoneyUtil.fenzhang(transaction_id, bigDecimal2.multiply(bigDecimal1), s2,nonce_str,"预约场地分账"); + if (!fenzhang.getCode().equals(200)){ + System.err.println("分账失败 原因是:"+fenzhang.getMsg()); + }else{ + siteBooking.setFenzhangNo(fenzhang.getData().toString()); + siteBooking.setFenzhangOrderNo(nonce_str); + siteBooking.setFenzhangAmount(bigDecimal2.multiply(bigDecimal1)); + siteBookingService.updateById(siteBooking); + } + } + } PrintWriter out = response.getWriter(); out.write(result); out.flush(); out.close(); } + } } catch (Exception e) { e.printStackTrace(); @@ -506,12 +547,15 @@ public ResultUtil<Map<String, Object>> queryMySiteById(Integer id) { try { HashMap<String, Object> map = new HashMap<>(); + System.err.println("预约id"+id); SiteBooking siteBooking = siteBookingService.getById(id); + System.err.println("预约"+siteBooking); Integer storeId = siteBooking.getStoreId(); Store byId1 = service.getById(storeId); Site site = siteService.getById(siteBooking.getSiteId()); map.put("siteName", byId1.getName()); SiteType siteType = siteTypeService.getById(site.getSiteTypeId()); + System.err.println("预约类型"+siteType); map.put("siteType", siteType.getName()); map.put("shopName", byId1.getName()); map.put("shopAddress", byId1.getAddress()); @@ -541,7 +585,9 @@ BeanUtils.copyProperties(siteBooking, siteBookingVo); siteBookingVo.setStartTime(siteBooking.getStartTime().getTime()); siteBookingVo.setEndTime(siteBooking.getEndTime().getTime()); - siteBookingVo.setPayTime(siteBooking.getPayTime().getTime()); + if (siteBooking.getPayTime()!=null){ + siteBookingVo.setPayTime(siteBooking.getPayTime().getTime()); + } map.put("data", siteBookingVo); map.put("ids", ids); return ResultUtil.success(map); diff --git a/cloud-server-other/src/main/java/com/dsh/other/entity/TGameRecord.java b/cloud-server-other/src/main/java/com/dsh/other/entity/TGameRecord.java index a639a50..dbaddfc 100644 --- a/cloud-server-other/src/main/java/com/dsh/other/entity/TGameRecord.java +++ b/cloud-server-other/src/main/java/com/dsh/other/entity/TGameRecord.java @@ -45,6 +45,11 @@ */ @TableField("payType") private Integer payType; + /** + * 场地id + */ + @TableField("siteId") + private Integer siteId; /** * 金额 @@ -62,17 +67,22 @@ private Date time; + /** * 分账流水号 */ + @TableField("fenzhangNo") private String fenzhangNo; /** * 分账业务号 存值表明已分账 未存表明未分账 */ + @TableField("fenzhangOrderNo") private String fenzhangOrderNo; // 分账金额 + @TableField("fenzhangAmount") private BigDecimal fenzhangAmount; // 分账回退流水号 + @TableField("fenzhangRefundNo") private String fenzhangRefundNo; @Override protected Serializable pkVal() { diff --git a/cloud-server-other/src/main/java/com/dsh/other/service/impl/SiteServiceImpl.java b/cloud-server-other/src/main/java/com/dsh/other/service/impl/SiteServiceImpl.java index 0397da7..6cc0dff 100644 --- a/cloud-server-other/src/main/java/com/dsh/other/service/impl/SiteServiceImpl.java +++ b/cloud-server-other/src/main/java/com/dsh/other/service/impl/SiteServiceImpl.java @@ -516,41 +516,7 @@ siteBooking.setPayOrderNo(transaction_id); siteBookingService.updateById(siteBooking); - if (byId.getOperatorId()!=null && byId.getOperatorId()!=0){ - // 休眠两分钟后再调用分账接口 避免提示订单正在处理中 - Thread.sleep(120000); - // 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 - OperatorUser operatorId = operatorUserService.getOne( - new QueryWrapper<OperatorUser>().eq("operatorId",byId.getOperatorId()) - ); - if (operatorId.getWechatProportion() == null){ - operatorId.setWechatProportion("0"); - } - if (operatorId.getAlipayProportion() == null){ - operatorId.setAlipayProportion("0"); - } - String proportion= operatorId.getWechatProportion()+","+operatorId.getAlipayProportion(); - String[] split = proportion.split(","); - String s1 = split[0]; - if (!s1.equals("未设置")){ - BigDecimal bigDecimal = new BigDecimal(s1); - // 分账比例 - BigDecimal bigDecimal1 = bigDecimal.divide(new BigDecimal(100)).setScale(2); - // 微信商户号 - String s2 =siteService.getmerchantNumberByOperatorId(byId.getOperatorId()); - String nonce_str = UUIDUtil.getRandomCode(16); - BigDecimal bigDecimal2 = new BigDecimal(paymentPrice); - ResultUtil fenzhang = payMoneyUtil.fenzhang(transaction_id, bigDecimal2.multiply(bigDecimal1), s2,nonce_str); - if (!fenzhang.getCode().equals(500)){ - System.err.println("分账失败 原因是:"+fenzhang.getMsg()); - }else{ - siteBooking.setFenzhangNo(fenzhang.getMsg()); - siteBooking.setFenzhangOrderNo(nonce_str); - siteBooking.setFenzhangAmount(bigDecimal2.multiply(bigDecimal1)); - siteBookingService.updateById(siteBooking); - } - } - } + break; } @@ -807,12 +773,11 @@ String randomCode = UUIDUtil.getRandomCode(16); String randomCode1 = UUIDUtil.getRandomCode(16); if (byId.getOperatorId()!=null && byId.getOperatorId()!=0){ - // 休眠两分钟后再调用分账接口 避免提示订单正在处理中 // 微信商户号 String s2 =siteService.getmerchantNumberByOperatorId(byId.getOperatorId()); - ResultUtil resultUtil = payMoneyUtil.fenzhangRefund(siteBooking.getFenzhangNo(), siteBooking.getFenzhangAmount(), s2, randomCode, randomCode1); - if (!resultUtil.getCode().equals(500)){ - System.err.println("分账回退失败 原因是:"+resultUtil.getMsg()); + ResultUtil resultUtil = payMoneyUtil.fenzhangRefund(siteBooking.getFenzhangNo(), siteBooking.getFenzhangAmount().multiply(new BigDecimal("100")), s2, randomCode, randomCode1); + if (!resultUtil.getCode().equals(200)){ + System.err.println("分账回退失败 原因是:"+resultUtil.getMsg()+resultUtil.getData()); }else{ siteBooking.setFenzhangRefundNo(resultUtil.getMsg()); siteBookingService.updateById(siteBooking); diff --git a/cloud-server-other/src/main/java/com/dsh/other/util/HttpClientUtil.java b/cloud-server-other/src/main/java/com/dsh/other/util/HttpClientUtil.java index b33680b..f4fe16c 100644 --- a/cloud-server-other/src/main/java/com/dsh/other/util/HttpClientUtil.java +++ b/cloud-server-other/src/main/java/com/dsh/other/util/HttpClientUtil.java @@ -244,7 +244,39 @@ SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); return HttpClients.custom().setSSLSocketFactory(sslsf).build(); } - + public static String pushHttpsRequsetXml1(String url, String xml, Map<String, String> header, String certPassword, String certPath, String certType) throws Exception { + HttpPost httpPost = new HttpPost(url); + for (String key : header.keySet()) { + httpPost.setHeader(key, header.get(key)); + } + httpPost.setHeader("Content-Type", "application/xml"); + httpPost.setEntity(new StringEntity(xml, "UTF-8")); + CloseableHttpClient httpCline = initCert1(certPassword, certPath, certType); + CloseableHttpResponse httpResponse = httpCline.execute(httpPost); + String content = null; + if (httpResponse.getStatusLine().getStatusCode() == 200) { + content = EntityUtils.toString(httpResponse.getEntity(), "UTF-8"); + } else { + content = "返回状态码:" + httpResponse.getStatusLine() + "。" + EntityUtils.toString(httpResponse.getEntity()); + } + close(httpResponse); + httpCline.close(); + return content; + } + private static CloseableHttpClient initCert1(String key, String certPath, String certType) throws Exception { + KeyStore keyStore = KeyStore.getInstance(certType); + InputStream inputStream = new FileInputStream(new File(certPath)); + try { + keyStore.load(inputStream, key.toCharArray()); + } finally { + inputStream.close(); + } + SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, key.toCharArray()).build(); + SSLConnectionSocketFactory sslsf = + new SSLConnectionSocketFactory(sslcontext, null, null, + SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); + return HttpClients.custom().setSSLSocketFactory(sslsf).build(); + } /** * 关闭资源 diff --git a/cloud-server-other/src/main/java/com/dsh/other/util/PayMoneyUtil.java b/cloud-server-other/src/main/java/com/dsh/other/util/PayMoneyUtil.java index a7b08c9..6d03524 100644 --- a/cloud-server-other/src/main/java/com/dsh/other/util/PayMoneyUtil.java +++ b/cloud-server-other/src/main/java/com/dsh/other/util/PayMoneyUtil.java @@ -1,6 +1,7 @@ package com.dsh.other.util; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayClient; @@ -24,10 +25,7 @@ import org.springframework.util.StringUtils; import javax.annotation.Resource; -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; +import javax.crypto.*; import javax.crypto.spec.SecretKeySpec; import javax.servlet.http.HttpServletRequest; import java.io.*; @@ -39,6 +37,8 @@ import java.security.NoSuchProviderException; import java.security.Security; import java.util.*; + +import static com.dsh.other.util.akeylogin.Md5Util.byteArrayToHexString; /** * 第三方支付工具类 @@ -550,22 +550,28 @@ * @param order 微信订单号 * @return */ - public ResultUtil fenzhang(String order,BigDecimal amount,String merchantNumber,String nonce_str) throws Exception { + public ResultUtil fenzhang(String order,BigDecimal amount,String merchantNumber, + String nonce_str,String description) throws Exception { Map<String, Object> map = new HashMap<>(); map.put("mch_id", mchId); map.put("appid", appid); map.put("nonce_str", nonce_str); map.put("transaction_id", order); + String out_order_no = UUIDUtil.getRandomCode(16); + map.put("out_order_no", out_order_no); // 将这个字符串使用json格式拼接起来 Map<String, Object> body = new HashMap<>(); body.put("type", "MERCHANT_ID"); + int i = amount.multiply(new BigDecimal("100")).intValue(); + body.put("amount", i); + body.put("type", "MERCHANT_ID"); body.put("account", merchantNumber); - body.put("amount", amount); - body.put("description", "订单分账"); + body.put("description", description); JSONObject jsonObject = new JSONObject(body); - String jsonString = jsonObject.toString(); - map.put("receiver",jsonString); - String s = this.weixinSignature(map); + JSONArray objects = new JSONArray(); + objects.add(jsonObject); + map.put("receivers",objects.toJSONString()); + String s = this.weixinSignature1(map); map.put("sign", s); String url = "https://api.mch.weixin.qq.com/secapi/pay/profitsharing"; //设置请求头 @@ -585,7 +591,7 @@ Map<String, String> map1 = null; String body1 = null; try { - body1 = HttpClientUtil.pushHttpsRequsetXml(url, xmlString.toString(), new HashMap<>(), mchId, certPath, "PKCS12"); + body1 = HttpClientUtil.pushHttpsRequsetXml1(url, xmlString.toString(), new HashMap<>(), mchId, certPath, "PKCS12"); } catch (Exception e) { e.printStackTrace(); } @@ -604,7 +610,7 @@ if ("SUCCESS".equals(return_code)) { String result_code = map1.get("result_code"); if ("SUCCESS".equals(result_code)) { - return ResultUtil.success(); + return ResultUtil.success(map1.get("order_id")); } else { // System.err.println(map1.get("err_code_des")); return ResultUtil.error(map1.get("err_code_des")); @@ -630,9 +636,9 @@ map.put("out_return_no", fenzhangRefundNo); map.put("return_account_type", "MERCHANT_ID"); map.put("return_account", merchantNumber); - map.put("return_amount", amount); - map.put("description", "用户退款"); - String s = this.weixinSignature(map); + map.put("return_amount", amount.intValue()); + map.put("description", "用户取消预约场地退款"); + String s = this.weixinSignature1(map); map.put("sign", s); String url = "https://api.mch.weixin.qq.com/secapi/pay/profitsharingreturn"; //设置请求头 @@ -652,7 +658,7 @@ Map<String, String> map1 = null; String body1 = null; try { - body1 = HttpClientUtil.pushHttpsRequsetXml(url, xmlString.toString(), new HashMap<>(), mchId, certPath, "PKCS12"); + body1 = HttpClientUtil.pushHttpsRequsetXml1(url, xmlString.toString(), new HashMap<>(), mchId, certPath, "PKCS12"); } catch (Exception e) { e.printStackTrace(); } @@ -887,7 +893,7 @@ Map<String, String> map1 = null; String body1 = null; try { - body1 = HttpClientUtil.pushHttpsRequsetXml(url, xmlString.toString(), new HashMap<>(), mchId, certPath, "PKCS12"); + body1 = HttpClientUtil.pushHttpsRequsetXml1(url, xmlString.toString(), new HashMap<>(), mchId, certPath, "PKCS12"); } catch (Exception e) { e.printStackTrace(); } @@ -1295,7 +1301,54 @@ return map; } - + private String weixinSignature1(Map<String, Object> map) { + try { + Set<Map.Entry<String, Object>> entries = map.entrySet(); + List<Map.Entry<String, Object>> infoIds = new ArrayList<Map.Entry<String, Object>>(entries); + // 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序) + Collections.sort(infoIds, new Comparator<Map.Entry<String, Object>>() { + public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) { + return (o1.getKey()).toString().compareTo(o2.getKey()); + } + }); + // 构造签名键值对的格式 + StringBuilder sb = new StringBuilder(); + for (Map.Entry<String, Object> item : infoIds) { + if (item.getKey() != null || item.getKey() != "") { + String key = item.getKey(); + Object val = item.getValue(); + if (!(val == "" || val == null)) { + sb.append(key + "=" + val + "&"); + } + } + } + sb.append("key=" + key); + String sign = sha256_HMAC(sb.toString(), key).toUpperCase(); + return sign; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + /** + * sha256_HMAC加密 + * @param message 消息 + * @param secret 秘钥 + * @return 加密后字符串 + */ + public String sha256_HMAC(String message, String secret) { + String hash = ""; + try { + Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); + SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256"); + sha256_HMAC.init(secret_key); + byte[] bytes = sha256_HMAC.doFinal(message.getBytes()); + hash = byteArrayToHexString(bytes); + } catch (Exception e) { + System.out.println("Error HmacSHA256 ===========" + e.getMessage()); + } + return hash; + } /** * 获取请求内容 * -- Gitblit v1.7.1