| | |
| | | tVipOrder.getMoney().toString(), |
| | | "/base/user/aliPayBuyVip"); |
| | | case 3: |
| | | // 苹果内购:回传流水号后立即开通会员;苹果服务器通知(/testApple)作为兜底,两条链路共用 completeVipOrder |
| | | if (tVipOrder == null) { |
| | | return AjaxResult.error("订单不存在"); |
| | | } |
| | | // 已经支付或已退款,避免重复回传覆盖状态 |
| | | if (tVipOrder.getPayState() != null && tVipOrder.getPayState() != 1) { |
| | | System.err.println("苹果支付订单无需重复处理 orderId=" + tVipOrder.getId() |
| | | + ", payState=" + tVipOrder.getPayState()); |
| | | return AjaxResult.success(); |
| | | } |
| | | if (!StringUtils.hasText(dto.getTransactionIdentifier())) { |
| | | return AjaxResult.error("苹果流水号不能为空"); |
| | | } |
| | | System.err.println("苹果支付回传流水号 orderId=" + tVipOrder.getId() |
| | | + ", transactionIdentifier=" + dto.getTransactionIdentifier()); |
| | | tVipOrder.setTransactionId(dto.getTransactionIdentifier()); |
| | | // 先落库流水号,保证后续苹果通知(/testApple)能按 transactionId 匹配到本订单 |
| | | vipOrderService.updateById(tVipOrder); |
| | | // 不依赖苹果通知的到达顺序:回传流水号后立即开通会员 |
| | | // 苹果通知(/testApple)作为兜底,重复调用时由 completeVipOrder 的幂等保护避免重复开通 |
| | | completeVipOrder(tVipOrder); |
| | | } |
| | | return AjaxResult.success(); |
| | | } |
| | |
| | | System.err.println("data"+data); |
| | | // 苹果流水号 |
| | | String string = transactionInfo.getString("originalTransactionId"); |
| | | // 订单匹配:优先按本次交易的 transactionId 匹配(客户端支付成功后已回传 /pay 落库), |
| | | // 匹配不到再退回 originalTransactionId(同一订阅的自动续订没有新订单,需挂到首单上) |
| | | TVipOrder one = vipOrderService.getOne(new QueryWrapper<TVipOrder>() |
| | | .eq("payType", 3) |
| | | .eq("transactionId", transactionId) |
| | | .last("limit 1")); |
| | | if (one == null) { |
| | | one = vipOrderService.getOne(new QueryWrapper<TVipOrder>() |
| | | .eq("payType", 3) |
| | | .eq("transactionId", string) |
| | | .eq("payType", 3)); |
| | | System.err.println("回调通知类型"+notificationType); |
| | | .last("limit 1")); |
| | | } |
| | | System.err.println("回调通知类型"+notificationType |
| | | + ", transactionId=" + transactionId |
| | | + ", originalTransactionId=" + string |
| | | + ", 匹配订单=" + (one == null ? "无" : one.getId())); |
| | | if ("REFUND".equals(notificationType)){ |
| | | if (one!=null && one.getPayState() == 2){ |
| | | one.setPayState(3); |
| | |
| | | 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); |
| | | } |
| | | } |
| | | // 与客户端回传流水号(/pay)共用同一段开通逻辑,保证两条链路行为一致 |
| | | completeVipOrder(one); |
| | | } |
| | | } |
| | | |
| | | vipOrderService.updateById(one); |
| | | System.err.println("苹果流水号"+string); |
| | | PrintWriter out = response.getWriter(); |
| | | out.write("success"); |
| | |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 苹果内购:将订单置为已支付,并开通/顺延会员 |
| | | * 客户端回传流水号(/pay)与苹果服务器通知(/testApple)共用此方法,保证两条链路行为一致 |
| | | * |
| | | * @param one 待支付的会员订单(非空) |
| | | */ |
| | | private void completeVipOrder(TVipOrder one) { |
| | | // 幂等保护:已支付(2)或已退款(3)的订单直接返回,避免 /pay 与苹果通知两条链路重复顺延会员 |
| | | if (one.getPayState() != null && one.getPayState() != 1) { |
| | | System.err.println("苹果订单已处理,跳过开通 orderId=" + one.getId() |
| | | + ", payState=" + one.getPayState()); |
| | | return; |
| | | } |
| | | one.setPayState(2); |
| | | one.setPayTime(new Date()); |
| | | |
| | | TUser user = userService.getById(one.getUserId()); |
| | | Calendar calendar = Calendar.getInstance(); |
| | | if (user.getVipPayTime() == null) { |
| | | // 首次充值会员:记录首次充值时间,会员到期时间从当前时间起算 |
| | | user.setVipPayTime(new Date()); |
| | | calendar.setTime(new Date()); |
| | | } else if (user.getVipEndTime().getTime() < System.currentTimeMillis()) { |
| | | // 非首次且会员已到期:从当前时间重新起算 |
| | | calendar.setTime(new Date()); |
| | | } else { |
| | | // 非首次且会员未到期:在原到期时间基础上顺延 |
| | | calendar.setTime(user.getVipEndTime()); |
| | | } |
| | | calendar.add(Calendar.MONTH, one.getCount()); |
| | | Date vipEndTime = calendar.getTime(); |
| | | vipEndTime.setHours(23); |
| | | vipEndTime.setMinutes(59); |
| | | vipEndTime.setSeconds(59); |
| | | one.setTime(vipEndTime); |
| | | user.setVipEndTime(vipEndTime); |
| | | userService.updateById(user); |
| | | // 支付成功,订单状态置为已支付 |
| | | vipOrderService.updateById(one); |
| | | } |
| | | |
| | | /** |
| | |
| | | System.err.println("data"+data); |
| | | // 苹果流水号 |
| | | String string = transactionInfo.getString("originalTransactionId"); |
| | | String transactionId = transactionInfo.getString("transactionId"); |
| | | // 订单匹配:优先按本次交易的 transactionId,匹配不到再退回 originalTransactionId |
| | | TVipOrder one = vipOrderService.getOne(new QueryWrapper<TVipOrder>() |
| | | .eq("payType", 3) |
| | | .eq("transactionId", transactionId) |
| | | .last("limit 1")); |
| | | if (one == null) { |
| | | one = vipOrderService.getOne(new QueryWrapper<TVipOrder>() |
| | | .eq("payType", 3) |
| | | .eq("transactionId", string) |
| | | .eq("payType", 3)); |
| | | .last("limit 1")); |
| | | } |
| | | if (one!=null && one.getPayState() == 2){ |
| | | one.setPayState(3); |
| | | one.setBackTime(new Date()); |
| | |
| | | byId1.setVipPayTime(tVipOrder.getPayTime()); |
| | | userService.updateById(byId1); |
| | | } |
| | | } |
| | | // 退款成功,更新订单状态 |
| | | vipOrderService.updateById(one); |
| | | } |
| | | System.err.println("苹果流水号"+string); |
| | | PrintWriter out = response.getWriter(); |
| | | out.write("success"); |