支付宝新版SDK-PC扫码支付-手机浏览器H5支付

一、前言

支付宝支付—沙箱环境使用

支付宝新版SDK-PC端扫码支付 + 手机浏览器H5支付「本文

PC端扫码支付,其实就是就是 电脑网站支付,本文基于支付宝沙箱环境,不了解的可以看一下上边的链接。

PS:本文是基于支付宝新版 SDK 重写的,用法非常简单,之前的旧版 SDK 就别参考了~

本文环境:

  • JDK1.8
  • IDEA 2020.3.2
  • SpringBoot 2.2.2
  • alipay-easysdk 2.2.0
  • 支付宝沙箱环境

二、引入依赖

源码地址:https://github.com/niceyoo/alipay-demo

创建一个 SpringBoot 应用(有基础的建议直接看↑源码),在 pom 中引入如下依赖:

<!-- alipay -->
<dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-easysdk</artifactId><version>2.2.0</version>
</dependency>

在 application.yml 文件中添加如下配置:

## 支付宝配置
alipay:# 应用IDappId: 你的appid# 应用私钥privateKey: 你的应用私钥privateKey# 支付宝公钥,注意不是生成的应用公钥publicKey: 你的支付宝公钥publicKey#支付网关配置,这一项是写死的,正式环境是openapi.alipay.comgateway: openapi.alipaydev.com# 支付宝前台跳转地址returnUrl: http://ngrok.sscai.club/html/success# 支付宝后台通知地址notifyUrl: http://ngrok.sscai.club/api/alipay/notify_url# 支付宝前台手机网页支付中途取消跳转地址errorUrl: http://ngrok.sscai.club/html/error

这些参数在哪里获取的?

1、appId(应用ID)

https://open.alipay.com/platform/appDaily.htm?tab=info

具体见下图所示:

2、publicKey、privateKey(支付宝公钥、应用私钥)

windows工具:点击此链接

macos工具:点击此链接

这块参考这篇文章的第三节吧:https://www.cnblogs.com/niceyoo/p/12196095.html

3、gateway(支付网关配置)

测试环境:openapi.alipaydev.com

正式环境:openapi.alipay.com

4、returnUrl、notifyUrl、errorUrl(跳转地址)

这三个地址在测试环境,可以使用内网映射的地址,尤其是 notifyUrl ,这个是支付宝的回调 URl,必须外网可访问。

内网映射可以使用免费的 natapp

natapp链接:https://natapp.cn/

具体用法可自行百度。

内网映射就是将内网映射到外网,实现通过外网链接访问本地的效果。
例如上方的:http://ngrok.sscai.club 指向我本地的 http://127.0.0.1:port

三、代码部分

1、支付宝参数配置类

上面定义的参数有了,接下来就是如何使用了。新增一个配置类(AlipayConfig):

import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;/*** @author : niceyoo* @version : 1.0* @title : AlipayApplication* @description : 支付宝支付配置类* @copyright :* @date :*/
@Component
public class AlipayConfig 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) throws Exception {/**初始化支付宝SDK**/Factory.setOptions(getOptions());System.out.println("**********支付宝SDK初始化完成**********");}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;}
}

PS:详细的参数文档:https://opendocs.alipay.com/apis/00y8k9

2、模拟订单Controller类
/*** @author : niceyoo* @version : 1.0* @title : AlipayController* @description : 订单支付控制层-测试代码* @copyright :* @date :*/
@RestController
@RequestMapping("/api/alipay")
public class AlipayController {@Autowiredprivate AlipayService alipayService;/*** @description: 支付宝电脑网页支付* @param subject: 订单名称* @param total: 金额* @return java.lang.String*/@PostMapping("/page")public String page(String subject, String total) {subject = "测试支付";total = "1000";return alipayService.page(subject, total);}/*** @description: 支付宝手机网页支付* @param subject: 订单名称* @param total: 金额* @return java.lang.String*/@PostMapping("/wap")public String wap(String subject, String total) {subject = "测试支付";total = "1000";return alipayService.wap(subject, total);}/*** @description: 支付宝异步回调* @param request: 请求* @return java.lang.String*/@PostMapping("/notify_url")public String notify_url(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));}/** 支付宝验签 **/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";}/*** @description: 支付宝退款* @param outTradeNo: 商家订单号* @param refundAmount: 退款金额(不能大于交易金额)* @return java.lang.String*/@PostMapping("/refund")public String refund(String outTradeNo, String refundAmount) {return alipayService.refund(outTradeNo, refundAmount);}}

订单 Controller 类主要模拟了四个方法:

  • page:网站支付
  • wap:手机支付
  • notify_url:支付回调方法
  • refund:退款调用方法
3、模拟订单Service类
/*** @author : niceyoo* @version : 1.0* @title : AlipayService* @description :* @copyright :* @date : 2021/2/8 12:27*/
@Service
public class AlipayService {/*** 支付成功后要跳转的页面*/@Value("${alipay.returnUrl}")private String returnUrl;/*** 支付宝前台手机网页支付中途取消跳转地址*/@Value("${alipay.errorUrl}")private String errorUrl;/**** @param subject* @param total* @return*/public String page(String subject, String total) {try {AlipayTradePagePayResponse response = Factory.Payment/** 选择电脑网站 **/.Page()/** 调用支付方法(订单名称, 商家订单号, 金额, 成功页面) **/.pay(subject, OrderUtil.getOrderNo(), total, returnUrl);return response.body;} catch (Exception e) {e.printStackTrace();}return null;}/**** @param subject* @param total* @return*/public String wap(String subject, String total) {try {AlipayTradeWapPayResponse response = Factory.Payment/** 选择手机网站 **/.Wap()/** 调用支付方法(订单名称, 商家订单号, 金额, 中途退出页面, 成功页面) **/.pay(subject, OrderUtil.getOrderNo(), total, errorUrl, returnUrl);return response.body;} catch (Exception e) {e.printStackTrace();}return null;}/**** @param outTradeNo* @param refundAmount* @return*/public String refund(String outTradeNo, String refundAmount) {try {AlipayTradeRefundResponse response = Factory.Payment.Common()/** 调用交易退款(商家订单号, 退款金额) **/.refund(outTradeNo, refundAmount);if (response.getMsg().equals("Success")) {return "退款成功";}} catch (Exception e) {e.printStackTrace();}return "退款失败";}}

Service 主要调用支付宝支付提供的便捷方法,大家可以看一下方法中的写法。

用到的模拟生成订单号的工具类:

public class OrderUtil {/***  根据时间戳生成订单号* */public static String getOrderNo () {DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");LocalDateTime localDateTime = Instant.ofEpochMilli(System.currentTimeMillis()).atZone(ZoneOffset.ofHours(8)).toLocalDateTime();return df.format(localDateTime);}}

4、前端截图以及支付演示

由于使用了 thymeleaf,增加了三个前端界面:

  • 首页调用支付
  • 支付成功界面
  • 支付失败界面

首页主要就是 form 表单的提交,调用了两个方法:网页支付、手机网站支付

<form enctype="multipart/form-data" action="/api/alipay/page" method="post"><button type="submit">电脑确认支付</button>
</form>
<form enctype="multipart/form-data" action="/api/alipay/wap" method="post"><button type="submit">手机确认支付</button>
</form>

支付时需要用到沙箱账号,即支付宝沙箱版,下载链接如下,一个我的下载链接,一个官方的,哪个下载快用哪个。

https://niceyoo.lanzous.com/i7QFulh3uri

https://sandbox.alipaydev.com/user/downloadApp.htm

4.1、点击电脑确认支付:PC端支付截图

4.2、点击手机确认支付:手机端支付截图

PS:进行支付测试,注意付款要用沙箱环境提供的支付宝APK。且环境必须手机浏览器环境下,非PC端操作。

支付成功后会支付宝会调回调方法:(下图是我的代理调用截图)

至此,从以上看来,其实不难发现支付宝支付是非常简单的。

ok,这篇文章就到这结束了,上边并没有详细介绍接口调用、参数说明等,详细介绍请查看官方文档:https://docs.open.alipay.com/270/105902/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/413849.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

华强北耳机修改序列号|支持中英文|自定义修改|傻瓜式一键修改序列号~

软件下载链接>>>&#xff1a;https://t.1yb.co/kQIu 你还在纠结买到的华强北耳机序列号查询不到吗&#xff1f; 你还在纠结因为刷机导致的序列号与充电仓序列号不一致吗&#xff1f; 你还在纠结自己的序列号不够有面吗… 先看一张效果图&#xff1a; 今天分享一下…

[js] 对`a == (‘1‘||‘2‘||‘3‘) ? false : true`写法进行改进,写出你优化后的方法

[js] 对a (1||2||3) ? false : true写法进行改进&#xff0c;写出你优化后的方法 ![1,2,3].includes(a) or ![1, 2, 3].includes(a ) or !{1: true, 2: true, 3: true}[a]个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很…

[BZOJ 1452] Count

Link: BZOJ 1452 传送门 Solution: 二维树状数组模板题 发现颜色数很少$c<100$&#xff0c;因此对于每个颜色都建一棵二维线段树即可 &#xff08;第一次写二维数据结构&#xff0c;发现套个循环就行了&#xff1f;&#xff09; Code: #include <bits/stdc.h>using na…

CentOS离线安装gcc环境(附安装包+图文并茂)

1、关于gcc linux内核本身不依赖gcc&#xff0c;gcc只是一个编译软件&#xff0c;是在kernel的源码变成可执行文件的时候起作用&#xff0c;真正使用起来就没有什么关系。 查看 gcc 版本 gcc -v 如果没有则显示&#xff1a; 2、安装步骤 2.1、下载gcc安装包 gcc下载地址&…

[js] Geolocation.getCurrentPosition()用来做什么的?在什么浏览器不受兼容?

[js] Geolocation.getCurrentPosition()用来做什么的&#xff1f;在什么浏览器不受兼容&#xff1f; 获取当前设备的位置 Android不支持个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌…

CentOS7安装redis并配置外网可访问(局域网可参考)

1、安装gcc编辑器 安装redis需要依赖gcc环境&#xff0c;执行如下命令安装&#xff1a; yum install -y gcc如果机器没有网络的话&#xff0c;可以参考这篇文章&#xff1a; CentOS离线安装gcc环境(附安装包图文并茂) 2、下载redis安装包 redis官网&#xff1a;https://re…

OSPF两种组播地址的区别和联系

1.点到点网络: 是连接单独的一对路由器的网络,点到点网络上的有效邻居总是可以形成邻接关系的,在这种网络上,OSPF包的目标地址使用的是224.0.0.52.广播型网络, 比如以太网,Token Ring和FDDI,这样的网络上会选举一个DR和BDR,DR/BDR的发送的OSPF包的目标地址为224.0.0.5;而除了DR…

[js] setTimeout的第三个参数有什么用?

[js] setTimeout的第三个参数有什么用&#xff1f; 第三个参数将作为定时器到期触发的函数的参数个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题

CodeForces 931C Laboratory Work 水题,构造

*这种题好像不用写题解... 题意: 一个人要改动别人的实验记录,实验记录记录是一个集合 实验记录本身满足:$max(X)-min(X)<2$ 改动结果要求: 1.新的集合平均值和之前的一样 2.新的集合,$max(Y)<max(X),min(Y)>min(X)$ 求新一个和之前相同数值最少的新记录 题解: 首先考…

悦虎144固件,华强北二代悦虎144固件,1562M芯片144固件

下载地址 https://t.1yb.co/k49w 关于固件 最新的悦虎1562M 144固件&#xff0c;适用于华强北二代悦虎主板&#xff0c;1562M洛达芯片。 关于本次升级&#xff1a;优化功耗&#xff0c;提升续航。

[js] 解释下深度优先遍历和广度优先遍历的区别及如何实现

[js] 解释下深度优先遍历和广度优先遍历的区别及如何实现 1、深度优先采用堆栈结构&#xff0c;先进后出&#xff0c;所占的空间较小&#xff0c;执行时间较长&#xff1b; 2、广度优先采用队列结构先进先出&#xff0c;所占空间较大&#xff0c;执行时间短&#xff0c;空间换…

RDD特性

转载于:https://www.cnblogs.com/ggzhangxiaochao/p/9237510.html

MMI_UT洛达检测软件使用,检测1562A

MMI_UT软件下载链接 > https://t.1yb.co/nLFU 如下为使用教程 关于华强北耳机如何检测已经写过几篇文章了&#xff0c;从后台看到大家给到我的私信&#xff0c;有时候真的挺多感慨的&#xff0c;买个jia耳机确实不容易啊~ 突然发现比买个正品还难&#xff0c;正品就算别的…

[js] 你认为es5的设计缺陷有哪些?

[js] 你认为es5的设计缺陷有哪些&#xff1f; 可以反过来想&#xff0c;es6新增的特性就是为了解决es5的设计缺陷个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题

安卓如何修改华强北二代耳机敲击指令?

经常有小伙伴在公中号后台私信我&#xff0c;小源&#xff01;为啥我的二代耳机敲击不管用啊~ 害&#xff0c;先检查一下是不是敲击的这个部位~ 如果敲击部位确认没问题的话&#xff0c;就要看一下是不是敲击设置的问题&#xff0c;默认左耳双击切换下一曲&#xff0c;默认右耳…

[js] 使用ajax轮询接口有什么优缺点?

[js] 使用ajax轮询接口有什么优缺点&#xff1f; 首先&#xff0c;所谓轮询接口的原理是 利用 setTimeout 定时请求API接口优点&#xff1a; 1&#xff0c;可以简单不用二次 开发websocket 实现所需功能 几乎没有学习成本 2&#xff0c;使用简单 缺点&#xff1a; 1&#xff0…

Django 2.0 学习(20):Django 中间件详解

Django 中间件详解 Django中间件 在Django中&#xff0c;中间件(middleware)其实就是一个类&#xff0c;在请求到来和结束后&#xff0c;Django会根据自己的规则在合适的时机执行中间件中相应的方法。 1.执行完所有的request方法到达执行流程&#xff1b;2.执行中间件的其他方法…

华强北二代悦虎1562M升级固件图文教程(详细多图文)

本文演示的固件在下方链接获取。 悦虎固件链接&#xff1a;https://t.1yb.co/kQH4 如下是刷固件(151版本)的图文步骤&#xff0c;注意&#xff0c;必须是悦虎1562M芯片。 PS&#xff1a;注意&#xff0c;此时所有的操作都是建立在耳机放在充电仓外的情况下执行。请结合图片文…

[js] 如何提升JSON.stringify的性能

[js] 如何提升JSON.stringify的性能 用第二个参数指定需要转换的属性&#xff0c;按需转换个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题

华强北三代悦虎1562A怎么样?

最近华强北三代耳机的更新频率有点高啊… 我这更文都快跟不上了。。 比如最近新出的慧联A6pro、悦虎三代1562A、大公牛等等&#xff0c;相信手快的小伙伴&#xff0c;估计这会都已经用上了吧&#xff1f; 刚好手里有一个悦虎&#xff0c;结合最近的使用情况&#xff0c;这一…