| | |
| | | import cc.mrbird.febs.mall.mapper.MallOrderInfoMapper; |
| | | import cc.mrbird.febs.pay.model.FIUUInitPayRequest; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import cn.hutool.json.JSONUtil; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import lombok.extern.slf4j.Slf4j; |
| | |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.annotation.Resource; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | |
| | | } |
| | | } |
| | | |
| | | @PostMapping("/notify") |
| | | public void handlePaymentNotification(HttpServletRequest request) { |
| | | // 1. 从POST请求中获取参数 |
| | | Map<String, String> params = new HashMap<>(); |
| | | request.getParameterMap().forEach((key, values) -> params.put(key, values[0])); |
| | | log.info("notify: {}", JSONUtil.parseObj(params)); |
| | | |
| | | // 2. 验证skey的完整性 |
| | | boolean isValid = verifySkey(params); |
| | | if (!isValid) { |
| | | return; |
| | | } |
| | | |
| | | // 3. 解析关键参数 |
| | | String status = params.get("status"); |
| | | String orderId = params.get("orderid"); |
| | | String amount = params.get("amount"); |
| | | String tranID = params.get("tranID"); |
| | | String paydate = params.get("paydate"); |
| | | |
| | | log.info("notify status: {}", status); |
| | | // 4. 根据状态码更新订单 |
| | | if ("00".equals(status)) { |
| | | // 支付成功,更新订单状态 |
| | | updateOrderStatus(orderId, status, amount, paydate, tranID); |
| | | // 可选:记录交易ID防止重复处理 |
| | | log.info("Payment succeeded for order: {}", orderId); |
| | | } else { |
| | | // 支付失败或待处理 |
| | | log.warn("Payment failed/pending for order: {}", orderId); |
| | | } |
| | | |
| | | // 5. 返回ACK响应(可选,但推荐) |
| | | return; |
| | | } |
| | | |
| | | private boolean verifySkey(Map<String, String> params) { |
| | | // 从配置或数据库中获取Secret Key |
| | | String secretKey = "59c709fc18978a6a83b87f05d37cecbf"; |
| | | |
| | | // 按API文档生成skey |
| | | 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 appcode = params.get("appcode"); |
| | | String paydate = params.get("paydate"); |
| | | String receivedSkey = params.get("skey"); |
| | | |
| | | // 第一步哈希:pre_skey = md5(txnID + orderID + status + domain + amount + currency) |
| | | String preSkey = DigestUtils.md5Hex(tranID + orderId + status + domain + amount + currency); |
| | | |
| | | log.info("notify preSkey: {}", preSkey); |
| | | // 第二步哈希:skey = md5(paydate + domain + pre_skey + appcode + secretKey) |
| | | String calculatedSkey = DigestUtils.md5Hex(paydate + domain + preSkey + appcode + secretKey); |
| | | |
| | | log.info("notify calculatedSkey: {}", calculatedSkey); |
| | | |
| | | return calculatedSkey.equals(receivedSkey); |
| | | } |
| | | |
| | | private void updateOrderStatus(String orderId, String status, String amount, String paydate, String tranID) { |
| | | // 实现订单状态更新逻辑(如更新数据库) |
| | | MallOrderInfo mallOrderInfo = ValidateEntityUtils.ensureColumnReturnEntity(orderId, MallOrderInfo::getId, mallOrderInfoMapper::selectOne, "订单不存在"); |
| | | ValidateEntityUtils.ensureNotEqual(mallOrderInfo.getPayResult(), "1", "订单已支付"); |
| | | ValidateEntityUtils.ensureEqual(mallOrderInfo.getAmount().toString(), amount, "订单金额异常"); |
| | | // 更新订单状态 |
| | | if ("00".equals(status)) { |
| | | mallOrderInfo.setStatus(OrderStatusEnum.WAIT_SHIPPING.getValue()); |
| | | mallOrderInfo.setPayResult("1"); |
| | | mallOrderInfo.setPayTime(DateUtil.parseDateTime(paydate)); |
| | | mallOrderInfo.setDeliveryState(OrderDeliveryStateEnum.DELIVERY_WAIT.getValue()); |
| | | mallOrderInfo.setPayOrderNo(tranID); |
| | | mallOrderInfoMapper.updateById(mallOrderInfo); |
| | | } |
| | | } |
| | | |
| | | // Java 回调接口 |
| | | @PostMapping("/callback") |
| | | public FebsResponse handlePaymentCallback(@RequestParam Map<String, String> params) { |
| | | try { |
| | | 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"); |
| | | 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"); |
| | | |
| | | // 计算 skey 验证 |
| | | String preSkey = DigestUtils.md5Hex(tranID + orderId + status + domain + amount + currency); |
| | | String calculatedSkey = DigestUtils.md5Hex(paydate + domain + preSkey + secretKey); |
| | | // 计算 skey 验证 |
| | | String preSkey = DigestUtils.md5Hex(tranID + orderId + status + domain + amount + currency); |
| | | String calculatedSkey = DigestUtils.md5Hex(paydate + domain + preSkey + secretKey); |
| | | |
| | | if (!calculatedSkey.equals(skey)) { |
| | | throw new FebsException("订单回调失败,---"+orderId); |
| | | } |
| | | |
| | | MallOrderInfo mallOrderInfo = ValidateEntityUtils.ensureColumnReturnEntity(orderId, MallOrderInfo::getId, mallOrderInfoMapper::selectOne, "订单不存在"); |
| | | ValidateEntityUtils.ensureEqual(mallOrderInfo.getPayResult(), "1", "订单已支付"); |
| | | ValidateEntityUtils.ensureEqual(mallOrderInfo.getAmount().toString(), amount, "订单金额异常"); |
| | | // 更新订单状态 |
| | | if ("00".equals(status)) { |
| | | mallOrderInfo.setStatus(OrderStatusEnum.WAIT_SHIPPING.getValue()); |
| | | mallOrderInfo.setPayResult("1"); |
| | | mallOrderInfo.setPayTime(DateUtil.parseDateTime(paydate)); |
| | | mallOrderInfo.setDeliveryState(OrderDeliveryStateEnum.DELIVERY_WAIT.getValue()); |
| | | mallOrderInfo.setPayOrderNo(tranID); |
| | | mallOrderInfoMapper.updateById(mallOrderInfo); |
| | | } |
| | | return new FebsResponse().success().message("OK"); |
| | | } catch (Exception e) { |
| | | return new FebsResponse().fail().message("Internal Error"); |
| | | if (!calculatedSkey.equals(skey)) { |
| | | throw new FebsException("订单回调失败,---"+orderId); |
| | | } |
| | | |
| | | updateOrderStatus(orderId, status, amount, paydate, tranID); |
| | | return new FebsResponse().success().data("/pages/order/pay/paySuccess?amount="+ amount +"&type=3"); |
| | | } |
| | | |
| | | /** |