diff --git a/server/like-admin/src/main/java/com/mdd/admin/service/impl/ChannelOaMenusServiceImpl.java b/server/like-admin/src/main/java/com/mdd/admin/service/impl/ChannelOaMenusServiceImpl.java index ecf7558d..f1e9b8ec 100644 --- a/server/like-admin/src/main/java/com/mdd/admin/service/impl/ChannelOaMenusServiceImpl.java +++ b/server/like-admin/src/main/java/com/mdd/admin/service/impl/ChannelOaMenusServiceImpl.java @@ -5,6 +5,7 @@ import com.alibaba.fastjson2.JSONArray; import com.baomidou.mybatisplus.core.toolkit.Assert; import com.mdd.admin.service.IChannelOaMenusService; import com.mdd.common.exception.OperateException; +import com.mdd.common.plugin.wechat.WxMnpDriver; import com.mdd.common.util.*; import me.chanjar.weixin.common.bean.menu.WxMenu; import me.chanjar.weixin.common.bean.menu.WxMenuButton; @@ -112,7 +113,7 @@ public class ChannelOaMenusServiceImpl implements IChannelOaMenusService { WxMenu wxMenu = new WxMenu(); wxMenu.setButtons(menuButtons); - WxMpService wxMpService = WeChatUtils.official(); + WxMpService wxMpService = WxMnpDriver.oa(); WxMpMenuService wxMpMenuService = new WxMpMenuServiceImpl(wxMpService); wxMpMenuService.menuCreate(wxMenu); } catch (WxErrorException e) { diff --git a/server/like-common/pom.xml b/server/like-common/pom.xml index f341b8bb..a6698199 100644 --- a/server/like-common/pom.xml +++ b/server/like-common/pom.xml @@ -208,7 +208,6 @@ com.github.binarywang weixin-java-pay - 4.4.0 diff --git a/server/like-common/src/main/java/com/mdd/common/plugin/wechat/WxPayDriver.java b/server/like-common/src/main/java/com/mdd/common/plugin/wechat/WxPayDriver.java index 3e25c2d3..9c252071 100644 --- a/server/like-common/src/main/java/com/mdd/common/plugin/wechat/WxPayDriver.java +++ b/server/like-common/src/main/java/com/mdd/common/plugin/wechat/WxPayDriver.java @@ -24,11 +24,17 @@ public class WxPayDriver { private static WxPayService wxPayService; + /** + * 注入支付配置依赖 + */ @Resource public void setDevPayConfigMapper(DevPayConfigMapper devPayConfigMapper) { WxPayDriver.devPayConfigMapper = devPayConfigMapper; } + /** + * 注入微信支付依赖 + */ @Resource public void setWxPayService(WxPayService wxPayService) { WxPayDriver.wxPayService = wxPayService; diff --git a/server/like-common/src/main/java/com/mdd/common/util/AmountUtil.java b/server/like-common/src/main/java/com/mdd/common/util/AmountUtil.java new file mode 100644 index 00000000..1d9ca05f --- /dev/null +++ b/server/like-common/src/main/java/com/mdd/common/util/AmountUtil.java @@ -0,0 +1,61 @@ +package com.mdd.common.util; + +import com.baomidou.mybatisplus.core.toolkit.Assert; + +import java.math.BigDecimal; + +/** + * 金额处理工具 + */ +public class AmountUtil { + + private AmountUtil() {} + + /** + * 将单位为元的金额转换为单位为分 + * + * @param yuan 单位为元的字符型值 + * @return int + */ + public static int yuan2Fen(String yuan) { + int value; + + try { + BigDecimal var1 = new BigDecimal(yuan); + BigDecimal var2 = new BigDecimal(100); + BigDecimal var3 = var1.multiply(var2); + value = Integer.parseInt(var3.stripTrailingZeros().toPlainString()); + } catch (Exception e) { + throw new IllegalArgumentException(String.format("非法金额[%s]", yuan)); + } + + Assert.isTrue(value >= 0, String.format("非法金额[%s]", yuan)); + return value; + } + + /** + * 将单位为分的金额转换为单位为元 + * + * @param fen 单位为分的字符型值 + * @return String + */ + public static String fen2Yuan(int fen) { + BigDecimal var1 = new BigDecimal(fen); + BigDecimal var2 = new BigDecimal(100); + BigDecimal var3 = var1.divide(var2, 3); + return var3.stripTrailingZeros().toPlainString(); + } + + /** + * 将单位为分的金额转换为单位为元 + * + * @param fen 单位为分的字符型值 + * @return BigDecimal + */ + public static BigDecimal fen2YuanDecimal(int fen) { + BigDecimal var1 = new BigDecimal(fen); + BigDecimal var2 = new BigDecimal(100); + return var1.divide(var2, 3); + } + +} diff --git a/server/like-front/src/main/java/com/mdd/front/controller/PayController.java b/server/like-front/src/main/java/com/mdd/front/controller/PayController.java index a6c7523d..2f24d194 100644 --- a/server/like-front/src/main/java/com/mdd/front/controller/PayController.java +++ b/server/like-front/src/main/java/com/mdd/front/controller/PayController.java @@ -1,25 +1,36 @@ package com.mdd.front.controller; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result; import com.mdd.common.aop.NotLogin; import com.mdd.common.core.AjaxResult; +import com.mdd.common.entity.RechargeOrder; +import com.mdd.common.exception.OperateException; +import com.mdd.common.mapper.RechargeOrderMapper; import com.mdd.front.LikeFrontThreadLocal; import com.mdd.front.service.IPayService; -import com.mdd.front.validate.PayPrepayValidate; +import com.mdd.front.validate.PaymentValidate; +import com.mdd.front.validate.users.UserUpdateValidate; import io.swagger.annotations.Api; -import io.swagger.models.auth.In; -import io.swagger.v3.oas.annotations.parameters.RequestBody; +import org.springframework.util.Assert; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; +import java.util.LinkedHashMap; +import java.util.Map; @RestController @RequestMapping("/api/pay") @Api(tags = "支付管理") public class PayController { + @Resource + RechargeOrderMapper rechargeOrderMapper; + @Resource IPayService iPayService; @@ -28,14 +39,57 @@ public class PayController { * * @return AjaxResult */ - @NotLogin @PostMapping("/prepay") - public AjaxResult prepay(@Validated @RequestBody PayPrepayValidate payPrepayValidate) throws Exception { - String scene = payPrepayValidate.getScene(); - Integer orderId = payPrepayValidate.getOrderId(); + public AjaxResult prepay(@Validated @RequestBody PaymentValidate paymentValidate) { + String scene = paymentValidate.getScene(); + Integer payWay = paymentValidate.getPayWay(); + Integer orderId = paymentValidate.getOrderId(); Integer terminal = LikeFrontThreadLocal.getTerminal(); - iPayService.prepay(scene, orderId, terminal); + // 订单处理 + int payStatus = 0; + switch (scene) { + case "recharge": + RechargeOrder rechargeOrder = rechargeOrderMapper.selectOne( + new QueryWrapper() + .eq("id", orderId) + .last("limit 1")); + + Assert.notNull(rechargeOrder, "订单不存在"); + + paymentValidate.setOrderSn(rechargeOrder.getOrderSn()); + paymentValidate.setUserId(rechargeOrder.getUserId()); + paymentValidate.setOrderAmount(rechargeOrder.getOrderAmount()); + paymentValidate.setDescription("余额充值"); + payStatus = rechargeOrder.getPayStatus(); + break; + case "order": + // todo 其它订单处理 + break; + } + + // 订单校验 + if (payStatus != 0) { + throw new OperateException("订单已支付"); + } + + // 发起支付 + try { + switch (payWay) { + case 1: + iPayService.walletPay(); + break; + case 2: + WxPayUnifiedOrderV3Result.JsapiResult result = iPayService.wxPay(paymentValidate, terminal); + return AjaxResult.success(result); + case 3: + iPayService.aliPay(); + break; + } + } catch (Exception e) { + throw new OperateException(e.getMessage()); + } + return AjaxResult.success(); } diff --git a/server/like-front/src/main/java/com/mdd/front/service/IPayService.java b/server/like-front/src/main/java/com/mdd/front/service/IPayService.java index 6922e231..30aaa043 100644 --- a/server/like-front/src/main/java/com/mdd/front/service/IPayService.java +++ b/server/like-front/src/main/java/com/mdd/front/service/IPayService.java @@ -1,10 +1,19 @@ package com.mdd.front.service; +import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result; +import com.mdd.front.validate.PaymentValidate; + /** * 支付接口服务类 */ public interface IPayService { - void prepay(String scene, Integer orderId, Integer terminal) throws Exception; + void walletPay(); + + WxPayUnifiedOrderV3Result.JsapiResult wxPay(PaymentValidate params, Integer terminal) throws Exception; + + void aliPay(); + + void handlePaidNotify(); } diff --git a/server/like-front/src/main/java/com/mdd/front/service/impl/PayServiceImpl.java b/server/like-front/src/main/java/com/mdd/front/service/impl/PayServiceImpl.java index 5675a65b..9aa03e55 100644 --- a/server/like-front/src/main/java/com/mdd/front/service/impl/PayServiceImpl.java +++ b/server/like-front/src/main/java/com/mdd/front/service/impl/PayServiceImpl.java @@ -5,12 +5,16 @@ import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request; import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result; import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum; import com.github.binarywang.wxpay.service.WxPayService; -import com.mdd.common.entity.RechargeOrder; -import com.mdd.common.mapper.RechargeOrderMapper; +import com.mdd.common.entity.user.UserAuth; +import com.mdd.common.enums.ClientEnum; +import com.mdd.common.mapper.user.UserAuthMapper; import com.mdd.common.plugin.wechat.WxPayDriver; +import com.mdd.common.util.AmountUtil; +import com.mdd.common.util.IpUtils; import com.mdd.common.util.RequestUtils; +import com.mdd.common.util.StringUtils; import com.mdd.front.service.IPayService; - +import com.mdd.front.validate.PaymentValidate; import org.springframework.stereotype.Service; import javax.annotation.Resource; @@ -21,18 +25,41 @@ import java.text.SimpleDateFormat; public class PayServiceImpl implements IPayService { @Resource - RechargeOrderMapper rechargeOrderMapper; + UserAuthMapper userAuthMapper; + /** + * 零钱支付 + */ @Override - public void prepay(String scene, Integer orderId, Integer terminal) throws Exception { - RechargeOrder rechargeOrder = rechargeOrderMapper.selectOne( - new QueryWrapper() - .eq("id", orderId) - .last("limit 1")); + public void walletPay() { - String orderSn = rechargeOrder.getOrderSn(); - Integer orderAmount = 1; - String orderDesc = "余额充值"; + } + + /** + * 微信支付 + * + * @param params 支付参数 + * @param terminal 终端 + * @throws Exception 异常 + */ + @Override + public WxPayUnifiedOrderV3Result.JsapiResult wxPay(PaymentValidate params, Integer terminal) throws Exception { + // 订单参数 + Integer userId = params.getUserId(); + String orderSn = params.getOrderSn(); + BigDecimal orderAmount = params.getOrderAmount(); + String description = params.getDescription(); + + // 查询OpenId + String openId = ""; + UserAuth userAuth = userAuthMapper.selectOne(new QueryWrapper() + .eq("user_id", userId) + .eq("terminal", terminal) + .last("limit 1")); + System.out.println(userAuth); + if (StringUtils.isNotNull(userAuth)) { + openId = userAuth.getOpenid(); + } // 失效时间 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); @@ -42,27 +69,51 @@ public class PayServiceImpl implements IPayService { // 订单信息 WxPayUnifiedOrderV3Request wxPayUnifiedOrderV3Request = new WxPayUnifiedOrderV3Request(); wxPayUnifiedOrderV3Request.setOutTradeNo(orderSn); - wxPayUnifiedOrderV3Request.setDescription(orderDesc); + wxPayUnifiedOrderV3Request.setDescription(description); wxPayUnifiedOrderV3Request.setTimeExpire(timeExpire); wxPayUnifiedOrderV3Request.setNotifyUrl(RequestUtils.uri() + "/api/pay/notifyMnp"); - - // 订单金额 WxPayUnifiedOrderV3Request.Amount amount = new WxPayUnifiedOrderV3Request.Amount(); - amount.setTotal(orderAmount); + amount.setTotal(AmountUtil.yuan2Fen(orderAmount.toPlainString())); amount.setCurrency("CNY"); wxPayUnifiedOrderV3Request.setAmount(amount); // 付款人员 WxPayUnifiedOrderV3Request.Payer payer = new WxPayUnifiedOrderV3Request.Payer(); - payer.setOpenid(""); + payer.setOpenid(openId); + + // H5平台 + if (terminal == ClientEnum.H5.getCode()) { + WxPayUnifiedOrderV3Request.SceneInfo sceneInfo = new WxPayUnifiedOrderV3Request.SceneInfo(); + WxPayUnifiedOrderV3Request.H5Info h5Info = new WxPayUnifiedOrderV3Request.H5Info(); + h5Info.setType("android"); + sceneInfo.setH5Info(h5Info); + sceneInfo.setPayerClientIp(IpUtils.getHostIp()); + sceneInfo.setDeviceId("1"); + wxPayUnifiedOrderV3Request.setSceneInfo(sceneInfo); + } // 发起订单 WxPayService wxPayService = WxPayDriver.handler(terminal); wxPayUnifiedOrderV3Request.setPayer(payer); WxPayUnifiedOrderV3Result.JsapiResult jsapiResult = wxPayService.createOrderV3(TradeTypeEnum.JSAPI, wxPayUnifiedOrderV3Request); - System.out.println(jsapiResult); + return jsapiResult; + } + + /** + * 支付宝支付 + */ + @Override + public void aliPay() { + + } + + /** + * 支付回调处理 + */ + public void handlePaidNotify() { + } } diff --git a/server/like-front/src/main/java/com/mdd/front/validate/PayPrepayValidate.java b/server/like-front/src/main/java/com/mdd/front/validate/PayPrepayValidate.java deleted file mode 100644 index ae25f536..00000000 --- a/server/like-front/src/main/java/com/mdd/front/validate/PayPrepayValidate.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.mdd.front.validate; - -import io.swagger.annotations.ApiModel; -import lombok.Data; - -import java.io.Serializable; - -@Data -@ApiModel("预支付订单参数") -public class PayPrepayValidate implements Serializable { - - private static final long serialVersionUID = 1L; - - private String scene; - - private Integer orderId; - -} diff --git a/server/like-front/src/main/java/com/mdd/front/validate/PaymentValidate.java b/server/like-front/src/main/java/com/mdd/front/validate/PaymentValidate.java new file mode 100644 index 00000000..fc3af539 --- /dev/null +++ b/server/like-front/src/main/java/com/mdd/front/validate/PaymentValidate.java @@ -0,0 +1,37 @@ +package com.mdd.front.validate; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.math.BigDecimal; + +@Data +@ApiModel("预支付订单参数") +public class PaymentValidate implements Serializable { + + private static final long serialVersionUID = 1L; + + @NotNull(message = "scene参数缺失") + @ApiModelProperty("支付场景") + private String scene; + + @NotNull(message = "payWay参数缺失") + @ApiModelProperty("支付方式") + private Integer payWay; + + @NotNull(message = "orderId参数缺失") + @ApiModelProperty("订单ID") + private Integer orderId; + + private Integer userId; + + private String orderSn; + + private BigDecimal orderAmount; + + private String description; + +}