支付模块问题实战解决

在写这部分代码的时候可以参考支付模块中会出现的问题,怎么解决?

当中运用到redis的地方有很多,大家可以给redis做持久化和集群办证数据不丢失

调用支付宝后我这边根据实际情况做了一些更改

public void alipay() throws AlipayApiException {
        String privateKey = "<-- 沙箱帐号的应用私钥 -->";
        String alipayPublicKey = "<-- 沙箱帐号的支付宝公钥 -->";
        AlipayConfig alipayConfig = new AlipayConfig();
        alipayConfig.setServerUrl("https://openapi-sandbox.dl.alipaydev.com/gateway.do");
        alipayConfig.setAppId("<-- 沙箱帐号的AppId -->");
        alipayConfig.setPrivateKey(privateKey);
        alipayConfig.setFormat("json");
        alipayConfig.setAlipayPublicKey(alipayPublicKey);
        alipayConfig.setCharset("UTF-8");
        alipayConfig.setSignType("RSA2");
        //redis获取房屋信息
        HousesEntity housesEntity = JSONObject.parseObject(redisCache.getCacheObject(TokenConstants.TOKEN+"Houses"), HousesEntity.class);
        AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        AlipayTradePagePayModel model = new AlipayTradePagePayModel();
        //获取签名
        String sign = housesEntity.getSign();
        request.setNotifyUrl(sign);
        String only = UUID.randomUUID().toString().replaceAll("-", "");
        model.setOutTradeNo(only);
        String housesPrice = String.valueOf(housesEntity.getHousesPrice());
        model.setTotalAmount(housesPrice);
        String housesName = housesEntity.getHousesName();
        model.setSubject(housesName);
        model.setProductCode("FAST_INSTANT_TRADE_PAY");
        request.setBizModel(model);
        //AlipayTradePagePayResponse response = alipayClient.pageExecute(request, "POST");
        // 如果需要返回GET请求,请使用
        AlipayTradePagePayResponse response = alipayClient.pageExecute(request, "GET");
        String pageRedirectionData = response.getBody();
        System.out.println(pageRedirectionData);
        if (response.isSuccess()) {
            System.out.println("调用成功");
            //回调订单,将订单状态改为已支付
            //设计幂等使用redis实现
            //在将请求放入缓存之前,判断是否有相同的请求存在
            if (redisCache.getCacheObject(TokenConstants.TOKEN+only) != null){
                throw new RuntimeException("已支付");
            }
            //使用redis来存储和处理请求
            redisCache.setCacheObject(TokenConstants.TOKEN+only,housesEntity,TokenConstants.EXPIRATION, TimeUnit.HOURS);
            //回调接口安全问题
            //通过发送者请求中的签名判断验证签名
            //签名验证
            boolean verify = AlipaySignature.rsaCheckV2(response.getParams(), alipayConfig.getAlipayPublicKey(), alipayConfig.getCharset(), alipayConfig.getSignType());
            if (verify){
                //更新订单状态
                orderService.updateById(OrderEntity.builder()
                        .orderId(only)
                        .orderPayMoney(BigDecimal.valueOf(10))
                        .orderPayTime(new Date())
                        .orderStart(1)
                        .build());
            }
        } else {
            System.out.println("调用失败");
            // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
            // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
            // System.out.println(diagnosisUrl);
        }
    }

 然后这里是我写下单并且支付的一个方法

@SneakyThrows
    @Override
    public Result releaseTwoHandHouses(HousesEntity housesEntity){

        // 获取当前登录用户信息
        UserInfoEntity info = this.info();

        // 创建新的订单实体对象
        OrderEntity orderEntity = new OrderEntity();

        // 检查用户余额是否充足
        if (info.getUserBalance().compareTo(BigDecimal.valueOf(10)) < 0) {
            throw new RuntimeException("余额不足");
        }

        // 设置房屋类型和发布者ID
        housesEntity.setHousesType("二手房");
        housesEntity.setPublisherId(info.getUserId());

        // 更新当前登录用户的余额
        UserInfoEntity updatedUserInfo = userInfoService.getById(info.getUserId());
        updatedUserInfo.setUserBalance(updatedUserInfo.getUserBalance().subtract(BigDecimal.valueOf(10)));

        // 生成唯一用户Key并创建Token
        String userKey = UUID.randomUUID().toString().replace("-", "");
        HashMap<String, Object> tokenData = new HashMap<>();
        tokenData.put(JwtConstants.USER_KEY, userKey);
        String token = JwtUtils.createToken(tokenData);

        // 将房屋实体存入Redis,并设置Token过期时间
        redisCache.setCacheObject(TokenConstants.TOKEN + userKey, housesEntity, TokenConstants.EXPIRATION, TimeUnit.HOURS);

        // 防止重复提交订单
        if (redisCache.getCacheObject(TokenConstants.TOKEN + userKey) != null) {
            throw new RuntimeException("订单已提交");
        }

        // 保存订单信息
        orderEntity.builder()
                .orderName("发布二手房")
                .orderTel(info.getUserPhone())
                .orderType("发布二手房")
                .orderPayMoney(BigDecimal.valueOf(10))
                .orderPayTime(new Date())
                .orderUserId(info.getUserId())
                .orderStart(2)
                .build();
        orderService.save(orderEntity);

        //生成签名
//        String sign = AlipaySignature.rsaSign(JSONObject.toJSONString(housesEntity), "RSA2", "utf-8", "RSA2");
        String sign = "123456";
        /**
         * 发送方将需要传输的数据
         * 使用预共享的密钥(如API密钥)和加密算法(如HMAC-SHA256)对数据进行签名,生成一个签名值
         * 将签名值附加到请求数据中,一起发送给接收方。
         */
        housesEntity.setSign(sign);

        // 存储房屋信息到Redis
        redisCache.setCacheObject(TokenConstants.TOKEN + "Houses", JSONObject.toJSONString(housesEntity), TokenConstants.EXPIRATION, TimeUnit.HOURS);

        // 执行支付宝相关操作(假设这个方法用于处理支付逻辑)
        this.alipay();

        // 更新用户余额信息
        userInfoService.updateById(updatedUserInfo);

        // 保存房屋实体
        this.save(housesEntity);

        // 返回发布成功的响应结果
        return Result.success("发布成功");
    }

这整个过程中都是使用mybatis-plus进行数据库的更改(后续也会发布一个关于mybatis-plus的文章供大家参考)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值