同步接口和异步接口【多测师_王sir】
1、定义
同步调用:当一个支付请求被发送到支付渠道方,支付渠道会很快返回一个结果。但是这个结果,只是告诉你调用成功了,不是扣款成功,这叫同步调用
异步调用:同步请求参数里面会有一个回调地址,这个地址是支付渠道在扣款成功后调用的,这叫异步调用
2、支付异步接口
当一个支付请求被发送到支付渠道方,支付渠道会很快返回一个结果。但是这个结果,只是告诉你调用成功了,不是扣款成功,这叫同步调用。很多新手会拿这个结果当作支付成功了,那就会被坑死,结果就是支付成功率特别高,伴随着一堆无法解释的坏账率,测试人员尤其要注意测试数据的篡改:金额,同步返回结果,订单号等。
同步请求参数里面会有一个回调地址,这个地址是支付渠道在扣款成功后调用的,这叫异步调用。一般同步接口仅检查参数是否正确,签名是否无误等。异步接口才告诉你扣款结果。一般异步接口有5秒以内的延迟。调用不成功会重试。有时候是这边成功了,但支付渠道侧没收到返回,于是会继续调。当天的支付到第二天还在被异步调用也都是正常的。这也是开发人员需要特别注意的地方,不要当做重复支付。测试人员也要对重复回调进行测试,应只有一次有效。这还不是最坑的,一般支付渠道侧,只有支付成功了才通知你。要是支付失败了,压根儿都不告诉你。 另一方面,如何老收不到异步结果呢?那就得查查了。同步结果不可靠,异步调用不可靠,那怎么确定支付结果?最终的杀招就是查单了,反查,一般支付渠道侧都会提供反查接口,定时获取DB中待支付的订单调用支付渠道侧的反查接口,最终把支付渠道侧扣款成功的订单完成掉。
3、理解
"同步" 就好比:你去外地上学(人生地不熟),突然生活费不够了;此时你决定打电话回家,通知家里转生活费过来,可是当你拨出电话时,对方一直处于待接听状态(即:打不通,联系不上),为了拿到生活费,你就不停的 oncall 、等待,最终可能不能及时要到生活费,导致你今天要做的事都没有完成,而白白花掉了时间。
"异步" 就是:在你打完电话发现没人接听时,猜想:对方可能在忙,暂时无法接听电话,所以你发了一条短信(或者语音留言,亦或是其他的方式)通知对方后便忙其他要紧的事了;这时你就不需要持续不断的拨打电话,还可以做其他事情;待一定时间后,对方看到你的留言便回复响应你,当然对方可能转钱也可能不转钱。但是整个一天下来,你还做了很多事情。 或者说你找室友临时借了一笔钱,又开始 happy 的上学时光了。
简而言之,言而总之: 同步就是我强依赖你(对方),我必须等到你的回复,才能做出下一步响应。即我的操作(行程)是顺序执行的,中间少了哪一步都不可以,或者说中间哪一步出错都不可以,类似于编程中程序被解释器顺序执行一样;同时如果我没有收到你的回复,我就一直处于等待、也就是阻塞的状态。 异步则相反,我并不强依赖你,我对你响应的时间也不敏感,无论你返回还是不返回,我都能继续运行;你响应并返回了,我就继续做之前的事情,你没有响应,我就做其他的事情。也就是说我不存在等待对方的概念,我就是非阻塞的。
4、Python 模拟测试异步接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | # order 下单接口: url = localhost: 1234 / order / create method = post body = { "goodsId" : "102030" , "userId" : "6666" , "num" : 10 , "amount" : 100 } response = { "code" : "0000" , "msg" : "sucess" , "data" :{ "order" : "dcs123456789" , "locator" : "/order/get_result/" } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # getOrder 查询订单接口: url = localhost: 1234 / order / get_result?orderId = dcs123456789 method = get response = { "code" : "0000" , "msg" : "sucess" , "data" :{ "order" : "dcs123456789" , "status" : 1 , "desc" : "下单成功" , "goodsId" : "102030" , "userId" : "6666" , "num" : 10 , "amount" : 100 } } |
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 | import time import requests def create_order(): url = "http://localhost:1234/order/create" # 异步接口 data = { "goodsId" : "102030" , "userId" : "6666" , "num" : 10 , "amount" : 100 } res = requests.post(url = url, json = data) return res.json().get( "data" ).get( "order" ) # 返回order_id用于追踪 def get_order_result(interval = 1 , time_out = 10 ): # 设置了默认时间间隔和超时时间,可以修改 order_id = create_order() # 查询结果接口 url = "http://localhost:1234/order/get_result?orderId={}" . format ( "2423432" ) start_time = time.time() # 启动时间 end_time = start_time + time_out #启动时间 + 超时时间 = 结束时间 count = 1 # 计数器, 此处是为了显示更直观, 可以去掉 while time.time() < end_time: # 当未到结束时间时, 循环请求 res = requests.get(url) # 请求查询结果接口 print (count) count + = 1 time.sleep(interval) # 休眠指定时间 if res: # 如果有数据则退出循环 break else : return None # 正常退出(达到end_time, 非break退出) 返回None return res.json() # break退出,返回接口数据 if __name__ = = '__main__' : # print(create_order()) print (get_order_result()) |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)