package com.izouma.nineth.web; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.alipay.api.AlipayApiException; import com.alipay.api.internal.util.AlipaySignature; import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse; import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.service.WxPayService; import com.github.kevinsawicki.http.HttpRequest; import com.huifu.adapay.Adapay; import com.huifu.adapay.core.AdapayCore; import com.huifu.adapay.core.util.AdapaySign; import com.izouma.nineth.config.AlipayProperties; import com.izouma.nineth.config.GeneralProperties; import com.izouma.nineth.config.RedisKeys; import com.izouma.nineth.enums.PayMethod; import com.izouma.nineth.enums.SandPayMethod; import com.izouma.nineth.event.OrderNotifyEvent; import com.izouma.nineth.repo.ErrorOrderRepo; import com.izouma.nineth.service.AssetService; import com.izouma.nineth.service.GiftOrderService; import com.izouma.nineth.service.MintOrderService; import com.izouma.nineth.service.OrderService; import com.izouma.nineth.utils.SnowflakeIdWorker; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.MapUtils; import org.apache.rocketmq.spring.core.RocketMQTemplate; import org.springframework.core.env.Environment; import org.springframework.data.redis.core.BoundSetOperations; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; import static com.alibaba.fastjson.serializer.SerializerFeature.PrettyFormat; @Slf4j @Controller @RequestMapping("/notify") @AllArgsConstructor public class OrderNotifyController { private final AlipayProperties alipayProperties; private final OrderService orderService; private final WxPayService wxPayService; private final AssetService assetService; private final GiftOrderService giftOrderService; private final SnowflakeIdWorker snowflakeIdWorker; private final RocketMQTemplate rocketMQTemplate; private final GeneralProperties generalProperties; private final MintOrderService mintOrderService; private final ErrorOrderRepo errorOrderRepo; private final RedisTemplate redisTemplate; private final Environment env; @PostMapping("/order/alipay") @ResponseBody public String notify(HttpServletRequest request) throws AlipayApiException { Map params = new HashMap<>(); Set> entrySet = request.getParameterMap().entrySet(); for (Map.Entry entry : entrySet) { String name = entry.getKey(); String[] values = entry.getValue(); int valLen = values.length; if (valLen == 1) { params.put(name, values[0]); } else if (valLen > 1) { StringBuilder sb = new StringBuilder(); for (String val : values) { sb.append(",").append(val); } params.put(name, sb.substring(1)); } else { params.put(name, ""); } } log.info("支付宝回调 {}", JSON.toJSONString(params, PrettyFormat)); AlipaySignature.rsaCheckV1(params, alipayProperties.getAliPublicKey(), "UTF-8", "RSA2"); if (MapUtils.getString(params, "trade_status").equals("TRADE_SUCCESS")) { JSONObject body = JSON.parseObject(params.get("body")); String action = body.getString("action"); switch (action) { case "payOrder": { Long orderId = body.getLong("orderId"); orderService.notifyOrder(orderId, PayMethod.ALIPAY, MapUtils.getString(params, "trade_no")); break; } case "payGiftOrder": { Long orderId = body.getLong("orderId"); giftOrderService.giftNotify(orderId, PayMethod.ALIPAY, MapUtils.getString(params, "trade_no")); break; } case "payMintOrder": { Long orderId = body.getLong("orderId"); mintOrderService.mintNotify(orderId, PayMethod.ALIPAY, MapUtils.getString(params, "trade_no")); break; } } return "success"; } return "error"; } @PostMapping(value = "/order/weixin", produces = "application/xml") @ResponseBody public String wxNotify(@RequestBody String xmlData) throws WxPayException { log.info("微信支付回调: {}", xmlData); final WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData); notifyResult.checkResult(wxPayService, "MD5", true); JSONObject attach = JSONObject.parseObject(notifyResult.getAttach()); String action = attach.getString("action"); switch (action) { case "payOrder": { Long orderId = attach.getLong("orderId"); orderService.notifyOrder(orderId, PayMethod.WEIXIN, notifyResult.getTransactionId()); break; } case "payGiftOrder": { Long orderId = attach.getLong("orderId"); giftOrderService.giftNotify(orderId, PayMethod.WEIXIN, notifyResult.getTransactionId()); break; } } return WxPayNotifyResponse.success("OK"); } @PostMapping(value = "/order/iap") @ResponseBody public String iap(@RequestParam String receiptData, @RequestParam Long orderId) { String data = "{\"receipt-data\":\"" + receiptData + "\"}"; String body = HttpRequest.post("https://buy.itunes.apple.com/verifyReceipt") .contentType("application/json") .send(data) .body(); JSONObject jsonObject = JSON.parseObject(body); int status = jsonObject.getInteger("status"); if (status == 21007) { jsonObject = JSON.parseObject(HttpRequest.post("https://sandbox.itunes.apple.com/verifyReceipt") .contentType("application/json") .send(data) .body()); status = jsonObject.getInteger("status"); } if (status == 0) { orderService.notifyOrder(orderId, PayMethod.WEIXIN, snowflakeIdWorker.nextId() + ""); } return "ok"; } // @PostMapping("/adapay/order/{orderId}") // @ResponseBody // public void adapayNotify(@PathVariable Long orderId, HttpServletRequest request) { // log.info("adapay notify: \n{}", JSON.toJSONString(request.getParameterMap(), PrettyFormat)); // try { // String data = request.getParameter("data"); // String sign = request.getParameter("sign"); // String type = request.getParameter("type"); // if ("payment.succeeded".equals(type)) { // boolean checkSign = AdapaySign.verifySign(data, sign, AdapayCore.PUBLIC_KEY); // log.info("checkSign {}", checkSign); // if (checkSign) { // JSONObject jsonObject = JSON.parseObject(data); // String channel = jsonObject.getString("pay_channel"); // String id = jsonObject.getString("id"); // // rocketMQTemplate.syncSend(generalProperties.getOrderNotifyTopic(), // new OrderNotifyEvent(orderId, channel.startsWith("wx") ? PayMethod.WEIXIN : PayMethod.ALIPAY, id, LocalDateTime.now())); // // orderService.notifyOrder(orderId, channel.startsWith("wx") ? PayMethod.WEIXIN : PayMethod.ALIPAY, id); // } // } // } catch (Exception e) { // e.printStackTrace(); // } // } @PostMapping("/adapay/order/{orderId}") @ResponseBody public void adapayNotify(@PathVariable Long orderId, HttpServletRequest request) throws Exception { adapayNotify(Adapay.defaultMerchantKey, orderId, request); } @PostMapping("/adapay/order/{merchant}/{orderId}") @ResponseBody public void adapayNotify(@PathVariable String merchant, @PathVariable Long orderId, HttpServletRequest request) throws Exception { log.info("adapay notify: \n{}", JSON.toJSONString(request.getParameterMap(), PrettyFormat)); String data = request.getParameter("data"); String sign = request.getParameter("sign"); String type = request.getParameter("type"); if ("payment.succeeded".equals(type)) { boolean checkSign = AdapaySign.verifySign(data, sign, AdapayCore.PUBLIC_KEY); log.info("checkSign {}", checkSign); if (checkSign) { JSONObject jsonObject = JSON.parseObject(data); String channel = jsonObject.getString("pay_channel"); String id = jsonObject.getString("id"); PayMethod payMethod = channel.startsWith("wx") ? PayMethod.WEIXIN : PayMethod.ALIPAY; BoundSetOperations listOps = redisTemplate.boundSetOps(RedisKeys.PAY_RECORD + orderId); listOps.add(merchant + "#" + id); listOps.expire(7, TimeUnit.DAYS); rocketMQTemplate.syncSend(generalProperties.getOrderNotifyTopic(), new OrderNotifyEvent(orderId, payMethod, id, System.currentTimeMillis())); } } } @PreAuthorize("hasRole('ADMIN')") @PostMapping("/adapay/ordertest/{orderId}") @ResponseBody public void adapayNotifyTest(@PathVariable Long orderId, @RequestParam String transactionId) throws Exception { BoundSetOperations listOps = redisTemplate.boundSetOps(RedisKeys.PAY_RECORD + orderId); listOps.add(transactionId); listOps.expire(7, TimeUnit.DAYS); rocketMQTemplate.syncSend(generalProperties.getOrderNotifyTopic(), new OrderNotifyEvent(orderId, PayMethod.ALIPAY, transactionId, System.currentTimeMillis())); } @PostMapping("/adapay/giftOrder/{orderId}") @ResponseBody public void adapayGiftNotify(@PathVariable Long orderId, HttpServletRequest request) { log.info("adapay gift notify: \n{}", JSON.toJSONString(request.getParameterMap(), PrettyFormat)); try { String data = request.getParameter("data"); String sign = request.getParameter("sign"); String type = request.getParameter("type"); if ("payment.succeeded".equals(type)) { boolean checkSign = AdapaySign.verifySign(data, sign, AdapayCore.PUBLIC_KEY); log.info("checkSign {}", checkSign); if (checkSign) { JSONObject jsonObject = JSON.parseObject(data); String channel = jsonObject.getString("pay_channel"); String id = jsonObject.getString("id"); giftOrderService.giftNotify(orderId, channel.startsWith("wx") ? PayMethod.WEIXIN : PayMethod.ALIPAY, id); } } } catch (Exception e) { e.printStackTrace(); } } @PostMapping("/adapay/mintOrder/{orderId}") @ResponseBody public void adapayMintNotify(@PathVariable Long orderId, HttpServletRequest request) { log.info("adapay mint notify: \n{}", JSON.toJSONString(request.getParameterMap(), PrettyFormat)); try { String data = request.getParameter("data"); String sign = request.getParameter("sign"); String type = request.getParameter("type"); if ("payment.succeeded".equals(type)) { boolean checkSign = AdapaySign.verifySign(data, sign, AdapayCore.PUBLIC_KEY); log.info("checkSign {}", checkSign); if (checkSign) { JSONObject jsonObject = JSON.parseObject(data); String channel = jsonObject.getString("pay_channel"); String id = jsonObject.getString("id"); mintOrderService.mintNotify(orderId, channel.startsWith("wx") ? PayMethod.WEIXIN : PayMethod.ALIPAY, id); } } } catch (Exception e) { e.printStackTrace(); } } }