前言
此系列作为我学习支付过程的记录文,第一次接触支付,最终目的是实现模拟第三方支付平台Mock。有啥不对的欢迎各路英雄好汉指正哈~~~
第一部分,弄清支付的实现原理
要想对支付进行全面深入的测试,弄清支付系统的实现原理是必不可少哒~在此我就不罗里吧嗦的了,给大家强行安利一个大神精华帖,传送门 -> 关于支付、关于安全的一些总结 (GOOGLE, APPLE, PAYPAL) ,里面对支付和安全的一些内容都讲解得非常清楚,受益匪浅哦~我是不会告诉你我连第一句话都是抄袭过来的~
第二部分,阅读支付平台的开发文档
这么快就来到这么难的一步了吗~
大牛说了,给支付平台做Mock前,要想找到最佳的实现方式,阅读支付平台的开发文档是个不错的选择~阅读文档后,你会对每个接口的请求和返回的内容格式都很清晰,清楚接下来你要拿什么数据做什么事。因此我也老老实实的去阅读了PayPal的开发文档,结果是脑子果然大了两倍!
我公司目前的项目只支持PayPal第三方支付平台,且业务需求是实现给项目打赏,功能比较单一,因此下列的内容都是针对自己项目展开的一些学习过程,从而入入支付的坑,所以大牛可以绕道了哈哈哈~~
PayPal Payments API
本项目支付调用的是PayPal的SDK,主要关注Create 和 Execute 两个接口,使用SDK的好处是通信过程中只要按照格式要求去请求接口就OK了,不需要牵扯到加密等复杂部分。以下是项目主要请求的内容和格式,以及返回的内容和格式。(主要来自Payments API,为图方便而记录下来,有需要的可以去看文档哈~)
- Create payment
Create请求的格式和内容:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23curl -v -X POST https://api.sandbox.paypal.com/v1/payments/payment #请求地址
-H "Content-Type:application/json" #请求头
-H "Authorization: Bearer <Access-Token>" #请求头,带Access-Token
-d ' #请求数据内容
{
"intent":"sale",
"payer":{
"payment_method":"paypal"
},
"transactions":[
{
"amount":{
"total":"30.11",
"currency":"USD"
},
"description":"The payment transaction description."
}
],
"redirect_urls":{
"return_url":"https://www.paypal.com/return", #可以设置为任一可以访问的url
"cancel_url":"https://www.paypal.com/cancel" #可以设置为任一可以访问的url
}
}'
Create返回的格式和内容: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{
"id":"PAY-1B56960729604235TKQQIYVY", #作为execute请求的参数
"intent":"sale",
"state":"created",
"payer":{
"payment_method":"paypal"
},
"transactions":[
{
"amount":{
"total":"30.11",
"currency":"USD"
},
"description":"The payment transaction description.",
"related_resources":[
]
}
],
"create_time":"2017-09-07T08:51:59Z",
"links":[
{
"href":"https://api.sandbox.paypal.com/v1/payments/payment/PAY-1B56960729604235TKQQIYVY",
"rel":"self",
"method":"GET"
},
{
"href":"https://api.sandbox.paypal.com/v1/payments//cgi-bin/webscr?cmd=_express-checkout&token=EC-60385559L1062554J", #请求payer_id的approval_url
"rel":"approval_url",
"method":"REDIRECT"
},
{
"href":"https://api.sandbox.paypal.com/v1/payments/payment/PAY-1B56960729604235TKQQIYVY/execute",
"rel":"execute",
"method":"POST"
}
]
}
- Execute approved PayPal payment
Execute请求的格式和内容:1
2
3
4
5
6curl -v -X POST https://api.sandbox.paypal.com/v1/payments/payment/PAY-9N9834337A9191208KOZOQWI/execute
-H "Content-Type:application/json"
-H "Authorization: Bearer <Access-Token>" #请求头,带Access-Token
-d '{
"payer_id": "CR87QHB7JTRSC" #确认支付的id标识
}'
Execute返回的格式和内容:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18{
"id": "PAY-9N9834337A9191208KOZOQWI",
"create_time": "2017-07-01T16:56:57Z",
"update_time": "2017-07-01T17:05:41Z",
"state": "approved", #支付后的状态
"intent": "order",
"payer": {
"payment_method": "paypal",
"payer_info": {
"email": "qa152-biz@paypal.com",
"first_name": "Thomas",
"last_name": "Miller",
"payer_id": "PUP87RBJV8HPU",
……
}
}
},
………………参考官方示例response
获取到execute的返回值,主要关注state关键字。
返回的值有created,approved,failed,以此来判断支付的状态。到了这一步,支付的整个流程就全部走通啦!以上只展示了成功的流程,对于其他异常的流程,可以自己修改请求去获取,这里就不累赘介绍啦!
第三部分,有关参数和细节
1.关于Access-Token的获取
PayPal后台有两个关键参数 clientId 和 clientSecret,这些可以在 Paypal 后台配置,把这两个参数请求给PayPal,然后会返回一个 access token。(前提是你需要登录PayPal的后台哦~关于账号密码,可以找你们的开发哥哥拿,简单粗暴!)
1 | curl -v https://api.sandbox.paypal.com/v1/oauth2/token \ |
PayPal后台关键参数入口在My Apps & Credentials -> REST Api apps -> 你的项目,点进去之后就可以看到了,具体的页面我就不展示啦,我害怕泄露天机然后被老板炒鱿鱼!:joy: :joy:
- 2.关于payer_id的获取
payer_id的获取需要从Create请求的返回结果approval_url中请求得到,需要在PayPal确认支付后才会返回给页面,直接一点的方法是在浏览器中输入approval_url,使用抓包工具截取返回结果,从而获取到payer_id,如图所示:
3.关于curl命令的运行工具
墙裂推荐使用Babun,一个 Windows 上的开箱即用的壳程序,安装 Babun 十分简单,解压缩包之后,执行里面的 install.bat 批处理脚本,然后静静等待执行结束即可,过程有些长,但一定要等待执行结束哦,安装结束后 Babun 会自动运行,且在桌面上生成快捷方式,谁用谁知道哈~~:sunglasses: :sunglasses: :sunglasses:4.使用python运行curl命令
是不是很头疼啊现在,不知道怎么转化,谷歌来谷歌去的,一会使用pycurl,一会想将curl命令转化为requests方式,就是找不到最佳的实现方式,就是找不到一种简单粗暴又无脑的方式去转化呢?!!!:sob: :sob: :sob:
别着急,甩你一个拯救苍生的快捷路径 -> 转curl为python ,还不赶快谢主隆恩哈哈哈:sunglasses: :sunglasses: :sunglasses:
这样的话,我们就可以进一步把上面的步骤一一整合成python的方式去实现啦,不过在整合之前,最好还是一步步来,体会一下这个实现的过程,收获颇多哦~~
- 5.将curl命令转化为requests的样子
以下展示获取access_token的python文件,以作观赏!想要将整个流程合为一个py,这个任务就交给聪明的小伙伴们啦~
1 | import requests |
总结
理顺完支付的过程,清楚了支付时请求了什么东东给第三方支付平台,也清楚了第三方支付平台支付完成后回调了什么东东给服务器,这样的话,就可以开始起一个mock服务,写几个function专门来处理这些支付回调的东西,然后再去项目接口内部修改注释掉相应的支付部分,通过hosts指向自己部署的服务,模拟返回第三方支付端参数达到支付mock效果。