Springboot集成支付宝沙箱支付(完整版)

您所在的位置:网站首页 网页改成小程序 Springboot集成支付宝沙箱支付(完整版)

Springboot集成支付宝沙箱支付(完整版)

2024-07-02 15:20:15| 来源: 网络整理| 查看: 265

B站视频讲解视频

https://www.bilibili.com/video/BV1KS4y1w7yE

学编程、做项目,请认准:B站程序员青戈

求个三连加关注,谢谢您嘞~

开发前准备

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

支付宝沙箱的配置

注册支付宝开发者账户,进入开发者控制台 https://openhome.alipay.com/platform/developerIndex.htm

沙箱快捷入口: https://open.alipay.com/develop/sandbox/app

进入沙箱: 沙箱的界面:

Java集成沙箱支付

下载依赖

com.alipay.sdk alipay-easysdk 2.2.0

在 application.yml 里面进行配置:

alipay: appId: appPrivateKey: alipayPublicKey: notifyUrl:

alipay的java配置:AplipayConfig.java

import com.alipay.easysdk.factory.Factory; import com.alipay.easysdk.kernel.Config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; @Data @Component @ConfigurationProperties(prefix = "alipay") public class AliPayConfig { private String appId; private String appPrivateKey; private String alipayPublicKey; private String notifyUrl; @PostConstruct public void init() { // 设置参数(全局只需设置一次) Config config = new Config(); config.protocol = "https"; config.gatewayHost = "openapi.alipaydev.com"; config.signType = "RSA2"; config.appId = this.appId; config.merchantPrivateKey = this.appPrivateKey; config.alipayPublicKey = this.alipayPublicKey; config.notifyUrl = this.notifyUrl; Factory.setOptions(config); System.out.println("=======支付宝SDK初始化成功======="); } } 支付接口

新建一个 AliPayController.java

import com.alipay.easysdk.factory.Factory; import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse; import com.example.springboot.controller.dto.AliPay; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.net.URLEncoder; @GetMapping("/pay") // &subject=xxx&traceNo=xxx&totalAmount=xxx public String pay(AliPay aliPay) { AlipayTradePagePayResponse response; try { // 发起API调用(以创建当面付收款二维码为例) response = Factory.Payment.Page() .pay(URLEncoder.encode(aliPay.getSubject(), "UTF-8"), aliPay.getTraceNo(), aliPay.getTotalAmount(), ""); } catch (Exception e) { System.err.println("调用遭遇异常,原因:" + e.getMessage()); throw new RuntimeException(e.getMessage(), e); } return response.getBody(); }

参数 Alipay.java

import lombok.Data; @Data public class AliPay { private String traceNo; private double totalAmount; private String subject; private String alipayTraceNo; }

**注意:在拦截器里面加上 忽略alipay接口的配置,这很重要!**

接口测试

然后我们访问URL进行测试,测试的url格式:http://localhost:9090/alipay/pay?subject=xxx&traceNo=xxx&totalAmount=1000

**大坑!!!:url中文问题**

错误截图: 类似这样的url:http://localhost:9090/alipay/pay?subject=中文&traceNo=121313123&totalAmount=1000 在请求后就会出现上面的错误!

解决方式:暂时替换url中的中文字符,换成这样的: http://localhost:9090/alipay/pay?subject=112233&traceNo=121313123&totalAmount=1000

这样就正常了: 在这里插入图片描述

然后使用沙箱账号登录,支付就可以 https://open.alipay.com/platform/appDaily.htm?tab=account

回调接口 import com.alipay.easysdk.factory.Factory; import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse; import com.example.springboot.controller.dto.AliPay; import com.example.springboot.mapper.OrdersMapper; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.util.HashMap; import java.util.Map; @RestController @RequestMapping("/alipay") public class AliPayController { @PostMapping("/notify") // 注意这里必须是POST接口 public String payNotify(HttpServletRequest request) throws Exception { if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) { System.out.println("=========支付宝异步回调========"); Map params = new HashMap(); Map requestParams = request.getParameterMap(); for (String name : requestParams.keySet()) { params.put(name, request.getParameter(name)); // System.out.println(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")); // 更新订单未已支付 ordersMapper.updateState(tradeNo, "已支付", gmtPayment, alipayTradeNo); } } return "success"; } } 内网穿透:https://natapp.cn/

配置免费的隧道,端口:9090: 软件下载地址: https://pan.baidu.com/s/192MYFg0Gh3P87wW-Tj4ivQ?pwd=uuqu

下载好软件后,打开配置下authtoken: 在这里插入图片描述 然后双击启动 start.bat 即可。

看到这个表示你启动成功了:

idea里面配置notify接口并测试

更改 application.yml 里的配置: 我们可以在 idea里面对回调的notifyUrl进行debug测试,看看支付成功之后会不会回调: 在这里插入图片描述

附:AlipayController完整代码

import com.alipay.easysdk.factory.Factory; import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse; import com.example.springboot.controller.dto.AliPay; import com.example.springboot.mapper.OrdersMapper; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.net.URLEncoder; import java.util.HashMap; import java.util.Map; @RestController @RequestMapping("/alipay") public class AliPayController { @Resource private OrdersMapper ordersMapper; @GetMapping("/pay") // &subject=xxx&traceNo=xxx&totalAmount=xxx public String pay(AliPay aliPay) { AlipayTradePagePayResponse response; try { // 发起API调用(以创建当面付收款二维码为例) response = Factory.Payment.Page() .pay(URLEncoder.encode(aliPay.getSubject(), "UTF-8"), aliPay.getTraceNo(), aliPay.getTotalAmount(), ""); } catch (Exception e) { System.err.println("调用遭遇异常,原因:" + e.getMessage()); throw new RuntimeException(e.getMessage(), e); } return response.getBody(); } @PostMapping("/notify") // 注意这里必须是POST接口 public String payNotify(HttpServletRequest request) throws Exception { if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) { System.out.println("=========支付宝异步回调========"); Map params = new HashMap(); Map requestParams = request.getParameterMap(); for (String name : requestParams.keySet()) { params.put(name, request.getParameter(name)); // System.out.println(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")); // 更新订单未已支付 ordersMapper.updateState(tradeNo, "已支付", gmtPayment, alipayTradeNo); } } return "success"; } }

至此,集成完毕!撒花!坑太多了!@!!

------------------------------------更新--------------------------------------------

解决subject中文问题

貌似这是 easy-sdk 本身的问题,它不支持中文的subject,否则 biz_content就会乱码,那我索性就用了 alipay-sdk 完整版的

pom:

com.alipay.sdk alipay-sdk-java 4.22.110.ALL

我们把AplipayController.java 改造下:

import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayClient; import com.alipay.api.DefaultAlipayClient; import com.alipay.api.request.AlipayTradePagePayRequest; import com.alipay.easysdk.factory.Factory; import com.example.springboot.config.AliPayConfig; import com.example.springboot.controller.dto.AliPay; import com.example.springboot.mapper.OrdersMapper; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.HashMap; import java.util.Map; // 完整版 sdk 解决了 subject中文乱码问题 @RestController @RequestMapping("/alipay") public class AliPayController { @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.setBizContent("{\"out_trade_no\":\"" + aliPay.getTraceNo() + "\"," + "\"total_amount\":\"" + aliPay.getTotalAmount() + "\"," + "\"subject\":\"" + aliPay.getSubject() + "\"," + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}"); 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(); } }

然后再重启,试试: 可以看到 url 中的中文已经正常了,并且支付页面出来了: 简直完美! 撒花!

三连!!!



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭