feat:钱包接口对接

This commit is contained in:
苏竹红
2025-11-13 18:44:19 +08:00
parent c99c4375d7
commit 9f042b9dbd
34 changed files with 1606 additions and 197 deletions

View File

@@ -0,0 +1,231 @@
package com.cool.store.http;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.utils.RsaSignUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* @Author suzhuhong
* @Date 2025/11/13 10:00
* @Version 1.0
*/
@Service
@Slf4j
public class WalletHttpClientRest {
@Autowired
private OkHttpClient okHttpClient;
@Autowired
private ObjectMapper objectMapper;
@Value("${cool.api.rsa.private.key}")
private String coolPrivateKey;
@Value("${wallet.api.rsa.public.key}")
private String walletPublicKey;
/**
* 发送带签名的POST请求
*/
public <T> T postWithSign(String url, Object request, Class<T> responseType) {
try {
// 1. 准备请求参数
Map<String, Object> requestParams = convertToMap(request);
requestParams.put("timestamp", System.currentTimeMillis());
requestParams.put("key", "360155690205317");
// 2. 生成签名
String signature = RsaSignUtil.generateSign(requestParams,coolPrivateKey);
requestParams.put("sign", signature);
// 3. 发送请求
String responseJson = executePost(url, requestParams);
// 4. 解析响应
return parseResponse(responseJson, responseType);
} catch (ServiceException e) {
throw e;
} catch (Exception e) {
// 其他异常统一包装为RuntimeException
log.error("发送带签名POST请求失败: {}", url, e);
throw new RuntimeException("接口调用异常: " + e.getMessage(), e);
}
}
/**
* 发送带签名和验签的POST请求
*/
public <T> T postWithSignAndVerify(String url, Object request, Class<T> responseType) {
try {
// 1. 准备请求参数
Map<String, Object> requestParams = convertToMap(request);
requestParams.put("timestamp", System.currentTimeMillis());
// 2. 生成签名
String signature = RsaSignUtil.generateSign(requestParams,coolPrivateKey);
requestParams.put("sign", signature);
// 3. 发送请求
String responseJson = executePost(url, requestParams);
// 4. 解析响应并验证签名
return parseAndVerifyResponse(responseJson, responseType);
} catch (Exception e) {
log.error("发送带签名和验签POST请求失败: {}", url, e);
throw new RuntimeException(e.getMessage());
}
}
/**
* 发送普通POST请求无签名
*/
public <T> T post(String url, Object request, Class<T> responseType) {
try {
String responseJson = executePost(url, request);
return parseResponse(responseJson, responseType);
} catch (Exception e) {
log.error("发送POST请求失败: {}", url, e);
throw new RuntimeException("调用外部接口失败: " + e.getMessage());
}
}
/**
* 执行POST请求
*/
private String executePost(String url, Object body) throws IOException {
String jsonBody = objectMapper.writeValueAsString(body);
RequestBody requestBody = RequestBody.create( MediaType.parse("application/json; charset=utf-8"),jsonBody);
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.addHeader("Content-Type", "application/json")
.build();
log.info("发送POST请求: {}, 数据: {}", url, jsonBody);
try (Response response = okHttpClient.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new ServiceException(ErrorCodeEnum.THIRD_API_ERROR,response.code() + " " + response.message());
}
String responseBody = response.body().string();
log.info("收到响应: {}", responseBody);
checkBusinessResponseCode(responseBody);
return responseBody;
}
}
private void checkBusinessResponseCode(String responseJson) throws IOException {
try {
Map<String, Object> responseMap = objectMapper.readValue(responseJson,
new TypeReference<Map<String, Object>>() {
});
Object codeObj = responseMap.get("code");
if (codeObj != null) {
int code = 0;
if (codeObj instanceof Number) {
code = ((Number) codeObj).intValue();
} else {
code = Integer.parseInt(codeObj.toString());
}
if (code != 200) {
String msg = (String) responseMap.get("msg");
throw new ServiceException(ErrorCodeEnum.THIRD_API_ERROR,
"code: " + code + ", msg: " + msg);
}
}
} catch (ServiceException e) {
throw e;
} catch (Exception e) {
// 如果解析失败,说明可能不是标准格式,继续处理
log.debug("无法解析响应码格式: {}", e.getMessage());
}
}
/**
* 解析响应
*/
@SuppressWarnings("unchecked")
private <T> T parseResponse(String responseJson, Class<T> responseType) throws Exception {
if (responseType == String.class) {
return (T) responseJson;
}
// 解析为通用响应格式
Map<String, Object> responseMap = objectMapper.readValue(responseJson,
new TypeReference<Map<String, Object>>() {});
// 如果返回类型是Map直接返回
if (responseType == Map.class) {
return (T) responseMap;
}
// 提取data字段
Object data = responseMap.get("data");
if (data != null && responseType != Object.class) {
return objectMapper.convertValue(data, responseType);
}
return objectMapper.convertValue(responseMap, responseType);
}
/**
* 解析响应并验证签名
*/
@SuppressWarnings("unchecked")
private <T> T parseAndVerifyResponse(String responseJson, Class<T> responseType) throws Exception {
// 解析为Map来验证签名
Map<String, Object> responseMap = objectMapper.readValue(responseJson,
new TypeReference<Map<String, Object>>() {});
// 验证响应签名
String responseSign = (String) responseMap.get("sign");
if (responseSign != null) {
// 移除sign字段后进行验签
Map<String, Object> verifyParams = new HashMap<>(responseMap);
boolean isValid = RsaSignUtil.verifySign(verifyParams, walletPublicKey);
if (!isValid) {
throw new SecurityException("响应签名验证失败");
}
log.debug("响应签名验证成功");
}
// 返回指定类型的数据
return parseResponse(responseJson, responseType);
}
/**
* 转换为Map
*/
@SuppressWarnings("unchecked")
private Map<String, Object> convertToMap(Object obj) {
if (obj instanceof Map) {
return (Map<String, Object>) obj;
}
return objectMapper.convertValue(obj, new TypeReference<Map<String, Object>>() {});
}
}

View File

@@ -0,0 +1,116 @@
package com.cool.store.service.wallet;
import com.cool.store.dto.wallet.*;
import com.cool.store.http.WalletHttpClientRest;
import com.cool.store.request.wallet.*;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* @Author suzhuhong
* @Date 2025/11/13 10:51
* @Version 1.0
*/
@Service
public class WalletApiService {
@Resource
WalletHttpClientRest walletHttpClientRest;
/**
* 在平安扫呗系统中,创建签约人账户
* @param request
* @return
*/
public StoreAccountDTO createStoreAndAccount(CreateStoreAndAccountRequest request){
return walletHttpClientRest.postWithSign("https://api.dev.wenmatech.com:443/open/crm/account/v1/createStoreAndAccount", request, StoreAccountDTO.class);
}
/**
* 开通失败 开通
* @param request
* @return
*/
public StoreAccountDTO updateStoreAccount(UpdateStoreAccountRequest request){
return walletHttpClientRest.postWithSign("https://api.dev.wenmatech.com:443/open/crm/account/v1/updateStoreAccount", request, StoreAccountDTO.class);
}
/**
* 创建门店接口
* @param request
* @return
*/
public AccountNoDTO createStore(CreateStoreRequest request){
return walletHttpClientRest.postWithSign("https://api.dev.wenmatech.com:443/open/crm/v1/createStoreAndAccount", request, AccountNoDTO.class);
}
/**
* 银行发送短信接口
* @param request
* @return
*/
public AccountAuthenticationDTO authentication(OutStoreIdRequest request){
return walletHttpClientRest.postWithSign("https://api.dev.wenmatech.com:443/open/crm/account/v1/authentication", request, AccountAuthenticationDTO.class);
}
/**
* 门店开通平安银行接口
* @param request
* @return
*/
public AccountVerifyDTO openAccount(AccountVerifyRequest request){
return walletHttpClientRest.postWithSign("https://api.dev.wenmatech.com:443/open/crm/account/v1/openAccount", request, AccountVerifyDTO.class);
}
/**
* 签约人账户打标升级
* @param request
* @return
*/
public AddTagDTO addTag(AccountAddTagRequest request){
return walletHttpClientRest.postWithSign("https://api.dev.wenmatech.com:443/open/crm/account/v1/addTag", request, AddTagDTO.class);
}
/**
* 获取账户信息
* @param request
* @return
*/
public AccountInfoDTO getAccountInfo(OutStoreIdRequest request){
return walletHttpClientRest.postWithSign("https://api.dev.wenmatech.com:443/open/crm/account/v1/getAccountInfo", request, AccountInfoDTO.class);
}
/**
* 大额预支付接口
* @param request
* @return
*/
public LargePaymentDTO largePayment(LargePaymentRequest request){
return walletHttpClientRest.postWithSign("https://api.dev.wenmatech.com:443/open/crm/payment/v1/largePayment", request, LargePaymentDTO.class);
}
/**
* 大额预支付查询接口
* @param request
* @return
*/
public PaymentDTO largePaymentQuery(PaymentDetailRequest request){
return walletHttpClientRest.postWithSign("https://api.dev.wenmatech.com:443/open/crm/trans/v1/largePaymentQuery", request, PaymentDTO.class);
}
/**
* 获取支行信息
* @param request
* @return
*/
public BankListDTO getBankList(GetBankRequest request) {
return walletHttpClientRest.postWithSign("https://api.dev.wenmatech.com:443/open/crm/base/v1/findPageBank", request, BankListDTO.class);
}
}