From dbdc1ed6a3ecdcb20981b9e84200c69424444d6d Mon Sep 17 00:00:00 2001 From: KKSU <15274802129@163.com> Date: Thu, 06 Feb 2025 15:59:20 +0800 Subject: [PATCH] feat(payment): 集成 FIUU 支付方式并优化退款流程 --- src/main/java/cc/mrbird/febs/pay/util/FiuuUtil.java | 144 ++++++++++++++++++++++++++++++++++++++++++++++++ src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallTeamLeaderServiceImpl.java | 9 +- src/main/java/cc/mrbird/febs/mall/dto/ApplyRefundOrderDto.java | 2 src/main/java/cc/mrbird/febs/pay/controller/FIUUController.java | 1 4 files changed, 151 insertions(+), 5 deletions(-) diff --git a/src/main/java/cc/mrbird/febs/mall/dto/ApplyRefundOrderDto.java b/src/main/java/cc/mrbird/febs/mall/dto/ApplyRefundOrderDto.java index 1b26ae1..87fce06 100644 --- a/src/main/java/cc/mrbird/febs/mall/dto/ApplyRefundOrderDto.java +++ b/src/main/java/cc/mrbird/febs/mall/dto/ApplyRefundOrderDto.java @@ -20,7 +20,7 @@ private Long itemId; //退款方式 1:微信 2:支付宝 3:其他 - @ApiModelProperty(value = "退款方式 1:微信 2:支付宝 3:余额", example = "描述") + @ApiModelProperty(value = "退款方式 1:微信 2:支付宝 3:余额 5:FIUU支付", example = "描述") private Integer type; //退款状态 1:成功 2:失败 3:退款中 diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallTeamLeaderServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallTeamLeaderServiceImpl.java index 00ba3cf..b7b4795 100644 --- a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallTeamLeaderServiceImpl.java +++ b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallTeamLeaderServiceImpl.java @@ -17,6 +17,7 @@ import cc.mrbird.febs.mall.vo.*; import cc.mrbird.febs.pay.model.OrderStateDto; import cc.mrbird.febs.pay.service.IXcxPayService; +import cc.mrbird.febs.pay.util.FiuuUtil; import cc.mrbird.febs.pay.util.WeixinServiceUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; @@ -57,6 +58,8 @@ private final MallRefundMapper mallRefundMapper; @Autowired private WeixinServiceUtil weixinServiceUtil; + @Autowired + private FiuuUtil fiuuUtil; private final XcxProperties xcxProperties = SpringContextHolder.getBean(XcxProperties.class); private final IMallMoneyFlowService mallMoneyFlowService; private final IApiMallMemberWalletService memberWalletService; @@ -421,8 +424,6 @@ String refundNo = mallRefundEntity.getRefundNo(); //退款订单金额 BigDecimal orderAmount = mallOrderInfo.getAmount(); - BigDecimal aa = new BigDecimal(100); - int orderMoney = orderAmount.multiply(aa).intValue(); //退款退款金额 // BigDecimal refundAmount = mallRefundEntity.getAmount(); @@ -488,11 +489,11 @@ Boolean flag = false; Boolean debug = xcxProperties.getDebug(); if (debug) { - boolean b = weixinServiceUtil.comRefund(orderNo, refundNo, 1, 1, null); + boolean b = fiuuUtil.comRefund(orderNo, refundNo, "1"); flag = b; } else { log.info("开始调用退款接口。。。退款编号为{}", refundNo); - boolean b = weixinServiceUtil.comRefund(orderNo, refundNo, orderMoney, refundMoney, null); + boolean b = fiuuUtil.comRefund(orderNo, refundNo, orderAmount.toString()); flag = b; } diff --git a/src/main/java/cc/mrbird/febs/pay/controller/FIUUController.java b/src/main/java/cc/mrbird/febs/pay/controller/FIUUController.java index 3686198..e419e3e 100644 --- a/src/main/java/cc/mrbird/febs/pay/controller/FIUUController.java +++ b/src/main/java/cc/mrbird/febs/pay/controller/FIUUController.java @@ -146,6 +146,7 @@ ValidateEntityUtils.ensureEqual(mallOrderInfo.getAmount().toString(), amount, "订单金额异常"); // 更新订单状态 if ("00".equals(status)) { + mallOrderInfo.setPayMethod("FIUU支付"); mallOrderInfo.setStatus(OrderStatusEnum.WAIT_SHIPPING.getValue()); mallOrderInfo.setPayResult("1"); mallOrderInfo.setPayTime(DateUtil.parseDateTime(paydate)); diff --git a/src/main/java/cc/mrbird/febs/pay/util/FiuuUtil.java b/src/main/java/cc/mrbird/febs/pay/util/FiuuUtil.java new file mode 100644 index 0000000..4dbfb32 --- /dev/null +++ b/src/main/java/cc/mrbird/febs/pay/util/FiuuUtil.java @@ -0,0 +1,144 @@ +package cc.mrbird.febs.pay.util; + +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.security.MessageDigest; +import java.util.LinkedHashMap; +import java.util.Map; + +@Slf4j +@Service(value="FiuuUtil") +public class FiuuUtil { + + private static final String API_URL = "https://api.fiuu.com/RMS/API/refundAPI/index.php"; + private static final String MERCHANT_ID = "e2umart01"; + private static final String SECRET_KEY = "59c709fc18978a6a83b87f05d37cecbf"; + @Transactional + public boolean comRefund(String outTradeNo, String outRefundNo,String amount){ + // 退款请求参数 + Map<String, String> params = new LinkedHashMap<>(); + params.put("RefundType", "P"); // P: Partial Refund, F: Full Refund + params.put("MerchantID", MERCHANT_ID); + params.put("RefID", outRefundNo); // 商户唯一退款ID + params.put("TxnID", outTradeNo); // Fiuu原始交易ID + params.put("Amount", amount); // 退款金额 + + // 生成签名 + String signature = null; + try { + signature = generateSignature(params); + } catch (Exception e) { + e.printStackTrace(); + } + params.put("Signature", signature); + + // 发送GET请求 + String response = null; + try { + response = sendRefundRequest(params); + } catch (Exception e) { + e.printStackTrace(); + } + System.out.println("退款响应: " + response); + + JSONObject jsonObject = JSONUtil.parseObj(response); + + String status = jsonObject.getStr("status"); + if ("00".equals(status)) { + return true; + }else{ + return false; + } + + } + public static void main(String[] args) { + try { + // 退款请求参数 + Map<String, String> params = new LinkedHashMap<>(); + params.put("RefundType", "P"); // P: Partial Refund, F: Full Refund + params.put("MerchantID", MERCHANT_ID); + params.put("RefID", "REF123456"); // 商户唯一退款ID + params.put("TxnID", "123456789"); // Fiuu原始交易ID + params.put("Amount", "100.00"); // 退款金额 + params.put("BankCode", "MBBEMYKL"); // 银行代码(可选) + params.put("BankCountry", "MY"); // 国家代码(可选) + params.put("BeneficiaryName", "John Doe"); // 收款人姓名(可选) + params.put("BeneficiaryAccNo", "1234567890"); // 收款账号(可选) + + // 生成签名 + String signature = generateSignature(params); + params.put("Signature", signature); + + // 发送GET请求 + String response = sendRefundRequest(params); + System.out.println("退款响应: " + response); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 生成MD5签名 + */ + private static String generateSignature(Map<String, String> params) throws Exception { + // 按顺序拼接参数:RefundType + MerchantID + RefID + TxnID + Amount + SecretKey + String rawData = params.get("RefundType") + + params.get("MerchantID") + + params.get("RefID") + + params.get("TxnID") + + params.get("Amount") + + SECRET_KEY; + + MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] hashBytes = md.digest(rawData.getBytes("UTF-8")); + + // 转换为十六进制字符串 + 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(); + } + + /** + * 发送退款请求(GET方式) + */ + private static String sendRefundRequest(Map<String, String> params) throws Exception { + StringBuilder urlBuilder = new StringBuilder(API_URL); + urlBuilder.append("?"); + + // 拼接查询参数 + for (Map.Entry<String, String> entry : params.entrySet()) { + urlBuilder.append(entry.getKey()) + .append("=") + .append(entry.getValue()) + .append("&"); + } + String url = urlBuilder.toString().replaceAll("&$", ""); // 去除末尾的& + + // 使用HttpClient发送请求 + try (CloseableHttpClient httpClient = HttpClients.createDefault()) { + HttpGet httpGet = new HttpGet(url); + try (CloseableHttpResponse response = httpClient.execute(httpGet)) { + HttpEntity entity = response.getEntity(); + return EntityUtils.toString(entity); + } + } + } + + +} -- Gitblit v1.9.1