package com.iformall.controller; import com.alibaba.fastjson.JSONObject; import com.github.binarywang.wxpay.v3.util.AesUtils; import com.iformall.annotation.AuthIgnore; import com.iformall.common.ErrorCode; import com.iformall.domain.po.ProductOrder; import com.iformall.domain.po.ProductOrderPay; import com.iformall.domain.po.WxAppinfo; import com.iformall.domain.po.WxPayAccount; import com.iformall.enums.EnumAppPlat; import com.iformall.enums.EnumProductOrderPayVendor; import com.iformall.interceptor.BodyReaderHttpServletRequestWrapper; import com.iformall.service.ProductOrderPayService; import com.iformall.service.ProductOrderService; import com.iformall.service.WxAppinfoService; import com.iformall.service.WxPayAccountService; import com.iformall.service.pay.PayServiceFactory; import com.iformall.service.pay.service.pay.PayAdapterService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.apache.commons.lang3.StringUtils; import org.jdom2.JDOMException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @RestController @RequestMapping("/payCallBack") @Api(description = "支付回调") public class CallbackPayController extends BaseController { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private WxAppinfoService wxAppinfoService; @Autowired private WxPayAccountService wxPayAccountService; @Autowired private ProductOrderPayService productOrderPayService; @Autowired private PayServiceFactory payServiceFactory; @AuthIgnore @ApiOperation("支付回调") @PostMapping(value = "{projectType}/pay/v3") public void _payV3Notify(@PathVariable Integer projectType, @RequestBody Map paranMap, HttpServletRequest request, HttpServletResponse response) { logger.debug("[" + getIpAddr() + "] CallbackPayController::_payV3Notify"); logger.info("微信支付回调结果通知{}"+JSONObject.toJSONString(paranMap)); /** * {"id":"4330b030-788f-5067-8c8a-69ee373d43ad","create_time":"2023-08-28T18:44:56+08:00","resource_type":"encrypt-resource","event_type":"TRANSACTION.SUCCESS","summary":"支付成功","resource":{"original_type":"transaction","algorithm":"AEAD_AES_256_GCM","ciphertext":"PneNTwSVDoirBNQsJstB/yX1dNMupj7uKQVEVfLOoyMSCqKh+KMwIdanidbcs6OnSy1Xmx4MploMaQ5rSg66sFDQ9nDuSVc4S/I3OVflu1l7z9vR+FJiztpTqhr/ekeNz9VivtqPPtn6N3dCyZb6iCEwnXT+TEB8SBZe4bPSPFGhB/MB9w1ZpqP14OvMDUnzKM15mdex6wmAJH6qIbd1aH3jrW/Lv7KeyfXEYrRDljq2Za6476UQxeAcsR3JA6QpWwrhYxpKFQEHuGMdiVC1KvQsP3+JUWOKSiQQ1r5upTACPI8n5B/kOeXJA8MnTgY/7lZiA6ys2dt8jqxzL8IlDracnlwvsiRAuXjRjcX6pYCz4q0HwIYb1nHXE+iRcSGm8h+xFFsnhGgxrhEVz6ARhK6ZtKtibCv7Ll/a/d090FBKtVXzCWB6cLMMmfrIwLQFqiFUtb6zsV/zusAJdwHZt3LmtgGahoV3+UPTnbztEAp5IJGz2imGPTsk7QpvKWQknf5FM/Z1fhr/vb+pZV5NGBZ+6l/mI8isA4HtljzNHU/PuKCGO8uWu6QFevgAftGGww==","associated_data":"transaction","nonce":"Hrcahgdp1eO6"}} */ try{ WxAppinfo appInfo = wxAppinfoService.getProjectCAppInfoFromRedis(projectType, EnumAppPlat.WX.getCode()); WxPayAccount payAccount = wxPayAccountService.getByIdFromRedis(appInfo.getPayId()); Map resource = (Map) paranMap.get("resource"); String associatedData = resource.get("associated_data"); String nonce = resource.get("nonce"); String ciphertext = resource.get("ciphertext"); String decryptString = AesUtils.decryptToString(associatedData, nonce, ciphertext, payAccount.getMerchantApiv3Key()); logger.info("微信支付回调解密数据{}"+decryptString); JSONObject jsonObject = JSONObject.parseObject(decryptString); String out_order_no = jsonObject.getString("out_trade_no"); /** * 交易类型,枚举值: * JSAPI:公众号支付 * NATIVE:扫码支付 * App:App支付 * MICROPAY:付款码支付 * MWEB:H5支付 * FACEPAY:刷脸支付 */ String trade_type = jsonObject.getString("trade_type"); EnumProductOrderPayVendor payVendorEnum = null; if("JSAPI".equals(trade_type)){ payVendorEnum = EnumProductOrderPayVendor.PAY_WAY_WECHAT; }else if("NATIVE".equals(trade_type)){ payVendorEnum = EnumProductOrderPayVendor.PAY_WAY_WECHAT_NATIVE; } if(payVendorEnum == null){ logger.error("微信支付回调处理支付方式异常{}"+trade_type); response.setStatus(ErrorCode.SYS_SERVER_ERROR.getCode()); } ProductOrderPay orderPay = productOrderPayService.getByOrder(Long.parseLong(out_order_no), payVendorEnum); PayAdapterService payAdapterService = payServiceFactory.getPayAdapterService(payVendorEnum.getCode()); productOrderPayService.handleProductOrderByQuery(appInfo,payAccount,orderPay,payAdapterService); response.setStatus(200); }catch(Exception e){ logger.error("微信支付回调处理异常{}"+e); response.setStatus(ErrorCode.SYS_SERVER_ERROR.getCode()); } } @AuthIgnore @ApiOperation("支付回调") @PostMapping(value = "{projectType}/ttNotify") public Map _ttNotify(@PathVariable Integer projectType, @RequestBody Map paranMap, HttpServletRequest request, HttpServletResponse response) { logger.debug("[" + getIpAddr() + "] CallbackPayController::_ttNotify"); Map resultMap = new HashMap<>(); logger.info("抖音支付回调结果通知{}"+JSONObject.toJSONString(paranMap)); /** * ----效验数据来源合法 */ try{ String msg = (String) paranMap.get("msg"); String type = (String) paranMap.get("type"); Map pMap = JSONObject.parseObject(msg, Map.class); // String appid = (String) pMap.get("appid"); // WxAppinfo appInfo = wxAppinfoService.getOnlyByAppIdFromRedis(appid); WxAppinfo appInfo = wxAppinfoService.getProjectCAppInfoFromRedis(projectType, EnumAppPlat.TOUTIAO.getCode()); WxPayAccount payAccount = wxPayAccountService.getByIdFromRedis(appInfo.getPayId()); if("payment".equals(type)){ String out_order_no = (String)pMap.get("cp_orderno"); EnumProductOrderPayVendor payVendorEnum = EnumProductOrderPayVendor.PAY_WAY_TT; ProductOrderPay orderPay = productOrderPayService.getByOrder(Long.parseLong(out_order_no), payVendorEnum); PayAdapterService payAdapterService = payServiceFactory.getPayAdapterService(payVendorEnum.getCode()); productOrderPayService.handleProductOrderByQuery(appInfo,payAccount,orderPay,payAdapterService); resultMap.put("err_no",0); resultMap.put("err_tips","success"); } }catch(Exception e){ logger.error("抖音支付回调处理异常"+e); resultMap.put("err_no",ErrorCode.SYS_SERVER_ERROR.getCode()); resultMap.put("err_tips","抖音支付回调处理异常"); } return resultMap; } @AuthIgnore @ApiOperation("支付回调") @PostMapping(value = "{projectType}/aliNotify") public String _aliNotify(@PathVariable Integer projectType, HttpServletRequest request, HttpServletResponse response) { logger.debug("[" + getIpAddr() + "] CallbackPayController::_aliNotify"); String body = ((BodyReaderHttpServletRequestWrapper) request).getBody(); logger.info("ali支付回调结果通知 body{}"+body); Map resultMap = new HashMap<>(); /** * ----效验数据来源合法 */ try{ Map paranMap = handBody(body); logger.info("ali支付回调结果通知 paranMap{}"+JSONObject.toJSONString(paranMap)); // String app_id = paranMap.get("app_id"); // WxAppinfo appInfo = wxAppinfoService.getOnlyByAppIdFromRedis(app_id); WxAppinfo appInfo = wxAppinfoService.getProjectCAppInfoFromRedis(projectType, EnumAppPlat.ALI.getCode()); WxPayAccount payAccount = wxPayAccountService.getByIdFromRedis(appInfo.getPayId()); String out_trade_no = paranMap.get("out_trade_no"); String trade_status = paranMap.get("trade_status"); if("TRADE_SUCCESS".equals(trade_status)){ EnumProductOrderPayVendor payVendorEnum = EnumProductOrderPayVendor.PAY_WAY_ALIPAY_WAP; ProductOrderPay orderPay = productOrderPayService.getByOrder(Long.parseLong(out_trade_no), payVendorEnum); PayAdapterService payAdapterService = payServiceFactory.getPayAdapterService(payVendorEnum.getCode()); productOrderPayService.handleProductOrderByQuery(appInfo,payAccount,orderPay,payAdapterService); } return "success"; }catch(Exception e){ logger.error("ali支付回调处理异常"+e); } return "fail"; } private Map handBody(String body){ Map map = new HashMap<>(); if(StringUtils.isNotBlank(body)){ String[] key_value = body.split("&"); if(key_value.length > 0){ for (String kv: key_value) { String[] split = kv.split("="); map.put(split[0],split[1]); } } } return map; } }