| | |
| | | package com.ruoyi.study.controller; |
| | | |
| | | |
| | | import com.auth0.jwt.JWT; |
| | | import com.auth0.jwt.algorithms.Algorithm; |
| | | import com.auth0.jwt.exceptions.SignatureVerificationException; |
| | | import com.auth0.jwt.interfaces.DecodedJWT; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.alipay.api.AlipayApiException; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.ruoyi.common.core.constant.Constants; |
| | |
| | | import io.swagger.annotations.ApiImplicitParam; |
| | | import io.swagger.annotations.ApiImplicitParams; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import io.swagger.models.auth.In; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.util.StringUtils; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.annotation.Resource; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.BufferedReader; |
| | | import java.io.ByteArrayInputStream; |
| | | import java.io.PrintWriter; |
| | | import java.math.BigDecimal; |
| | | import java.security.PublicKey; |
| | | import java.security.cert.CertificateException; |
| | | import java.security.cert.CertificateFactory; |
| | | import java.security.cert.X509Certificate; |
| | | import java.security.interfaces.ECPublicKey; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.*; |
| | | |
| | |
| | | |
| | | @Autowired |
| | | private PayMoneyUtil payMoneyUtil; |
| | | public static JSONObject verifyAndGet(String jws) throws CertificateException { |
| | | DecodedJWT decodedJWT = JWT.decode(jws); |
| | | // 拿到 header 中 x5c 数组中第一个 |
| | | String header = new String(java.util.Base64.getDecoder().decode(decodedJWT.getHeader())); |
| | | String x5c = JSONObject.parseObject(header).getJSONArray("x5c").getString(0); |
| | | |
| | | // 获取公钥 |
| | | PublicKey publicKey = getPublicKeyByX5c(x5c); |
| | | |
| | | // 验证 token |
| | | Algorithm algorithm = Algorithm.ECDSA256((ECPublicKey) publicKey, null); |
| | | |
| | | try { |
| | | algorithm.verify(decodedJWT); |
| | | } catch (SignatureVerificationException e) { |
| | | throw new RuntimeException("签名验证失败"); |
| | | } |
| | | // 解析数据 |
| | | return JSONObject.parseObject(new String(java.util.Base64.getDecoder().decode(decodedJWT.getPayload()))); |
| | | } |
| | | |
| | | /** |
| | | * 获取公钥 |
| | | * @param x5c |
| | | * @return |
| | | * @throws |
| | | */ |
| | | private static PublicKey getPublicKeyByX5c(String x5c) throws CertificateException { |
| | | byte[] x5c0Bytes = java.util.Base64.getDecoder().decode(x5c); |
| | | CertificateFactory fact = CertificateFactory.getInstance("X.509"); |
| | | X509Certificate cer = (X509Certificate) fact.generateCertificate(new ByteArrayInputStream(x5c0Bytes)); |
| | | return cer.getPublicKey(); |
| | | } |
| | | @PostMapping("/pay") |
| | | @ApiOperation(value = "购买会员支付操作", tags = {"家长端-个人中心"}) |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(name = "Authorization", value = "Bearer eyJhbGciOiJIUzUxMiJ....", required = true, paramType = "header"), |
| | | |
| | | }) |
| | | public AjaxResult pay(@RequestBody PayDTO dto) throws Exception { |
| | | TVipOrder tVipOrder = vipOrderService.getById(dto.getOrderId()); |
| | |
| | | UUIDUtil.getRandomCode(8), |
| | | tVipOrder.getMoney().toString(), |
| | | "/base/user/aliPayBuyVip"); |
| | | case 3: |
| | | tVipOrder.setTransactionId(dto.getTransactionIdentifier()); |
| | | vipOrderService.updateById(tVipOrder); |
| | | } |
| | | return AjaxResult.success(); |
| | | } |
| | | @PostMapping("/queryOrderState") |
| | | @ApiOperation(value = "苹果内购查询支付状态", tags = {"苹果内购查询支付状态"}) |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(name = "Authorization", value = "Bearer eyJhbGciOiJIUzUxMiJ....", required = true, paramType = "header"), |
| | | @ApiImplicitParam(name = "orderId", value = "订单id", required = true) |
| | | }) |
| | | public AjaxResult<Boolean> pay(Integer orderId) throws Exception { |
| | | System.err.println("苹果orderId:"+orderId); |
| | | TVipOrder byId = vipOrderService.getById(orderId); |
| | | if (byId.getPayState() == 2){ |
| | | return AjaxResult.success(true); |
| | | }else{ |
| | | return AjaxResult.success(false); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | @PostMapping("/order") |
| | | @ApiOperation(value = "购买会员下单操作", tags = {"家长端-个人中心"}) |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(name = "Authorization", value = "Bearer eyJhbGciOiJIUzUxMiJ....", required = true, paramType = "header"), |
| | | @ApiImplicitParam(name = "payType", value = "支付类型 1=微信 2=支付宝", required = true), |
| | | @ApiImplicitParam(name = "id", value = "会员规格id", required = true), |
| | | @ApiImplicitParam(name = "payType", value = "支付类型 1=微信 2=支付宝 3=苹果内购", required = true), |
| | | @ApiImplicitParam(name = "id", value = "会员规格id", required = false), |
| | | @ApiImplicitParam(name = "count", value = "购买会员月数--ios用", required = false), |
| | | @ApiImplicitParam(name = "price", value = "价格--ios用", required = false), |
| | | }) |
| | | public R<PayVO> order(Integer payType, Integer id) throws Exception { |
| | | public R<PayVO> order(Integer payType, Integer id,Integer count,BigDecimal price) throws Exception { |
| | | if (tokenService.getLoginUser1() == null) { |
| | | return R.tokenError("登录失效"); |
| | | } |
| | | // todo price根据用户环境确定单位 可能为刀或欧等等 也许后续需要处理转换 存元 |
| | | Integer userid = tokenService.getLoginUser1().getUserid(); |
| | | TVipOrder tVipOrder = new TVipOrder(); |
| | | List<TVipSet> data = managementClient.getVipSet1().getData(); |
| | | if (price!=null){ |
| | | id = null; |
| | | } |
| | | Integer time = 0; |
| | | if (id!=null){ |
| | | for (TVipSet datum : data) { |
| | | if (datum.getId() == id) { |
| | | tVipOrder.setMoney(datum.getAmount()); |
| | | time = datum.getTime(); |
| | | tVipOrder.setCount(time); |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(new Date()); |
| | | calendar.add(Calendar.MONTH, time); |
| | | Date dateAfterOneMonth = calendar.getTime(); |
| | | dateAfterOneMonth.setHours(23); |
| | | dateAfterOneMonth.setMinutes(59); |
| | | dateAfterOneMonth.setSeconds(59); |
| | | tVipOrder.setTime(dateAfterOneMonth); |
| | | tVipOrder.setCount(time); |
| | | break; |
| | | } |
| | | } |
| | | }else{ |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(new Date()); |
| | | calendar.add(Calendar.MONTH, count); |
| | | Date dateAfterOneMonth = calendar.getTime(); |
| | | dateAfterOneMonth.setHours(23); |
| | | dateAfterOneMonth.setMinutes(59); |
| | | dateAfterOneMonth.setSeconds(59); |
| | | tVipOrder.setTime(dateAfterOneMonth); |
| | | tVipOrder.setCount(count); |
| | | } |
| | | tVipOrder.setPayState(1); |
| | | tVipOrder.setUserId(userid); |
| | | tVipOrder.setPayType(payType); |
| | | vipOrderService.save(tVipOrder); |
| | | PayVO payVO = new PayVO(); |
| | | payVO.setOrderId(tVipOrder.getId()); |
| | | payVO.setId(id); |
| | | return R.ok(payVO); |
| | | } |
| | | @PostMapping("/orderStudent") |
| | | @ApiOperation(value = "学习端购买会员下单操作", tags = {"家长端-个人中心"}) |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(name = "Authorization", value = "Bearer eyJhbGciOiJIUzUxMiJ....", required = true, paramType = "header"), |
| | | @ApiImplicitParam(name = "payType", value = "支付类型 1=微信 2=支付宝 3=苹果内购", required = true), |
| | | @ApiImplicitParam(name = "id", value = "会员规格id", required = false), |
| | | @ApiImplicitParam(name = "count", value = "购买会员月数--ios用", required = false), |
| | | @ApiImplicitParam(name = "price", value = "价格--ios用", required = false), |
| | | }) |
| | | public R<PayVO> orderStudent(Integer payType, Integer id,Integer count,BigDecimal price) throws Exception { |
| | | if (tokenService.getLoginUserStudy() == null) { |
| | | return R.tokenError("登录失效"); |
| | | } |
| | | Integer userid = tokenService.getLoginUserStudy().getUserid(); |
| | | TVipOrder tVipOrder = new TVipOrder(); |
| | | List<TVipSet> data = managementClient.getVipSet1().getData(); |
| | | Integer time = 0; |
| | | if (id!=null){ |
| | | for (TVipSet datum : data) { |
| | | if (datum.getId() == id) { |
| | | tVipOrder.setMoney(datum.getAmount()); |
| | | time = datum.getTime(); |
| | | } |
| | | } |
| | | } |
| | | tVipOrder.setPayState(1); |
| | | tVipOrder.setUserId(userid); |
| | | tVipOrder.setPayType(payType); |
| | | if (count!=null){ |
| | | tVipOrder.setCount(count); |
| | | tVipOrder.setMoney(price); |
| | | }else{ |
| | | tVipOrder.setCount(time); |
| | | } |
| | | vipOrderService.save(tVipOrder); |
| | | PayVO payVO = new PayVO(); |
| | | payVO.setOrderId(tVipOrder.getId()); |
| | | payVO.setId(id); |
| | | return R.ok(payVO); |
| | | |
| | | |
| | | } |
| | | |
| | | @ResponseBody |
| | | @PostMapping("/testApple") |
| | | public void testApple(HttpServletRequest request, HttpServletResponse response) { |
| | | try { |
| | | System.err.println("请求"+request); |
| | | BufferedReader reader = request.getReader(); |
| | | String string1 = reader.toString(); |
| | | System.err.println("请求reader"+string1); |
| | | StringBuilder requestBody = new StringBuilder(); |
| | | String line; |
| | | while ((line = reader.readLine()) != null) { |
| | | requestBody.append(line); |
| | | } |
| | | System.err.println("全部请求体"+requestBody); |
| | | org.json.JSONObject jsonObject1 = new org.json.JSONObject(requestBody.toString()); |
| | | System.err.println("json串"+jsonObject1); |
| | | String o = jsonObject1.getString("signedPayload"); |
| | | JSONObject payload = verifyAndGet(o); |
| | | String notificationType = payload.get("notificationType").toString(); |
| | | JSONObject data = payload.getJSONObject("data"); |
| | | String signedTransactionInfo = data.get("signedTransactionInfo").toString(); |
| | | String environment = data.get("environment").toString(); |
| | | JSONObject transactionInfo = verifyAndGet(signedTransactionInfo); |
| | | String transactionId = transactionInfo.get("transactionId").toString(); |
| | | String originalTransactionId = transactionInfo.get("originalTransactionId").toString(); |
| | | String productId = transactionInfo.get("productId").toString(); |
| | | System.err.println("json串"+transactionInfo); |
| | | System.err.println("data"+data); |
| | | // 苹果流水号 |
| | | String string = transactionInfo.getString("originalTransactionId"); |
| | | TVipOrder one = vipOrderService.getOne(new QueryWrapper<TVipOrder>() |
| | | .eq("transactionId", string) |
| | | .eq("payType", 3)); |
| | | System.err.println("回调通知类型"+notificationType); |
| | | if ("REFUND".equals(notificationType)){ |
| | | if (one!=null && one.getPayState() == 2){ |
| | | one.setPayState(3); |
| | | one.setBackTime(new Date()); |
| | | // 用户的vip剩余时间减少 |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(new Date()); |
| | | calendar.add(Calendar.MONTH, -one.getCount()); |
| | | Integer userId = one.getUserId(); |
| | | TUser byId1 = userService.getById(userId); |
| | | // 判断用户是不是第一次充值 |
| | | List<TVipOrder> list = vipOrderService.list(new QueryWrapper<TVipOrder>() |
| | | .eq("userId", userId) |
| | | .ne("id",one.getId()) |
| | | .eq("payState", 2) |
| | | .orderByDesc("createTime")); |
| | | int size = list.size(); |
| | | if (size == 0) { |
| | | System.err.println("证明这是用户第一次充值会员 将首次充值会员时间和会员到期时间清空"); |
| | | // 证明这是用户第一次充值会员 将首次充值会员时间和会员到期时间清空 |
| | | byId1.setVipEndTime(null); |
| | | byId1.setVipPayTime(null); |
| | | userService.updateById(byId1); |
| | | userService.updateOne(byId1.getId(), null, null); |
| | | } else { |
| | | System.err.println("最近的一次充值会员时间 将会员到期时间回退到上一次"); |
| | | // 最近的一次充值会员时间 |
| | | TVipOrder tVipOrder = list.get(0); |
| | | // 将会员到期时间回退到上一次 |
| | | byId1.setVipEndTime(tVipOrder.getTime()); |
| | | byId1.setVipPayTime(tVipOrder.getPayTime()); |
| | | userService.updateById(byId1); |
| | | } |
| | | } |
| | | vipOrderService.updateById(one); |
| | | }else{ |
| | | if (one!=null){ |
| | | one.setPayState(2); |
| | | one.setPayTime(new Date()); |
| | | |
| | | TUser byId1 = userService.getById(one.getUserId()); |
| | | if (byId1.getVipPayTime() == null) { |
| | | // 是否是首次充值会员 |
| | | byId1.setVipPayTime(new Date()); |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(new Date()); |
| | | calendar.add(Calendar.MONTH, one.getCount()); |
| | | Date dateAfterOneMonth = calendar.getTime(); |
| | | dateAfterOneMonth.setHours(23); |
| | | dateAfterOneMonth.setMinutes(59); |
| | | dateAfterOneMonth.setSeconds(59); |
| | | byId1.setVipEndTime(dateAfterOneMonth); |
| | | one.setTime(dateAfterOneMonth); |
| | | userService.updateById(byId1); |
| | | } else { |
| | | // 不是首次 判断vipEndTime 是否到期 如果没有 加指定月份时间 如果到期了 将会员到期时间从当前增加指定月份 |
| | | if (byId1.getVipEndTime().getTime() < new Date().getTime()) { |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(new Date()); |
| | | calendar.add(Calendar.MONTH, one.getCount()); |
| | | Date dateAfterOneMonth = calendar.getTime(); |
| | | dateAfterOneMonth.setHours(23); |
| | | dateAfterOneMonth.setMinutes(59); |
| | | dateAfterOneMonth.setSeconds(59); |
| | | one.setTime(dateAfterOneMonth); |
| | | byId1.setVipEndTime(dateAfterOneMonth); |
| | | userService.updateById(byId1); |
| | | } else { |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(byId1.getVipEndTime()); |
| | | calendar.add(Calendar.MONTH, one.getCount()); |
| | | Date dateAfterOneMonth = calendar.getTime(); |
| | | dateAfterOneMonth.setHours(23); |
| | | dateAfterOneMonth.setMinutes(59); |
| | | dateAfterOneMonth.setSeconds(59); |
| | | one.setTime(dateAfterOneMonth); |
| | | byId1.setVipEndTime(dateAfterOneMonth); |
| | | userService.updateById(byId1); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | vipOrderService.updateById(one); |
| | | System.err.println("苹果流水号"+string); |
| | | PrintWriter out = response.getWriter(); |
| | | out.write("success"); |
| | | out.flush(); |
| | | out.close(); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 处理苹果退款 回调通知 |
| | | * @param request |
| | | * @param response |
| | | */ |
| | | @ResponseBody |
| | | @PostMapping("/refundApple") |
| | | public void refundApple(HttpServletRequest request, HttpServletResponse response) { |
| | | try { |
| | | System.err.println("请求"+request); |
| | | BufferedReader reader = request.getReader(); |
| | | String string1 = reader.toString(); |
| | | System.err.println("请求reader"+string1); |
| | | StringBuilder requestBody = new StringBuilder(); |
| | | String line; |
| | | while ((line = reader.readLine()) != null) { |
| | | requestBody.append(line); |
| | | } |
| | | System.err.println("全部请求体"+requestBody); |
| | | org.json.JSONObject jsonObject1 = new org.json.JSONObject(requestBody.toString()); |
| | | System.err.println("json串"+jsonObject1); |
| | | String o = jsonObject1.getString("signedPayload"); |
| | | JSONObject payload = verifyAndGet(o); |
| | | String notificationType = payload.get("notificationType").toString(); |
| | | |
| | | JSONObject data = payload.getJSONObject("data"); |
| | | String signedTransactionInfo = data.get("signedTransactionInfo").toString(); |
| | | JSONObject transactionInfo = verifyAndGet(signedTransactionInfo); |
| | | System.err.println("解签后的json串"+transactionInfo); |
| | | System.err.println("data"+data); |
| | | // 苹果流水号 |
| | | String string = transactionInfo.getString("originalTransactionId"); |
| | | TVipOrder one = vipOrderService.getOne(new QueryWrapper<TVipOrder>() |
| | | .eq("transactionId", string) |
| | | .eq("payType", 3)); |
| | | if (one!=null && one.getPayState() == 2){ |
| | | one.setPayState(3); |
| | | one.setBackTime(new Date()); |
| | | // 用户的vip剩余时间减少 |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(new Date()); |
| | | calendar.add(Calendar.MONTH, -one.getCount()); |
| | | Integer userId = one.getUserId(); |
| | | TUser byId1 = userService.getById(userId); |
| | | // 判断用户是不是第一次充值 |
| | | List<TVipOrder> list = vipOrderService.list(new QueryWrapper<TVipOrder>() |
| | | .eq("userId", userId) |
| | | .eq("payState", 2) |
| | | .orderByDesc("createTime")); |
| | | int size = list.size(); |
| | | if (size == 0) { |
| | | System.err.println("证明这是用户第一次充值会员 将首次充值会员时间和会员到期时间清空"); |
| | | // 证明这是用户第一次充值会员 将首次充值会员时间和会员到期时间清空 |
| | | byId1.setVipEndTime(null); |
| | | byId1.setVipPayTime(null); |
| | | userService.updateById(byId1); |
| | | userService.updateOne(byId1.getId(), null, null); |
| | | } else { |
| | | System.err.println("最近的一次充值会员时间 将会员到期时间回退到上一次"); |
| | | // 最近的一次充值会员时间 |
| | | TVipOrder tVipOrder = list.get(0); |
| | | // 将会员到期时间回退到上一次 |
| | | byId1.setVipEndTime(tVipOrder.getTime()); |
| | | byId1.setVipPayTime(tVipOrder.getPayTime()); |
| | | userService.updateById(byId1); |
| | | } |
| | | } |
| | | vipOrderService.updateById(one); |
| | | System.err.println("苹果流水号"+string); |
| | | PrintWriter out = response.getWriter(); |
| | | out.write("success"); |
| | | out.flush(); |
| | | out.close(); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | @ResponseBody |
| | | @PostMapping("/aliPayBuyVip") |
| | | public void addVipPaymentAliCallback(HttpServletRequest request, HttpServletResponse response) { |
| | |
| | | dateAfterOneMonth.setSeconds(59); |
| | | byId1.setVipEndTime(dateAfterOneMonth); |
| | | byId.setTime(dateAfterOneMonth); |
| | | |
| | | } else { |
| | | // 不是首次 判断vipEndTime 是否到期 如果没有 加指定月份时间 如果到期了 将会员到期时间从当前增加指定月份 |
| | | if (byId1.getVipEndTime().getTime() < new Date().getTime()) { |