记得上下班打卡 | git大法好,push需谨慎

Commit 2b106139 authored by wangyifan's avatar wangyifan

收钱吧最新接口对接-商城相关接口

parent 6225004b
...@@ -5,8 +5,10 @@ import io.swagger.annotations.ApiModel; ...@@ -5,8 +5,10 @@ import io.swagger.annotations.ApiModel;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import java.util.List;
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ApiModel(value = "商城商品接口响应") @ApiModel(value = "商城商品接口响应")
@Data @Data
public class MallProductsQueryResponse extends BaseResponse<MallProductsQueryData>{ public class MallProductsQueryResponse extends BaseResponse<List<MallProductsQueryData>>{
} }
...@@ -3,6 +3,8 @@ package com.liquidnet.service.goblin.service; ...@@ -3,6 +3,8 @@ package com.liquidnet.service.goblin.service;
import com.liquidnet.service.goblin.param.shouqianba.request.*; import com.liquidnet.service.goblin.param.shouqianba.request.*;
import com.liquidnet.service.goblin.param.shouqianba.response.data.*; import com.liquidnet.service.goblin.param.shouqianba.response.data.*;
import java.util.List;
/** /**
* 收钱吧对接接口定义 * 收钱吧对接接口定义
* *
...@@ -24,6 +26,7 @@ public interface IGoblinShouQianBaService { ...@@ -24,6 +26,7 @@ public interface IGoblinShouQianBaService {
/** /**
* 创建订单 * 创建订单
*
* @param request * @param request
* @return * @return
*/ */
...@@ -32,12 +35,14 @@ public interface IGoblinShouQianBaService { ...@@ -32,12 +35,14 @@ public interface IGoblinShouQianBaService {
/** /**
* 创建收单 * 创建收单
* 如果上一步创建收单失败 可以使用这个接口重新创建收单 * 如果上一步创建收单失败 可以使用这个接口重新创建收单
*
* @return * @return
*/ */
AcquiringCreateData createAcquiring(AcquiringCreateRequest request); AcquiringCreateData createAcquiring(AcquiringCreateRequest request);
/** /**
* 查询收银台 * 查询收银台
*
* @param request * @param request
* @return * @return
*/ */
...@@ -45,6 +50,7 @@ public interface IGoblinShouQianBaService { ...@@ -45,6 +50,7 @@ public interface IGoblinShouQianBaService {
/** /**
* 创建微信预支付订单 * 创建微信预支付订单
*
* @param request * @param request
* @return * @return
*/ */
...@@ -52,6 +58,7 @@ public interface IGoblinShouQianBaService { ...@@ -52,6 +58,7 @@ public interface IGoblinShouQianBaService {
/** /**
* 查询券码 * 查询券码
*
* @param request * @param request
* @return * @return
*/ */
...@@ -59,6 +66,7 @@ public interface IGoblinShouQianBaService { ...@@ -59,6 +66,7 @@ public interface IGoblinShouQianBaService {
/** /**
* 券码状态同步 * 券码状态同步
*
* @param request * @param request
* @return * @return
*/ */
...@@ -66,6 +74,7 @@ public interface IGoblinShouQianBaService { ...@@ -66,6 +74,7 @@ public interface IGoblinShouQianBaService {
/** /**
* 券退款 * 券退款
*
* @param request * @param request
* @return * @return
*/ */
...@@ -73,16 +82,17 @@ public interface IGoblinShouQianBaService { ...@@ -73,16 +82,17 @@ public interface IGoblinShouQianBaService {
/** /**
* 商城列表接口 * 商城列表接口
*
* @param request * @param request
* @return * @return
*/ */
MallListQueryData queryMallList(MallListQueryRequest request); List<MallListQueryData> queryMallList(MallListQueryRequest request);
/** /**
* 商城商品接口 * 商城商品接口
*
* @param request * @param request
* @return * @return
*/ */
MallProductsQueryData queryMallProducts(MallProductsQueryRequest request); List<MallProductsQueryData> queryMallProducts(MallProductsQueryRequest request);
} }
...@@ -26,3 +26,11 @@ liquidnet: ...@@ -26,3 +26,11 @@ liquidnet:
public-key: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArR8pqWsRMqiunn8uEZGF9AeizJK0vuWjlcNnTbw9Sb96dMVuYu3SRj+Dx4E4SgyEL4CYROou1xwY57kAKEqHdH7o1W41O9jYjXZG38BrtBR+D9Qh9OqGxCZ+e4Gi38XHGg6fn67iXefOqp1kWGd4qc8tIZO1lIDXS19R09D/mESNBMulQdVPyZF7gvd11A+7EEOfRlSOjrtqIoUWV0GIqhLPUtGJk8Uq/d9NLitJyvK3tgz8cvJ4RyK6UpGtRDrqiBiQxbvK9EqMd1sw3zkvM03szSWon4LHFNqvDr6RYfFyFUCvX9UPYmeritENnroEuTBlTFLLb68ed4HZEZDPTQIDAQAB" public-key: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArR8pqWsRMqiunn8uEZGF9AeizJK0vuWjlcNnTbw9Sb96dMVuYu3SRj+Dx4E4SgyEL4CYROou1xwY57kAKEqHdH7o1W41O9jYjXZG38BrtBR+D9Qh9OqGxCZ+e4Gi38XHGg6fn67iXefOqp1kWGd4qc8tIZO1lIDXS19R09D/mESNBMulQdVPyZF7gvd11A+7EEOfRlSOjrtqIoUWV0GIqhLPUtGJk8Uq/d9NLitJyvK3tgz8cvJ4RyK6UpGtRDrqiBiQxbvK9EqMd1sw3zkvM03szSWon4LHFNqvDr6RYfFyFUCvX9UPYmeritENnroEuTBlTFLLb68ed4HZEZDPTQIDAQAB"
private-key: "MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDJAOaA1ikJzDL0vUuTyl3/vlHyuSod6/gFLLrSTD6EJkma5Ld34HHu82/5pEojEvbcU113L9j3fUJlpyjX6CFk6j2KjMIuyFxhgrVFi5WT5m74wYohoWNifkQrgwsO3oxI7cewWFu/w7/yCK9dzI4QxasGUKH9iPweI+26IR0DBbOfC9GVudOy2b2xLrGAevEEHdVTNqrQNdlrTzqAH7r3uk8s2vaBZX+O4gyf7eKdHdC4CVSWfYPLO1sA48MxNwI7OExxfGeV+0wmBMGRSoZ5FhWsqZs+f9jGcmfF+uEfAO71PqHjezXYxq7+oWDfDBPCTc5fo9w5v1HV0aZaYOe1AgMBAAECggEBAI4yR98fInse7XF8NOpBwIv6/QhEfAoc9CHdCfFaJOPiHjIo2a5BpvhPWYj288eqU998TmPSAqDbCUzWm6taOb2lhJHukDT+Y3RMPqcLX275Fsp+SJUQEjoMb3eExh7ny8CQDrOvXoDkH3c/M6ic3Gf7Hslh46dz8D/2VOhXIqoObPlSLzniwiMTDBEwB7IRc3Q+r4V6ZnKt8wjKQZpotBA3TlJlEBBj/h5SbWokwMQbTqFkjl7gVe0ase2WfV+cD4qhPZx6CWphPVyWelg+wpDqXOIQdnE8pgri5a9ZkzgPTOrKyCm+EOa9lZAp81tnb2iFhrlkKPSWUW8zLtZzxMECgYEA+sNyF0U9anyxeKxXtlGKKuMHJSnBpZeU6FSvZjTewFH2Sxh3QwZjg6h5BfvTLH1XfNerx3gdpAPJ+EyAZuEibDr47bp+j4CtT27dVolz5XQ5ugOadwzdNZkq6vhuq1aGATmS/mlNE1/pdMEP9F6hi2HYncER6BFOy0xSwMKCnRECgYEAzTNxhvZ0pb2hPKylxHUydkm3Uznq5Zkquv6II6W5aiKvceETHwdRZLoKc+I0kd0/4fBfJI2Jsjexy51ERiG+8y4wVrcrky6NLw6mnXSvnTSQCftbexheJTg9c5dpfKIj+rxtuBeZ3Sj1MJQ6OSBUYu3iTqstO0Rgp/1ofWQJ8GUCgYEAspxzr0+KJ0cZwbI/54S8vT9n33iWjbQiRDnNlScjYij/HQ4YJI1wZF6jlTeBerbskeesWy+bLS/ltA4Jhz3knuKCXBHyA5TL3UBCN1lAS7c1RuE6LIHlLkAi6ap6aV//ou+3W671T0+JobfB/XVJ61WOTQ8wCfQKA5QhfVsOXYECgYEAvzbm3Ysfm6qfazi+p9lGErASov1fhGA8T1AMcJtnsh1sO8Qu20UodaJfRylNL3dqphIltpwl6eq4RTLhgjDEDTvHU6cQdfB1I5qVbDhlxSpL5uFRl91XLXvA18wKQledC3M3Esr7V/loscIOl1knCaD+t6wPVCEdqK0dB2uHT3kCgYEA3p3rlmCmWzkZ/U8jE4087YEkJWV+r86YC63r4YZEqZtfHk4hNchAYke4jYPqkTtmRVZi2C6KuVr5M3ASHmGWorBY0VA9Abd3daniNocZCeMOt4Z7U6MIbqW7KYSrjx8V8HIsdH7HF97ofRuMH6oaz9bFMM6XwrEAMY+zTdH9A4Y=" private-key: "MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDJAOaA1ikJzDL0vUuTyl3/vlHyuSod6/gFLLrSTD6EJkma5Ld34HHu82/5pEojEvbcU113L9j3fUJlpyjX6CFk6j2KjMIuyFxhgrVFi5WT5m74wYohoWNifkQrgwsO3oxI7cewWFu/w7/yCK9dzI4QxasGUKH9iPweI+26IR0DBbOfC9GVudOy2b2xLrGAevEEHdVTNqrQNdlrTzqAH7r3uk8s2vaBZX+O4gyf7eKdHdC4CVSWfYPLO1sA48MxNwI7OExxfGeV+0wmBMGRSoZ5FhWsqZs+f9jGcmfF+uEfAO71PqHjezXYxq7+oWDfDBPCTc5fo9w5v1HV0aZaYOe1AgMBAAECggEBAI4yR98fInse7XF8NOpBwIv6/QhEfAoc9CHdCfFaJOPiHjIo2a5BpvhPWYj288eqU998TmPSAqDbCUzWm6taOb2lhJHukDT+Y3RMPqcLX275Fsp+SJUQEjoMb3eExh7ny8CQDrOvXoDkH3c/M6ic3Gf7Hslh46dz8D/2VOhXIqoObPlSLzniwiMTDBEwB7IRc3Q+r4V6ZnKt8wjKQZpotBA3TlJlEBBj/h5SbWokwMQbTqFkjl7gVe0ase2WfV+cD4qhPZx6CWphPVyWelg+wpDqXOIQdnE8pgri5a9ZkzgPTOrKyCm+EOa9lZAp81tnb2iFhrlkKPSWUW8zLtZzxMECgYEA+sNyF0U9anyxeKxXtlGKKuMHJSnBpZeU6FSvZjTewFH2Sxh3QwZjg6h5BfvTLH1XfNerx3gdpAPJ+EyAZuEibDr47bp+j4CtT27dVolz5XQ5ugOadwzdNZkq6vhuq1aGATmS/mlNE1/pdMEP9F6hi2HYncER6BFOy0xSwMKCnRECgYEAzTNxhvZ0pb2hPKylxHUydkm3Uznq5Zkquv6II6W5aiKvceETHwdRZLoKc+I0kd0/4fBfJI2Jsjexy51ERiG+8y4wVrcrky6NLw6mnXSvnTSQCftbexheJTg9c5dpfKIj+rxtuBeZ3Sj1MJQ6OSBUYu3iTqstO0Rgp/1ofWQJ8GUCgYEAspxzr0+KJ0cZwbI/54S8vT9n33iWjbQiRDnNlScjYij/HQ4YJI1wZF6jlTeBerbskeesWy+bLS/ltA4Jhz3knuKCXBHyA5TL3UBCN1lAS7c1RuE6LIHlLkAi6ap6aV//ou+3W671T0+JobfB/XVJ61WOTQ8wCfQKA5QhfVsOXYECgYEAvzbm3Ysfm6qfazi+p9lGErASov1fhGA8T1AMcJtnsh1sO8Qu20UodaJfRylNL3dqphIltpwl6eq4RTLhgjDEDTvHU6cQdfB1I5qVbDhlxSpL5uFRl91XLXvA18wKQledC3M3Esr7V/loscIOl1knCaD+t6wPVCEdqK0dB2uHT3kCgYEA3p3rlmCmWzkZ/U8jE4087YEkJWV+r86YC63r4YZEqZtfHk4hNchAYke4jYPqkTtmRVZi2C6KuVr5M3ASHmGWorBY0VA9Abd3daniNocZCeMOt4Z7U6MIbqW7KYSrjx8V8HIsdH7HF97ofRuMH6oaz9bFMM6XwrEAMY+zTdH9A4Y="
notify-url: 'https://testgoblin.zhengzai.tv/goblin/bracelet/callback' notify-url: 'https://testgoblin.zhengzai.tv/goblin/bracelet/callback'
shouqianba:
base-api: 'https://open-apisix.iwosai.com'
app-id: '2025082700005615'
app-key: '4d5c7647853bba34a0b5af42bc2400e7'
app-code: 'DWTY'
public-key: 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3Hlg887xrRWYxPqLDX53oimjsxfd7PDdhQ4zHUYA1eQP6PMyhAo+GU/oq4RQVpW6LrG0PWA6CoD7qva6T0NwsDWn5/fmWhmH+Ad6K5WG5jY9ZVjnys9R+HGeFyE7hSkhqSgiSlEMv9IBJD5p9ZqBZ0FAPotMS/RIBHANVA37J0Zlp9wakvUegcXb3hl9xp+aRsjikhS5h89qiPPXGkWq9dsQrbpDODP8RziqskxzIzu4tYtvLkUZ/Ak9LCRu63SSGX+yAj24mG9Q+4taWGX32AmuVFK9CGDoec0IYx8ouUtiGWVBqZz0dRteKbBbL6MtnPjUxT+wMc6rarPL8zj9vwIDAQAB'
package com.liquidnet.service.goblin.config.properties;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = "liquidnet.shouqianba")
@Component
@Setter
@Getter
public class ShouqianbaProperties {
private String appId;
private String appKey;
private String appCode;
private String publicKey;
private String baseApi;
}
...@@ -4,9 +4,9 @@ import com.fasterxml.jackson.core.type.TypeReference; ...@@ -4,9 +4,9 @@ import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.liquidnet.commons.lang.util.HttpUtil; import com.liquidnet.commons.lang.util.HttpUtil;
import com.liquidnet.commons.lang.util.MD5Utils; import com.liquidnet.commons.lang.util.MD5Utils;
import com.liquidnet.service.goblin.config.properties.ShouqianbaProperties;
import com.liquidnet.service.goblin.param.shouqianba.request.*; import com.liquidnet.service.goblin.param.shouqianba.request.*;
import com.liquidnet.service.goblin.param.shouqianba.response.OrderCreateResponse; import com.liquidnet.service.goblin.param.shouqianba.response.*;
import com.liquidnet.service.goblin.param.shouqianba.response.SettlementCreateResponse;
import com.liquidnet.service.goblin.param.shouqianba.response.data.*; import com.liquidnet.service.goblin.param.shouqianba.response.data.*;
import com.liquidnet.service.goblin.service.IGoblinShouQianBaService; import com.liquidnet.service.goblin.service.IGoblinShouQianBaService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
...@@ -20,6 +20,7 @@ import java.security.PublicKey; ...@@ -20,6 +20,7 @@ import java.security.PublicKey;
import java.security.Signature; import java.security.Signature;
import java.security.spec.X509EncodedKeySpec; import java.security.spec.X509EncodedKeySpec;
import java.util.Base64; import java.util.Base64;
import java.util.List;
import java.util.TreeMap; import java.util.TreeMap;
/** /**
...@@ -32,14 +33,18 @@ import java.util.TreeMap; ...@@ -32,14 +33,18 @@ import java.util.TreeMap;
@Service @Service
public class GoblinShouQianBaServiceImpl implements IGoblinShouQianBaService { public class GoblinShouQianBaServiceImpl implements IGoblinShouQianBaService {
private final ShouqianbaProperties shouqianbaProperties;
public GoblinShouQianBaServiceImpl(ShouqianbaProperties properties) {
this.shouqianbaProperties = properties;
if (this.shouqianbaProperties == null) {
throw new IllegalArgumentException("找不到应用配置");
}
}
private static final ObjectMapper objectMapper = new ObjectMapper(); private static final ObjectMapper objectMapper = new ObjectMapper();
// TODO: 先写固定常量,后期可配置文件化
public static final String BASE_API = "https://api.shouqianba.com";
private static final String APPID = "test_appid";
private static final String APPKEY = "test_appkey";
// TODO: 收钱吧公钥,建议改为配置
private static final String SHOUQIANBA_PUB_KEY = "test_pub_key";
/** /**
* 创建结算明细 * 创建结算明细
...@@ -49,127 +54,166 @@ public class GoblinShouQianBaServiceImpl implements IGoblinShouQianBaService { ...@@ -49,127 +54,166 @@ public class GoblinShouQianBaServiceImpl implements IGoblinShouQianBaService {
*/ */
@Override @Override
public SettlementCreateData createSettlement(SettlementCreateRequest request) { public SettlementCreateData createSettlement(SettlementCreateRequest request) {
final String url = BASE_API + "/optimus/core/mall/createPreOrder"; return executeShouQianBaRequest("/optimus/core/mall/createCheckoutItems", "创建结算明细", request, SettlementCreateResponse.class);
log.info("[收钱吧] 创建结算明细, 请求URL: {}, 请求参数: {}", url, request);
try {
// body进行序列化成TreeMap以后 最后转成json(为了排序稳定)
TreeMap<String, Object> map = objectMapper.convertValue(
request,
new TypeReference<TreeMap<String, Object>>() {
}
);
String requestBody = objectMapper.writeValueAsString(map);
// 构建请求头(添加签名参数)
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("Authorization", getSign(requestBody));
String responseStr = HttpUtil.postJson(url, requestBody, headers);
log.info("[收钱吧] 创建结算明细, 响应体: {}", responseStr);
// 转换响应报文
SettlementCreateResponse response = objectMapper.readValue(responseStr, SettlementCreateResponse.class);
if (response != null && Boolean.TRUE.equals(response.getSuccess())) {
return response.getData();
} else {
log.error("[收钱吧] 创建结算明细业务失败, code: {}, msg: {}",
response != null ? response.getCode() : "null",
response != null ? response.getMsg() : "null");
return null;
}
} catch (Exception e) {
log.error("[收钱吧] 创建结算明细发生异常, 请求参数: {}", request, e);
return null;
}
} }
/**
* 创建订单
*
* @param request
* @return
*/
@Override @Override
public OrderCreateData createOrder(OrderCreateRequest request) { public OrderCreateData createOrder(OrderCreateRequest request) {
final String url = BASE_API + "/optimus/core/order/placeOrder"; return executeShouQianBaRequest("/optimus/core/order/placeOrder", "创建订单", request, OrderCreateResponse.class);
log.info("[收钱吧] 创建订单, 请求URL: {}, 请求参数: {}", url, request);
try {
// body进行序列化成TreeMap以后 最后转成json(为了排序稳定)
TreeMap<String, Object> map = objectMapper.convertValue(
request,
new TypeReference<TreeMap<String, Object>>() {
}
);
String requestBody = objectMapper.writeValueAsString(map);
// 构建请求头(添加签名参数)
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("Authorization", getSign(requestBody));
String responseStr = HttpUtil.postJson(url, requestBody, headers);
log.info("[收钱吧] 创建订单, 响应体: {}", responseStr);
// 转换响应报文
OrderCreateResponse response = objectMapper.readValue(responseStr, OrderCreateResponse.class);
if (response != null && Boolean.TRUE.equals(response.getSuccess())) {
return response.getData();
} else {
log.error("[收钱吧] 创建订单失败, code: {}, msg: {}",
response != null ? response.getCode() : "null",
response != null ? response.getMsg() : "null");
return null;
}
} catch (Exception e) {
log.error("[收钱吧] 创建订单发生异常, 请求参数: {}", request, e);
return null;
}
} }
/**
* 创建收单
* 如果上一步创建收单失败 可以使用这个接口重新创建收单
*
* @return
*/
@Override @Override
public AcquiringCreateData createAcquiring(AcquiringCreateRequest request) { public AcquiringCreateData createAcquiring(AcquiringCreateRequest request) {
return null; return executeShouQianBaRequest("/optimus/core/order/createAcquiring", "创建收单环节", request, AcquiringCreateResponse.class);
} }
/**
* 查询收银台
*
* @param request
* @return
*/
@Override @Override
public CashierQueryData queryCashier(CashierQueryRequest request) { public CashierQueryData queryCashier(CashierQueryRequest request) {
return executeShouQianBaRequest("/optimus/core/cashier/queryCashierPage", "查询收银台", request, CashierQueryResponse.class);
return null;
} }
/**
* 创建微信预支付订单
*
* @param request
* @return
*/
@Override @Override
public CreateWechatPrepayOrderData createWechatPrepayOrder(CreateWechatPrepayOrderRequest request) { public CreateWechatPrepayOrderData createWechatPrepayOrder(CreateWechatPrepayOrderRequest request) {
return null; return executeShouQianBaRequest("/optimus/core/cashier/proxyPreCreatedPay", "创建微信预支付订单", request, CreateWechatPrepayOrderResponse.class);
} }
/**
* 查询券码
*
* @param request
* @return
*/
@Override @Override
public CouponQueryData queryCoupon(CouponQueryRequest request) { public CouponQueryData queryCoupon(CouponQueryRequest request) {
return null; return executeShouQianBaRequest("/optimus/core/voucher/queryOrderVoucherList", "查询优惠券", request, CouponQueryResponse.class);
} }
/**
* 券码状态同步
*
* @param request
* @return
*/
@Override @Override
public boolean syncCouponStatus(CouponStatusSyncRequest request) { public boolean syncCouponStatus(CouponStatusSyncRequest request) {
return false; CouponStatusSyncResponse response = executeRequestAndGetResponse("/optimus/core/voucher/modifyOrderVoucherList", "同步优惠券状态", request, CouponStatusSyncResponse.class);
return response != null && Boolean.TRUE.equals(response.getSuccess());
} }
/**
* 券退款
*
* @param request
* @return
*/
@Override @Override
public CouponRefundData refundCoupon(CouponRefundRequest request) { public CouponRefundData refundCoupon(CouponRefundRequest request) {
return null; return executeShouQianBaRequest("/optimus/core/aftersale/applyRefund", "退款优惠券", request, CouponRefundResponse.class);
} }
/**
* 商城列表接口
*
* @param request
* @return
*/
@Override @Override
public MallListQueryData queryMallList(MallListQueryRequest request) { public List<MallListQueryData> queryMallList(MallListQueryRequest request) {
return null; return executeShouQianBaRequest("/optimus/open/mall/queryMallList", "查询门店列表", request, MallListQueryResponse.class);
} }
/**
* 商城商品接口
*
* @param request
* @return
*/
@Override @Override
public MallProductsQueryData queryMallProducts(MallProductsQueryRequest request) { public List<MallProductsQueryData> queryMallProducts(MallProductsQueryRequest request) {
return executeShouQianBaRequest("/optimus/open/mall/queryMallProducts", "查询门店商品", request, MallProductsQueryResponse.class);
}
/**
* 发送HTTP请求并返回Response对象
*/
private <T extends BaseResponse<?>> T executeRequestAndGetResponse(
String apiPath, String businessName, Object request, Class<T> responseClass) {
final String url = shouqianbaProperties.getBaseApi() + apiPath;
log.info("[收钱吧] {}, 请求URL: {}, 请求参数: {}", businessName, url, request);
try {
// body进行序列化成TreeMap以后 最后转成json(为了排序稳定)
TreeMap<String, Object> map = objectMapper.convertValue(
request,
new TypeReference<TreeMap<String, Object>>() {
}
);
String requestBody = objectMapper.writeValueAsString(map);
// 构建请求头(添加签名参数)
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("Authorization", getSign(requestBody));
String responseStr = HttpUtil.postJson(url, requestBody, headers);
log.info("[收钱吧] {}, 响应体: {}", businessName, responseStr);
// 转换响应报文
T response = objectMapper.readValue(responseStr, responseClass);
if (response != null && !Boolean.TRUE.equals(response.getSuccess())) {
log.error("[收钱吧] {}业务失败, code: {}, msg: {}", businessName,
response.getCode(), response.getMsg());
}
return response;
} catch (Exception e) {
log.error("[收钱吧] {}发生异常, 请求参数: {}", businessName, request, e);
return null;
}
}
/**
* 封装收钱吧接口调用,提取公共逻辑并发起请求,默认返回Data
*/
private <D, T extends BaseResponse<D>> D executeShouQianBaRequest(
String apiPath, String businessName, Object request, Class<T> responseClass) {
T response = executeRequestAndGetResponse(apiPath, businessName, request, responseClass);
if (response != null && Boolean.TRUE.equals(response.getSuccess())) {
return response.getData();
}
return null; return null;
} }
private String getSign(String bodyJsonStr) { private String getSign(String bodyJsonStr) {
try { try {
// 签名算法: sign = MD5( CONCAT( body + appkey ) ) // 签名算法: sign = MD5( CONCAT( body + appkey ) )
String rawStr = bodyJsonStr + APPKEY; String rawStr = bodyJsonStr + shouqianbaProperties.getAppKey();
String sign = MD5Utils.md5(rawStr); String sign = MD5Utils.md5(rawStr);
// 签名首部: Authorization: appid + " " + sign // 签名首部: Authorization: appid + " " + sign
return APPID + " " + sign; return shouqianbaProperties.getAppId() + " " + sign;
} catch (Exception e) { } catch (Exception e) {
log.error("[收钱吧] 生成签名发生异常", e); log.error("[收钱吧] 生成签名发生异常", e);
return ""; return "";
...@@ -189,7 +233,7 @@ public class GoblinShouQianBaServiceImpl implements IGoblinShouQianBaService { ...@@ -189,7 +233,7 @@ public class GoblinShouQianBaServiceImpl implements IGoblinShouQianBaService {
public boolean verifySignature(String signature, String eventId, String timestamp, String nonce, String content) { public boolean verifySignature(String signature, String eventId, String timestamp, String nonce, String content) {
// 签名原串 = eventId + timestamp + nonce + content // 签名原串 = eventId + timestamp + nonce + content
String plaintext = eventId + timestamp + nonce + content; String plaintext = eventId + timestamp + nonce + content;
return verifySignatureSHA256WithRSA(plaintext, signature, SHOUQIANBA_PUB_KEY); return verifySignatureSHA256WithRSA(plaintext, signature, shouqianbaProperties.getPublicKey());
} }
public boolean verifySignatureSHA256WithRSA(String plaintext, String inputSignature, String pubKey) { public boolean verifySignatureSHA256WithRSA(String plaintext, String inputSignature, String pubKey) {
......
package com.liquidnet.service.goblin.test;
import com.liquidnet.service.goblin.param.shouqianba.request.MallListQueryRequest;
import com.liquidnet.service.goblin.param.shouqianba.response.data.MallListQueryData;
import com.liquidnet.service.goblin.service.IGoblinShouQianBaService;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;
@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class GoblinShouQianBaServiceImplTest {
@Autowired
private IGoblinShouQianBaService goblinShouQianBaService;
@Test
public void queryMallListTest(){
MallListQueryRequest mallListQueryRequest = new MallListQueryRequest();
List<MallListQueryData> mallListQueryData = goblinShouQianBaService.queryMallList(mallListQueryRequest);
Assert.assertNotNull(mallListQueryData);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment