数币接口迁移

This commit is contained in:
DB 2024-01-31 09:14:11 +08:00
parent 40efe42369
commit 73c31ce07a
40 changed files with 1531 additions and 227 deletions

View File

@ -3,6 +3,7 @@ package com.cpop.api.tencent.wxWork.handler;
import com.alibaba.fastjson.JSONObject;
import com.cpop.api.tencent.wxWork.core.config.WxWorkApiConfig;
import com.cpop.api.tencent.wxWork.webHook.WebHookSendTextRequest;
import com.cpop.common.utils.http.HttpUtils;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -12,8 +13,8 @@ import java.util.List;
/**
* @author DB
* @createTime 2023/09/15 16:24
* @description 企微机器人
* @since 2023/09/15 16:24
* 企微机器人
*/
@Component
public class WebHookSendHandler {
@ -22,9 +23,9 @@ public class WebHookSendHandler {
private WxWorkApiConfig config;
/**
* @descriptions 机器人发送文本
* 机器人发送文本
* @author DB
* @date 2023/09/15 17:56
* @since 2023/09/15 17:56
* @param key 机器人键
* @param phoneList 通知人手机号
* @param content 内容
@ -38,25 +39,9 @@ public class WebHookSendHandler {
text.setContent(content);
text.setMentionedMobileList(phoneList);
request.setText(text);
sendPost(config.getWebhook() + key, JSONObject.toJSONString(request));
Response response = HttpUtils.sendOkHttpPost(config.getWebhook() + key, JSONObject.toJSONString(request));
response.close();
}
/**
* @param url 地址
* @param jsonBody 请求体
* @descriptions 发送post请求
* @author DB
* @date 2023/09/15 17:28
*/
private void sendPost(String url, String jsonBody) throws IOException {
OkHttpClient client = new OkHttpClient().newBuilder().build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, jsonBody);
Request request = new Request.Builder()
.url(url)
.method("POST", body)
.addHeader("Content-Type", "application/json")
.build();
client.newCall(request).execute();
}
}

View File

@ -25,7 +25,8 @@ import com.cpop.jambox.framework.constant.JamboxCloudUrl;
import com.cpop.jambox.framework.constant.JamboxRedisConstant;
import com.cpop.jambox.framework.enums.EasyLearnPayPayEnum;
import com.cpop.pay.framewok.config.wxPay.WxPayConfiguration;
import com.cpop.pay.framewok.core.dto.ecpp.EcppSmsCodeDto;
import com.cpop.pay.framewok.core.request.ecpp.EcppSmsCodeRequest;
import com.cpop.pay.framewok.core.response.ecpp.EcppSmsCodeResponse;
import com.cpop.pay.framewok.handler.ecpp.EcppHandler;
import com.cpop.pay.framewok.handler.wxPay.WxPayHandler;
import com.cpop.pay.framewok.task.WxPayAsyncTask;
@ -998,8 +999,10 @@ public class EasyLearnOrderServiceImpl extends ServiceImpl<EasyLearnOrderMapper,
*/
@Override
public void sendEcppMsmCode(String phone) {
EcppSmsCodeDto dto = new EcppSmsCodeDto();
dto.setSmsTpCd("YGJ_SIGN");
SpringUtils.getBean(EcppHandler.class).sendEcppMsmCode(dto);
EcppSmsCodeRequest request = new EcppSmsCodeRequest();
request.setSmsTpCd("YGJ_SIGN");
EcppSmsCodeResponse response = SpringUtils.getBean(EcppHandler.class).sendEcppMsmCode(request);
}
}

View File

@ -20,7 +20,7 @@ import com.cpop.jambox.business.service.BrandExtendService;
import com.cpop.mall.business.bo.*;
import com.cpop.mall.business.dto.UserPointDto;
import com.cpop.pay.framewok.config.wxPay.WxPayConfiguration;
import com.cpop.pay.framewok.core.dto.WxPayGoodsDetailDto;
import com.cpop.pay.framewok.core.dto.easyLearn.WxPayGoodsDetailDto;
import com.cpop.mall.business.entity.*;
import com.cpop.mall.business.mapper.OrderMapper;
import com.cpop.mall.business.service.*;
@ -35,9 +35,6 @@ import com.cpop.mall.framework.task.OrderOverTimeUnPayTask;
import com.cpop.mall.framework.task.ProductRecordSyncStockTask;
import com.cpop.pay.framewok.task.WxPayAsyncTask;
import com.cpop.pay.framewok.handler.wxPay.WxPayHandler;
import com.cpop.system.business.entity.Brand;
import com.cpop.system.business.service.BrandService;
import com.cpop.system.business.service.ProfitSharingService;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.exception.WxPayException;
@ -59,7 +56,6 @@ import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import static com.cpop.core.base.table.table.SysUserTableDef.SYS_USER;
@ -69,7 +65,6 @@ import static com.cpop.mall.business.entity.table.OrderRefundTableDef.ORDER_REFU
import static com.cpop.mall.business.entity.table.OrderTableDef.ORDER;
import static com.cpop.mall.business.entity.table.ProductRecordTableDef.PRODUCT_RECORD;
import static com.cpop.mall.business.entity.table.ProductTableDef.PRODUCT;
import static com.cpop.system.business.entity.table.ProfitSharingTableDef.PROFIT_SHARING;
import static com.cpop.system.business.entity.table.StoreTableDef.STORE;
import static com.mybatisflex.core.query.QueryMethods.sum;

View File

@ -111,4 +111,8 @@ wx:
# 先学后付用户签约通知地址
learn-now-pay-later-user-sign-plan-notify-url: https://frp-oak.top:11899/Cpop-Oam/callback/easyLearn/learnNowPayLaterUserSignPlanNotify
# 先学后付用户核销通知地址
learn-now-pay-later-service-order-notify-url: https://frp-oak.top:11899/Cpop-Oam/callback/easyLearn/learnNowPayLaterUserSignPlanNotify
learn-now-pay-later-service-order-notify-url: https://frp-oak.top:11899/Cpop-Oam/callback/easyLearn/learnNowPayLaterUserSignPlanNotify
#数币
ecpp:
pay:
base-url: https://newstage.ecnyenter.com

View File

@ -3,6 +3,7 @@ package com.cpop.oam.web;
import com.cpop.api.tencent.wxWork.handler.WebHookSendHandler;
import com.cpop.core.utils.RsaUtils;
import com.cpop.core.utils.SpringUtils;
import com.cpop.pay.framewok.handler.ecpp.EcppHandler;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@ -46,4 +47,9 @@ public class CpopApiTests {
String decrypt = rsaUtils.decrypt(jambox0831);
System.out.println(decrypt);
}
@Test
public void getSecurityKeyTest(){
SpringUtils.getBean(EcppHandler.class).getSecurityKey();
}
}

View File

@ -1,5 +1,6 @@
package com.cpop.oam.web;
import com.alibaba.fastjson.JSONArray;
import com.cpop.common.utils.StringUtils;
import com.cpop.core.utils.SpringUtils;
import com.cpop.jambox.business.entity.BrandExtend;
@ -13,18 +14,24 @@ import com.cpop.jambox.business.service.StoreExtendService;
import com.cpop.system.business.entity.Store;
import com.cpop.system.business.entity.StoreSign;
import com.cpop.system.business.entity.WxPayScore;
import com.cpop.system.business.mapper.StoreMapper;
import com.cpop.system.business.service.StoreService;
import com.cpop.system.business.service.StoreSignService;
import com.cpop.system.business.service.WxPayScoreService;
import com.mybatisflex.core.datasource.DataSourceKey;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.Db;
import com.mybatisflex.core.row.DbChain;
import com.mybatisflex.core.row.Row;
import com.mybatisflex.core.row.RowUtil;
import com.mybatisflex.core.update.UpdateChain;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
@ -209,7 +216,7 @@ public class CpopDataSyncTests {
*/
@Test
public void syncOldStoreSignData() {
List<Row> rowList;
/*List<Row> rowList;
try {
DataSourceKey.use("jambox");
rowList = DbChain.table("OAM_data_sign")
@ -226,66 +233,38 @@ public class CpopDataSyncTests {
DataSourceKey.clear();
}
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//无品牌校区
List<Row> notBrandStore = rowList.stream().filter(item -> StringUtils.isBlank(item.getString("brandCloudId"))).collect(Collectors.toList());
notBrandStore.forEach(item->{
if (StringUtils.isNotBlank(item.getString("signStaffId"))){
item.put("haveCounselor",true);
}
if (item.getString("createDate").length() < 11) {
item.put("createTime", LocalDateTime.parse(item.getString("createDate") + " 00:00:00", dateTimeFormatter));
} else {
item.put("createTime", LocalDateTime.parse(item.getString("createDate"), dateTimeFormatter));
}
if (StringUtils.isNotBlank(item.getString("renewDate"))){
item.put("haveActive",true);
}
item.put("sourceType","JAMBOX");
});
//先同步校区数据
List<Store> stores = RowUtil.toEntityList(notBrandStore, Store.class);
SpringUtils.getBean(StoreService.class).saveBatch(stores);
List<StoreExtend> storeExtends = new ArrayList<>();
for (int i = 0; i < stores.size(); i++) {
StoreExtend storeExtend = new StoreExtend();
storeExtend.setStoreId(stores.get(i).getId());
storeExtend.setCreateTime(LocalDateTime.now());
storeExtend.setStoreCloudId(notBrandStore.get(i).getString("storeCloudId"));
storeExtends.add(storeExtend);
}
SpringUtils.getBean(StoreExtendService.class).saveBatch(storeExtends);
//获取所有校区
Map<String, String> storeIdMap = Db.selectListByQuery(STORE.getTableName(), QueryWrapper.create().select(STORE.ID, STORE_EXTEND.STORE_CLOUD_ID)
.leftJoin(STORE_EXTEND).on(STORE_EXTEND.STORE_ID.eq(STORE.ID)))
.stream().collect(Collectors.toMap(item -> item.getString("storeCloudId"), item -> item.getString("id")));
//过滤出已签约的数据
//List<Row> waitSignStore = rowList.stream().filter(item -> StringUtils.equals(item.getString("signStatus"), "待签约")).collect(Collectors.toList());
/*Map<String, String> phoneToId = DbChain.table(STAFF.getTableName())
.select(STAFF.ID)
.select(SYS_USER.PHONE_NUMBER.as("phone"))
.from(STAFF)
.leftJoin(SYS_USER).on(SYS_USER.ID.eq(STAFF.USER_ID))
.list()
.stream().collect(Collectors.toMap(item -> item.getString("phone"), item -> item.getString("id")));
Map<String, String> cloudToId = SpringUtils.getBean(StoreExtendService.class).list()
.stream().collect(Collectors.toMap(StoreExtend::getStoreCloudId, StoreExtend::getStoreId));
rowList.forEach(item->{
if (StringUtils.isNotBlank(item.getString("phone"))){
item.set("sign_staff_id",phoneToId.get(item.getString("phone")));
List<Row> waitSignStore = rowList.stream().filter(item -> !StringUtils.equals(item.getString("signStatus"), "待签约")).collect(Collectors.toList());
List<StoreSign> storeSigns = new ArrayList<>();
waitSignStore.forEach(item -> {
StoreSign storeSign = new StoreSign();
storeSign.setSignStaffId(item.getString("signStaffId"));
storeSign.setStoreId(storeIdMap.get(item.getString("storeCloudId")));
storeSign.setExpireDate(item.getDate("expireDate").toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
if (item.getString("signCreateTime") != null){
if (item.getString("signCreateTime").length() < 11) {
storeSign.setCreateTime(LocalDateTime.parse(item.getString("signCreateTime") + " 00:00:00", dateTimeFormatter));
} else {
storeSign.setCreateTime(LocalDateTime.parse(item.getString("signCreateTime"), dateTimeFormatter));
}
}
item.set("store_id",cloudToId.get(item.getString("storeCloudId")));
});
List<StoreSign> entityList = RowUtil.toEntityList(rowList, StoreSign.class)
.stream().filter(item->StringUtils.isNotBlank(item.getStoreId())).collect(Collectors.toList());
Db.executeBatch(entityList, StoreSignMapper.class, (mapper, storeSign) -> {
// 以上的这个 mapper未被使用
UpdateChain.of(mapper)
.set(STORE_SIGN.CREATE_TIME,storeSign.getCreateTime())
.set(STORE_SIGN.UPDATE_TIME,storeSign.getUpdateTime())
.set(STORE_SIGN.SIGN_STAFF_ID,storeSign.getSignStaffId())
.where(STORE_SIGN.STORE_ID.eq(storeSign.getStoreId()))
.update();
storeSigns.add(storeSign);
});*/
SpringUtils.getBean(StoreService.class).updateChain()
.set(STORE.SIGN_ID, null)
.update();
List<StoreSign> list = SpringUtils.getBean(StoreSignService.class).list();
Db.executeBatch(list.stream().filter(item->StringUtils.isNotBlank(item.getStoreId())).collect(Collectors.toList()), StoreMapper.class, (mapper, data) -> {
UpdateChain.of(mapper).set(STORE.SIGN_ID, data.getId())
.where(STORE.ID.eq(data.getStoreId()))
.update();
});
}
@Test

View File

@ -1,10 +1,15 @@
package com.cpop.oam.business.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.cpop.api.tencent.wxWork.handler.WebHookSendHandler;
import com.cpop.common.utils.StringUtils;
import com.cpop.common.utils.bean.BeanUtils;
import com.cpop.core.base.entity.LoginUser;
import com.cpop.core.base.entity.PageDomain;
import com.cpop.core.base.exception.ServiceException;
import com.cpop.core.base.table.SysConfig;
import com.cpop.core.service.CoreService;
import com.cpop.core.service.RedisService;
import com.cpop.core.utils.SecurityUtils;
import com.cpop.core.utils.SpringUtils;
import com.cpop.core.utils.sql.SqlUtils;
@ -12,17 +17,21 @@ import com.cpop.oam.business.bo.*;
import com.cpop.oam.business.entity.FinanceReimburse;
import com.cpop.oam.business.entity.FinanceReimburseStage;
import com.cpop.oam.business.mapper.FinanceReimburseMapper;
import com.cpop.oam.business.service.CommonService;
import com.cpop.oam.business.service.FinanceReimburseService;
import com.cpop.oam.business.service.FinanceReimburseStageService;
import com.cpop.oam.business.vo.FinanceReimburseAuditPageVo;
import com.cpop.oam.business.vo.FinanceReimbursePageVo;
import com.cpop.oam.business.vo.ReimbursePersonStatisticVo;
import com.cpop.oam.framework.constant.WebHookKeyConstant;
import com.cpop.oam.framework.enums.OamConfigEnum;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
@ -169,6 +178,26 @@ public class FinanceReimburseServiceImpl extends ServiceImpl<FinanceReimburseMap
financeReimburse.setStaffId(loginUserInfo.getString("id"))
.setStatus(0);
this.save(financeReimburse);
//提醒审核员工
try {
List<String> phoneList = new ArrayList<>();
phoneList.add(loginUserInfo.getString("phoneNumber"));
// 获取审核管理员手机号
RedisService redisService = SpringUtils.getBean(RedisService.class);
CommonService commonService = SpringUtils.getBean(CommonService.class);
String auditStaffPhone = redisService.getCacheObject(commonService.getCacheKey(OamConfigEnum.CANCEL_AFTER_VERIFICATION_STAFF_PHONE.getKey()));
if (StringUtils.isBlank(auditStaffPhone)) {
SysConfig sysConfig = SpringUtils.getBean(CoreService.class).selectConfigByKey(commonService.getCacheKey(OamConfigEnum.AUDIT_STAFF_PHONE.getKey()));
auditStaffPhone = sysConfig.getConfigValue();
redisService.setCacheObject(commonService.getCacheKey(OamConfigEnum.AUDIT_STAFF_PHONE.getKey()), auditStaffPhone);
}
phoneList.add(auditStaffPhone);
SpringUtils.getBean(WebHookSendHandler.class).webHookSendText(WebHookKeyConstant.FINANCE_BOT, phoneList,
"您有一笔新的报销需要处理:\n",
false);
} catch (IOException e) {
throw new ServiceException("发送消息通知失败!");
}
}
/**

View File

@ -6,25 +6,26 @@ import cn.hutool.crypto.asymmetric.Sign;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cpop.pay.framewok.core.dto.ecpp.EcppBaseDto;
import com.cpop.pay.framewok.core.dto.ecpp.EcppVerifyDto;
import com.cpop.pay.framewok.core.request.ecpp.EcppBaseRequest;
import com.cpop.pay.framewok.core.request.ecpp.EcppVerifyRequest;
import com.cpop.pay.framewok.core.response.ecpp.EcppVerifyResponse;
import com.google.common.base.Joiner;
import lombok.Getter;
import lombok.Setter;
import okhttp3.*;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import javax.crypto.Cipher;
import javax.net.ssl.*;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.*;
import java.security.cert.X509Certificate;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@ -39,10 +40,11 @@ import java.util.List;
@EnableConfigurationProperties(EcppProperties.class)
public class EcppConfiguration {
/**
* 数币参数
*/
private EcppProperties ecppProperties;
EcppProperties ecppProperties;
public EcppConfiguration(EcppProperties ecppProperties) {
this.ecppProperties = ecppProperties;
}
@Setter
private volatile String jSessionId;
@ -61,11 +63,38 @@ public class EcppConfiguration {
* @param dto 请求数据
* @return Response
*/
public <T extends EcppVerifyDto> Response sendEcppPost(String url, T dto) throws IOException {
public <T extends EcppVerifyRequest> Response sendEcppPost(String url, T ecppRequest) throws IOException {
OkHttpClient client = new OkHttpClient().newBuilder().build();
MediaType mediaType = MediaType.Companion.parse("application/json;charset=utf-8");
EcppBaseDto ecppBaseDto = new EcppBaseDto(dto);
RequestBody body = RequestBody.Companion.create(JSONObject.toJSONString(ecppBaseDto), mediaType);
EcppBaseRequest ecppBaseRequest = new EcppBaseRequest(ecppRequest);
RequestBody body = RequestBody.Companion.create(JSONObject.toJSONString(ecppBaseRequest), mediaType);
String timestamp = String.valueOf(System.currentTimeMillis());
Request request = new Request
.Builder()
.url(url)
.post(body)
.addHeader("Content-Type", "application/json")
//.addHeader("VERIFY",getVerify(timestamp))
.addHeader("ecpp-header",getEcppHeader(timestamp))
.build();
return client.newCall(request).execute();
}
/**
* 发送数币请求
* @author DB
* @since 2024/1/29
* @param url 路径
* @param jsonBody 请求数据
* @return Response
*/
public Response sendEcppPost(String url, String jsonBody) throws IOException {
OkHttpClient client = new OkHttpClient().newBuilder()
.sslSocketFactory(getSslSocketFactory(), getX509TrustManager())
.hostnameVerifier(getHostnameVerifier())
.build();
MediaType mediaType = MediaType.Companion.parse("application/json;charset=utf-8");
RequestBody body = RequestBody.Companion.create(jsonBody, mediaType);
String timestamp = String.valueOf(System.currentTimeMillis());
Request request = new Request
.Builder()
@ -78,7 +107,7 @@ public class EcppConfiguration {
return client.newCall(request).execute();
}
public <V extends EcppVerifyDto> V parseEcppResponse(Response response, Class<V> clazz) throws IOException {
public <V extends EcppVerifyResponse> V parseEcppResponse(Response response, Class<V> clazz) throws IOException {
//读取响应体
ResponseBody body = response.body();
JSONObject result = JSONObject.parseObject(body.string());
@ -173,4 +202,57 @@ public class EcppConfiguration {
byte[] result = cipher.doFinal(Base64.decode(text));
return new String(result);
}
//获取这个SSLSocketFactory
private SSLSocketFactory getSslSocketFactory() {
try {
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, getTrustManager(), new SecureRandom());
return sslContext.getSocketFactory();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//获取TrustManager
private TrustManager[] getTrustManager() {
return new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[]{};
}
}
};
}
//获取HostnameVerifier
private HostnameVerifier getHostnameVerifier() {
return (s, sslSession) -> true;
}
private X509TrustManager getX509TrustManager() {
X509TrustManager trustManager = null;
try {
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
}
trustManager = (X509TrustManager) trustManagers[0];
} catch (Exception e) {
e.printStackTrace();
}
return trustManager;
}
}

View File

@ -10,10 +10,50 @@ public interface EcppApiConstant {
/**
* 安全密钥
*/
String SECURITY_KEY = "/prepay/security/consultSessionKey";
String SECURITY_KEY = "/auth/security/consultSessionKey";
/**
* 发送短信
*/
String SEND_MSG = "/prepay/sendSmsCode";
/**
* 预付服务登记
*/
String SERVICE_ENTRY = "/prepay/serviceEntry";
/**
* 预付服务查询
*/
String SERVICE_QUERY = "/prepay/serviceQuery";
/**
* 签约查询
*/
String SIGNING_QUERY = "/prepay/signingQuery";
/**
* 核销确认
*/
String WRITE_OFF_CONFIRM = "/prepay/writeOffConfirm";
/**
* 客户实名验证
*/
String CUSTOMER_VERIFY = "/prepay/merchantVerify";
/**
* 核销查询
*/
String WRITE_OFF_QUERY = "/prepay/writeOffQuery";
/**
* 注销退卡
*/
String LOGOUT_RETURN_CARD = "/prepay/logout";
/**
* 交易列表
*/
String TRADE_LIST = "/prepay/tradeList";
}

View File

@ -1,4 +1,4 @@
package com.cpop.pay.framewok.core.dto;
package com.cpop.pay.framewok.core.dto.easyLearn;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

View File

@ -1,4 +1,4 @@
package com.cpop.pay.framewok.core.dto;
package com.cpop.pay.framewok.core.dto.easyLearn;
import com.cpop.core.base.enums.OrderSource;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package com.cpop.pay.framewok.core.dto;
package com.cpop.pay.framewok.core.dto.easyLearn;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
@ -8,8 +8,8 @@ import java.math.BigDecimal;
/**
* @author DB
* @createTime 2023/10/27 15:36
* @description 微信支付商品详情dto
* @since 2023/10/27 15:36
* 微信支付商品详情dto
*/
@Data
public class WxPayGoodsDetailDto implements Serializable {

View File

@ -1,34 +0,0 @@
package com.cpop.pay.framewok.core.entity;
import lombok.Data;
/**
* Ecpp核心请求类
* @author DB
* @version 1.0.0
* @since 2023-12-12 9:18
*/
@Data
public class EcppBaseRequest {
/**
* 00通用01设备
*/
private String jSessionType;;
/**
* 会话类型为设备时送设备标识
*/
private String jSessionId;
/**
* 1DES2AES3SM4
*/
private Integer type;
/**
* 由业务报文JSON加密而成
*/
private String content;
}

View File

@ -1,43 +0,0 @@
package com.cpop.pay.framewok.core.entity;
import lombok.Data;
/**
* Ecpp核心响应类
* @author DB
* @version 1.0.0
* @since 2023-12-12 9:23
*/
@Data
public class EcppBaseResponse {
/**
* 响应消息
*/
private String msg;
/**
* 响应数据
*/
private String data;
/**
* 00通用01设备
*/
private String jSessionType;;
/**
* 会话类型为设备时送设备标识
*/
private String jSessionId;
/**
* 加密类型
*/
private Integer type;
/**
* 响应密文
*/
private String content;
}

View File

@ -1,4 +1,4 @@
package com.cpop.pay.framewok.core.dto.ecpp;
package com.cpop.pay.framewok.core.request.ecpp;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
@ -32,12 +32,12 @@ import java.util.List;
@Data
@Slf4j
@NoArgsConstructor
public class EcppBaseDto {
public class EcppBaseRequest {
{
jSessionType = "00";
}
public <T extends EcppVerifyDto > EcppBaseDto(T data) {
public <T extends EcppVerifyRequest> EcppBaseRequest(T data) {
setContent(data);
}
@ -61,7 +61,7 @@ public class EcppBaseDto {
*/
private String content;
private <T extends EcppVerifyDto> void setContent(T data) {
private <T extends EcppVerifyRequest> void setContent(T data) {
String unSignStr = getUnSignStr(data);
EcppConfiguration ecppConfiguration = SpringUtils.getBean(EcppConfiguration.class);
EcppProperties ecppProperties = ecppConfiguration.getEcppProperties();

View File

@ -0,0 +1,42 @@
package com.cpop.pay.framewok.core.request.ecpp;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author DB
* @version 1.0.0
* @since 2024-01-30 16:48
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class EcppCustomerVerifyRequest extends EcppVerifyRequest{
/**
* 渠道编号
*/
private String channelCode = "01";
/**
* 证件类型代码
*/
private String certTpCd = "1010";
/**
* 证件号码
*/
@JSONField(name = "certNo")
private String idNumber;
/**
* 证件姓名
*/
@JSONField(name = "certNm")
private String customerName;
/**
* 批次编号
*/
private String batchNo;
}

View File

@ -0,0 +1,78 @@
package com.cpop.pay.framewok.core.request.ecpp;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author DB
* @version 1.0.0
* @since 2024-01-30 17:15
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class EcppLogoutReturnCardRequest extends EcppVerifyRequest{
/**
* 商户id
*/
private String merchantId = "100";
/**
* 渠道编号
*/
private String channelCode = "01";
/**
* 预付服务编号
*/
@JSONField(name = "prpySvcId")
private String serviceNo;
/**
* 手机号码
*/
@JSONField(name = "cstMblNo")
private String customerPhone;
/**
* 交易流水号
*/
@JSONField(name = "txnSrlNo")
private String orderDetailId;
/**
* 客户名称
*/
@JSONField(name = "cstNm")
private String customerName;
/**
* 客户账号
*/
@JSONField(name = "cstAccNo")
private String customerAccount;
/**
* 客户账户名称
*/
@JSONField(name = "cstAccNm")
private String customerAccountName;
/**
* 客户账户行代码
*/
@JSONField(name = "cstAccBnkCd")
private String customerAccountCode;
/**
* 证件类型
*/
private String certTp = "1010";
/**
* 证件号码
*/
@JSONField(name = "certNo")
private String idNo;
}

View File

@ -0,0 +1,171 @@
package com.cpop.pay.framewok.core.request.ecpp;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
/**
* @author DB
* @version 1.0.0
* @since 2024-01-30 15:31
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class EcppServiceEntryRequest extends EcppVerifyRequest {
/**
* 速达商户Id
*/
private String merchantId = "100";
/**
* 渠道编号
*/
private String channelCode = "01";
/**
* 服务名称
*/
private String serviceName;
/**
* 服务开始日期
*/
private String serviceStartDate;
public void setServiceStartDate(LocalDate serviceStartDate) {
this.serviceStartDate = serviceStartDate.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
}
/**
* 服务结束日期
*/
private String serviceEndDate;
public void setServiceEndDate(LocalDate serviceEndDate) {
this.serviceEndDate = serviceEndDate.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
}
/**
* 服务数量
*/
private String serviceQuantity;
public void setServiceQuantity(Integer serviceQuantity) {
this.serviceQuantity = serviceQuantity.toString();
}
/**
* 服务金额
*/
private String serviceAmount;
public void setServiceAmount(BigDecimal serviceAmount) {
DecimalFormat decimalFormat = new DecimalFormat("#0.00");
this.serviceAmount = decimalFormat.format(serviceAmount);
}
/**
* 服务等级 01匿名预付02弱实名预付03强实名预付
*/
private String serviceGrade = "01";
/**
* 核销模式 01按次数02按金额
*/
private String writeOffMode = "02";
/**
* 适用门店描述
*/
private String applyDesc = "适用门店描述";
/**
* 卡片归还规则描述
*/
private String returnDesc = "卡片归还规则描述";
/**
* 到期清算基数 01按总额02按余额
*/
private String expLiquidateCardinal;
public void setExpLiquidateCardinal(Integer expLiquidateCardinal) {
this.expLiquidateCardinal = "0" + expLiquidateCardinal;
}
/**
* 到期清算模式 01按比例02按金额
*/
private String expLiquidateMode;
public void setExpLiquidateMode(Integer expLiquidateMode) {
this.expLiquidateMode = "0" + expLiquidateMode;
}
/**
* 到期清算比例 合约到期资金处置所属合作方的份额比例值输入10.00 代表 10.00%到期清算模式按比例时必填
*/
private String expLiquidateRate;
public void setExpLiquidateRate(BigDecimal expLiquidateRate) {
DecimalFormat decimalFormat = new DecimalFormat("#0.00");
this.expLiquidateRate = decimalFormat.format(expLiquidateRate);
}
/**
* 到期清算金额 合约到期资金处置所属合作方的金额值到期清算模式按金额时必填
*/
private String expLiquidateAmount;
public void setExpLiquidateAmount(BigDecimal expLiquidateAmount) {
DecimalFormat decimalFormat = new DecimalFormat("#0.00");
this.expLiquidateAmount = decimalFormat.format(expLiquidateAmount);
}
/**
* 违约清算基数 01按总额02按余额
*/
private String defaultLiquidateCardinal;
public void setDefaultLiquidateCardinal(Integer defaultLiquidateCardinal) {
this.defaultLiquidateCardinal = "0" + defaultLiquidateCardinal;
}
/**
* 违约清算模式 01按比例02按金额
*/
private String defaultLiquidateMode;
public void setDefaultLiquidateMode(Integer defaultLiquidateMode) {
this.defaultLiquidateMode = "0" + defaultLiquidateMode;
}
/**
* 违约清算比例 客户主动违约资金处置所属合作方的份额比例值输入 10.00 代表 10.00%到期清算模式按比例时必填
*/
private String defaultLiquidateRate;
public void setDefaultLiquidateRate(BigDecimal defaultLiquidateRate) {
DecimalFormat decimalFormat = new DecimalFormat("#0.00");
this.defaultLiquidateRate = decimalFormat.format(defaultLiquidateRate);
}
/**
* 违约清算金额 客户主动违约资金处置所属合作方的金额值到期清算模式按金额时必填
*/
private String defaultLiquidateAmount;
public void setDefaultLiquidateAmount(BigDecimal defaultLiquidateAmount) {
DecimalFormat decimalFormat = new DecimalFormat("#0.00");
this.defaultLiquidateAmount = decimalFormat.format(defaultLiquidateAmount);
}
/**
* 服务图片
*/
private EcppServiceImageRequest serviceImage;
}

View File

@ -0,0 +1,22 @@
package com.cpop.pay.framewok.core.request.ecpp;
import lombok.Data;
/**
* @author DB
* @version 1.0.0
* @since 2024-01-30 15:56
*/
@Data
public class EcppServiceImageRequest {
/**
* 图片类型 1服务图片2服务 Logo
*/
String imageType;
/**
* 图片内容 图片 base64 字符串
*/
String imageContent;
}

View File

@ -0,0 +1,39 @@
package com.cpop.pay.framewok.core.request.ecpp;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author DB
* @version 1.0.0
* @since 2024-01-30 16:09
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class EcppServiceQueryRequest extends EcppVerifyRequest{
/**
* 渠道编号 01建行
*/
private String channelCode = "01";
/**
* 平台商户 Id
*/
private String merchantId = "100";
/**
* 批次编号
*/
private String batchNo;
/**
* 页码
*/
private String pageIndex = "1";
/**
* 页容量
*/
private String pageSize = "10";
}

View File

@ -0,0 +1,43 @@
package com.cpop.pay.framewok.core.request.ecpp;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author DB
* @version 1.0.0
* @since 2024-01-30 16:22
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class EcppSigningQueryRequest extends EcppVerifyRequest{
/**
* 商户编号
*/
private String merchantId = "100";
/**
* 渠道编号
*/
private String channelCode = "01";
/**
* 交易流水号
*/
@JSONField(name = "txnSrlNo")
private String orderDetailId;
/**
* 预付服务编号
*/
@JSONField(name = "prpySvcId")
private String serviceNo;
/**
* 客户手机号
*/
@JSONField(name = "cstMblNo")
private String customerPhone;
}

View File

@ -1,4 +1,4 @@
package com.cpop.pay.framewok.core.dto.ecpp;
package com.cpop.pay.framewok.core.request.ecpp;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
@ -11,7 +11,7 @@ import lombok.EqualsAndHashCode;
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class EcppSmsCodeDto extends EcppVerifyDto {
public class EcppSmsCodeRequest extends EcppVerifyRequest {
/**
* 渠道编号 01建行

View File

@ -0,0 +1,43 @@
package com.cpop.pay.framewok.core.request.ecpp;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author DB
* @version 1.0.0
* @since 2024-01-30 17:29
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class EcppTradeListRequest extends EcppVerifyRequest{
/**
* 渠道编号
*/
private String channelCode = "01";
/**
* 服务编号
*/
@JSONField(name = "prpySvcId")
private String serviceNo;
/**
* 客户手机号
*/
@JSONField(name = "cstMblNo")
private String customerPhone;
/**
* 分页参数
*/
@JSONField(name = "pageIndex")
private String page;
/**
* 分页参数
*/
private String pageSize;
}

View File

@ -1,4 +1,4 @@
package com.cpop.pay.framewok.core.dto.ecpp;
package com.cpop.pay.framewok.core.request.ecpp;
import com.cpop.pay.framewok.anno.EcppUnSignField;
import lombok.AllArgsConstructor;
@ -13,7 +13,7 @@ import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class EcppVerifyDto {
public class EcppVerifyRequest {
/**
* 签名

View File

@ -0,0 +1,79 @@
package com.cpop.pay.framewok.core.request.ecpp;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author DB
* @version 1.0.0
* @since 2024-01-30 16:36
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class EcppWriteOffConfirmRequest extends EcppVerifyRequest {
/**
* 商户编号
*/
private String merchantId = "100";
/**
* 渠道编号(01建行)
*/
private String channelCode= "01";
/**
* 交易流水号
*/
@JSONField(name = "txnSrlNo")
private String orderDetailId;
/**
* 预付服务编号
*/
@JSONField(name = "prpySvcId")
private String serviceNo;
/**
* 客户手机号
*/
@JSONField(name = "cstMblNo")
private String customerPhone;
/**
* 核销模式
*/
private String txnMode = "01";
/**
* 核销次数
*/
private String txnCnt;
/**
* 核销金额
*/
private String txnAmt;
/**
* 行方交易流水号
*/
private String instTxnSrlNo;
/**
* 事件跟踪号
*/
private String evtTrcNo;
/**
* 短信验证码
*/
private String smsVldCd;
/**
* 申请流水号
*/
@JSONField(name = "aplyTrcNo")
private String applyTraceNo;
}

View File

@ -0,0 +1,41 @@
package com.cpop.pay.framewok.core.request.ecpp;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author DB
* @version 1.0.0
* @since 2024-01-30 16:58
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class EcppWriteOffQueryRequest extends EcppVerifyRequest {
/**
* 平台商户 Id
*/
private String merchantId = "100";
/**
* 渠道编号
*/
private String channelCode = "01";
/**
* 交易流水号
*/
@JSONField(name = "txnSrlNo")
private String orderDetailId;
/**
* 行方交易流水号
*/
private String instTxnSrlNo;
/**
* 事件跟踪号
*/
private String evtTrcNo;
}

View File

@ -0,0 +1,24 @@
package com.cpop.pay.framewok.core.response.ecpp;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author DB
* @version 1.0.0
* @since 2024-01-30 16:48
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class EcppCustomerVerifyResponse extends EcppVerifyResponse{
/**
* 成功标识
*/
private String scsInd;
/**
* 事件跟踪号
*/
private String evtTrcNo;
}

View File

@ -0,0 +1,61 @@
package com.cpop.pay.framewok.core.response.ecpp;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author DB
* @version 1.0.0
* @since 2024-01-30 17:15
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class EcppLogoutReturnCardResponse extends EcppVerifyResponse{
/**
* 行方交易流水号
*/
private String instTxnSrlNo;
/**
* 预付服务编号
*/
@JSONField(name = "prpySvcId")
private String serviceNo;
/**
* 付款人名称
*/
@JSONField(name = "payerNm")
private String payerName;
/**
* 付款人账号
*/
@JSONField(name = "payerAccNo")
private String payerAccount;
/**
* 收款人名称
*/
@JSONField(name = "payerNm")
private String payeeName;
/**
* 收款人账号
*/
@JSONField(name = "payerNm")
private String payeeAccount;
/**
* 交易金额
*/
private String txnAmt;
/**
* 交易备注
*/
private String txnRmk;
}

View File

@ -0,0 +1,24 @@
package com.cpop.pay.framewok.core.response.ecpp;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author DB
* @version 1.0.0
* @since 2024-01-30 15:58
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class EcppServiceEntryResponse extends EcppVerifyResponse {
/**
* 签约状态 01待审核02已签约03待解约04已解约
*/
private String signingStatus;
/**
* 批次号
*/
private String batchNo;
}

View File

@ -0,0 +1,31 @@
package com.cpop.pay.framewok.core.response.ecpp;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
/**
* @author DB
* @version 1.0.0
* @since 2024-01-30 16:09
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class EcppServiceQueryResponse extends EcppVerifyResponse {
/**
* 总页数
*/
private String pageCount;
/**
* 总数
*/
private String recordCount;
/**
* 数据记录
*/
private List<EcppServiceRecordResponse> records;
}

View File

@ -0,0 +1,68 @@
package com.cpop.pay.framewok.core.response.ecpp;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
/**
* @author DB
* @version 1.0.0
* @since 2024-01-30 16:17
*/
@Data
public class EcppServiceRecordResponse {
/**
* 批次编号
*/
private String batchNo;
/**
* 签约状态
*/
private String signingStatus;
/**
* 申请日期
*/
private String applyDate;
/**
* 渠道商户编号
*/
@JSONField(name = "channelMchtNo")
private String channelMchNo;
/**
* 渠道商户名称
*/
@JSONField(name = "channelMchtNm")
private String channelMchName;
/**
* 服务名称
*/
private String serviceName;
/**
* 服务开始日期
*/
private String serviceStartDate;
/**
* 服务结束日期
*/
private String serviceEndDate;
/**
* 服务数量
*/
private String serviceQuantity;
/**
* 服务金额
*/
private String serviceAmount;
/**
* 存管比例
*/
private String depositoryRate;
}

View File

@ -0,0 +1,88 @@
package com.cpop.pay.framewok.core.response.ecpp;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author DB
* @version 1.0.0
* @since 2024-01-30 16:22
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class EcppSigningQueryResponse extends EcppVerifyResponse {
/**
* 客户手机号
*/
@JSONField(name = "mobileNumber")
private String customerPhone;
/**
* 客户名称
*/
@JSONField(name = "cstNm")
private String customerName;
/**
* 客户账号
*/
@JSONField(name = "mchtstlAccNo")
private String customerAccount;
/**
* 签约状态 009018:签约已支付009019:签约待支付
*/
private String signingStatus;
/**
* 总次数
*/
private Integer totalCnt;
/**
* 总金额
*/
private String totalAmt;
/**
* 核销次数
*/
private String writeOffCnt;
/**
* 核销金额
*/
private String writeOffAmt;
/**
* 剩余核销次数
*/
private Integer surplusCnt;
/**
* 剩余核销金额
*/
private String surplusAmt;
/**
* 签约时间
*/
private String signTime;
/**
* 解约时间
*/
private String terminateTime;
/**
* 合约到期日期
*/
private String arExpDate;
/**
* 合约备注
*/
private String arRmk;
}

View File

@ -0,0 +1,22 @@
package com.cpop.pay.framewok.core.response.ecpp;
import com.alibaba.fastjson.annotation.JSONField;
import com.cpop.pay.framewok.core.request.ecpp.EcppVerifyRequest;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author DB
* @version 1.0.0
* @since 2024-01-29 16:54
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class EcppSmsCodeResponse extends EcppVerifyResponse {
/**
* 申请跟踪
*/
@JSONField(name = "aplyTrcNo")
private String applyTracking;
}

View File

@ -0,0 +1,32 @@
package com.cpop.pay.framewok.core.response.ecpp;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
/**
* @author DB
* @version 1.0.0
* @since 2024-01-30 17:29
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class EcppTradeListResponse extends EcppVerifyResponse {
/**
* 页数
*/
private String totalPage;
/**
* 总记录数
*/
private String totalRecord;
/**
* 数据
*/
private List<EcppTradeRecordResponse> records;
}

View File

@ -0,0 +1,70 @@
package com.cpop.pay.framewok.core.response.ecpp;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
/**
* @author DB
* @version 1.0.0
* @since 2024-01-30 17:33
*/
@Data
public class EcppTradeRecordResponse {
/**
* 交易流水号
*/
@JSONField(name = "txnSrlNo")
private String orderDetailId;
/**
* 商户简称
*/
@JSONField(name = "mchtAbbr")
private String merchantName;
/**
* 交易类型
*/
@JSONField(name = "txnTpCd")
private String tradeType;
/**
* 交易金额
*/
private String txnAmt;
/**
* 交易时间
*/
private String txnTime;
/**
* 交易状态
*/
private String txnStCd;
/**
* 付款人名称
*/
@JSONField(name = "payerNm")
private String payerName;
/**
* 付款人账号
*/
@JSONField(name = "payerAccNo")
private String payerAccount;
/**
* 收款人名称
*/
@JSONField(name = "payerNm")
private String payeeName;
/**
* 收款人账号
*/
@JSONField(name = "payerNm")
private String payeeAccount;
}

View File

@ -0,0 +1,23 @@
package com.cpop.pay.framewok.core.response.ecpp;
import com.cpop.pay.framewok.anno.EcppUnSignField;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author DB
* @version 1.0.0
* @since 2024-01-29 15:28
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class EcppVerifyResponse {
/**
* 签名
*/
@EcppUnSignField
private String signature;
}

View File

@ -0,0 +1,36 @@
package com.cpop.pay.framewok.core.response.ecpp;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author DB
* @version 1.0.0
* @since 2024-01-30 16:36
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class EcppWriteOffConfirmResponse extends EcppVerifyResponse {
/**
* 事件跟踪号
*/
private String evtTrcNo;
/**
* 交易流水号
*/
@JSONField(name = "txnSrlNo")
private String orderDetailId;
/**
* 交易状态代码
*/
private String txnStCd;
/**
* 银行流水号
*/
private String instTxnSrlNo;
}

View File

@ -0,0 +1,57 @@
package com.cpop.pay.framewok.core.response.ecpp;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author DB
* @version 1.0.0
* @since 2024-01-30 16:58
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class EcppWriteOffQueryResponse extends EcppVerifyResponse {
/**
* 事件跟踪号
*/
private String evtTrcNo;
/**
* 交易流水号
*/
@JSONField(name = "txnSrlNo")
private String orderDetailId;
/**
* 行方交易流水号
*/
private String instTxnSrlNo;
/**
* 监管合约编号
*/
private String regArNo;
/**
* 交易状态代码
*/
private String txnStCd;
/**
* 交易次数
*/
private String txnCnt;
/**
* 交易金额
*/
private String txnAmt;
/**
* 预付服务编号
*/
@JSONField(name = "prpySvcId")
private String serviceNo;
}

View File

@ -4,21 +4,20 @@ import com.alibaba.fastjson.JSONObject;
import com.cpop.common.utils.StringUtils;
import com.cpop.core.base.exception.ServiceException;
import com.cpop.core.base.exception.UtilException;
import com.cpop.core.utils.SpringUtils;
import com.cpop.core.utils.uuid.IdUtils;
import com.cpop.pay.framewok.config.ecpp.EcppConfiguration;
import com.cpop.pay.framewok.core.constant.EcppApiConstant;
import com.cpop.pay.framewok.core.dto.ecpp.EcppBaseDto;
import com.cpop.pay.framewok.core.dto.ecpp.EcppSmsCodeDto;
import com.cpop.pay.framewok.core.dto.ecpp.EcppVerifyDto;
import com.cpop.pay.framewok.core.request.ecpp.*;
import com.cpop.pay.framewok.core.response.ecpp.*;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
/**
* @author DB
@ -29,27 +28,29 @@ import java.util.Map;
@Slf4j
public class EcppHandler {
@Autowired
private EcppConfiguration ecppConfiguration;
/**
* 获取安全密钥
* @author DB
* @since 2024/1/29
*/
public void getSecurityKey() {
EcppConfiguration ecppConfiguration = SpringUtils.getBean(EcppConfiguration.class);
if (ecppConfiguration.checkKeyTime()) {
return;
}
log.info("======================= 获取速达会话密钥 ========================");
Response response = null;
String s1 = IdUtils.fastSimpleUUID();
String s1 = UUID.randomUUID().toString().replaceAll("-", "");
try {
EcppVerifyDto ecppVerifyDto = new EcppVerifyDto(ecppConfiguration.encrypt(ecppConfiguration.getEcppProperties().getPublicKey(), s1));
response = ecppConfiguration.sendEcppPost(ecppConfiguration.getEcppProperties().getBaseUrl() + EcppApiConstant.SECURITY_KEY, ecppVerifyDto);
Map<String, String> data = new HashMap<>();
data.put("content", ecppConfiguration.encrypt(ecppConfiguration.getEcppProperties().getPublicKey(), s1));
response = ecppConfiguration.sendEcppPost(ecppConfiguration.getEcppProperties().getBaseUrl() + EcppApiConstant.SECURITY_KEY, JSONObject.toJSONString(data));
JSONObject result = JSONObject.parseObject(response.body().string());
String code = result.getString("code");
if (StringUtils.equals(code, "402.2")) {
log.error("获取速达会话密钥header出错" + result);
getSecurityKey();
return;
}
if (StringUtils.equals(code, "200") && result.getJSONObject("data") != null) {
@ -62,6 +63,8 @@ public class EcppHandler {
log.info("速达会话密钥:{} , 速达密钥iv向量{}速达JSessionId: {}", ecppConfiguration.getSessionKey(), ecppConfiguration.getSessionIv(), ecppConfiguration.getJSessionId());
log.info("======================= 获取速达会话密钥成功 ========================");
ecppConfiguration.setNextExpireTime(System.currentTimeMillis() + ecppConfiguration.getEXPIRE_TIME());
} else {
throw new UtilException("获取速达会话密钥失败:" + result.getString("msg"));
}
} catch (Exception e) {
throw new UtilException(e);
@ -71,25 +74,6 @@ public class EcppHandler {
}
}
/**
* 获取短信验证码
* @author DB
* @since 2024/1/29
* @param dto 请求
*/
public void sendEcppMsmCode(EcppSmsCodeDto dto) {
EcppConfiguration ecppConfiguration = SpringUtils.getBean(EcppConfiguration.class);
Response response = null;
try {
response = ecppConfiguration.sendEcppPost(ecppConfiguration.getEcppProperties().getBaseUrl() + EcppApiConstant.SEND_MSG, dto);
} catch (IOException e) {
throw new ServiceException(e.getMessage());
} finally {
assert response != null;
response.close();
}
}
private String hexXor(String str1, String str2) {
try {
String[] arr1 = str1.split("");
@ -107,4 +91,183 @@ public class EcppHandler {
return "";
}
}
/**
* 获取短信验证码
* @author DB
* @since 2024/1/29
* @param dto 请求
*/
public EcppSmsCodeResponse sendEcppMsmCode(EcppSmsCodeRequest request) {
Response response = null;
try {
response = ecppConfiguration.sendEcppPost(ecppConfiguration.getEcppProperties().getBaseUrl() + EcppApiConstant.SEND_MSG, request);
return ecppConfiguration.parseEcppResponse(response,EcppSmsCodeResponse.class);
} catch (IOException e) {
throw new ServiceException(e.getMessage());
} finally {
assert response != null;
response.close();
}
}
/**
* 预付服务登记签订预付服务获得预付卡售卡资格进行预付服务登记前先完成预付商户登记
* @author DB
* @since 2024/1/30
* @param request 请求
* @return EcppServiceEntryResponse 响应
*/
public EcppServiceEntryResponse serviceEntry(EcppServiceEntryRequest request) {
Response response = null;
try {
response = ecppConfiguration.sendEcppPost(ecppConfiguration.getEcppProperties().getBaseUrl() + EcppApiConstant.SERVICE_ENTRY, request);
return ecppConfiguration.parseEcppResponse(response, EcppServiceEntryResponse.class);
} catch (IOException e) {
throw new ServiceException(e.getMessage());
} finally {
assert response != null;
response.close();
}
}
/**
* 预付服务查询
* @author DB
* @since 2024/1/30
* @param request 请求
* @return EcppServiceQueryResponse 响应
*/
public EcppServiceQueryResponse serviceQuery(EcppServiceQueryRequest request) {
Response response = null;
try {
response = ecppConfiguration.sendEcppPost(ecppConfiguration.getEcppProperties().getBaseUrl() + EcppApiConstant.SERVICE_QUERY, request);
return ecppConfiguration.parseEcppResponse(response, EcppServiceQueryResponse.class);
} catch (IOException e) {
throw new ServiceException(e.getMessage());
} finally {
assert response != null;
response.close();
}
}
/**
* 签约查询
* @author DB
* @since 2024/1/30
* @param request 请求
* @return EcppSigningQueryResponse 响应
*/
public EcppSigningQueryResponse signingQuery(EcppSigningQueryRequest request) {
Response response = null;
try {
response = ecppConfiguration.sendEcppPost(ecppConfiguration.getEcppProperties().getBaseUrl() + EcppApiConstant.SIGNING_QUERY, request);
return ecppConfiguration.parseEcppResponse(response, EcppSigningQueryResponse.class);
} catch (IOException e) {
throw new ServiceException(e.getMessage());
} finally {
assert response != null;
response.close();
}
}
/**
* 客户身份校验
* @author DB
* @since 2024/1/30
* @param request 请求
* @return EcppCustomerVerifyResponse 响应
*/
public EcppCustomerVerifyResponse customerVerify(EcppCustomerVerifyRequest request) {
Response response = null;
try {
response = ecppConfiguration.sendEcppPost(ecppConfiguration.getEcppProperties().getBaseUrl() + EcppApiConstant.CUSTOMER_VERIFY, request);
return ecppConfiguration.parseEcppResponse(response, EcppCustomerVerifyResponse.class);
} catch (IOException e) {
throw new ServiceException(e.getMessage());
} finally {
assert response != null;
response.close();
}
}
/**
* 核销确认
* @author DB
* @since 2024/1/30
* @param request 请求
* @return EcppWriteOffConfirmResponse 响应
*/
public EcppWriteOffConfirmResponse writeOffConfirm(EcppWriteOffConfirmRequest request) {
Response response = null;
try {
response = ecppConfiguration.sendEcppPost(ecppConfiguration.getEcppProperties().getBaseUrl() + EcppApiConstant.WRITE_OFF_CONFIRM, request);
return ecppConfiguration.parseEcppResponse(response, EcppWriteOffConfirmResponse.class);
} catch (IOException e) {
throw new ServiceException(e.getMessage());
} finally {
assert response != null;
response.close();
}
}
/**
* 核销查询
* @author DB
* @since 2024/1/30
* @param request 请求
* @return EcppWriteOffQueryResponse
*/
public EcppWriteOffQueryResponse writeOffQuery(EcppWriteOffQueryRequest request) {
Response response = null;
try {
response = ecppConfiguration.sendEcppPost(ecppConfiguration.getEcppProperties().getBaseUrl() + EcppApiConstant.WRITE_OFF_QUERY, request);
return ecppConfiguration.parseEcppResponse(response, EcppWriteOffQueryResponse.class);
} catch (IOException e) {
throw new ServiceException(e.getMessage());
} finally {
assert response != null;
response.close();
}
}
/**
* 注销退卡
* @author DB
* @since 2024/1/30
* @param request 请求
* @return EcppLogoutReturnCardResponse
*/
public EcppLogoutReturnCardResponse logoutReturnCard(EcppLogoutReturnCardRequest request) {
Response response = null;
try {
response = ecppConfiguration.sendEcppPost(ecppConfiguration.getEcppProperties().getBaseUrl() + EcppApiConstant.LOGOUT_RETURN_CARD, request);
return ecppConfiguration.parseEcppResponse(response, EcppLogoutReturnCardResponse.class);
} catch (IOException e) {
throw new ServiceException(e.getMessage());
} finally {
assert response != null;
response.close();
}
}
/**
* 交易列表
* @author DB
* @since 2024/1/31
* @param request 请求
* @return EcppTradeListResponse
*/
public EcppTradeListResponse tradeList(EcppTradeListRequest request) {
Response response = null;
try {
response = ecppConfiguration.sendEcppPost(ecppConfiguration.getEcppProperties().getBaseUrl() + EcppApiConstant.TRADE_LIST, request);
return ecppConfiguration.parseEcppResponse(response, EcppTradeListResponse.class);
} catch (IOException e) {
throw new ServiceException(e.getMessage());
} finally {
assert response != null;
response.close();
}
}
}

View File

@ -22,4 +22,5 @@ ecpp:
pay:
app-id: 1000
app-type: 1
public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA32A6vFBgXZgVgzaboSHjMMfJxrxXITDkdgzMR/WpTdxJvqZyyZtPOtdL4wg6St4lki4W/SMH6zTWJX07HYeWl8KiSOAXr2kcqHWPhO+rmtq8rMaR831f9ot7GK/6hkKUFRQZ8Uev8pGnOO4w5n+AaLOkohd+K0WXoaNokD+vxvZO7+yTYY/WAT30ItaMY0Ld5o3rRRo63lHuNlBjQ6mP8U6pPXek0J+oONraxJwZPsCEGTw3tfsXi0uMViRRXfp33H2xBZ11wrRrY/l5Pp8YPpJCxrCyzGcwlNqsT4VuEW4NglMyyU0g0J9mR+eIZS2kmuhpwjshyGC2Soc7DYdNUwIDAQAB
public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA32A6vFBgXZgVgzaboSHjMMfJxrxXITDkdgzMR/WpTdxJvqZyyZtPOtdL4wg6St4lki4W/SMH6zTWJX07HYeWl8KiSOAXr2kcqHWPhO+rmtq8rMaR831f9ot7GK/6hkKUFRQZ8Uev8pGnOO4w5n+AaLOkohd+K0WXoaNokD+vxvZO7+yTYY/WAT30ItaMY0Ld5o3rRRo63lHuNlBjQ6mP8U6pPXek0J+oONraxJwZPsCEGTw3tfsXi0uMViRRXfp33H2xBZ11wrRrY/l5Pp8YPpJCxrCyzGcwlNqsT4VuEW4NglMyyU0g0J9mR+eIZS2kmuhpwjshyGC2Soc7DYdNUwIDAQAB
private-key: MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC56o035yHE/4ClfGJZbSBLunYsPcOFsjOGTy5BBMW5GQRS81VpUulUK8kAmjD1UC0A3oSYhi8dOSb/93QqOUDL/v0x5h34Aqdm42BGzNEmAQ0SQzXr1+r8lspMXFc74JJnON2a1iD1OnU8wXXd+8QlfFpxovADVgJwxJclDXbJcSJc6DcsZhjp685irKJLvp/P3hk8moHjd5w4fK+csTpl64GYgLAAXkeKme9FQjb0/6KxykCkGEYsEb09Ye2XfStqzogZN7BbzqB9Bsuf1gS/MiIzKoLXR4glmEvtTgFb7gCCWH4lLFs47JoBKgxmL6V+UWVFB4zGJwSU9ocDiZ+JAgMBAAECggEAKOsOmbctH4Z8ce+mVbhG22P2jlYpqktGO9FBhN3gBpUS9o7HxZ6R7AyW+KL3E4bJ4N8Yn9kolW32v29fCcwADuXYJBtZjTRIU8THc82wWoTws4xHWdjzxxQJAjVwnaUXk9BYNbPbHR34n56Uqn629OkhntEVsiZD8z3RZj5IXp0/wDolzU++pfQ8w+kkUOIFh5puARve41aHBYYpcK+B3Vbrmt0rh9ag+JUbaus1FuJFCG3OndUBw+M/G9gQdz0BOIiSHurmw+JVxn9VeQZ0N2W0GDkwlSNt0dJYeN846xP9aszox0RRlOS/KOPySN7guZg6VHEM/vejHRkRXcSW4QKBgQDdVLLL98cKWwmoE9y2/oQXItvfcOLqSBibEG2KBTkjouJ2/em0iFAZT3NYDUlBxMhQgVdJGZdRKSxcxsxFk4WhvfRCXz+LoJHyO48du3Ir+sED6AShTpUhirOvbhuqU90/UR0yWG5e94KTkXToFS1SHa4MLFyqFYsnkFAnYOVFlwKBgQDXCbyfv/Pk2u+7Y9z6UPMksGrFBVR8gHCRoDqc4UjniWAP017I1U01M8019UOAA1wq9A4IOxHKHaRvq/xgm++4bqGSsRO61Oq5veXufT0iNke9EfnZ5Xv3w1sg6Yyca++pyUHDj71nAdWUCbTxisbOL8czYyZjL77lmGH2uogn3wKBgE3Om7hml5tFW8SxjtLp8IetonwPVEYmKDhC8y8lHOwxM8m/A2yKyxXKv3LB4PH0+rKKdaPmEjLe9ZB79o2zCbRNcdPvZghw3z23wF0ka0OYuEfmRdJrLLQI7ZgLbkBXkRzUKB5txgcuncHAzcdUwoTumCQBaGYGgs/axMLDJnZrAoGAFVgREeYypi+ZBgeWgn4QdD7SijXKOgVhpwK5bqLp4pl/IHMBgHuziylWIBn1Fjq/JkBNOEHstRwWG0N97HTt6WeJwA61f6Dsn30a2n4x2Dh9DGZBX4BouqH4ZJ7p5wjLpBWm4mtdCGFlOqlv/V2h+AtEAXTA9a1ijFWAu8WuCA8CgYBnThuufsLG6rzVmK+b8b+sRtZ+8IVE85mVKNH30ThCc8EJEK4DT02ESRZhtOagRQ3n2J/ozGEf4jZ+tfcGoCv5f3EAHcRKN9EwG0hl2WH2Sjw0YZu1qKQbkQQXIAU40BSRDm0xgAWIsSnxuxn7oTZtRDActawGU4LshkQyymAKXA==