Springboot集成支付宝沙箱支付(完整版)
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集成沙箱支付
下载依赖
<dependency> <groupId>com.alipay.sdk</groupId> <artifactId>alipay-easysdk</artifactId> <version>2.2.0</version> </dependency> 12345
在 application.yml 里面进行配置:
alipay: appId: appPrivateKey: alipayPublicKey: notifyUrl: 12345
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初始化成功======="); } }
12345678910111213141516171819202122232425262728293031323334 支付接口新建一个 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(); }
123456789101112131415161718192021参数 Alipay.java
import lombok.Data; @Data public class AliPay { private String traceNo; private double totalAmount; private String subject; private String alipayTraceNo; } 12345678910
**注意:在拦截器里面加上 忽略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<String, String> params = new HashMap<>(); Map<String, String[]> 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"; } }
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 内网穿透:https://natapp.cn/配置免费的隧道,端口:9090:
软件下载地址:
https://pan.baidu.com/s/192MYFg0Gh3P87wW-Tj4ivQ?pwd=uuqu
下载好软件后,打开配置下authtoken:
然后双击启动 start.bat 即可。
看到这个表示你启动成功了:
更改 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<String, String> params = new HashMap<>(); Map<String, String[]> 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"; } }
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172至此,集成完毕!撒花!坑太多了!@!!
------------------------------------更新--------------------------------------------
解决subject中文问题
貌似这是 easy-sdk 本身的问题,它不支持中文的subject,否则 biz_content就会乱码,那我索性就用了 alipay-sdk 完整版的
pom:
<dependency> <groupId>com.alipay.sdk</groupId> <artifactId>alipay-sdk-java</artifactId> <version>4.22.110.ALL</version> </dependency> 12345
我们把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(); } }
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647然后再重启,试试:
可以看到 url 中的中文已经正常了,并且支付页面出来了:
简直完美!
撒花!
三连!!!
相关知识
网站增加支付宝花呗在线支付
app调起支付宝-后端预支付
花小猪打车怎么用支付宝支付
支付宝如何修改花呗支付方式
支付宝中标铁路客票电子支付系统
支付宝花呗/花呗分期支付说明
移动支付新方式:花不愁与支付宝
支付宝刷脸支付系统怎么加盟
华为“花瓣支付”来了,与微信、支付宝有什么区别
华为推出独立于支付宝、微信的支付平台,为“花瓣支付”
网址: Springboot集成支付宝沙箱支付(完整版) https://www.huajiangbk.com/newsview849424.html
上一篇: 支付宝,网银在线,快钱 3大支付 |
下一篇: Android PayPal支付 |
推荐分享

- 1君子兰什么品种最名贵 十大名 4012
- 2世界上最名贵的10种兰花图片 3364
- 3花圈挽联怎么写? 3286
- 4迷信说家里不能放假花 家里摆 1878
- 5香山红叶什么时候红 1493
- 6花的意思,花的解释,花的拼音 1210
- 7教师节送什么花最合适 1167
- 8勿忘我花图片 1103
- 9橄榄枝的象征意义 1093
- 10洛阳的市花 1039