支付宝沙箱支付(包括直接扫码支付)SpringBoot
准备工作
1、登录支付宝开放平台:https://open.alipay.com/platform/developerIndex.htm
2、点击研发服务:
3、设置密匙
由于我设置过了,里面有密匙,你们要点击那个支付宝密匙生成器,快捷链接:https://miniu.alipay.com/keytool/create
点确定之后,就和我这个一样了
好了,准备工作搞完了,页面先别关
2、网页支付
2.1 项目结构
为了通俗易懂,我就省略了业务层和持久层,直接伪造数据,防止大家对有些方法疑惑。
2.2 pom.xml
<!--用到的依赖-->
<dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-easysdk</artifactId><version>2.2.0</version>
</dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId>
</dependency>
2.3 application.yml
alipay:appId: privateKey: publicKey: gateway: openapi.alipaydev.com # 不用修改returnUrl: http://127.0.0.1:8080/return.html # 支付成功后跳转的页面,可以为空,也可以根据回调接口的判断来返回信息notifyUrl: http://域名/pay/notify # 当支付成功后,支付宝的回调接口,是你本地的接口,如果没有域名的话要内网穿透
内网穿透可以参考:https://blog.csdn.net/wulei2921625957/article/details/113776112?spm=1001.2014.3001.5501
解释:
- appId
- privateKey
- publicKey
2.4 ProjectInit.java
/*** 项目初始化*/
@Component
public class ProjectInit implements ApplicationRunner {//应用id@Value("${alipay.appId}")private String appId;//私钥@Value("${alipay.privateKey}")private String privateKey;//公钥@Value("${alipay.publicKey}")private String publicKey;//支付宝网关@Value("${alipay.gateway}")private String gateway;//支付成功后的接口回调地址,不是回调的友好页面,不要弄混了@Value("${alipay.notifyUrl}")private String notifyUrl;/*** 项目初始化事件*/@Overridepublic void run(ApplicationArguments args) {//初始化支付宝SDKFactory.setOptions(getOptions());}private Config getOptions() {//这里省略了一些不必要的配置,可参考文档的说明Config config = new Config();config.protocol = "https";config.gatewayHost = this.gateway;config.signType = "RSA2";config.appId = this.appId;// 为避免私钥随源码泄露,推荐从文件中读取私钥字符串而不是写入源码中config.merchantPrivateKey = this.privateKey;//注:如果采用非证书模式,则无需赋值上面的三个证书路径,改为赋值如下的支付宝公钥字符串即可config.alipayPublicKey = this.publicKey;//可设置异步通知接收服务地址(可选)config.notifyUrl = notifyUrl;return config;}
}
2.5 PayController.java
/*** @program: alipay* @create: 2021-06-25 14:44*/
@RestController
public class PayController {//支付成功后要跳转的页面@Value("${alipay.returnUrl}")private String returnUrl;/*** 下单支付* 当用户点击支付的时候,应该是要传参的,我这里就直接省略了,免得修改麻烦,大家应该可以自己实现*/@SneakyThrows@RequestMapping(value = "/pay", method = RequestMethod.POST)public String pay() {AlipayTradePagePayResponse response = Factory.Payment//选择网页支付平台.Page()//调用支付方法:订单名称、订单号、金额、回调页面.pay("测试商品", UUID.randomUUID().toString(), "5", returnUrl);//这里可以加入业务代码:比如生成订单等等。。return response.body;}/*** 支付后异步回调的接口* 这个接口需要内网穿透,因为要别人访问你的本地网站** @param request* @return*/@RequestMapping(value = "/notify", method = RequestMethod.POST)public String notifyAsync(HttpServletRequest request) {Map<String, String> map = new HashMap();Enumeration<String> parameterNames = request.getParameterNames();while (parameterNames.hasMoreElements()) {String key = parameterNames.nextElement();String value = request.getParameter(key);map.put(key, value);}//验签try {if (Factory.Payment.Common().verifyNotify(map)) {//验证用户的支付结果String trade_status = request.getParameter("trade_status");if ("TRADE_SUCCESS".equals(trade_status)) {//这里可以更新订单的状态等等。。}} else {return "fail";}} catch (Exception e) {return "fail";}return "success";}
}
2.6 前端页面
index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>确认订单</title>
</head>
<body>
<div>您的订单信息如下,请确认无误后支付:<br/>xxxxxxxxxx省略订单信息xxxxxxxxxx<form action="/pay" method="post"><button type="submit">确认支付</button></form>
</div>
</body>
</html>
return.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>支付成功</title>
</head>
<body>
<div>您已成功购买此商品,感谢您的支持
</div>
</body>
</html>
至此,最简单的支付就搭建完成了,可以启动项目访问首页(劝大家换个浏览器访问,或者关闭当前浏览器所有页面,重新打开)点击支付后回调到下面的页面
那怎么支付呢?直接用账号或者扫码(不是我们日常的支付宝,是沙箱版支付宝),那账号呢?
支付成功后会跳到事先写好的return页面。
那要怎么体现前后端的交互呢?当前端发起请求的时候,我们后端应该要生成一条订单插入数据库,设置一个状态,然后用户支付成功后,根据回调函数更新数据库订单的状态即可,这个时候,前端就要定时监听了,监听我们后端写的获取订单的状态接口。如果支付成功,则结束监听,可以利用这一点替换掉yml文件里面设置的返回页面,根据这个来跳转即可。
那如果用户多次获取二维码,那我们会生成许多无用的订单,这个时候我觉得用Redis存储订单Id并设置有效时间,配合后端可以写一个定时任务来清理无用的订单即可。
3、扫码支付
我这里举例类似于上面的打赏功能,实现起来还是比较简单的。前端代码我就不展示了,等会说下思路即可。
重新搭建一个项目吧
pom.xml
和上面一样的
application.yml
和上面一样的
ProjectInit.java
和上面一样的
AlipayServiceImpl.java
@Service
public class AlipayServiceImpl implements AlipayService {//这个服务是订单服务,我就不展示了,主要的功能就是插入订单,更新订单状态。可以自己写@Autowiredprivate OrderService orderService; /*** 生成二维码,当面付** @param order 订单类,大家应该可以想到里面应该有哪些字段*/@SneakyThrows@Overridepublic Map<String, Object> FaceTofACEPay(Order order) {/*** 订单的公共操作*/MyUtil myUtil = new MyUtil();//获取二维码的同时要生成订单号String orderId = myUtil.getUUID();order.setOrderId(orderId);//获取当前日期String orderDate = myUtil.getCurrentDetailedTime();order.setOrderDate(orderDate);//设置订单为未支付状态order.setOrderStatus(0);Integer integer;HashMap<String, Object> map = new HashMap<>();AlipayTradePrecreateResponse response = Factory.Payment.FaceToFace().preCreate("树洞赞赏", orderId, "" + order.getOrderAmount());if (ResponseChecker.success(response)) {String qrCode = response.getQrCode();map.put("qrCode", qrCode); //生成的二维码链接,不可直接打开,后面会说到map.put("orderId", orderId); //生成的订单号应该要返回给前端integer = orderService.insertOrder(order); //插入订单数据库} else {integer = 0;map.put("qrCode", "");map.put("orderId", "");}if (integer <= 0) {//我自定义的异常类throw new BusinessException(EnumBusinessError.UNKNOWN_ERROR, "生成二维码失败");}return map;}/*** 支付异步回调* 代码跟上面的案例大同小异* @param mapParams* @return*/@SneakyThrows@Overridepublic String notifyUrl(HttpServletRequest request) {Map<String, String> map = new HashMap();Enumeration<String> parameterNames = request.getParameterNames();while (parameterNames.hasMoreElements()) {String key = parameterNames.nextElement();String value = request.getParameter(key);map.put(key, value);}//验签try {if (Factory.Payment.Common().verifyNotify(map)) {//验证用户的支付结果String trade_status = request.getParameter("trade_status");if ("TRADE_SUCCESS".equals(trade_status)) {//这里可以根据业务更新订单支付状态.....Order order = new Order();String orderId = map.get("out_trade_no");order.setOrderId(orderId);order.setOrderStatus(1);orderService.updateOrder(order);return "success";}} else {return "fail";}return "fail";}
}
PayController.java
@RestController
public class PayController {@Autowiredprivate OrderService orderService;@Autowiredprivate AlipayService alipayService;/*** 前端定时检查订单的支付状态** @param order 订单类作为接收参数 用到了里面的 orderId* CommonReturnType 这个就是统一返回前端的结果 code msg data* @return*/@RequestMapping(value = "/checkOrderStatus", method = RequestMethod.POST)public CommonReturnType checkOrderStatus(@RequestBody Order order) {boolean b = orderService.checkOrderStatus(order);return CommonReturnType.create(b);}/*** 获取支付二维码** @param order 订单类作为接收参数 用到了里面的 order金额 字段* @return* @throws Exception*/@RequestMapping(value = "/getQrCode", method = {RequestMethod.POST})public CommonReturnType FacetoFacePay(@RequestBody Order order) throws Exception {Map<String, Object> map = alipayService.FaceTofACEPay(order);return CommonReturnType.create(map);}/*** 异步回调接口* */@RequestMapping(value = "/notifyUrl", method = RequestMethod.POST)public String notifyInterface(HttpServletRequest request) throws Exception {return alipayService.notifyUrl(request);}
}
现在后端搭建完毕,前端就不写了,直接调用接口即可:
获取二维码接口: 在线的二维码转换网站:http://qrcode.cnaidc.com/
监听支付状态接口:监听的时候,前端要定时监听,一般为1s到2s的样子发一次请求,如果刷新了二维码,那就要重新带上新的订单ID重新监听。
支付宝沙箱支付(包括直接扫码支付)SpringBoot相关推荐
- php验证是否是微信支付,利用thinkphp判断微信中的支付还是微信扫码支付还是手...
进行判断,根不同的客户端,显示不同的内容,如果不是手机,则只显示扫码微信支付,如果是微信公众号中,则只显示公众号支付 阿里西西web开发网为大家整理了这篇利用thinkphp判断微信中的支付还是微信扫 ...
- ThinkPHP整合微信支付之Native 扫码支付 模式二
大家好,这篇文章是继微信支付之Native 扫码支付 模式一之后的微信支付系列教程第三篇:扫码支付之模式二 介绍下扫码支付目前有两种模式,模式一比模式二稍微复杂点,至于模式一与模式二的具体内容,流程, ...
- PHP 支付PC端扫码支付、APP接口调起支付宝支付、微信公众号接入支付宝支付
第一:第三方支付原理 第二:支付接口申请流程 地址:https://docs.open.alipay.com/270/105899/ : 参考地址:https://blog.csdn.net/nove ...
- 对支付宝微信们来说,扫码支付限额 500 元新规意味着什么?
点击上方"CSDN",选择"置顶公众号" 关键时刻,第一时间送达! 12月27日下午,据中国人民银行(下称央行)网站消息,将于近日发布关于印发<条码支付业 ...
- 微信支付宝支付代理 微信扫码支付收银系统
随着城市的多元化,中西结合,现代与古代文化的交融,人们的衣食住行也在发生着翻天覆地的变化,在10年前,出门消费都是现金或者刷卡.而现在你去购物都有会考虑一个问题:能不能用支付宝,微信支付?扫码支付已经 ...
- 支付宝扫码支付和微信扫码支付共存的情况下,如何避免同一个订单被多次支付
前面分享了一篇 JAVA后端调用微信支付"统一下单"接口实现微信二维码扫码支付 的博客,虽然二维码在生成的时候可以设置有效期,但是这依旧不能保证整个业务流程和数据的安全.因为通常网 ...
- PB实现微信、支付宝、新大陆星POS扫码支付接口
PB调用C#动态库实现新大陆星POS扫码支付接口. 实例下载地址:https://download.csdn.net/download/weixin_41317666/12418679 string ...
- 微信支付开发(2) 扫码支付模式一
关键字:微信支付 微信支付v3 native支付 扫码支付模式一 统一支付 Native支付 prepay_id 作者:方倍工作室 原文: http://www.cnblogs.com/txw195 ...
- 商户接入微信支付方法(扫码支付、刷卡、app)
微信支付的几种方式解读: 微信支付商户平台的付款方式有以下几种: 公众号支付:在微信内的商家页面上完成公众号支付 APP支付:在APP中,调起微信进行APP支付 扫码支付:扫描二维码(包含PC网站)进 ...
最新文章
- Java数据结构Map遍历和排序
- servlet请求与响应的练习实例
- 2.2.1 处理机调度的概念和层次
- java 可忽略参数_如何使用“&var =”忽略URL参数
- 机器学习中规则化和模型选择知识
- 风格迁移模型测试效果
- C#操作DOS命令,并获取处理返回值
- 独立站需要用到哪些营销手段?
- 对于根目录磁盘满的了问题
- 计算机专业英语词汇pdf,计算机专业英语词汇1700词.pdf
- Js关于光标对象与定位插入图片
- 【英特尔杯】Python调取萤石网络摄像头视频
- 基于搜狗新闻语料库的词向量模型训练(Windows下)
- 叮叮获取所有用户信息_使用Postman获取微信公众号用户列表,循环遍历查询所有用户的详细信息...
- Tmux 常用快捷键
- 51单片机学习笔记——STC15W201S系列
- 台电的平板大家慎重购买,售后堪忧
- 高光时刻 | 方正璞华联合开发的「人力资源法律服务共享平台」在创新创业大赛中获奖
- 使用Bitmap生成透明底图,并保存到本地SD卡中
- Brendan Gregg