package com.talentcard.server.business.payment; import java.util.Map; import com.alibaba.fastjson.JSON; import com.talentcard.server.business.merchant.MerchantSettlementService; import com.talentcard.server.business.payment.huifu.HuifuSignatureService; import com.talentcard.server.common.BusinessException; import com.talentcard.server.common.ErrorCode; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api/payments/huifu") public class PaymentCallbackController { private final HuifuPaymentCallbackService callbackService; private final HuifuSignatureService signatureService; private final MerchantSettlementService settlementService; public PaymentCallbackController(HuifuPaymentCallbackService callbackService, HuifuSignatureService signatureService, MerchantSettlementService settlementService) { this.callbackService = callbackService; this.signatureService = signatureService; this.settlementService = settlementService; } @PostMapping(value = "/notify", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.TEXT_PLAIN_VALUE) public ResponseEntity notify(@RequestParam Map form) { return ResponseEntity.ok(callbackService.handle(form.get("resp_data"), form.get("sign"))); } @PostMapping(value = "/merchant-business-notify", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.TEXT_PLAIN_VALUE) public ResponseEntity merchantBusinessNotify(@RequestParam Map form) { String payload = form.get("resp_data"), signature = form.get("sign"); if (!signatureService.verifyCallbackPayload(payload, signature)) throw new BusinessException(ErrorCode.FORBIDDEN, "Invalid Huifu merchant business callback signature"); @SuppressWarnings("unchecked") Map data = JSON.parseObject(payload, Map.class); String no = data.get("req_seq_id") == null ? "" : String.valueOf(data.get("req_seq_id")).trim(); if (!settlementService.handleBankCardCallback(data)) throw new BusinessException(ErrorCode.NOT_FOUND, "Unknown Huifu merchant business callback"); return ResponseEntity.ok("RECV_ORD_ID_" + no); } @PostMapping(value = "/merchant-onboarding-notify", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.TEXT_PLAIN_VALUE) public ResponseEntity merchantOnboardingNotify(@RequestParam Map form) { String payload = form.get("resp_data"), signature = form.get("sign"); if (!signatureService.verifyCallbackPayload(payload, signature)) throw new BusinessException(ErrorCode.FORBIDDEN, "Invalid Huifu merchant onboarding callback signature"); @SuppressWarnings("unchecked") Map data = JSON.parseObject(payload, Map.class); String no = data.get("req_seq_id") == null ? "" : String.valueOf(data.get("req_seq_id")).trim(); if (!settlementService.handleOnboardingCallback(data)) throw new BusinessException(ErrorCode.NOT_FOUND, "Unknown Huifu merchant onboarding callback"); return ResponseEntity.ok("RECV_ORD_ID_" + no); } @PostMapping(value = "/merchant-wechat-config-notify", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.TEXT_PLAIN_VALUE) public ResponseEntity merchantWechatConfigNotify(@RequestParam Map form) { Map data = verifiedData(form, "WeChat merchant configuration"); if (!settlementService.handleWechatConfigCallback(data)) throw new BusinessException(ErrorCode.NOT_FOUND, "Unknown Huifu WeChat merchant configuration callback"); return ResponseEntity.ok("RECV_ORD_ID_" + acknowledgementId(data)); } @PostMapping(value = "/merchant-business-open-notify", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.TEXT_PLAIN_VALUE) public ResponseEntity merchantBusinessOpenNotify(@RequestParam Map form) { Map data = verifiedData(form, "merchant business opening"); if (!settlementService.handleBusinessOpenCallback(data)) throw new BusinessException(ErrorCode.NOT_FOUND, "Unknown Huifu merchant business opening callback"); return ResponseEntity.ok("RECV_ORD_ID_" + acknowledgementId(data)); } @SuppressWarnings("unchecked") private Map verifiedData(Map form, String operation) { String payload = form.get("resp_data"), signature = form.get("sign"); if (!signatureService.verifyCallbackPayload(payload, signature)) throw new BusinessException(ErrorCode.FORBIDDEN, "Invalid Huifu " + operation + " callback signature"); Map callback = JSON.parseObject(payload, Map.class); Object nested = callback.get("data"); if (nested instanceof Map value) return (Map) value; if (nested instanceof String value && !value.isBlank()) return JSON.parseObject(value, Map.class); return callback; } private String acknowledgementId(Map data) { Object value = data.get("ord_id"); if (value == null || String.valueOf(value).isBlank()) value = data.get("req_seq_id"); return value == null ? "" : String.valueOf(value).trim(); } }