本文只介绍当面付(扫码支付)和APP支付

一. 接入准备

#这里分两种情况,正式环境和沙箱环境,本文使用沙箱环境

1.进入支付宝开放平台,创建应用

登录 支付宝开放平台,创建应用并提交审核,审核通过后会生成应用唯一标识 APPID,并且可以申请开通开放产品使用权限。通过 APPID 应用才能调用开放产品的接口能力。详情请参考 创建应用。

2.配置应用

应用创建完成后,系统会自动跳转到应用详情页面。您可以在 能力列表 中点击 添加能力 来添加 当面付 功能。详情请参见 添加应用功能。 添加需要的能力

3.开发设置

进入开发设置中完成接口加签方式、IP白名单、应用网关、接口内容加密方式开发信息设置。详情请参见 配置应用环境

  • 接口加签方式:必填。用于保障商户应用和支付宝交互的安全性,配置详情参见 接口加签方式配置说明
  • IP白名单:选填。用于保障用户资金安全,说明详情参见 IP 白名单接入指南

  • 应用网关:选填。用于接收支付宝异步通知消息,说明详情参见 应用网关

  • 接口内容加密方式:选填。用于加/解密 OpenAPI bizContent 报文内容及加/解密部分用户隐私信息,说明详情参见 接口内容加密方式

  • 授权回调地址:选填。第三方应用授权 或 用户信息授权 后回调地址。授权链接中配置的 redirect_uri 的值必须与此值保持一致 (如:https://www.alipay.com) ,用户成功授权后将在该 url 后携带授权码等信息并跳转至该页。当填入该地址时,系统会自动进行安全检测,详情请参考 安全检测

4.设置接口加签方式

支付宝开放平台的应用管理体系,使用了公私钥的机制,商户可通过设置接口加签方式为自身应用配置 公私钥/公私钥证书 来保障商户应用和支付宝交互的安全性。密钥的获取方式请参见 生成密钥

公钥证书与公钥的区别请参见 普通公钥与公钥证书区别

简单说一下公钥私钥

使用支付宝支付加密方式有两种:1. 公钥私钥  2. 证书

1. 可使用支付宝提供的开发助手生成证书,生成后,支付宝会提供给你三个证书,分别为:私钥证书、公钥证书、支付宝公钥证书,

将生成的公钥证书配置到支付宝平台中,剩下的私钥证书和支付宝公钥留在本地使用

2. 同上使用支付宝开发助手生成密钥,将生成的公钥配置到支付宝,将支付宝公钥复制到本地。

密钥的作用:私钥签名,公钥验签;公钥加密,私钥解密;私钥是不能公开的。

为什么有两套密钥:开发者生成的私钥公钥、支付宝公钥-支付宝私钥;开发者需要签名,支付宝平台也需要签名。

其他步骤参照支付宝开放平台接入流程。

二. 编码阶段

1. 下载支付宝sdk

java使用maven引入即可

2.编码

封装配置类

 1 @Data
2 @Configuration
3 @ConfigurationProperties(prefix = "alipay")
4 public class AliPayConfig implements Serializable {
5
6 private static final long serialVersionUID = -4736760736935998953L;
7
8 public AliPayConfig(){}
9
10 public AlipayClient build(){
11 if(this.alipayClient == null){
12 return new DefaultAlipayClient(this.getGatewayUrl(),
13 this.getAppId(),
14 this.getPrivateKey(),
15 this.getFormat(),
16 this.getCharset(),
17 this.getAliPublicKey(),
18 this.getSignType());
19 }
20 return this.alipayClient;
21 }
22
23 /**
24 * 支付宝网关
25 */
26 private String gatewayUrl;
27
28 /**
29 * 新版本
30 */
31 private String newGatewayUrl;
32
33 /**
34 * AppId
35 */
36 private String appId;
37
38 /**
39 * 应用私钥
40 */
41 private String privateKey;
42
43 /**
44 * 请求使用的编码格式,如utf-8,gbk,gb2312等
45 */
46 private String charset;
47
48 /**
49 * 仅支持JSON
50 */
51 private String format;
52
53 /**
54 * 支付宝公钥
55 */
56 private String aliPublicKey;
57
58 /**
59 * 加密方式 目前支持RSA2和RSA,推荐使用RSA2
60 */
61 private String signType;
62
63 /**
64 * 回调地址
65 */
66 private String notifyUrl;
67
68 /**
69 * ali 客户端
70 */
71 private AlipayClient alipayClient;
72
73 /**
74 * 获取Config配置类
75 * @return Config
76 */
77 public Config getConfig(){
78 Config config = new Config();
79 config.protocol = "https";
80 config.gatewayHost = this.getNewGatewayUrl();
81 config.signType = this.getSignType();
82 config.appId = this.getAppId();
83 config.merchantPrivateKey = this.getPrivateKey();
84 config.alipayPublicKey = this.getAliPublicKey();
85 config.notifyUrl = this.getNotifyUrl();
86 return config;
87 }
88 }

老版支付宝sdk

 1 @Slf4j
2 public class AliPayApi {
3
4 /**
5 * 统一收单线下交易预创建 (老版本sdk)
6 * 扫码支付
7 * @param model
8 * @param aliPayConfig
9 * @return
10 */
11 public static AlipayTradePrecreateResponse tradePayToScanCode(AlipayTradePrecreateModel model, AliPayConfig aliPayConfig){
12 log.info("扫码支付:"+model.getOutTradeNo());
13 // 1.实例化API对应的request类
14 AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
15 request.setBizModel(model);
16 // 2.发起请求
17 AlipayTradePrecreateResponse response = null;
18 try {
19 response = aliPayConfig.getAlipayClient().execute(request);
20 // 3.是否调用成功
21 if(response.isSuccess()){
22 log.info("扫码支付调用成功:" + response.getBody());
23 return response;
24 }
25 } catch (AlipayApiException e) {
26 log.info("扫码支付调用失败:" + e.getErrMsg());
27 throw new RuntimeException(e);
28 }
29 log.debug("扫码支付调用失败:" + response.getMsg());
30 return null;
31 }
32 }

新版支付宝sdk

 1 /**
2 * 支付宝支付 新版sdk
3 * Create by Echo<php637.com> on 2021/1/22 0022
4 */
5 @Slf4j
6 public class AliPayNewApi {
7
8 /**
9 * 统一收单线下交易预创建
10 * 扫码支付
11 * @param model
12 * @param aliPayProperties
13 * @return
14 */
15 public static AlipayTradePrecreateResponse tradePayToScanCode(AlipayTradePrecreateModel model, AliPayConfig aliPayProperties){
16 log.info("扫码支付:" + model.getOutTradeNo());
17 // 1. 设置参数
18 Factory.setOptions(aliPayProperties.getConfig());
19 AlipayTradePrecreateResponse response = null;
20 try{
21 // 2. 发起Api调用
22 response = Factory.Payment.FaceToFace().preCreate(model.getSubject(), model.getOutTradeNo(), model.getTotalAmount());
23 dumpResponse(response);
24 // 3. 处理响应
25 if(ResponseChecker.success(response)){
26 log.info("扫码支付调用成功:" + response.getHttpBody());
27 return response;
28 }
29 } catch (Exception e) {
30 log.debug("扫码支付调用异常:" + e.getMessage());
31 throw new RuntimeException(e);
32 }
33 log.debug("扫码支付调用失败:" + response.getMsg());
34 return null;
35 }
36
37 /**
38 * App支付
39 * @param model
40 * @param aliPayConfig
41 * @return
42 */
43 public static AlipayTradeAppPayResponse tradePayToApp(AlipayTradeAppPayModel model, AliPayConfig aliPayConfig){
44 log.info("支付宝app支付:" + model.getOutTradeNo());
45 // 1. 设置参数
46 Factory.setOptions(aliPayConfig.getConfig());
47 AlipayTradeAppPayResponse response = null;
48 try{
49 // 2. 发起Api调用
50 response = Factory.Payment.App().pay(model.getSubject(), model.getOutTradeNo(), model.getTotalAmount());
51 // 3. 处理响应
52 if (ResponseChecker.success(response)){
53 return response;
54 }
55 } catch (Exception e) {
56 log.debug("支付宝app支付调用异常:" + e.getMessage());
57 throw new RuntimeException(e);
58 }
59 log.debug("支付宝app支付调用失败:" + response.getBody());
60 return null;
61 }
62
63 // 简单打印应答
64 private static void dumpResponse(AlipayTradePrecreateResponse response) {
65 if (response != null) {
66 log.info(String.format("code:%s, msg:%s", response.getCode(), response.getMsg()));
67 if (StringUtils.isNotEmpty(response.getSubCode())) {
68 log.info(String.format("subCode:%s, subMsg:%s", response.getSubCode(),
69 response.getSubMsg()));
70 }
71 log.info("body:" + response.getHttpBody());
72 }
73 }
74 }

测试和回调

 1     @Autowired
2 private AliPayConfig aliPayProperties;
3
4 @Autowired
5 private SmsUtils smsUtils;
6
7 /**
8 * 扫码支付测试 老版本
9 * @return
10 */
11 @RequestMapping("/test1")
12 public Object test1(){
13 AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
14 model.setOutTradeNo("123456789");
15 model.setSubject("测试商品");
16 model.setTotalAmount("20");
17 System.out.println(AliPayApi.tradePayToScanCode(model, aliPayProperties));
18 return new Return().success();
19 }
20
21 /**
22 * 扫码支付测试 新版本
23 * @return
24 */
25 @RequestMapping("/test2")
26 public Object test2(){
27 AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
28 model.setOutTradeNo("12341234");
29 model.setSubject("新版支付");
30 model.setTotalAmount("10");
31 System.out.println(AliPayNewApi.tradePayToScanCode(model, aliPayProperties));
32 return new Return().success();
33 }
34
35 /**
36 * app支付测试 新版本
37 * @return
38 */
39 @RequestMapping("/test3")
40 public Object test3(){
41 AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
42 model.setOutTradeNo("123412314");
43 model.setSubject("新版app支付");
44 model.setTotalAmount("10");
45 return new Return().success(AliPayNewApi.tradePayToApp(model, aliPayProperties));
46 }
47
48 /**
49 * 回调
50 * @param request
51 * @return
52 */
53 @RequestMapping("/notify")
54 public Object alinNotify(HttpServletRequest request){
55 // 1.获取回调参数
56 Map<String, String> params = new HashMap<>();
57 Map requestParams = request.getParameterMap();
58 for (Iterator iterable = requestParams.keySet().iterator(); iterable.hasNext();){
59 String name = (String) iterable.next();
60 String[] values = (String[]) requestParams.get(name);
61 StringBuffer valueStr = new StringBuffer();
62 for (int i = 0; i < values.length; i++){
63 if(i == values.length - 1){
64 valueStr.append(values[i]);
65 }else{
66 valueStr.append(values[i]);
67 valueStr.append(",");
68 }
69 params.put(name, valueStr.toString());
70 }
71 }
72 log.info("支付宝回调,sign:{},trade_status:{},参数:{}",params.get("sign"),params.get("trade_status"),params.toString());
73 // 2.验签
74 params.remove("sign");
75 params.remove("sign_type");
76 try {
77 boolean checkRes = AlipaySignature.rsaCheckV1(params, aliPayProperties.getAliPublicKey(), aliPayProperties.getCharset(), aliPayProperties.getSignType());
78 if (!checkRes){
79 return new Return().failed("非法请求,验证失败");
80 }
81 } catch (AlipayApiException e) {
82 log.debug("支付宝验签异常:{}", e.getErrMsg());
83 }
84 // 3.服务端订单参数验证及其他逻辑
85 // TODO
86 return "SUCCESS";
87 }

SpringBoot中实现支付宝支付的更多相关文章

  1. iOS中 最新支付宝支付(AliPay) 韩俊强的博客

    每日更新关注:http://weibo.com/hanjunqiang  新浪微博 现在的支付方式一般有三种, 支付宝, 微信, 网银. 个人觉得最简单易用的还是支付宝, 微信虽然看起来币支付宝要简单 ...

  2. 在django中实现支付宝支付(支付宝接口调用)

    支付宝支付 正式环境:用营业执照,申请商户号,appid 测试环境:沙箱环境:https://openhome.alipay.com/platform/appDaily.htm?tab=info 支付 ...

  3. 微信公众号中的支付宝支付与微信支付 && 支付宝支付问题(微信bug)

    一般,在微信公众号中的商城都是需要支持微信支付和支付宝支付的,当然,较大的公司对于鹅厂和阿里的站队就不说了,所以这里简单记录一下支付宝支付和微信支付的主要流程.说是简单介绍,这是因为确实不难,因为前端 ...

  4. 【zhifu】web开发中的支付宝支付和微信支付

    一.支付类型: 支付宝支付: 支付宝app内的网页支付: app外(即普通浏览器)网页支付: 微信支付: 微信app内的支付(在这里叫公众号支付) app外的支付(微信H5支付): 微信公众号的支付宝 ...

  5. TP5 中实现支付宝支付 利用model层调用支付宝类库

    <?php /** * Created by PhpStorm. * User: admin * Date: 2017/8/16 * Time: 09:16 */ namespace app\a ...

  6. springboot项目对接支付宝支付

    支付宝对接文档 一.准备工作 1. 首先要到 蚂蚁金服开发者中心 https://openhome.alipay.com/platform/home.htm 注册商家账户,并认证. 2.下载java版 ...

  7. web开发中的支付宝支付和微信支付

    https://www.jianshu.com/p/155757d2b9eb <!-- wxPay --SDK--> <script src="https://res.wx ...

  8. iOS开发笔记14:微博/微信登录与分享、微信/支付宝支付

    产品中接入了微博/微信的第三方登录分享功能.微信和支付宝的第三方支付功能,之前在开发过程中涉及到这些部分,于是抽空将接入过程梳理了一遍. 1.微博.微信.支付宝SDK相关接入设置 (1)微博SDK S ...

  9. laravel实现支付宝支付功能

    起因 前段时间因为项目中需要实现支付宝手机网站支付功能,所以写下这篇文章以作记录,不足之处,欢迎指教. 后端框架:Laravel 5.5 业务功能 适用于商家在移动端网页应用中集成支付宝支付功能.商家 ...

随机推荐

  1. 羊城杯wp babyre

    肝了好久,没爆破出来,就很难受,就差这题没写了,其他三题感觉挺简单的,这题其实也不是很难,我感觉是在考算法. 在输入之前有个smc的函数,先动调,attach上去,ida打开那个关键函数. 代码逻辑还 ...

  2. buu 相册

    一.拖入jeb,这个神器里面,感觉对jeb使用还是不熟悉,对我逆向产生了一些障碍. 抓住题目给的提示,邮箱,全局直接搜索,mail. 看下它的交叉引用 找到了发邮件的方法, C2的MAILFROME说 ...

  3. HCNA Routing&Switching之OSPF度量值和基础配置命令总结

    前文我们了解了OSPF的网络类型,OSPF中的DR和BDR的选举规则.作用等相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15054938.html: ...

  4. 【洛谷P1318积水面积】最小生成树

    我写一篇绝对原创的题解,算法原创,求洛谷通过!!!(让更多人看到这篇题解) 绝大多数人肯定认为这道题是一道模拟题 以下为正解 我们来看一下这一道题,其实就是找到左右高点,在模拟. 但是这个是正常人的想 ...

  5. CF1214E Petya and Construction Set题解

    原来这就叫构造题,了 这道题的做法,我自己诌了一个形象的名字--"挂葡萄"法( 首先,"搭葡萄架":考虑到每个距离 \(d_i\) 只与 \(2i-1,2i\) ...

  6. 【Lucas组合数定理】组合-FZU 2020

    组合 FZU-2020 题目描述 给出组合数C(n,m), 表示从n个元素中选出m个元素的方案数.例如C(5,2) = 10, C(4,2) = 6.可是当n,m比较大的时候,C(n,m)很大!于是x ...

  7. 注解@ConfigurationProperties使用方法(二十)

    前言 最近在思考使用java config的方式进行配置,java config是指基于java配置的spring.传统的Spring一般都是基本xml配置的,后来spring3.0新增了许多java ...

  8. Python基础之用PyQt5写一个tabview

    前面学习了menu的画图,现在学习tabview的画图,关于怎么打开designer.exe部分就不详细介绍了. 第一步:拖动一个Tab Widget控件到窗口去. 将控件拖上去之后就是这个样子,默认 ...

  9. 第五篇--Chorme浏览器主页被篡改

    解决方法:关闭谷歌浏览器,右击桌面快捷方式,查看属性,然后将target后面的网址删掉.并且任务栏的google打开方式,最好也把流氓网址删掉.之后就正常了.

  10. vue目首屏添加skeleton骨架屏

    1. 安装插件:npm install vue-skeleton-webpack-plugin 2. 在src目录下创建 Skeleton.vue <template> <div c ...