2018年2月27日 下午9:40
相关内容:
学习的知识点
熟悉支付宝对接的核心文档,调通支付宝支付功能的官方Demo
解析支付宝SDK对接源码
RSA1和RSA2验证签名及加解密
避免支付宝重复通知和数据校验
natapp外网穿透和tomcat remote debug
生成二维码,并持久化到图片服务器
一些重要的官方文档
总文档:http://learning.happymmall.com/alipaydoc.html
沙箱登录:https://openhome.alipay.com/platform/appDaily.htm
沙箱环境使用说明:https://doc.open.alipay.com/doc2/detail.htm?treeId=200&articleId=105311&docType=1
如何使用沙箱环境:https://support.open.alipay.com/support/hotProblemDetail.htm?spm=a219a.7386793.0.0.uS5uZ6&id=251932&tagId=100248
当面付产品介绍:https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.hV5Clx&treeId=193&articleId=105072&docType=1
扫码支付接入指引:https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.Ia6Wqy&treeId=193&articleId=106078&docType=1
当面付快速接入:https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.bROnXf&treeId=193&articleId=105170&docType=1
当面付接入必读:https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.hV5Clx&treeId=193&articleId=105322&docType=1
当面付进阶功能:https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.YFmkxI&treeId=193&articleId=105190&docType=1
当面付异步通知-仅用于扫码支付:https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.BykVSR&treeId=193&articleId=103296&docType=1
当面付SDK&DEMO:https://support.open.alipay.com/docs/doc.htm?spm=a219a.7386797.0.0.k0rwWc&treeId=193&articleId=105201&docType=1
服务端SDK:https://doc.open.alipay.com/doc2/detail?treeId=54&articleId=103419&docType=1
生成RSA密钥:https://doc.open.alipay.com/docs/doc.htm?treeId=291&articleId=105971&docType=1
线上创建应用说明:https://doc.open.alipay.com/doc2/detail.htm?treeId=200&articleId=105310&docType=1#s0
支付宝扫码重要细节
- 主动轮训和回调的区别
- 避免单边账
- 同步请求的加签和验证签名
- 回调的验证
- 过虑重复通知
- 一定好验证并保证接受的异步通知是支付宝发出的
- 回调请求的放回
支付宝依赖的jar包:
- 第一部分:否则会报红线错误❌
- 位置:webapp_WEB-INF_lib

- 添加方式:

- 最重要的:如何将一个本地jar发布到服务器上!!!
- POM.xml的这个配置目的:是让项目发布的时候能够添加上alipay的jar包,否则会出现class not found的问题
- 关于打包发布的理解看这篇文章,很好@使用tomcat发布自己的Java项目 - CSDN博客

- 为啥要起lib为文件夹的名字
- 与项目发布后jar包所在的文件夹名相同,仅此而已,舒服

- 与项目发布后jar包所在的文件夹名相同,仅此而已,舒服
- 位置:webapp_WEB-INF_lib
- 第二部分:
- 交给maven配置,自动添加
- 所在的位置POM.xml
- 注意:这个一定要使用配套的版本,这些jar包是和alipay的jar包相配合使用的

具体代码功能详解:
一共有三个对外接口:
- pay接口:返回订单号和ftp服务器中的二维码路径
- alipayCallback:插入payinfo信息,使alipay不再回调
- queryOrderPayStatus:判断订单状态
具体的看代码,注释我写的很详细
- OrderController.java
- OrderServiceImpl.java
OrderController.java1
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78("pay.do")
//session:判断用户类型 orderNo:订单号 request:获取文件夹路径
//最后的返回:得到一个responseService,其中的data类型是Map<String ,String> resultMap 其中保存这订单号和ftp服务器中的二维码路径
public ServerResponse pay(HttpSession session, Long orderNo, HttpServletRequest request){
User user = (User)session.getAttribute(Const.CURRENT_USER);
if(user ==null){
return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),ResponseCode.NEED_LOGIN.getDesc());
}
//获取文件夹的上传路径。表示获得服务器的绝对路径的意思。但是最终我们要从服务器上传到FTP中去 blog.csdn.net/inite/article/details/75577970
String path = request.getSession().getServletContext().getRealPath("upload");
return iOrderService.pay(orderNo,user.getId(),path);
}
("alipay_callback.do")
/*
这个是alipay服务器调用的回调接口,不是我们自己调用的
1.让我们在payinfo数据表中存入付款信息
2.alipay服务器根据返回的结果,判断还用不用接着回调了
request来取得alipay的回调过程中传给我们的参数
整个过程参考:https://docs.open.alipay.com/194/103296
*/
public Object alipayCallback(HttpServletRequest request){
Map<String,String> params = Maps.newHashMap();
Map requestParams = request.getParameterMap();
for(Iterator 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]+",";
}
params.put(name,valueStr);
}
logger.info("支付宝回调,sign:{},trade_status:{},参数:{}",params.get("sign"),params.get("trade_status"),params.toString());
//非常重要,验证回调的正确性,是不是支付宝发的.并且呢还要避免重复通知.
params.remove("sign_type");
try {
boolean alipayRSACheckedV2 = AlipaySignature.rsaCheckV2(params, Configs.getAlipayPublicKey(),"utf-8",Configs.getSignType());
if(!alipayRSACheckedV2){
return ServerResponse.createByErrorMessage("非法请求,验证不通过,再恶意请求我就报警找网警了");
}
} catch (AlipayApiException e) {
logger.error("支付宝验证回调异常",e);
}
//todo 验证各种数据
//在这个函数中处理了:过虑重复通知 然后将payinfo数据表需要的数据保存在payinfo中,插入到数据库中
ServerResponse serverResponse = iOrderService.aliCallback(params);
if(serverResponse.isSuccess()){
return Const.AlipayCallback.RESPONSE_SUCCESS;
}
return Const.AlipayCallback.RESPONSE_FAILED;
}
//查询订单状态
("query_order_pay_status.do")
public ServerResponse<Boolean> queryOrderPayStatus(HttpSession session, Long orderNo){
User user = (User)session.getAttribute(Const.CURRENT_USER);
if(user ==null){
return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),ResponseCode.NEED_LOGIN.getDesc());
}
ServerResponse serverResponse = iOrderService.queryOrderPayStatus(user.getId(),orderNo);
if(serverResponse.isSuccess()){
return ServerResponse.createBySuccess(true);
}
return ServerResponse.createBySuccess(false);
}
OrderServiceImpl.java
1 |
|