1、支付

支付宝&蚂蚁金服开发者平台:

https://open.alipay.com/platform/home.htm

文档地址:

创建应用对应文档 https://openhome.alipay.com/docCenter/docCenter.htm

网页移动应用文档 https://opendocs.alipay.com/open/200/105304

支付宝支付流程

image-20220228230726942

跳转的页面是根据AlipayTemplate定义的回调地址来进行跳转

1
2
3
4
5
6
7
   // 服务器[异步通知]页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
// 支付宝会悄悄的给我们发送一个请求,告诉我们支付成功的信息
private String notify_url = "http://member.gulimall.com/memberOrder.html";

// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
//同步通知,支付成功,一般跳转到成功页
private String return_url = "http://member.gulimall.com/memberOrder.html";

支付成功后异步回调接口处理,需要有服务器或配置了内网穿透才能接收到该方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
    /**
* 支付宝异步通知回调接口,需要拥有内网穿透或服务器
* @param request
* @return
*/
@PostMapping("/payed/notify")
public String handleAlipayed(PayAsyncVo vo, HttpServletRequest request) throws UnsupportedEncodingException, AlipayApiException {
/**
* 重要一步验签名
* 防止别人通过postman给我们发送一个请求,告诉我们请求成功,为了防止这种效果通过验签
*/
Map<String,String> params = new HashMap<String,String>();
Map<String,String[]> requestParams = request.getParameterMap();
for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
String[] values = (String[]) requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i]
: valueStr + values[i] + ",";
}
//乱码解决,这段代码在出现乱码时使用
valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
params.put(name, valueStr);
}
// 支付宝验签 防止恶意提交
boolean signVerified = AlipaySignature.rsaCheckV1(params
, alipayTemplate.getAlipay_public_key()
, alipayTemplate.getCharset()
, alipayTemplate.getSign_type());
if (signVerified) {
String result = orderService.handleAlipayed(vo);
return result;
} else {
return "error";
}
}
}

收单问题

image-20220228233211250

支付流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
+ 支付跳转
+ controller
+ 根据订单号查询封装订单Vo
+ 调用支付方法
+ 响应返回一个页面(支付宝收银台)
+ 直接交给浏览器即可
+ 跳转到会员订单列表页
+ 支付成功跳转controller
+ 会员服务feign远程调用订单服务
+ 查询用户订单详情controller
+ 根据id查询订单
+ 遍历订单
+ 根据订单id查询订单项
+ 封装订单项详情
+ 配置feign cookie同步拦截器(请求带上cookie)
+ 异步通知(支付宝推荐)
+ 不断通知,直到商户返回收到(最大努力通知型方案)
+ 保证外网能够访问到
+ 内网穿透
+ server_name 加上外网的地址,保证可以进行server的跳转
+ 异步通知获取参数接口
+ 抽取异步参数的Vo
+ 修改状态之前,需要验签(是否支付宝的数据)
+ 验签代码,从demo中复制
+ 支付成功处理(修改状态)
+ 保存交易流水
+ 数据库保证订单号、交易号等唯一
+ 修改订单状态
+ 查询订单,改为已支付
+ 收单
+ 问题
+ 在支付页面过久,关单后才支付
+ 库存关单后解锁,订单支付后变为已支付
+ 支付宝自动收单功能(自动关闭收银台)
+ 解锁库存完,支付完的异步通知才到
+ 订单解锁,手动收单

2、RSA、加密加签、密钥

对称加密:

image-20220228230515319

对称加密

  • 加密解密用同一把钥匙
  • 一把钥匙不安全

非对称加密 :

image-20220228230534327

非对称加密

  • 加密解密使用不同钥匙

公钥私钥:

公钥和私钥是一个相对概念,它们的公私性是相对于生成者来说的。

一对密钥生成后,保存在生成者手里的就是私钥, 生成者发布出去大家用的就是公钥

image-20220228231813227

3、内网穿透

image-20220228231656684

1、简介

内网穿透功能可以允许我们使用外网的网址来访问主机 正常的外网需要访问我们项目的流程是:

1、买服务器并且有公网固定IP

2、买域名映射到服务器的IP

3、域名需要进行备案和审核

2、使用场景

1、开发测试(微信、支付宝)

2、智慧互联

3、远程控制

4、私有云

1
2
+ 优点
+ 免服务器部署,直接在本地启动项目指定端口进行内网穿透即可