当前位置:   article > 正文

微信支付回调通知实现_streamutils.inputstream2string

streamutils.inputstream2string

一 准备

1 配置ngrok

将ngrok映射到本地8170端口,并启动

2 添加工具类

在common_util中添加工具类StreamUtils

  1. package com.atguigu.guli.service.trade.util;
  2. import java.io.ByteArrayOutputStream;
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. public class StreamUtils {
  6. private static int _buffer_size = 1024;
  7. /**
  8. * InputStream流转换成String字符串
  9. * @param inStream InputStream流
  10. * @param encoding 编码格式
  11. * @return String字符串
  12. */
  13. public static String inputStream2String(InputStream inStream, String encoding){
  14. String result = null;
  15. ByteArrayOutputStream outStream = null;
  16. try {
  17. if(inStream != null){
  18. outStream = new ByteArrayOutputStream();
  19. byte[] tempBytes = new byte[_buffer_size];
  20. int count = -1;
  21. while((count = inStream.read(tempBytes, 0, _buffer_size)) != -1){
  22. outStream.write(tempBytes, 0, count);
  23. }
  24. tempBytes = null;
  25. outStream.flush();
  26. result = new String(outStream.toByteArray(), encoding);
  27. outStream.close();
  28. }
  29. } catch (Exception e) {
  30. result = null;
  31. } finally {
  32. try {
  33. if(inStream != null) {
  34. inStream.close();
  35. inStream = null;
  36. }
  37. if(outStream != null) {
  38. outStream.close();
  39. outStream = null;
  40. }
  41. } catch (IOException e) {
  42. e.printStackTrace();
  43. }
  44. }
  45. return result;
  46. }
  47. }

二 支付回调

1 回调方法

该链接是通过【统一下单API】中提交的参数notify_url设置,如果链接无法访问,商户将无法接收到微信通知。

参考文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_7&index=8

2 控制器

  1. /**
  2. * 功能描述:微信回调通知
  3. *
  4. * @author cakin
  5. * @date 2021/1/13
  6. * @param request 请求
  7. * @return response 响应
  8. */
  9. @PostMapping("callback/notify")
  10. public String wxNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
  11. log.info("\n callback/notify 被调用");
  12. ServletInputStream inputStream = request.getInputStream();
  13. String notifyXml = StreamUtils.inputStream2String(inputStream, "utf-8");
  14. log.info("\n notifyXml = \n " + notifyXml);
  15. // 验签:验证签名是否正确
  16. if (WXPayUtil.isSignatureValid(notifyXml, weixinPayProperties.getPartnerKey())) {
  17. // 解析返回结果
  18. Map<String, String> notifyMap = WXPayUtil.xmlToMap(notifyXml);
  19. // 判断支付是否成功
  20. if ("SUCCESS".equals(notifyMap.get("result_code"))) {
  21. // 金额校验
  22. String totalFee = notifyMap.get("total_fee"); //支付结果返回的订单金额
  23. String outTradeNo = notifyMap.get("out_trade_no");//订单号
  24. Order order = orderService.getOrderByOrderNo(outTradeNo);//查询本地订单
  25. // 校验返回的订单金额是否与商户侧的订单金额一致
  26. if (order != null && order.getTotalFee().intValue() == Integer.parseInt(totalFee)) {
  27. // 接口调用的幂等性:无论接口被调用多少次,最后所影响的结果都是一致的
  28. if (order.getStatus() == 0) {
  29. // 更新订单状态
  30. orderService.updateOrderStatus(notifyMap);
  31. }
  32. // 支付成功:给微信发送我已接收通知的响应
  33. // 创建响应对象
  34. Map<String, String> returnMap = new HashMap<>();
  35. returnMap.put("return_code", "SUCCESS");
  36. returnMap.put("return_msg", "OK");
  37. String returnXml = WXPayUtil.mapToXml(returnMap);
  38. response.setContentType("text/xml");
  39. log.info("支付成功,通知已处理");
  40. return returnXml;
  41. }
  42. }
  43. }
  44. // 创建响应对象:微信接收到校验失败的结果后,会反复的调用当前回调函数
  45. Map<String, String> returnMap = new HashMap<>();
  46. returnMap.put("return_code", "FAIL");
  47. returnMap.put("return_msg", "");
  48. String returnXml = WXPayUtil.mapToXml(returnMap);
  49. response.setContentType("text/xml");
  50. log.info("校验失败");
  51. return returnXml;
  52. }

3 服务层

接口

void updateOrderStatus(Map<String, String> notifyMap);

实现

  1. @Transactional(rollbackFor = Exception.class)
  2. @Override
  3. public void updateOrderStatus(Map<String, String> notifyMap) {
  4. // 更新订单状态
  5. String outTradeNo = notifyMap.get("out_trade_no");
  6. Order order = this.getOrderByOrderNo(outTradeNo);
  7. order.setStatus(1);//支付成功
  8. baseMapper.updateById(order);
  9. // 记录支付日志
  10. PayLog payLog = new PayLog();
  11. payLog.setOrderNo(outTradeNo);
  12. payLog.setPayTime(new Date());
  13. payLog.setPayType(1);//支付类型:微信支付
  14. payLog.setTotalFee(Long.parseLong(notifyMap.get("total_fee")));
  15. payLog.setTradeState(notifyMap.get("result_code"));
  16. payLog.setTransactionId(notifyMap.get("transaction_id"));
  17. payLog.setAttr(new Gson().toJson(notifyMap));
  18. payLogMapper.insert(payLog);
  19. //更新课程销量
  20. eduCourseService.updateBuyCountById(order.getCourseId());
  21. }

 

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号