00:00
那前面我们结合内网穿透打通了我们支付宝的这个异步回调地址,最终呢,保证我们只要有订单成功,然后我们支付宝就会调用我们指定的这个异步通知,然后呢,最终穿透会来调用到我们这个方法,那么这个方法呢,相当于就能感知到每一个订单它的支付成功消息,那我们接下来就在这儿来打印一下,看我们真的支付成功以后,支付宝在调用我们异步通知的时候,会给我们传哪些内容,这呢我们获取到所有的请求参数,这个map,我们可以来编辑一下这个map,看一下都有什么内容,我们使用它的这个key set,先得到map里边的所有K,然后呢来调用这个for each,我可以来编历一下,这是呢,我们这个相当于每一个请求参数的K,然后我们接下来再来获取它请求参数的值,Request get permit,好,我们直接拿这个K得到它的这个值,我们可以来看一下支付都给我们传了哪些数据,我们就在这来输出一个,输出一个S。
01:00
好,我们这个呢,参数名,那就是我们现在指定的这个K啊来K,然后呢,再来加上一个参数值箭头参数值,参数值呢,那就加上我们的这个Y6值。我们只要收到支付宝每一个参数,我们都来打印一下,打印完了呢,告诉支付宝success,我们先来启动测试一下,看我们这个支付成功,我们会收到哪些,好来到我们这个古力ma商城,现在来的一个鼓励ma,保证我们现在呢是登录状态没问题,然后我们去来结算。点一个购物车来点击去结算,来到我们这个结算页来稍等一下来重新刷新这个连接拒绝,那就是服务还没有启动完成,我们得等上一阵我们再来进行刷新,好,现在这个结算页呢,我们就选中了,包括我们这个价格六块,我们可以选一个九块的运费,我们要支付17406,来点一个提交订单。那订单一提交,我们来到支付确认页,来选择支付宝进行支付。那我们来使用沙箱,把这个沙箱的这个用户信息我复制过来,好来登录付款,使用沙箱账号支付密码1234566个1.1个下一步,然后我们来到支付页,我们这个余额还有这个9万,我们现在呢再来支付123456,我点一个确认付款,那只要支付成功,那首先呢会跳页面,但是大家看现在页面呢,其实还没调过来,支付宝的异步通知呢,早都到了,然后我们这一块呢,会收到这么多的数据,支不给我们传了什么g MT create,那么这个订单的创建时间,以及我们的这个UTF8,我们是使用编码的,包括订单的标题签名,还有我们这个buy尔ID是什么人购买的,以及我们订单的这个备注等等,所有的这一块信息,支付宝呢,全部拿过来,那拿过来包括每一个东西都是什么意思,我们完全呢可以来参照,比如我来复制一个try number或者try status,我来复制过来来参。
02:59
到我们支付宝给的文档就行了,在支付宝这个电脑网站支付,我们来看到这个异步结果通知里边,那就来找一下每一个文档里边呢,其实都说的非常清楚,这个trade status是交易状态,交易状态呢都有哪些交易状态,我们这儿呢就会有,那我们现在传过来的交易状态叫trade success,包括拿着这个trade的success来找,就应该有信息交易状态说明,那就在这trade success代表支付成功,那我们相当于就能支付知道我们是哪个订单,现在呢是交易成功,这有一个叫autotrat number对外交易号,这就是我们系统里边创建的订单,那像这个订单就支付成功了,我们这儿呢还有一个trade number,这个try number呢是支付宝给我们的流水号,我们把这个复制过来,比如我们在文档里边再来查一下,看一下trade number trade number呢是支付宝交易号,相当于我们此次支付,支付宝给我们开的一个凭证,而我们auto trade number是商户订单号。
04:00
所以就应该我们会看到页面还没整回来的时候,我们这个异步通知就已经到了,所以我们就应该到异步通知的这一块,我们去来修改订单的状态,那么现在呢,都知道订单的成功了,所以我们在这要修改之前。我们还是那一句话,我们防止别人伪造支付宝的请求,给我们传递过来这么多的数据,而且呢,支付宝会来传递这么多数据,那么每次都要获取挺麻烦,我们可以专门把这些数据呢,抽取一个VO,这个VO我们也给大家写好了,我们直接把这个相当于所有我们刚才遍历出来拿到的这个属性,我们就来拿一个扎B1封装就行了,这个呢,支付里边我们要封装的就是这个异步VO,这个VO呢就是这样,那们什么GMT库艾,刚才我们给支付宝给我们传回来的所有数据,我们这都有,包括每一个数据是什么信息,直接参照文档就都有,好,我们把这个VO复制过来。我们放到我们这个订单服务VO里边走,这是我们支付的异步VO,这个异步VO呢,那接下来我们在这就可以收到这个消息,我们就叫派我们这个异步VO叫asy nc这个VO,因为支付宝呢会传来很多的请求参数,它呢会自动的帮我们这个封装成VO数据,那封装成VO数据以后呢,接下来我们就可以来进行处理了,把这一块就拿,拿到我就把这一块删除,那这个VO数据里边呢,就有相关的这个功能,所以我们就希望能有一个order service,根据我们返回的这个VO能帮我们来修改订单的状态,好,我们来一起处理就行了,Auto,然后呢,我们调用order service,点一个handle。
05:43
拍result,处理我们的支付结果,就要处理支付结果,那接下来呢,就会返回一个围,包括我们处理成功还是失败,如果成功了,我们要给支付宝返回success,否则我们返回一个其他的都行,支付宝另行给我们再通知,所以我们最终呢,希望这一块处理完也给我们返回一个状态result,这个result呢是success或者其他,所以我们接下来就来返回,给支付宝返回,那家们就来写这个处理方法,那么在这里边来处理支付宝的返回数据,来写一个owa,这不是autowa,来添加上它的实现走。
06:22
这一块的功能就是处理处理处理咱们这个支付宝的咱们这个支付结果,这个支付结果呢,因为里边封装了所有我们感兴趣的数据都有,而且呢,我们建议大家只要我们每支付成功一条数据,我们呢都应该给我们这个订单服务里边我们还有一张表叫payment info,这就是我们的支付流水,现在我们记录一下我们哪个订单号,支付宝的交易号是什么,然后呢,支付了多长的这个金额,以及它的这个主题信息等等等等,把这些状态呢,我们最好呢也都记录一下,这是我们的交易流水,那进入这个流水的作用就是为了我们后来的对账,比如我们这个每一个月我们可以汇总一个对账,我们看哪些订单在支付宝里边是不是都是成功的,我们要一一跟支付宝来进行一个对账,所以我们接下来就来把这个交易流水我们先来保存起来,我们做的第一步先来保存交易流水。
07:22
保存咱们这个交易流水,这个交易流水呢,我们就直接new一个,我们这个交易流水是一个叫payment银,好创建一个payment info这个实体类,然后我们呢,把它往里边一保存就行了,然后这个交易流水我拿过来,这个交易流水要设置的信息跟我们这个VO里边的很多信息有些呢字段不对应。所以我们得逐个封装交易流水里边,比如支付宝的这个交易号,我们现在呢,就封装几个核心的info n点,点一个get,应该是我们从这个VIVO里边来获取一下,那么支付宝给我们返回的这个数据里边呢,就有支付宝的这个交易号,是这个创业的number,还有我们这个订单这个号,还有我们这个set,我们这个order SN,那现在呢,是哪个订单,我VI里边也都有get order SN order trade number,而我们这个对外交易号是不是这个订单号这块呢,都需要参照支付宝把这一块是什么你都表示出来,这块呢也都说了。而接下来我再来设置一个当前的状态信息,这个状态trade status,交易状态,交易状态呢,我们在这也来一保存,在infoity里边点一个set,我们叫要trade status status payment status,那么支付的这个状态,支付的状态在view里边也有,我们直接get一个trade status。
08:48
还有接下来我们的一些时间,比如我们这个创建时间,确认时间,回调时间,回调内容这些呢,我们都可以来整一个,我们就来放一个这个回调时间,Set一个call back time,我们这个回调时间,我们从这个VO里边拿到这个时间,Get一个notify time,这就是我们的通知时间,但这个通知时间呢,我们看到这个notify time呢是一个string,我们当然完全可以把它转成一个date日期也没问题,支付宝给我们给回来的本来就是一个日期,所以我们接下来拿到这个日期时间,然后呢,我们把这个流水往进一保存,我们现在呢要用到流水的service,那么现在就拿到这个order,现在有一个叫payment payment的这个service,那么现在就直接叫payment。
09:39
Ino的这个service,好,这什么这个流水信息,我们把这个流水信息呢一保存,而且大家注意我们这个流水呢,肯定只能一个订单对应一个流水,不可能说一个订单会生成很多的支付流水,因为我们只可能支付一次,我们来点一个insert,这个service里边呢,肯定有一个保存方法,Save方法,我们就直接把它一保存,那为了我们能一个订单对应一个流水,包括一个支付宝的这个对流水号,我们也对应一个流水,我们就可以给他来限制一下,改变表,我们主要来添加一个索引,这个索引呢里边呢,订单号肯定呢,一个订单一个流水,它呢是一个唯一的。
10:21
走,然后呢,包括我们这一块的这个支付宝这个对外交易号,支付宝的这个交易号这个呢也是唯一的,所以我们现在呢,先来插入上一条我们的这个流水信息,那插入完了以后呢,加第二步来修改,修改我们这个订单的状态信息,订单的状态呢,就直接拿来进行修改就行了,而且我们得判断,因为现在能收到这个点一个get,我们这个status try status try status会有哪些状态呢?我们支付宝这一块呢,也告诉我们了,来找之前的这个trade status,它呢是一个字符串,它呢可能会是一个状态叫success,这个success呢就是交易成功,还有finish就是交易结束,还有我们这个close,就是交易超时关闭,或者我们这个支付完成以后退款,它进行了关闭,所以我们只要是我们这个success状态,我们就应该修改,包括我们这个success状态,我们往下看这块呢,也会提示的很清楚。我们这。
11:22
这些状态都是什么?他这说状态trade success,触发条件就是我们呢,如果支持退款功能,我们付款成功,那就是success,如果不支持退款成功,能付款成功,那就是finish的,所以有可能有两种付款成功,那无论哪种,那都是成功,我们现在来判断,如果点一个equals,如果equals呢,Trade success,这就是付款成功,或者我们现在的这个equals,点一个我们的这个equals equals什么我们现在的。这个还有一个叫try finish,这也是付款成功,只要付款成功,我们就来修改订单的状态,变为已支付,所以我们来写一个if,然后我们来把这个if来准备好了以后,那接下来我们就来修改一下订单的状态,另外我们这个订单号呢很长,我们之前每一张表这个订单号我们来看一下,它这个长度呢不够,所以我们为了刚才不报错,最好写一个64位挺长的,好,然后接下来我们再来做一个测试,现在呢,我们这个订单现在呢是支付成功,我们现在能感知到这个支付成功。
12:32
你们来到这儿修改拿到这个状态,这是支付成功状态,支付成功状态呢,我们相当于就要修改订单,按照我们指定的订单号,相当修改这个订单为支付成功就行了,是哪个订单,就是auto trade number对外交易号就表示的是我们当前的这个订单,我们文档里边也说的很清楚了,所们希望订单的service能有一个方法,就叫update order,然后呢,变为我们这个paid letters,变为我们这个已支付状态,要修改哪个订单,就是这个订单修改成什么状态,或者我们就有一个方法叫update,修改我们这个订单状态,修改成什么状态,我们传过来,现在我们专门有一个订单的枚举,Order status枚举,那么现在呢,就是支付成功了,已付款,那就是在这个我们就叫get code,那希望呢,就有一个这个方法,然后只要我们这一块执行一切没问题,那就给它返回success。
13:32
只要有问题,我们哪一块会有问题呢?比如我们这个流水多处理了,那么就会数据库报异常,所以们现在就来感知是success还是异常,来处理一下这个方法,好创建出这个方法的实现,修改我们这个订单的状态,这个订单的状态呢,我们现在就直接用我们的base member数据库的这个东西来改就行了,Base member好来修改我们这个订单状态,来创建出我们这个方法,走,我们在order dio里边来创建了这个方法,我们先给这个方法生成每一个参数的power标识,然后呢,接下来我们再来添加上我们的statement,然后我们接下来就来写我们这个订单状态的修改,你这个SQ语句呢,应该是这样来到我们这个订单表里边,我们订单现在支付成功了,只是修改一个成功状态,那就是up修改我们这张表set,那么这个表里边呢,有一个订单的status来看一下。
14:29
它呢有一个状态就是这个status status修改我们这个状态,修改这个状态变成什么呢?Staus,而且呢,它是一个我们这个属性,好我们现在呢,把这个属性就来复制过来,把我们这个status,那现在要修改我们的这个状态变为来加上这个单引号,我们的这个状态呢,现在变为我们指定的这个状态,它等于我们指定的值,Where,为什么按照我们这个订单号来改状态的,所以按照我们这个订单号,订单号等于这个指定的值,好那现在呢,就是这个CTRLC,把这个方法呢给这一复制,然后我们这个订单的状态,那就是井号大括号你传过来的这个状态,然后订单号那就是号大括号你传过来的订单号,好,那接下来我们这一块的方法就写好了,相当于修改我们这个订单状态,来到我们这个service,我调这个方法呢,最终修改完,但是大家注意我们的这个controller会调用我们业务。
15:29
来进行修改处理,但是修改处理之前我们要做一个核心的操作叫验签,那什么是验签,就是我们来验证是不是支付宝给我们返回的数据,那万一我们现在这打通了,万一别人用pman给我们发一个请求,告诉我们支付成功了,但是实际上是假的,那就出问题了,所以我们现在呢,一定要验签,验证是不是支付宝给我们发回来的数据,那怎么验看我们这个支付宝以前的这个DEMO里边,它这个支付成功呢?有一个异步通知,这个notify URL,这个GSP,因为在我们这个之前配置的时候,那么支付成功以后来到他的这个notify URL notify URL里边,它就写了这么一堆代码,这一堆代码呢,先是把我们所有请求参数包装成一个map,再来调用它来进行签名验证,验签通过了才能干下边的事情,验签不通过什么都不能做,所以我们在这儿呢,就来把这个方法直接拿过来,来哈希map,我就等。
16:29
导进来,我们该导的呢,我们全部导导进来,然后还有我们这个签名方法走,我们也导进来,阿里的这个配置这块的,整个这个配置呢,我们现在已经没在阿里里边了,现在我们是在这个阿里temp,我们这个阿里的这个模板里边。那么现在来注入我们这个阿里的支付模板,这个阿里PA temple。好,我们这个案例支付模板,这个支付模板里边呢,我们所有的数据我们都配好了,我们就直接来到这儿。
17:00
它里边有这么一个属性,有一个这个公钥的属性,来看一下,点一个get,这个public key,这是我们的公钥,一定要确认,第一个呢,我们来看传的是什么,第一个我们验签,验签呢,第一个传的是阿里派public key,好,第二个呢是char set,那么就来获取一下阿里派的char set tempt的char set get char set,第三个是获取我们这个签名方式,阿里派tempile。就是我们当前的这个T,它的签名方式。我们在这呢都配置好了签名方式,然后呢调用我们这个方法进行验签,当然这些呢肯定有异常,有异常抛异常就行了,包括我们这一块呢,也有异场抛一场,这一块呢是来解决乱码的,好我们在这儿呢就不管了,然后整个签名呢,会返回一个成功或者失败,在这呢得判断,如果签名验证成功,那说明这是支付宝传来的数据,在这儿控制台输出一下,那就叫签名验证成功,验证成功以后呢,那么才能调用我们的这个业务逻辑,然后我们最终来返回成功还是失败,那么签名验证失败了,我们就给支付宝直接随便返回一个,只要不是success,我来返回一个error,这都行。所以呢,我们要做所有业务逻辑之前,我们一定要验证签名。
18:23
这样呢,防止数据被篡改和伪造,那现在重新把打开订单服务来重新支付一下,那只要我们支付成功,我们订单的状态跳到订单的支付页,我们把这个状态呢,改完以后,它就应该是支付成功来看一下我们最终的效果好,现在这个订单服务已经启动成功,然后接下来我们重新加下单,来到我们这个古力庙走。那现在呢,是登录状态没问题,来使用购物车我们去结算,现在呢,就上买上我们这个一件商品,那沙箱的余额好像不够了,好我们来点一个去结算,那这一件商品呢,我们来选中下边的这个收货地址啊接下来我们去结算5808来到我们这个订单支付页,我们现在是12897这个订单来点一个支付宝,那现在来进行支付,还是使用我们这个沙箱账户来直接复制过来。
19:14
那么沙箱账户密码呢,123456好,我们点一个,下一步把这一块控制台呢,我们先来清空,来准备要异步回调,来输入123456好,我们点一个确定,然后呢,我们只要支付成功,我们在这呢就会异步回调,异步回调呢,我们来到这,我们来看field error on object,说我们的这个PA异步支付的这个VO,这个VO的notify time注入数据的时候,它的这个数据呢是2002这个东西,然后呢,要把它。转成我们这个类型是type Miss match完转成JAU这个日期类,这是一个类型转换失败的这个东西,然后这个string呢,现在转不了我们这个日期,我们想要转日期呢,就得明确告诉人家我们这个日期格式化的方式,所以我们现在呢,可以在我们的这一块配置文件中来说一下spring mvc,我们这个spring mvc里边有一个日期的date format,我们日期的格式化方式,我们现在呢,就是这个格式化方式是YYYY-MM年月日杠DD,然后呢空格10HH分,然后呢还有秒,我们把这个格式化的这个数据类型,我们说好了以后才能格式化成我们要用的这个类型,我们来重新返回,那么这个订单呢,就算是失败了,好,现在我们这个订单服务我们来启动成功,来重新测试一下,我们现在重新来走整个下单的流程。
20:46
我们来写一个古粒ma com,好来去下单还是买这一个,而且呢,由于我们之前自己没改订单的状态,所以我们的这个库存呢会自动回滚,所以现在呢,这个商品库存一直是两个,我们现在没有支付成功任何一个订单,因为没有修改状态,好点一个提交订单,好提交订单以后呢,我们来点一个支付宝,然后使用我们这个沙箱账号来进行支付,这是什我们的沙箱账号,来到我们这儿来点一个支付,走支付的快一点,我们订单一分钟过期,过期以后呢,它会立即解锁库存。
21:21
好,现在呢,去来进行支付,来输123456,我们点一个确认付款,来到我们这个订单这一块。来看现在我们传递回来的数据,只要我们这个支付成功,那么这个异步通知呢,就应该调用,调用呢,我们下边这块就应该有执行逻辑来看一下,那现在已经返回到我们这个页面了,是我们这个6017这个页面,但是我们这个异步通知呢,来看一下它的这个调用这块呢,好像没有来调用我们这个异步通知,来稍等一下,来看一下我们这个异步通知,如果调用的话,我们会打印签名验证成功,那如果没调用,那肯定就是签名验证失败,我们最好也打印一下签名验证失败,那有可能呢,是它没调用签名验证失败了,来重新测试一下,走我们这个测试环境呢,签名经常验证失败,这是一个常规现象,而且呢,他说这有一个乱码解决,我们在乱码的时候呢,才使用这种方式解决,能把这个呢就注掉,为了保证他的这个签名验证成功,来重新return一下,因为正常的逻辑呢,一定要写这一块的所有代码。
22:27
好,现在订单服务呢,我们这个启动成功,来重新来下单进行测试,只要我们这个签名能认证成功,我们订单的状态就会自动修改,否则呢,我们这个订单就算是失败了,现在在这儿来做一个重新测试,那先来清空我们这个控制台。好,来,重新来进行下单。这有一个古丽麦尔康走。来重新下单走,现在还是来买上一件,那在这来点一个提交订单5805。来使用我们的这个支付宝支付,来选择沙箱。
23:02
好,我们来登录沙箱,1234566个一把我们这个控制台呢,我们先来清空。清空,只要我们这个支付成功,那现在呢,就会跳到我们这个异步通知来看一下。你们看我们这个异步通通知签名验证成功没问题,那验证成功跳到我们最终的这个订单页,因为现在呢,只要验证成功,就将订单数据就修改了,能看到这块的这个订单,42744274已付款没问题,这就是我们整个支付宝的这块流程,只要我们这个签名验证成功以后,我们一定呢,调用我们自己的业务逻辑,再来修改一下订单状态。
我来说两句