一:异步通知是支付宝回调商户的服务器,所以这个地址需要通过外网访问,在真实项目中都会有对应的服务器,但是在测试中只有使用内网穿透工具
推荐使用NATAPP-内网穿透 基于ngrok的国内高速内网映射工具
配置好内网穿透之后不要忘记在常量类中配置异步返回的地址
二:异步通知
@RequestMapping("/alpay")
@ResponseBody
public String alpay(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {// 获取支付宝POST过来反馈信息Map<String, String> params = new HashMap<>();Map<String, String[]> requestParams = httpServletRequest.getParameterMap();for (String name : requestParams.keySet()) {String[] values = requestParams.get( name );StringBuilder valueStr = new StringBuilder();for (String value : values) {valueStr.append( value );}params.put( name, valueStr.toString() );}// 调用支付宝SDK进行验签boolean verifyResult = false;try {verifyResult = AlipaySignature.rsaCheckV1( params, constant.PublicKey, "UTF-8", "RSA2" );} catch (Exception e) {e.printStackTrace();}// 验签通过,则处理业务逻辑if (verifyResult) {System.out.println( "异步验证通过" );//支付String tradeStatus = params.get( "trade_status" );if (tradeStatus.equals( "TRADE_SUCCESS" )) {// 交易支付成功,处理支付成功的逻辑String orderId = params.get( "out_trade_no" );String tradeNo = params.get( "trade_no" );String total_amount = params.get( "total_amount" );System.out.println( "订单id:" + orderId );System.out.println( "流水号:" + tradeNo );System.out.println( "支付金额:" + total_amount );
//根据订单号调用查询接口,查询支付信息AlipayTradeQueryResponse query = query( params.get( "out_trade_no" ) );
//查询支付信息,获取支付金额和订单金额是否一致,一致就就修改订单状态String totalAmount = query.getTotalAmount();if (totalAmount.equals( total_amount )) {boolean b = sysOrdersService.updateState( orderId );System.out.println( "修改数据库订单状态是否成功:" + b );}}}return "success";} else {// 验签失败,记录日志或进行其他后续处理System.out.println( "异步验证失败" );return "failure";}
}
三:查询交易信息接口
/*** 查询交易信息** @param outTradeNo* @return*/public static AlipayTradeQueryResponse query(String outTradeNo) {try {AlipayClient alipayClient = new DefaultAlipayClient(constant.serverUrl,constant.appId,constant.privateKey,constant.format,constant.charset,constant.PublicKey,constant.signType );AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();JSONObject bizContent = new JSONObject();bizContent.put( "out_trade_no", outTradeNo );request.setBizContent( bizContent.toString() );AlipayTradeQueryResponse response = alipayClient.execute( request );if (response.isSuccess()) {System.out.println( "调用查询接口成功" );return response;} else {System.out.println( "调用查询接口失败" );}} catch (AlipayApiException e) {e.printStackTrace();}return null;}
四:测试
查看支付宝是否调用异步通知接口,数据库状态是否修改
新建订单
控制台输出
数据库
状态修改成功