一:异步通知是支付宝回调商户的服务器,所以这个地址需要通过外网访问,在真实项目中都会有对应的服务器,但是在测试中只有使用内网穿透工具
推荐使用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;
}
四:测试
查看支付宝是否调用异步通知接口,数据库状态是否修改
新建订单
控制台输出
数据库
状态修改成功