springboot功能模块之支付宝沙箱支付

easy支付官方文档:https://opendocs.alipay.com/open/009ys9
通用版文档:https://opendocs.alipay.com/open/02np94

一、 沙箱支付

1.1什么是沙箱支付

支付宝沙箱支付(Alipay Sandbox Payment)是支付宝提供的一个模拟支付环境,用于开发和测试支付宝支付功能的开发者工具。在真实的支付宝环境中进行支付开发和测试可能涉及真实资金和真实用户账户,而沙箱环境则提供了一个安全、隔离的环境,使开发者能够模拟支付过程,测试支付功能,而不会使用真实资金。

使用支付宝沙箱支付环境,开发者可以模拟各种支付场景,包括交易创建、支付请求、支付回调等,以验证支付功能的正确性和稳定性。沙箱环境中的所有交易和数据都是虚拟的,不会产生真实的交易或资金流动。

支付宝沙箱支付提供了开发者工具和接口,使开发者能够在模拟环境下进行支付流程的调试和测试。开发者可以在沙箱环境中创建测试账户、配置模拟的交易金额和状态,使用沙箱环境中的接口进行支付操作,并模拟支付回调接口接收支付结果。

通过使用支付宝沙箱支付,开发者可以更安全、更有效地进行支付功能的开发和测试,避免了对真实环境的影响和风险。一旦支付功能在沙箱环境中验证通过,开发者可以将其部署到真实的支付宝生产环境中,与真实用户进行交互和支付。

1.2配置沙箱账号

打开沙箱地址:登录 - 支付宝

需要获取:AppId、支付宝网关地址、应用私钥、支付宝公钥

1.3配置秘钥(自定义密钥)

下载安装支付宝开放平台开发助手:小程序文档 - 支付宝文档中心

安装完成之后,点击“支付宝开放平台开发助手”开始生成密钥。

选择密钥方式,选择RSA2方式,最后点击生成密钥即可生成得到私钥和公钥。

1.4生成支付宝公钥

根据支付宝开放平台开发助手生成的应用公钥,生成支付宝公钥:

找到支付宝开放平台的沙箱应用一栏,选择“开发信息”接口加签方式中的自定义密钥方式,点击设置并查看按钮:

生成支付宝公钥,如下:

二、开发接入

2.1配置依赖

 <!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-easysdk -->
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>4.35.79.ALL</version>
        </dependency>

2.2配置AlipayConfig

开发文档:小程序文档 - 支付宝文档中心

第一步:修改沙箱支付配置参数:

alipay:
  appId: xxx
  appPrivateKey: xxx
  alipayPublicKey: xxx
  notifyUrl: http://xxx/alipay/notify

第二步:写配置类

@Component
@Data
@ConfigurationProperties(prefix = "alipay")
public class AliPayConfig {

    private String appId;
    private String appPrivateKey;
    private String alipayPublicKey;
    private String notifyUrl;

}

2.3修改订单生成代码

@RestController
@RequestMapping("/alipay")
public class AliPayController {

    // 支付宝沙箱网关地址
    private static final String GATEWAY_URL = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
    private static final String FORMAT = "JSON";
    private static final String CHARSET = "UTF-8";
    //签名方式
    private static final String SIGN_TYPE = "RSA2";

    @Resource
    private AliPayConfig aliPayConfig;

    @Resource
    private OrdersServiceImpl ordersService;

    @GetMapping("/pay")  //  /alipay/pay?orderNo=xxx
    public void pay(String orderNo, HttpServletResponse httpResponse) throws Exception {
        // 查询订单信息
        Orders orders = ordersService.selectByOrderNo(orderNo);
        if (orders == null) {
            return;
        }
        // 1. 创建Client,通用SDK提供的Client,负责调用支付宝的API
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);

        // 2. 创建 Request并设置Request参数
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();  // 发送请求的 Request类
        request.setNotifyUrl(aliPayConfig.getNotifyUrl());
        JSONObject bizContent = new JSONObject();
        bizContent.set("out_trade_no", orders.getOrderNo());  // 我们自己生成的订单编号
        bizContent.set("total_amount", orders.getTotal()); // 订单的总金额
        bizContent.set("subject", orders.getGoodsName());   // 支付的名称
        bizContent.set("product_code", "FAST_INSTANT_TRADE_PAY");  // 固定配置
        request.setBizContent(bizContent.toString());
        request.setReturnUrl("http://localhost:5173/orders"); // 支付完成后自动跳转到本地页面的路径
        // 执行请求,拿到响应的结果,返回给浏览器
        String form = "";
        try {
            form = alipayClient.pageExecute(request).getBody(); // 调用SDK生成表单
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        httpResponse.setContentType("text/html;charset=" + CHARSET);
        httpResponse.getWriter().write(form);// 直接将完整的表单html输出到页面
        httpResponse.getWriter().flush();
        httpResponse.getWriter().close();
    }

    @PostMapping("/notify")  // 注意这里必须是POST接口
    public void payNotify(HttpServletRequest request) throws Exception {
        if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
            System.out.println("=========支付宝异步回调========");

            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String name : requestParams.keySet()) {
                params.put(name, request.getParameter(name));
            }

            String sign = params.get("sign");
            String content = AlipaySignature.getSignCheckContentV1(params);
            boolean checkSignature = AlipaySignature.rsa256CheckContent(content, sign, aliPayConfig.getAlipayPublicKey(), "UTF-8"); // 验证签名
            // 支付宝验签
            if (checkSignature) {
                // 验签通过
                System.out.println("交易名称: " + params.get("subject"));
                System.out.println("交易状态: " + params.get("trade_status"));
                System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
                System.out.println("商户订单号: " + params.get("out_trade_no"));
                System.out.println("交易金额: " + params.get("total_amount"));
                System.out.println("买家在支付宝唯一id: " + params.get("buyer_id"));
                System.out.println("买家付款时间: " + params.get("gmt_payment"));
                System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));


                String tradeNo = params.get("out_trade_no");
                String gmtPayment = params.get("gmt_payment");
                String alipayTradeNo = params.get("trade_no");
                // 更新订单状态为已支付,设置支付信息
                Orders orders = ordersService.selectByOrderNo(tradeNo);
                orders.setStatus("已支付");
                orders.setPayTime(gmtPayment);
                orders.setPayNo(alipayTradeNo);
                ordersService.updateById(orders);
            }
        }
    }

}

2.4退款功能


   @GetMapping("/return")
    public Result returnPay(AliPay aliPay) throws AlipayApiException {
        // 7天无理由退款
        String now = DateUtil.now();
        Orders orders = ordersMapper.getByNo(aliPay.getTraceNo());
        if (orders != null) {
            // hutool工具类,判断时间间隔
            long between = DateUtil.between(DateUtil.parseDateTime(orders.getPaymentTime()), DateUtil.parseDateTime(now), DateUnit.DAY);
            if (between > 7) {
                return Result.error("-1", "该订单已超过7天,不支持退款");
            }
        }


        // 1. 创建Client,通用SDK提供的Client,负责调用支付宝的API
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL,
                aliPayConfig.getAppId(), aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET,
                aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
        // 2. 创建 Request,设置参数
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.set("trade_no", aliPay.getAlipayTraceNo());  // 支付宝回调的订单流水号
        bizContent.set("refund_amount", aliPay.getTotalAmount());  // 订单的总金额
        bizContent.set("out_request_no", aliPay.getTraceNo());   //  我的订单编号

        // 返回参数选项,按需传入
        //JSONArray queryOptions = new JSONArray();
        //queryOptions.add("refund_detail_item_list");
        //bizContent.put("query_options", queryOptions);

        request.setBizContent(bizContent.toString());

        // 3. 执行请求
        AlipayTradeRefundResponse response = alipayClient.execute(request);
        if (response.isSuccess()) {  // 退款成功,isSuccess 为true
            System.out.println("调用成功");

            // 4. 更新数据库状态
            ordersMapper.updatePayState(aliPay.getTraceNo(), "已退款", now);
            return Result.success();
        } else {   // 退款失败,isSuccess 为false
            System.out.println(response.getBody());
            return Result.error(response.getCode(), response.getBody());
        }

    }


2.5 真实应用支付配置

a. 修改支付成功拼接的url(无dev)

b.修改appid,修改成,真实应用的appid即可

https://opendocs.alipay.com/open/03k9zr?pathHash=38327ac8

https://opensupport.alipay.com/support/FAQ/f3ab72f1-af25-4f88-8ff5-fbb66be1aa11

 

### 支付宝沙箱支付系统论文框架结构 撰写关于支付宝沙箱支付系统的论文时,可以从以下几个方面构建完整的框架结构。以下是详细的章节划分及其内容概述: #### 1. 论文背景与意义 该部分应阐述支付宝沙箱支付的研究背景和发展现状,强调其在电子商务中的重要性和应用前景。同时,需说明研究此主题的意义和目标。 - **1.1 背景介绍** 随着互联网技术的迅猛发展,电子支付已成为日常生活中不可或缺的一部分[^5]。支付宝作为中国领先的第三方支付平台之一,提供了多种便捷的服务,其中沙箱环境为开发者测试支付功能提供了便利条件。 - **1.2 研究目的与意义** 对于企业和个人开发者而言,掌握如何利用支付宝沙箱进行支付集成至关重要。这不仅能降低开发成本,还能提升用户体验。因此,深入探讨支付宝沙箱支付机制具有重要的理论价值和实践指导作用[^2]。 #### 2. 相关概念和技术基础 详细介绍涉及的关键技术和术语,帮助读者理解整个系统的工作原理。 - **2.1 支付宝沙箱基本概念** 解释什么是支付宝沙箱(Sandbox),它的主要用途是什么?为什么要在正式上线前使用沙箱来进行模拟测试? - **2.2 技术栈描述** 描述用于实现该项目的主要技术工具,例如Spring Boot框架、MyBatis持久层框架、MySQL数据库管理以及Ajax前端交互技术等[^1]。如果涉及到前后端分离,则还需提及Vue.js或其他类似的JavaScript库/框架的作用[^3]。 #### 3. 系统设计与实现 这是整篇论文的核心部分,具体讲解系统的设计理念、架构图解及其实现细节。 - **3.1 整体架构设计** 提供一张清晰明了的整体架构图,并配以文字解释各个组成部分之间的关系。比如采用的是典型的三层架构还是微服务架构形式? - **3.2 数据库设计方案** 展示数据库表结构设计文档,包括但不限于用户信息表、订单详情表等相关联的数据模型定义[^2]。 - **3.3 关键模块分析** - 用户认证授权流程; - 商品购买下单逻辑; - 实际支付环节处理方法(含沙箱配置步骤); #### 4. 功能演示与案例分享 通过实际运行截图或者视频链接等形式直观呈现已完成的功能效果,并选取几个典型场景加以说明。 #### 5. 性能评估与安全性考量 讨论当前版本存在的局限性以及未来可能改进的方向,特别是针对安全防护措施方面的思考。 - **5.1 测试结果总结** 列举几组实验数据对比图表来验证方案的有效性。 - **5.2 安全隐患防范策略** 结合OWASP Top Ten等行业标准列举常见威胁类型,并给出针对性解决方案建议。 #### 6. 结论与展望 最后归纳全文要点重申研究成果的重要性,并对未来发展趋势做出预测。 --- ### 示例代码片段 以下是一个简单的RESTful API接口示例,展示了如何接收来自客户端发起的一笔虚拟交易请求并将之转发至支付宝官方服务器完成最终结算操作的过程: ```java @RestController @RequestMapping("/api/payments") public class PaymentController { @PostMapping("/createOrder") public ResponseEntity<String> createOrder(@RequestBody OrderRequest request){ try{ AlipayClient alipayClient = new DefaultAlipayClient( "https://openapi.alipaydev.com/gateway.do", "<your_app_id>", "<your_private_key>", "json", "UTF-8", "<alipay_public_key>" ); AlipayTradePagePayRequest aliRequest = new AlipayTradePagePayRequest(); JSONObject bizContentJsonObj=new JSONObject(); bizContentJsonObj.put("out_trade_no",request.getOrderId()); bizContentJsonObj.put("total_amount",request.getAmount().toString()); bizContentJsonObj.put("subject","Test Product"); bizContentJsonObj.put("product_code","FAST_INSTANT_TRADE_PAY"); aliRequest.setBizContent(bizContentJsonObj.toString()); String result=alipayClient.pageExecute(aliRequest).getBody(); return ResponseEntity.ok(result); }catch(Exception e){ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage()); } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烟雨平生9527

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值