WebhookController.java 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. package com.szwl.controller;
  2. import cn.com.sand.third.org.apache.commons.codec.digest.HmacUtils;
  3. import com.alibaba.fastjson.JSON;
  4. import com.alibaba.fastjson.JSONObject;
  5. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  6. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  7. import com.fasterxml.jackson.core.JsonProcessingException;
  8. import com.fasterxml.jackson.databind.JsonNode;
  9. import com.fasterxml.jackson.databind.ObjectMapper;
  10. import com.szwl.model.entity.TCoinOrder;
  11. import com.szwl.model.utils.PushUtils;
  12. import com.szwl.service.TCoinOrderService;
  13. import com.szwl.service.TEquipmentService;
  14. import lombok.extern.slf4j.Slf4j;
  15. import org.springframework.stereotype.Controller;
  16. import org.springframework.web.bind.annotation.PostMapping;
  17. import org.springframework.web.bind.annotation.RequestBody;
  18. import org.springframework.web.bind.annotation.ResponseBody;
  19. import javax.annotation.Resource;
  20. import javax.servlet.http.HttpServletRequest;
  21. import javax.servlet.http.HttpServletResponse;
  22. import java.util.Objects;
  23. import static com.szwl.common.WebhooksCommon.WEBHOOKS_KEY_PAYMENT_INTENT;
  24. import static com.szwl.common.WebhooksCommon.WEBHOOKS_KEY_REFUND;
  25. @Controller
  26. @Slf4j
  27. public class WebhookController {
  28. @Resource
  29. TCoinOrderService tCoinOrderService;
  30. @Resource
  31. TEquipmentService tEquipmentService;
  32. // @Resource
  33. // AirwallexService airwallexService;
  34. // public ResponseModel<?> createAWebhook(String[] envents, String requiredId, String url, String version) {
  35. // log.info("创建webhook");
  36. // String accessToken = airwallexService.getAccessToken();
  37. //
  38. // airwallexService.caWebhook(envents, requiredId, url, version);
  39. //
  40. // return
  41. // }
  42. /**
  43. * 获取退款的回调
  44. * @param request
  45. * @param response
  46. * @return
  47. */
  48. @ResponseBody
  49. @PostMapping("/webhook/refund")
  50. public String receiveRefund(HttpServletRequest request, @RequestBody String payload, HttpServletResponse response) {
  51. String responseBody = "";
  52. StringBuilder valueToDigest = new StringBuilder();
  53. // Get the timestamp from header
  54. String timestamp = request.getHeader("x-timestamp");
  55. valueToDigest.append(timestamp);
  56. valueToDigest.append(payload);
  57. // Get the signature from header
  58. String signature = request.getHeader("x-signature");
  59. // Get your secret
  60. String secret = getSecretRefund();
  61. if (HmacUtils.hmacSha256Hex(secret, valueToDigest.toString()).equals(signature)) {
  62. // Do something with event
  63. response.setStatus(HttpServletResponse.SC_OK);
  64. JSONObject jsonObject = JSON.parseObject(payload);
  65. JSONObject object = jsonObject.getJSONObject("data").getJSONObject("object");
  66. String refundId = object.getString("id");
  67. String status = object.getString("status");
  68. // JSONObject jsonObject = JSON.parseObject(payload);
  69. // String data = jsonObject.getString("data");
  70. // JSONObject jsonObject1 = JSON.parseObject(data);
  71. // String dataObject = jsonObject1.getString("object");
  72. // JSONObject jsonObject2 = JSON.parseObject(dataObject);
  73. // String refundId = jsonObject2.getString("id");
  74. // String status = jsonObject2.getString("status");
  75. // 如果退款成功
  76. if (status.equals("RECEIVED") || status.equals("ACCEPTED") || status.equals("SUCCEEDED")) {
  77. LambdaQueryWrapper<TCoinOrder> lambdaQueryWrapper = Wrappers.lambdaQuery();
  78. lambdaQueryWrapper.eq(TCoinOrder::getRefundId, refundId);
  79. TCoinOrder tCoinOrder = tCoinOrderService.getOne(lambdaQueryWrapper);
  80. if (Objects.isNull(tCoinOrder)) {
  81. return "订单为空/error";
  82. }
  83. // 设置订单支付状态为 已退款
  84. tCoinOrder.setStatus(3);
  85. tCoinOrderService.updateById(tCoinOrder);
  86. }
  87. } else {
  88. // Invalid signature
  89. response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
  90. responseBody = "failed to verify the signature";
  91. }
  92. return responseBody;
  93. }
  94. /**
  95. * 获取支付意向的回调
  96. * @param request
  97. * @param payload
  98. * @param response
  99. * @return
  100. */
  101. @ResponseBody
  102. @PostMapping("/webhook/paymentIntent")
  103. public String receivePaymentIntent(HttpServletRequest request, @RequestBody String payload, HttpServletResponse response) {
  104. String responseBody = "";
  105. StringBuilder valueToDigest = new StringBuilder();
  106. // Get the timestamp from header
  107. String timestamp = request.getHeader("x-timestamp");
  108. valueToDigest.append(timestamp);
  109. valueToDigest.append(payload);
  110. // Get the signature from header
  111. String signature = request.getHeader("x-signature");
  112. // Get your secret
  113. String secret = getSecretPaymentInent();
  114. if (HmacUtils.hmacSha256Hex(secret, valueToDigest.toString()).equals(signature)) {
  115. // Do something with event
  116. response.setStatus(HttpServletResponse.SC_OK);
  117. responseBody = "payment intent ok";
  118. // 如果用户支付成功,将订单支付状态改成 1已支付。
  119. // JSONObject jsonObj = JSON.parseObject(payload);
  120. // String data = jsonObj.getString("data");
  121. // JSONObject jsonObject1 = JSON.parseObject(data);
  122. // String dataObject = jsonObject1.getString("object");
  123. // JSONObject jsonObject2 = JSON.parseObject(dataObject);
  124. // String paymentIntentId = jsonObject2.getString("id");
  125. // JSONObject data1 = jsonObj.getJSONObject("data");
  126. // JSONObject object = data1.getJSONObject("object");
  127. // String paymentIntentId = object.getString("id");
  128. // QueryWrapper<TOrderAbroad> tOrderAbroadQueryWrapper = new QueryWrapper<>();
  129. // tOrderAbroadQueryWrapper.eq("payment_intent_id",paymentIntentId);
  130. String paymentIntentId = JSON.parseObject(payload).getJSONObject("data").getJSONObject("object").getString("id");
  131. // JSONObject jsonObj = Optional.ofNullable(jsonObject)
  132. // .flatMap(jsonObject1 -> Optional.ofNullable(jsonObject1.getJSONObject("data")))
  133. // .flatMap(jsonObject1 -> Optional.ofNullable(jsonObject1.getJSONObject("object")))
  134. // .flatMap(jsonObject1 -> Optional.ofNullable(jsonObject1.getJSONObject("id")))
  135. // .orElse(null);
  136. // JSONObject idJson = Optional.ofNullable(jsonObj)
  137. // .flatMap(jsonObject -> Optional.ofNullable(jsonObject.getJSONObject("data")))
  138. // .flatMap(jsonObject -> Optional.ofNullable(jsonObject.getJSONObject("object")))
  139. // .flatMap(jsonObject -> Optional.ofNullable(jsonObject.getJSONObject("id")))
  140. // .orElse(null);
  141. // JSONObject idJson = Optional.ofNullable(jsonObj)
  142. // .map(jsonObject -> jsonObject.getJSONObject("data"))
  143. // .map(jsonObject -> jsonObject.getJSONObject("object"))
  144. // .map(jsonObject -> jsonObject.getJSONObject("id"))
  145. // .orElse(null);
  146. // String paymentIntentId = JSON.toJSONString(idJson);
  147. LambdaQueryWrapper<TCoinOrder> lambdaQueryWrapper = Wrappers.lambdaQuery();
  148. lambdaQueryWrapper.eq(TCoinOrder::getPaymentIntentId, paymentIntentId);
  149. // QueryWrapper<TOrderAbroad> lambdaQueryWrapper = new QueryWrapper<>();
  150. // lambdaQueryWrapper.eq("payment_intent_id", paymentIntentId);
  151. TCoinOrder coinOrder = tCoinOrderService.getOne(lambdaQueryWrapper);
  152. System.out.println(coinOrder);
  153. coinOrder.setStatus(1); // 订单状态设置为已支付
  154. tCoinOrderService.updateById(coinOrder);
  155. // TODO: 然后再去分销,给每个账户钱包加钱
  156. // 先获取订单信息中的 altInfo 字段,然后拆分,获取其中每个 adminId 和对应的金额
  157. String altInfo = coinOrder.getAltInfo();
  158. try {
  159. ObjectMapper objectMapper = new ObjectMapper();
  160. JsonNode jsonNode = objectMapper.readTree(altInfo);
  161. for (JsonNode node : jsonNode) {
  162. String airBeneId = node.get("airBeneId").asText();
  163. String airAmount = node.get("airAmount").asText();
  164. }
  165. } catch (JsonProcessingException e) {
  166. throw new RuntimeException(e);
  167. }
  168. // 通知做糖
  169. JSONObject kindData = new JSONObject();
  170. kindData.put("sn", coinOrder.getMerchantOrderId());
  171. kindData.put("productName", coinOrder.getProductName());
  172. tEquipmentService.sentMessage(coinOrder.getClientId(), PushUtils.buildJson("pay_success", kindData.toString()).toString());
  173. } else {
  174. // Invalid signature
  175. response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
  176. responseBody = "failed to verify the signature";
  177. // TODO: 验签失败,先retrieve手动获取订单信息,如果成功,走上面那一套,如果失败不做处理
  178. }
  179. // System.out.println(response);
  180. // System.out.println(responseBody);
  181. return responseBody;
  182. }
  183. private String getSecretPaymentInent() {
  184. return WEBHOOKS_KEY_PAYMENT_INTENT;
  185. }
  186. private String getSecretRefund() {
  187. return WEBHOOKS_KEY_REFUND;
  188. }
  189. }