SpringBoot 整合支付宝沙箱支付——从接入到回调

发布时间:2026/9/27 17:30:44

SpringBoot 整合支付宝沙箱支付——从接入到回调
支付是电商系统的核心功能。接入支付宝需要企业资质但支付宝提供了沙箱环境——模拟真实支付流程不需要真实商户号适合开发测试和学习。一、沙箱环境准备1. 登录开放平台打开 open.alipay.com → 控制台 → 沙箱应用2. 获取配置参数APP_ID: 9021000122691234沙箱专用 应用私钥: 生成的 RSA2 私钥 支付宝公钥: 生成的 RSA2 公钥 服务器异步通知地址: http://你的地址/pay/notify3. 沙箱账号沙箱环境提供测试买家账号买家账号: rixwby5818sandbox.com 登录密码: 111111 支付密码: 111111二、SpringBoot 集成1. 引入依赖dependencygroupIdcom.alipay.sdk/groupIdartifactIdalipay-sdk-java/artifactIdversion4.38.200.ALL/version/dependency2. 配置alipay:app-id:9021000122691234app-private-key:|-----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQ... 你的应用私钥不要写在配置里建议用Jasypt加密 -----END RSA PRIVATE KEY-----alipay-public-key:|-----BEGIN PUBLIC KEY----- MIIBIjANBgk... 支付宝公钥 -----END PUBLIC KEY-----notify-url:http://你的公网IP/pay/notifyreturn-url:http://localhost:9090/pay/returngateway-url:https://openapi-sandbox.dl.alipaydev.com/gateway.do3. 配置类ConfigurationConfigurationProperties(prefixalipay)DatapublicclassAlipayConfig{privateStringappId;privateStringappPrivateKey;privateStringalipayPublicKey;privateStringnotifyUrl;privateStringreturnUrl;privateStringgatewayUrl;BeanpublicAlipayClientalipayClient(){returnnewDefaultAlipayClient(gatewayUrl,appId,appPrivateKey,json,utf-8,alipayPublicKey,RSA2);}}三、统一下单接口ServicepublicclassAlipayService{AutowiredprivateAlipayClientalipayClient;AutowiredprivateAlipayConfigalipayConfig;/** * 创建支付订单返回支付页面表单 */publicStringcreatePay(StringorderNo,BigDecimalamount,Stringsubject){AlipayTradePagePayRequestrequestnewAlipayTradePagePayRequest();// 同步回调地址用户支付完成后跳转request.setReturnUrl(alipayConfig.getReturnUrl());// 异步回调地址支付宝服务器通知request.setNotifyUrl(alipayConfig.getNotifyUrl());JSONObjectbiznewJSONObject();biz.put(out_trade_no,orderNo);// 商户订单号biz.put(total_amount,amount.toString());// 支付金额biz.put(subject,subject);// 订单标题biz.put(product_code,FAST_INSTANT_TRADE_PAY);// 电脑网站支付request.setBizContent(biz.toJSONString());try{AlipayTradePagePayResponseresponsealipayClient.pageExecute(request);if(response.isSuccess()){returnresponse.getBody();// 返回 HTML 表单}}catch(AlipayApiExceptione){thrownewRuntimeException(支付宝下单失败,e);}returnnull;}}四、ControllerRestControllerRequestMapping(/pay)publicclassPayController{AutowiredprivateAlipayServicealipayService;/** * 发起支付 */PostMapping(/create)publicResultVOStringcreatePay(RequestBodyPayDTOdto){// 生成订单号StringorderNoORDIdUtil.simpleUUID().toUpperCase();StringformalipayService.createPay(orderNo,dto.getAmount(),dto.getSubject());returnResultVO.success(form);}/** * 同步回调用户支付完成后跳转到此页面 */GetMapping(/return)publicStringreturnUrl(HttpServletRequestrequest){// 获取支付宝返回的参数MapString,StringparamsgetParamsFromRequest(request);try{// 验签AlipaySignature.rsaCheckV1(params,alipayConfig.getAlipayPublicKey(),utf-8,RSA2);StringorderNoparams.get(out_trade_no);StringtradeNoparams.get(trade_no);return支付成功订单号: orderNo;}catch(AlipayApiExceptione){return验签失败;}}/** * 异步回调支付宝服务器通知必须返回 success */PostMapping(/notify)publicStringnotifyUrl(HttpServletRequestrequest){MapString,StringparamsgetParamsFromRequest(request);try{booleansignVerifiedAlipaySignature.rsaCheckV1(params,alipayConfig.getAlipayPublicKey(),utf-8,RSA2);if(signVerified){StringorderNoparams.get(out_trade_no);StringtradeNoparams.get(trade_no);StringtradeStatusparams.get(trade_status);// 支付成功if(TRADE_SUCCESS.equals(tradeStatus)){// 更新订单状态、归还库存等业务逻辑updateOrderStatus(orderNo,tradeNo);}returnsuccess;// 必须返回 success否则支付宝会重复通知}}catch(AlipayApiExceptione){e.printStackTrace();}returnfail;}privateMapString,StringgetParamsFromRequest(HttpServletRequestrequest){MapString,StringparamsnewHashMap();MapString,String[]requestParamsrequest.getParameterMap();for(Stringname:requestParams.keySet()){params.put(name,request.getParameter(name));}returnparams;}}五、秒杀系统集成支付支付完成后更新订单状态并归还库存ServicepublicclassPayService{AutowiredprivateOrderServiceorderService;AutowiredprivateProductServiceproductService;/** * 支付成功回调处理 */TransactionalpublicvoidhandlePaySuccess(StringorderNo,StringtradeNo){// 1. 查询订单SeckillOrderorderorderService.lambdaQuery().eq(SeckillOrder::getOrderNo,orderNo).one();if(ordernull||order.getStatus()!0){return;// 订单不存在或已处理}// 2. 更新订单状态为已支付order.setStatus(1);order.setPayTime(LocalDateTime.now());order.setTradeNo(tradeNo);orderService.updateById(order);// 3. 记录支付日志log.info(支付成功: 订单{}, 支付宝交易号{},orderNo,tradeNo);}}六、前端调用buttononclickpay()支付宝支付/buttonscriptasyncfunctionpay(){constrespawaitfetch(/pay/create,{method:POST,headers:{Content-Type:application/json},body:JSON.stringify({amount:99.99,subject:秒杀商品 - iPhone 15})});constresultawaitresp.json();if(result.code200){// 把返回的 HTML 表单写到页面并自动提交document.body.innerHTMLresult.data;document.forms[0].submit();// 自动跳转到支付宝}}/script七、注意事项异步通知必须返回 “success”全小写否则支付宝会重复通知 8 次验签必不可少防止伪造回调幂等处理——支付宝通知可能重复判断订单状态防止重复更新沙箱金额随便填不会真实扣款上生产环境只需把gateway-url换成生产地址其他代码不变 觉得有用的话点赞 关注【张老师技术栈】吧每周更新 Java/Python/爬虫 实战干货不让你白来。

相关新闻

Unity MyFramework:框架里的代码简化技巧(三)

Unity MyFramework:框架里的代码简化技巧(三)

2026/9/26 12:24:19

前两篇写了 MyFramework 里一些常用的代码简化技巧。 这一篇继续写第三组。 不过这次只写真正能让调用侧代码变短的东西。 也就是一眼能看到: 原本要写几行,现在一行就能表达清楚。 这类工具不是复杂系统。 它们更多是项目长期开发中沉淀出来的小函…

英雄联盟Akari助手:5个核心功能让你的游戏体验提升300%

英雄联盟Akari助手:5个核心功能让你的游戏体验提升300%

2026/8/23 1:08:00

英雄联盟Akari助手:5个核心功能让你的游戏体验提升300% 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 还在为英雄联盟中繁琐的配置…

告别漫画加载烦恼:用哔咔漫画下载器打造个人离线图书馆

告别漫画加载烦恼:用哔咔漫画下载器打造个人离线图书馆

2026/8/23 1:08:00

告别漫画加载烦恼:用哔咔漫画下载器打造个人离线图书馆 【免费下载链接】picacomic-downloader 哔咔漫画 picacomic pica漫画 bika漫画 PicACG 多线程下载器,带图形界面 带收藏夹,已打包exe 下载速度飞快 项目地址: https://gitcode.com/gh…

CANN/GE ACL数据集缓冲区添加函数

CANN/GE ACL数据集缓冲区添加函数

2026/9/26 19:14:12

aclmdlAddDatasetBuffer 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyTorch、Te…

用ffmpeg高效批量调整图片尺寸的实战指南

用ffmpeg高效批量调整图片尺寸的实战指南

2026/9/27 1:30:29

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

2026/9/27 1:30:37

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱 【免费下载链接】transformers 🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and mu…

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

2026/9/27 1:30:35

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system sup…

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

2026/9/27 1:30:34

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

2026/9/26 16:36:51

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system supporting mi…

远程协作的工作台整理

远程协作的工作台整理

2026/9/26 14:29:04

远程协作的工作台整理远程协作的核心不是再加一个工具,而是让交接信息足够完整。异步任务要写明目标、输入位置、完成标准和需要决策的人。 工作台的最小配置 将日程、待办、代码和沟通入口收拢到少数固定位置;通知按紧急程度分层。工作台不需要模仿办公…

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

2026/9/26 13:57:22

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

2026/9/26 23:35:16

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…