1、进入支付宝开放平台
支付宝开发者平台开放平台
1.1 登录支付宝账号后下拉选择网页/移动应用开发
1.2 创建网页应用
1.3 创建成功后进入沙箱
沙箱比较不好找到 沙箱地址在这里:
登录 – 支付宝
欢迎登录支付宝,支付宝-全球领先的独立第三方支付平台,致力于为广大用户提供安全快速的电子支付/网上支付/安全支付/手机支付体验以及转账收款/水电煤缴费/信用卡还款等生活服务应用;为广大为从事电子商务的网站提供支付产品/支付服务的在线订购和技术支持等服务,帮助商家快速接入支付工具,高效、安全、快捷地开展电子商务。
1.4 点击启用公钥(有重要作用!springboot整合时会用到)
2、开始springboot与支付宝沙箱的整合
2.1导入支付宝api的依赖
1 2 | com.alipay.sdkalipay-easysdk2.2.1com.alipay.sdkalipay-sdk-java4.22.113.ALL |
2.2 配置 application.yml 沙箱参数
1 2 3 4 5 6 7 | #支付宝 alipay: appId: appPrivateKey: alipayPublicKey: notifyUrl: returnUrl: |
这五个参数都是什么意思呢?
appId: 沙箱中的应用id
appPrivateKey: 应用私钥
alipayPublicKey: 支付宝公钥
notifyUrl: 调用支付宝支付接口后产生的回调,需要内网穿透,后面详细讲,先不配置
returnUrl: 支付成功后的页面跳转,设置成你项目中的成功支付界面(可不填)
appPrivateKey: 应用私钥与 alipayPublicKey: 支付宝公钥在这里:点击查看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import com.alipay.api.DefaultAlipayClient; /** * @method: $ * @description: * @date: $ * @author: myth * @return $ */ public class AliPayUtils { public static AlipayClient alipayClient; static { alipayClient = new DefaultAlipayClient( "123123123" , "MIIEvgIBADANBgkq......." , "json" , //UTF-8编码格式 "UTF-8" , "MIIBIjANBgkqhk......" , //RSA非对称加密 "RSA2" ); } public static AlipayClient getAlipayClient() { return alipayClient; } } |
2.3 在过滤器和拦截器中忽略掉alipay的系列端口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | package com.gyp.studytour.common; import com.gyp.studytour.common.JwtInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; @Configuration public class InterceptorConfig extends WebMvcConfigurationSupport { @Override protected void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(jwtInterceptor()) .addPathPatterns( "/**" ).excludePathPatterns( "/alipay/**" ); super .addInterceptors(registry); } @Bean public JwtInterceptor jwtInterceptor() { return new JwtInterceptor(); } } |
2.4 新建AlipayController.java,定义了支付接口与支付回调接口:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.time.LocalDateTime; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * @Author myth * @Date Created in 2024/4/23 15:23 * @DESCRIPTION: * @Version V1.0 */ @RestController @RequestMapping ( "alipay" ) @Transactional (rollbackFor = Exception. class ) public class AliPayController { @Resource AliPayConfig aliPayConfig; @Resource AddressBookMapper addressBookMapper; @Autowired OrderServiceImpl orderServiceImpl; private static final String FORMAT = "JSON" ; private static final String CHARSET = "utf-8" ; private static final String SIGN_TYPE = "RSA2" ; @GetMapping ( "/pay" ) // 前端路径参数格式?subject=xxx&traceNo=xxx&totalAmount=xxx public void pay(AliPay aliPay, HttpServletResponse httpResponse) throws Exception { AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(), aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE); AlipayTradePagePayRequest request = new AlipayTradePagePayRequest(); request.setNotifyUrl(aliPayConfig.getNotifyUrl()); request.setReturnUrl(aliPayConfig.getReturnUrl()); request.setBizContent( "{" out_trade_no ":" " + aliPay.getTraceNo() + " "," + "" total_amount ":" " + aliPay.getTotalAmount() + " "," + "" subject ":" " + aliPay.getSubject() + " "," + "" product_code ":" FAST_INSTANT_TRADE_PAY "}" ); String form = "" ; try { // 调用SDK生成表单 form = alipayClient.pageExecute(request).getBody(); } catch (AlipayApiException e) { e.printStackTrace(); } httpResponse.setContentType( "text/html;charset=" + CHARSET); // 直接将完整的表单html输出到页面 httpResponse.getWriter().write(form); httpResponse.getWriter().flush(); httpResponse.getWriter().close(); } @PostMapping ( "/notify" ) // 注意这里必须是POST接口 public String payNotify(HttpServletRequest request) throws Exception { if (request.getParameter( "trade_status" ).equals( "TRADE_SUCCESS" )) { Map params = new HashMap(); Map requestParams = request.getParameterMap(); for (String name : requestParams.keySet()) { params.put(name, request.getParameter(name)); } String tradeNo = params.get( "out_trade_no" ); String gmtPayment = params.get( "gmt_payment" ); String alipayTradeNo = params.get( "trade_no" ); // 支付宝验签 if (Factory.Payment.Common().verifyNotify(params)) { // 验签通过 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" )); // 更新订单已支付的逻辑代码 } } return "success" ; } } |
前端页面调用
1 |
2.5 编写AliPay.java 接收前端传来的参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | package com.songqiao.waimai.alipay.payparameter; import lombok.Data; /** * @Author myth * @Date Created in 2024/4/23 15:26 * @DESCRIPTION: alipay接口参数 * @Version V1.0 */ @Data public class AliPay { //订单编号 private String traceNo; //商品金额 private double totalAmount; //商品名称 private String subject; //订单追踪号,商户自己生成,可已不使用 private String alipayTraceNo; } |
在application.yml中还有一个重要的参数 notifyUrl 没有配置,这个参数是支付成功后支付宝的回调函数访问本地系统的路径,需要以内网穿透的方式让支付宝访问本地系统。
3、使用natapp进行内网穿透
3.1 进入natapp官网注册账号,并进行实名认证、与支付宝账号进行绑定。
NATAPP-内网穿透 基于ngrok的国内高速内网映射工具
natapp是基于ngrok的国内高速内网穿透专业服务商,独家彻底解决ngrok1.7内存泄漏问题.稳定拒绝掉线,适用于微信开发调试,本地架设演示服务器,外网可以访问,远程服务器,远程桌面,远程办公,游戏联机等
NATAPP-内网穿透 基于ngrok的国内高速内网映射工具
3.2 下载指定版本的natapp应用
我这里选用的是Windows 64位下载,下载并解压成功后的内容为:
3.2.1 运行natapp.exe
出现以下界面
3.2.2 配置natapp中的隧道
回到natapp官网,点击购买隧道->免费隧道->创建隧道并配置程序中的端口等信息
创建成功后点击我的隧道->点击配置->点击复制获取authtoken
3.2.3 启动自己本机的web服务
在natapp.exe启动后的命令行输入natapp -authtoken=刚刚复制的token,就会与本机的8080端口映射成功!
出现如图所示状态后,那么恭喜你!外网即可访问你的本机的8080端口,支付宝api支付成功后即可完成回调!
3.3 配置application.yml中notifyUrl参数
4、支付宝沙箱支付前端Vue代码
调用后端接口并拼接get请求的参数,完成
1 2 3 4 | async goToPaySuccess(){ //在这里我选择了window.open(url,'_self')形式,也就是不跳转新的页面,在本页面直接跳转 window.open( "http://127.0.0.1:8080/alipay/pay?subject=" + "鱼头," + this .note+ "&traceNo=" +Math.floor(Math.random() * 900000 ) + 100000 + "&totalAmount=" + this .goodsPrice, '_self' ) }, |
5、启动项目并测试功能
点击支付按钮后跳转支付界面,为了避免被当做违规图片,我把二维码遮盖了。
注意!大坑!此时要求你登录的支付宝账号密码是支付宝沙箱的账号密码!不要混淆!
支付宝沙箱账号密码在沙箱中查看!
登录 – 支付宝
欢迎登录支付宝,支付宝-全球领先的独立第三方支付平台,致力于为广大用户提供安全快速的电子支付/网上支付/安全支付/手机支付体验以及转账收款/水电煤缴费/信用卡还款等生活服务应用;为广大为从事电子商务的网站提供支付产品/支付服务的在线订购和技术支持等服务,帮助商家快速接入支付工具,高效、安全、快捷地开展电子商务。
输入账号密码后即可进行付款
确认付款后会有两种结果:1.付款成功界面 2.付款成功后跳转到你指定的页面(在前面的application.yml的配置中设置) 如果没有配置就会展示成功界面,配置了就会在几秒后跳转到你配置的界面中去!
以上就是SpringBoot实现支付宝沙箱支付的完整步骤的详细内容,更多关于SpringBoot沙箱支付的资料请关注IT俱乐部其它相关文章!