From d08a04ee79db9370f6d3c9a7e4ad41911d2d9390 Mon Sep 17 00:00:00 2001 From: KKSU <15274802129@163.com> Date: Sat, 08 Feb 2025 10:09:23 +0800 Subject: [PATCH] refactor(pay): 重构富友支付回调接口 --- src/main/java/cc/mrbird/febs/pay/controller/FiuuReturnController.java | 78 +++++++++++++++++++++++++++------------ 1 files changed, 54 insertions(+), 24 deletions(-) diff --git a/src/main/java/cc/mrbird/febs/pay/controller/FiuuReturnController.java b/src/main/java/cc/mrbird/febs/pay/controller/FiuuReturnController.java index 1f79e7b..0dca5b3 100644 --- a/src/main/java/cc/mrbird/febs/pay/controller/FiuuReturnController.java +++ b/src/main/java/cc/mrbird/febs/pay/controller/FiuuReturnController.java @@ -9,15 +9,16 @@ import cn.hutool.core.date.DateUtil; import io.swagger.annotations.Api; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.codec.digest.DigestUtils; import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.annotation.Resource; -import java.util.Map; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; @Slf4j @Controller @@ -25,47 +26,76 @@ @RequestMapping(value = "/api/fuPayReturn") public class FiuuReturnController { - + private static final String SECRET_KEY = "59c709fc18978a6a83b87f05d37cecbf"; @Resource private MallOrderInfoMapper mallOrderInfoMapper; // Java 通知接口 暂时停止使用 @PostMapping("/callback") - public String handlePaymentCallback(@RequestParam Map<String, String> params, Model model) { - String secretKey = "59c709fc18978a6a83b87f05d37cecbf"; - String tranID = params.get("tranID"); - String orderId = params.get("orderid"); - String status = params.get("status"); - String domain = params.get("domain"); - String amount = params.get("amount"); - String currency = params.get("currency"); - String paydate = params.get("paydate"); - String skey = params.get("skey"); + public void handlePaymentCallback( + @RequestParam("amount") String amount, + @RequestParam("orderid") String orderId, + @RequestParam("tranID") String tranId, + @RequestParam("status") String status, + @RequestParam("domain") String domain, + @RequestParam("currency") String currency, + @RequestParam("paydate") String payDate, + @RequestParam("approcode") String appCode, + @RequestParam("skey") String receivedSkey, + HttpServletResponse response) throws IOException{ // 计算 skey 验证 - String preSkey = DigestUtils.md5Hex(tranID + orderId + status + domain + amount + currency); - String calculatedSkey = DigestUtils.md5Hex(paydate + domain + preSkey + secretKey); + String calculatedSkey = calculateSkey(tranId, orderId, status, domain, amount, currency, payDate, appCode); MallOrderInfo mallOrderInfo = ValidateEntityUtils .ensureColumnReturnEntity(orderId, MallOrderInfo::getId, mallOrderInfoMapper::selectOne, "订单不存在"); log.info("callback status: {}", status); - log.info("callback skey: {}", preSkey); + log.info("callback skey: {}", receivedSkey); log.info("callback calculatedSkey: {}", calculatedSkey); log.info("callback payResult: {}", mallOrderInfo.getPayResult()); if("1".equals(mallOrderInfo.getPayResult())){ - return "success"; + response.sendRedirect("/pages/order/pay/paySuccess?amount="+amount+"&type=3"); + return; } - - if (!calculatedSkey.equals(skey)) { + if (!calculatedSkey.equalsIgnoreCase(receivedSkey)) { + // 记录安全警告日志 throw new FebsException("订单回调失败,---"+orderId); } if ("00".equals(status)) { - updateOrderStatus(orderId, status, amount, paydate, tranID); - return "success"; - }else{ - return "fail"; + updateOrderStatus(orderId, status, amount, payDate, tranId); + response.sendRedirect("/pages/order/pay/paySuccess?amount="+amount+"&type=3"); + return; } } + private String calculateSkey(String tranId, String orderId, String status, + String domain, String amount, String currency, + String payDate, String appCode) { + try { + // 第一步哈希计算 + String preSkey = tranId + orderId + status + domain + amount + currency; + String preSkeyHash = md5(preSkey); + + // 第二步哈希计算 + String finalInput = payDate + domain + preSkeyHash + appCode + SECRET_KEY; + return md5(finalInput); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("MD5算法不可用", e); + } + } + + private String md5(String input) throws NoSuchAlgorithmException { + MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] hashBytes = md.digest(input.getBytes()); + + StringBuilder hexString = new StringBuilder(); + for (byte b : hashBytes) { + String hex = Integer.toHexString(0xff & b); + if (hex.length() == 1) hexString.append('0'); + hexString.append(hex); + } + return hexString.toString(); + } + private void updateOrderStatus(String orderId, String status, String amount, String paydate, String tranID) { // 实现订单状态更新逻辑(如更新数据库) MallOrderInfo mallOrderInfo = ValidateEntityUtils.ensureColumnReturnEntity(orderId, MallOrderInfo::getId, mallOrderInfoMapper::selectOne, "订单不存在"); -- Gitblit v1.9.1