New file |
| | |
| | | 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); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | } |