springboot接入沙箱支付宝的支付流程

支付宝沙箱环境文档

支付宝沙箱账号-开放平台管理

首先梳理一下支付流程:

  1. 用户点击下单按钮
  2. 商户系统生成订单,并构造支付请求,将请求发送给支付宝
  3. 在支付宝APP上,支付宝为用户展示相关信息,用户输入密码完成支付
  4. 支付完毕后将支付结果返回给商户系统(或者商户系统主动查询结果)
  5. 商户系统侧将订单支付结果展示给用户

 

粗略使用说明

1.下载支付宝SDK https://opendocs.alipay.com/common/02kkv2?pathHash=358ff034

2.生成二维码使用说明

通过zxing的jar包为一个链接生成专用二维码 使用说明

在生成二维码的时候我们会生成对应的订单,扫描的时候只需要传id参数即可

3.扫码请求的使用示例

复制代码
    @RequestMapping("/alipay")
    public void doPost(HttpServletRequest httpRequest,
                       HttpServletResponse httpResponse) throws IOException, AlipayApiException {
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, APP_ID, APP_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE);
        //获得初始化的AlipayClient
        AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();//创建API对应的request
        alipayRequest.setNotifyUrl(public_network+"/orders/paynotify");//在公共参数中设置回跳和通知地址
        alipayRequest.setBizContent("{" +
                "    \"out_trade_no\":\"202410100010101001\"," +
                "    \"total_amount\":0.1," +
                "    \"subject\":\"Iphone6 16G\"," +
                "    \"product_code\":\"QUICK_WAP_WAY\"" +
                "  }");//填充业务参数
        String form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单
        httpResponse.setContentType("text/html;charset=" + AlipayConfig.CHARSET);
        httpResponse.getWriter().write(form);//直接将完整的表单html输出到页面
        httpResponse.getWriter().flush();
    }
复制代码

out_trade_no:要求商户系统内唯一

product_code:文档没写,默认是不可改的固定值

4.主动查询支付结果示例(此外包括上述扫码请求时的通知地址,)
复制代码
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","GBK","alipay_public_key","RSA2");
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
JSONObject bizContent = new JSONObject();
bizContent.put("out_trade_no", "20150320010101001");
//bizContent.put("trade_no", "2014112611001004680073956707");
request.setBizContent(bizContent.toString());
AlipayTradeQueryResponse response = alipayClient.execute(request);
if(response.isSuccess()){
    System.out.println("调用成功");
} else {
    System.out.println("调用失败");
}
复制代码

out_trade_no与trade_no二选一即可查询

 回调接口:alipayRequest.setNotifyUrl()中设置回调地址

复制代码
 @PostMapping("/paynotify")
    public void paynotify(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException, AlipayApiException, IOException {
        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] + ",";
            }
            params.put(name, valueStr);
        }
        boolean verify_result = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2");
        if (verify_result) {//验证成功
            //商户订单号
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
            //支付宝交易号
            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
            //交易状态
            String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");
            if (trade_status.equals("TRADE_SUCCESS")) {//交易成功

            }
            response.getWriter().write("success");
        } else {
            response.getWriter().write("fail");
        }
    }
复制代码

 

实际设计方案:

 

表结构设计说明:

为什么要设计一个订单明细表:一个订单可能包含多个产品,是一对多的关系

为什么要设计一个支付记录表:在支付宝的使用中,如果我们把orders的id作为out_trade_no,那么如果我们在支付出现异常后,由于同一个out_trade_no不能重复使用而无法继续。因此我们引入记录表:记录表的pay_no作为out_trade_no,这样可以防止支付失败的异常问题。简单来说,out_trade_no在这个设计结构中不论使用结果如何都永远只会使用一次,并且在使用完成后会修改主表order的status

 

后端支付宝接口使用流程

1.点击支付按钮时,将商品记录填入记录表中,再将商品填入商品订单,根据用户id和商品信息生成二维码,二维码最少提供支付宝支付需要的唯一单号、总价格、商品信息。将二维码的base64返回给前端展示

2.用户扫码后,在支付宝同意支付并由支付宝返回支付信息

3.支付完成后按理来说,我们的表信息应该已经修改。这里就需要我们主动向支付宝发起请求,如果支付已经完成,则修改订单表与支付记录表的状态。

此外我们也可以在扫码下单处增加回调,支付完成并且成功后同样修改订单表和支付记录表的状态

posted @   天启A  阅读(139)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示