项目
博客
文档
归档
资源链接
关于我
项目
博客
文档
归档
资源链接
关于我
38| 内网穿透工具和支付结果通知回调模块开发
2024-09-18
·
·
原创
·
·
本文共 412个字,预计阅读需要 2分钟。
### 内网穿透映射工具介绍和使用 什么是内网穿透 - 支付成功需要配置回调通知应用服务器订单支付成功,需要配置对应的域名 - 在本地电脑开发,支付宝没法回调,所以需要配置个地址映射,就是外部服务器 - 可以通过这个地址访问当前开发电脑的地址 工具 * ngrock https://ngrok.com/ * 花生壳 https://hsk.oray.com/ * natapp https://natapp.cn/ * 小米球 http://ngrok.ciqiuwl.cn/ 账号申请 ```shell #配置token和子域名 token: A3dc8765c57f4e6e8Ac84276deA889c4 #增加权限 chmod 777 ./* #启动 ./ngrok -log=ngrok.log -config ngrok.conf start httptun httpstun ``` 地址配置 * 回调地址:外网可以访问 * http://xdclass.ngrok2.xiaomiqiu.cn/api/callback/order/v1/alipay * 支付成功配置:外网可以访问 ![](https://yn-blog.oss-cn-chengdu.aliyuncs.com/v_2023/2024-09-18/ab53fc9a-0aaf-47d7-969e-6adca06d8451.png) * 访问测试 ### 支付宝支付结果通知回调地址配置和接口开发 * 补充支付宝手机支付文档:https://opendocs.alipay.com/open/203/105286 * 支付宝沙箱环境配置支付结果通知回调地址 * 配置文件配置支付结果通知回调地址 * controller接口开发 ```java @Api("订单回调通知模块") @Controller @RequestMapping("/odr/callback/v1") @Slf4j public class CallbackController { @Autowired private ProductOrderService productOrderService; /** * 支付回调通知 post方式 */ @PostMapping("alipay") public String alipayCallback(HttpServletRequest request, HttpServletResponse response){ //将异步通知中收到的所有参数存储到map中 Map
paramsMap = convertRequestParamsToMap(request); log.info("支付宝回调通知结果:{}",paramsMap); //调用SDK验证签名 try { boolean signVerified = AlipaySignature.rsaCheckV1(paramsMap, AlipayConfig.ALIPAY_PUB_KEY, AlipayConfig.CHARSET, AlipayConfig.SIGN_TYPE); if(signVerified){ JsonData jsonData = productOrderService.handlerOrderCallbackMsg(ProductOrderPayTypeEnum.ALIPAY,paramsMap); if(jsonData.getCode() == 0){ //通知结果确认成功,不然会一直通知,八次都没返回success就认为交易失败 return "success"; } } } catch (AlipayApiException e) { log.info("支付宝回调验证签名失败:异常:{},参数:{}",e,paramsMap); } return "failure"; } } ``` * 工具转换 ```java /** * 将request中的参数转换成Map * @param request * @return */ private static Map
convertRequestParamsToMap(HttpServletRequest request) { Map
paramsMap = new HashMap<>(16); Set
> entrySet = request.getParameterMap().entrySet(); for (Map.Entry
entry : entrySet) { String name = entry.getKey(); String[] values = entry.getValue(); int size = values.length; if (size == 1) { paramsMap.put(name, values[0]); } else { paramsMap.put(name, ""); } } System.out.println(paramsMap); return paramsMap; } ``` ### 支付宝支付结果通知回调验证签和更新订单状态开发 * 文档:https://opensupport.alipay.com/support/helpcenter/193/201602472200?ant_source=antsupport * 回调业务逻辑开发 * 更新订单状态 * 如何保证幂等性: 可以不做幂等性处理,本身不影响 ```java /*** * 支付通知结果更新订单状态 */ @Override public JsonData handlerOrderCallbackMsg(ProductOrderPayTypeEnum payType, Map
paramsMap) { //MQ投递 --》在慢慢消费 if(payType.name().equalsIgnoreCase(ProductOrderPayTypeEnum.ALIPAY.name())){ //支付宝支付 //获取商户订单号 String outTradeNo = paramsMap.get("out_trade_no"); //交易的状态 String tradeStatus = paramsMap.get("trade_status"); if("TRADE_SUCCESS".equalsIgnoreCase(tradeStatus) || "TRADE_FINISHED".equalsIgnoreCase(tradeStatus)){ //更新订单状态 baseMapper.updateOrderPayState(outTradeNo,ProductOrderStateEnum.PAY.name(),ProductOrderStateEnum.NEW.name()); return JsonData.buildSuccess(); } } else if(payType.name().equalsIgnoreCase(ProductOrderPayTypeEnum.WECHAT.name())){ //微信支付 TODO } return JsonData.buildResult(BizCodeEnum.PAY_ORDER_CALLBACK_NOT_SUCCESS); } ``` maper.xml ```xml
update product_order set `state`=#{newState} where out_trade_no = #{outTradeNo} and `state` = #{oldState}
```