深入支付宝支付扫描支付-跳转支付宝二维码页面支付与自定义生成二维码支付-2跳转固定的支付宝页面进行扫码支付

1、前端-使用window.location.href来请求接口不要使用ajax,我们请求后台支付接口后要跳转到支付宝的支付页面,安全起见,这里入参传订单ID就够了,使用订单ID从后台拿订单数据

2、控制器

 @ApiOperation("根据订单ID生成支付宝支付二维码")
    @GetMapping("/alipay")
    public String alipay(String orderId, HttpServletResponse response) throws AlipayApiException {
       return orderService.alipay(orderId, response);

    }

3、支付业务,支付宝接口文档参考“电脑网址支付——alipay.trade.page.pay(统一收单下单并支付页面接口)

    @Override
    public String alipay(String orderId, HttpServletResponse servletResponse) throws AlipayApiException {
        ServiceOrder order = orderMapper.selectById(orderId);//订单校验?如剔除订单项中已被置为删除的
        AlipayVo vo = new AlipayVo();
        vo.setOut_trade_no(order.getOrderNo());
        vo.setTotal_amount(String.valueOf(order.getPayPrice()));
        vo.setSubject("jwolf测试");
        vo.setProduct_code("FAST_INSTANT_TRADE_PAY"); //这个是固定的
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setBizContent(JSON.toJSONString(vo));
        request.setReturnUrl(alipayReturnUrl);
        request.setNotifyUrl(alipayNotifyUrl);
        // 执行支付宝请求,其实就是httpclient请求
        // 注意这里使用的是AlipayTradePagePayRequest,返回的是response.getBody(),与自定义二维码不同
        AlipayTradePagePayResponse response = alipayClient.pageExecute(request);
        if (!response.isSuccess()) {
            throw new CommonException("支付异常");
        }  
        return response.getBody();
    }

4、返回给页面的是如下字符串,就是一个表单,表单会立即提交然后生成二维码到支付宝的固定页面,下面的form表单是带有returnURL的。支付宝扫描支付成功后进入显示支付宝支付成功,然后页面定时器重定向到商户定义的returnURL接口。这就是同步回调。支付宝还会调用配置给它的异步回调接口告知商户后台,商户后台接收到回调请求开始处理自身业务,然后返回给支付宝“SUCCESS”,如果支付宝一直没有及时收到响应会进行衰减请求

5、同步通知。前后端分离需要自己拼接HTML页面,比较麻烦,然后response响应回去,没分离则直接跳视图填充数据就OK了

    public void alipayReturnUrl(HttpServletRequest request, HttpServletResponse response) throws IOException, AlipayApiException {
        log.info("支付宝同步回调");
        //获取支付宝GET过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决,这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        boolean signVerified = AlipaySignature.rsaCheckV1(params, zfbPublicKey, AlipayClientConfiguration.charset, AlipayClientConfiguration.signType);
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        if (!signVerified) {
            out.println("<html>验签失败</html>");
        }
        //商户订单号
        String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
        //支付宝交易号
        String tradeNo = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
        String totalAmount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8");
        String tradeStatus = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");
        ServiceOrder order = orderMapper.selectOne(new QueryWrapper<ServiceOrder>().eq("order_no", out_trade_no));
        String msg = tradeStatus.equals("TRADE_SUCCESS") ? "支付成功" : "支付失败";
        msg += JSON.toJSONString(order);
        //前后端分离需要自己拼接HTML页面,比较麻烦,然后response响应回去,没分离则直接跳视图就可以了
        out.println("<html>" + msg + "</html>");

    }

6、异步通知,请求参数处理和验签都和同步通知一样,不同的是同步通知是返回一个页面,这里要修改订单状态,即支付后续逻辑,注意幂等,不要出现两次“发货”。商户的自身业务最好异步执行,可以避免执行失败或超时导致支付宝再次回调,可能会有幂等问题。最好是异步处理支付成功后的业务。异步业务最好多打印日志以备对账使用,这时的订单状态应该是支付成功与订单完成中间的一个“发货”过渡状态,异步业务正常执行完就修改订单状态为完成,而处理失败了可采取人工干预等

  @Override
    public String alipayNotifyUrl(HttpServletRequest request) throws AlipayApiException {
        log.info("支付宝异步回调");
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决,这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        boolean flag = AlipaySignature.rsaCheckV1(params, zfbPublicKey, AlipayClientConfiguration.charset, AlipayClientConfiguration.signType);
        // 获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
        if (flag == true) {// 验证成功
            String trade_status = request.getParameter("trade_status"); // 交易状态
            String out_trade_no = request.getParameter("out_trade_no"); // 获取订单号
            log.info("回调过程获取的订单编号:{},订单状态:{}", out_trade_no, trade_status);        
            if (!"TRADE_SUCCESS".equals(trade_status)) {
                return "";
            }
            log.info("支付宝订单支付成功!开始本地支付成功后业务");
            int update = orderMapper.update(new ServiceOrder().setStatus(Constants.OrderStatus.PAY_OK.getOrderStatus()), new QueryWrapper<ServiceOrder>().eq("order_no", out_trade_no).eq("status", Constants.OrderStatus.NO_PAY.getOrderStatus()));
            if (update != 1) {
                log.error("支付成功,但跟新订单状态为处理出现失败,订单号:{}", out_trade_no);
                return "";
            } else {
                //异步处理该订单。收了钱不能退款,告诉用户成功。异步处理订单如有错误需要人工处理。
                asyncProcessOrder(out_trade_no);
                return "SUCCESS";
            }
        }
        return "";
    }

 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
支付宝小程序扫码跳转指定页面的实现方式是在小程序的app.js文件中的onLaunch方法中获取到二维码的参数,并将其存储在全局变量中。具体的代码如下所示:\[1\]\[2\] ```javascript onLaunch(options) { // 获取关联普通链接二维码的码值(即二维码地址),放到全局变量qrCode中 if (options.query && options.query.qrCode) { this.qrCode = options.query.qrCode; } } ``` 在二维码链接的地址中,包含了需要跳转页面信息。例如,如果二维码链接的地址为https://www.test.com/abc,则在小程序中扫描二维码后,可以通过截取字符串的方式获取到具体需要使用的参数。\[3\]通过这些参数,可以实现在支付宝小程序中跳转到指定页面。 #### 引用[.reference_title] - *1* [记录支付宝微信小程序扫码进入指定页面](https://blog.csdn.net/weixin_53224223/article/details/127451226)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [实现支付宝APP扫码跳转小程序并传参](https://blog.csdn.net/2301_77281342/article/details/129797966)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值