parent
0c47196664
commit
367478c18c
@ -0,0 +1,49 @@ |
|||||||
|
package com.cweb.controller; |
||||||
|
|
||||||
|
import com.hfkj.common.utils.ResponseMsgUtil; |
||||||
|
import com.hfkj.model.ResponseData; |
||||||
|
import com.hfkj.service.BsMerPlatformNoService; |
||||||
|
import com.hfkj.sysenum.PlatformTypeEnum; |
||||||
|
import io.swagger.annotations.Api; |
||||||
|
import io.swagger.annotations.ApiOperation; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
import org.springframework.stereotype.Controller; |
||||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||||
|
import org.springframework.web.bind.annotation.RequestMethod; |
||||||
|
import org.springframework.web.bind.annotation.RequestParam; |
||||||
|
import org.springframework.web.bind.annotation.ResponseBody; |
||||||
|
|
||||||
|
import javax.annotation.Resource; |
||||||
|
|
||||||
|
/** |
||||||
|
* @className: BsMerPlatformNo |
||||||
|
* @author: HuRui |
||||||
|
* @date: 2023/5/23 |
||||||
|
**/ |
||||||
|
@Controller |
||||||
|
@Api(value = "设备管理") |
||||||
|
@RequestMapping(value = "/merPlatformNo") |
||||||
|
public class BsMerPlatformNoController { |
||||||
|
|
||||||
|
private static Logger log = LoggerFactory.getLogger(BsMerLedgerController.class); |
||||||
|
|
||||||
|
@Resource |
||||||
|
private BsMerPlatformNoService merPlatformNoService; |
||||||
|
|
||||||
|
@RequestMapping(value="/getMerPlatformNo",method = RequestMethod.GET) |
||||||
|
@ResponseBody |
||||||
|
@ApiOperation(value = "查询商户分账功能") |
||||||
|
public ResponseData getMerPlatformNo(@RequestParam(name = "merId", required = true) Long merId, |
||||||
|
@RequestParam(name = "platformType", required = true) Integer platformType) { |
||||||
|
try { |
||||||
|
|
||||||
|
return ResponseMsgUtil.success(merPlatformNoService.getPlatformNo(merId, PlatformTypeEnum.getDataByNumber(platformType))); |
||||||
|
|
||||||
|
} catch (Exception e) { |
||||||
|
log.error(e.getMessage(), e); |
||||||
|
return ResponseMsgUtil.exception(e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,56 @@ |
|||||||
|
package com.api.config; |
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject; |
||||||
|
import com.hfkj.common.exception.*; |
||||||
|
import com.hfkj.common.utils.ResponseMsgUtil; |
||||||
|
import com.hfkj.model.ResponseData; |
||||||
|
import org.springframework.http.HttpStatus; |
||||||
|
import org.springframework.http.ResponseEntity; |
||||||
|
import org.springframework.validation.BindException; |
||||||
|
import org.springframework.validation.ObjectError; |
||||||
|
import org.springframework.web.bind.MethodArgumentNotValidException; |
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler; |
||||||
|
import org.springframework.web.bind.annotation.RestControllerAdvice; |
||||||
|
|
||||||
|
import javax.validation.ConstraintViolation; |
||||||
|
import javax.validation.ConstraintViolationException; |
||||||
|
import javax.xml.bind.ValidationException; |
||||||
|
import java.util.List; |
||||||
|
import java.util.stream.Collectors; |
||||||
|
|
||||||
|
/** |
||||||
|
* @className: RestExceptionHandler |
||||||
|
* @author: HuRui |
||||||
|
* @date: 2023/5/23 |
||||||
|
**/ |
||||||
|
|
||||||
|
@RestControllerAdvice |
||||||
|
public class RestExceptionHandler { |
||||||
|
|
||||||
|
/** |
||||||
|
* 默认全局异常处理。 |
||||||
|
* @param e the e |
||||||
|
* @return ResultData |
||||||
|
*/ |
||||||
|
@ExceptionHandler(value = {BindException.class, ValidationException.class, MethodArgumentNotValidException.class}) |
||||||
|
public ResponseData handleValidatedException(Exception e) { |
||||||
|
|
||||||
|
if (e instanceof MethodArgumentNotValidException) { |
||||||
|
MethodArgumentNotValidException ex =(MethodArgumentNotValidException) e; |
||||||
|
ObjectError objectError = ex.getBindingResult().getAllErrors().stream().collect(Collectors.toList()).get(0); |
||||||
|
return ResponseMsgUtil.builderResponse(SysCode.OpenApi.getCode()+ErrorCode.OPEN_API_REQ_PARAMS_ERR.getCode(), objectError.getDefaultMessage(),null); |
||||||
|
|
||||||
|
} else if (e instanceof ConstraintViolationException) { |
||||||
|
ConstraintViolationException ex = (ConstraintViolationException) e; |
||||||
|
ConstraintViolation<?> constraintViolation = ex.getConstraintViolations().stream().collect(Collectors.toList()).get(0); |
||||||
|
return ResponseMsgUtil.builderResponse(SysCode.OpenApi.getCode()+ErrorCode.OPEN_API_REQ_PARAMS_ERR.getCode(), constraintViolation.getMessage(),null); |
||||||
|
|
||||||
|
} else if (e instanceof BindException) { |
||||||
|
BindException ex = (BindException ) e; |
||||||
|
ObjectError objectError = ex.getAllErrors().stream().collect(Collectors.toList()).get(0); |
||||||
|
return ResponseMsgUtil.builderResponse(SysCode.OpenApi.getCode()+ErrorCode.OPEN_API_REQ_PARAMS_ERR.getCode(), objectError.getDefaultMessage(),null); |
||||||
|
} |
||||||
|
return ResponseMsgUtil.builderResponse(SysCode.OpenApi.getCode()+ErrorCode.OPEN_API_REQ_PARAMS_ERR.getCode(), ErrorCode.OPEN_API_REQ_PARAMS_ERR.getMsg(),null); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -1,60 +0,0 @@ |
|||||||
package com.api.config.controller; |
|
||||||
|
|
||||||
import com.github.pagehelper.PageHelper; |
|
||||||
import com.github.pagehelper.PageInfo; |
|
||||||
import com.hfkj.channel.lakala.config.LaKaLaConfig; |
|
||||||
import com.hfkj.channel.saas.utils.SaasCommon; |
|
||||||
import com.hfkj.common.exception.ErrorCode; |
|
||||||
import com.hfkj.common.exception.ErrorHelp; |
|
||||||
import com.hfkj.common.exception.SysCode; |
|
||||||
import com.hfkj.common.utils.ResponseMsgUtil; |
|
||||||
import com.hfkj.entity.BsCompany; |
|
||||||
import com.hfkj.entity.SecRegion; |
|
||||||
import com.hfkj.model.ResponseData; |
|
||||||
import com.hfkj.model.StoreModel; |
|
||||||
import com.hfkj.service.BsCompanyService; |
|
||||||
import com.hfkj.service.BsIndustryService; |
|
||||||
import com.hfkj.service.BsLklMccService; |
|
||||||
import com.hfkj.service.CommonService; |
|
||||||
import io.swagger.annotations.Api; |
|
||||||
import io.swagger.annotations.ApiOperation; |
|
||||||
import org.apache.commons.lang3.StringUtils; |
|
||||||
import org.slf4j.Logger; |
|
||||||
import org.slf4j.LoggerFactory; |
|
||||||
import org.springframework.web.bind.annotation.*; |
|
||||||
|
|
||||||
import javax.annotation.Resource; |
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.HashMap; |
|
||||||
import java.util.List; |
|
||||||
import java.util.Map; |
|
||||||
|
|
||||||
|
|
||||||
@RestController |
|
||||||
@RequestMapping(value="/common") |
|
||||||
@Api(value="共用接口") |
|
||||||
public class CommonController { |
|
||||||
|
|
||||||
Logger log = LoggerFactory.getLogger(CommonController.class); |
|
||||||
|
|
||||||
@Resource |
|
||||||
private BsIndustryService industryService; |
|
||||||
|
|
||||||
|
|
||||||
@RequestMapping(value="/getIndustry",method = RequestMethod.GET) |
|
||||||
@ResponseBody |
|
||||||
@ApiOperation(value = "获取行业数据") |
|
||||||
public ResponseData getIndustry() { |
|
||||||
try { |
|
||||||
|
|
||||||
return ResponseMsgUtil.success(industryService.getCacheIndustry()); |
|
||||||
|
|
||||||
} catch (Exception e) { |
|
||||||
log.error("CommonController --> getIndustry() error!", e); |
|
||||||
return ResponseMsgUtil.exception(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} |
|
@ -0,0 +1,112 @@ |
|||||||
|
package com.api.controller.v1; |
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject; |
||||||
|
import com.hfkj.common.exception.ErrorCode; |
||||||
|
import com.hfkj.common.exception.ErrorHelp; |
||||||
|
import com.hfkj.common.exception.SysCode; |
||||||
|
import com.hfkj.common.utils.ResponseMsgUtil; |
||||||
|
import com.hfkj.model.ResponseData; |
||||||
|
import com.hfkj.openapi.v1.model.TokenGrantType; |
||||||
|
import com.hfkj.openapi.v1.service.AuthTokenService; |
||||||
|
import com.hfkj.service.BsMerKeyService; |
||||||
|
import io.swagger.annotations.Api; |
||||||
|
import io.swagger.annotations.ApiOperation; |
||||||
|
import org.apache.commons.collections4.MapUtils; |
||||||
|
import org.apache.commons.lang3.StringUtils; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
import org.springframework.stereotype.Controller; |
||||||
|
import org.springframework.web.bind.annotation.RequestBody; |
||||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||||
|
import org.springframework.web.bind.annotation.RequestMethod; |
||||||
|
import org.springframework.web.bind.annotation.ResponseBody; |
||||||
|
|
||||||
|
import javax.annotation.Resource; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* @className: CommonController |
||||||
|
* @author: HuRui |
||||||
|
* @date: 2023/5/23 |
||||||
|
**/ |
||||||
|
@Controller |
||||||
|
@Api(value = "公共") |
||||||
|
@RequestMapping(value = "/v1/auth") |
||||||
|
public class AuthController { |
||||||
|
|
||||||
|
private static Logger log = LoggerFactory.getLogger(AuthController.class); |
||||||
|
|
||||||
|
@Resource |
||||||
|
private BsMerKeyService merKeyService; |
||||||
|
@Resource |
||||||
|
private AuthTokenService authTokenService; |
||||||
|
|
||||||
|
@RequestMapping(value="/token",method = RequestMethod.POST) |
||||||
|
@ResponseBody |
||||||
|
@ApiOperation(value = "获取token") |
||||||
|
public ResponseData token(@RequestBody JSONObject body) { |
||||||
|
try { |
||||||
|
if (body == null |
||||||
|
|| StringUtils.isBlank(body.getString("grantType")) |
||||||
|
|| StringUtils.isBlank(body.getString("merchantNo")) |
||||||
|
|| StringUtils.isBlank(body.getString("merchantKey"))) { |
||||||
|
log.error("获取token error!", "参数错误"); |
||||||
|
throw ErrorHelp.genException(SysCode.OpenApi, ErrorCode.OPEN_API_REQ_PARAMS_ERR, ""); |
||||||
|
} |
||||||
|
|
||||||
|
// 查询授权类型
|
||||||
|
TokenGrantType tokenGrantType = TokenGrantType.getDataByCode(body.getString("grantType")); |
||||||
|
if (tokenGrantType == null) { |
||||||
|
throw ErrorHelp.genException(SysCode.OpenApi, ErrorCode.OPEN_API_TOKEN_GRANT_TYPE_ERR, ""); |
||||||
|
} |
||||||
|
String merNo = body.getString("merchantNo"); |
||||||
|
String merKey = body.getString("merchantKey"); |
||||||
|
|
||||||
|
// 查询商户秘钥
|
||||||
|
String key = merKeyService.getKeyByMerNo(merNo); |
||||||
|
if (StringUtils.isBlank(key)) { |
||||||
|
throw ErrorHelp.genException(SysCode.OpenApi, ErrorCode.OPEN_API_COMMON, "未配置商户秘钥"); |
||||||
|
} |
||||||
|
if (!merKey.equals(key)) { |
||||||
|
throw ErrorHelp.genException(SysCode.OpenApi, ErrorCode.OPEN_API_KEY_ERR, ""); |
||||||
|
} |
||||||
|
return ResponseMsgUtil.success(authTokenService.createToken(merNo)); |
||||||
|
|
||||||
|
} catch (Exception e) { |
||||||
|
log.error(e.getMessage(), e); |
||||||
|
return ResponseMsgUtil.exception(e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@RequestMapping(value="/refresh",method = RequestMethod.POST) |
||||||
|
@ResponseBody |
||||||
|
@ApiOperation(value = "刷新token") |
||||||
|
public ResponseData refresh(@RequestBody JSONObject body) { |
||||||
|
try { |
||||||
|
if (body == null |
||||||
|
|| StringUtils.isBlank(body.getString("grantType")) |
||||||
|
|| StringUtils.isBlank(body.getString("merchantKey")) |
||||||
|
|| StringUtils.isBlank(body.getString("merchantKey")) |
||||||
|
) { |
||||||
|
log.error("获取token error!", "参数错误"); |
||||||
|
throw ErrorHelp.genException(SysCode.OpenApi, ErrorCode.REQ_PARAMS_ERROR, ""); |
||||||
|
} |
||||||
|
String merNo = body.getString("merchantNo"); |
||||||
|
String merKey = body.getString("merchantKey"); |
||||||
|
// 查询商户秘钥
|
||||||
|
String key = merKeyService.getKeyByMerNo(merNo); |
||||||
|
if (StringUtils.isBlank(key)) { |
||||||
|
throw ErrorHelp.genException(SysCode.OpenApi, ErrorCode.OPEN_API_COMMON, "未配置商户秘钥"); |
||||||
|
} |
||||||
|
if (!merKey.equals(key)) { |
||||||
|
throw ErrorHelp.genException(SysCode.OpenApi, ErrorCode.OPEN_API_KEY_ERR, ""); |
||||||
|
} |
||||||
|
return ResponseMsgUtil.success(authTokenService.refresh(merNo)); |
||||||
|
|
||||||
|
} catch (Exception e) { |
||||||
|
log.error(e.getMessage(), e); |
||||||
|
return ResponseMsgUtil.exception(e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -1,59 +0,0 @@ |
|||||||
package com.api.controller.v1; |
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONObject; |
|
||||||
import com.github.pagehelper.PageHelper; |
|
||||||
import com.github.pagehelper.PageInfo; |
|
||||||
import com.hfkj.common.exception.ErrorCode; |
|
||||||
import com.hfkj.common.exception.ErrorHelp; |
|
||||||
import com.hfkj.common.exception.SysCode; |
|
||||||
import com.hfkj.common.security.UserCenter; |
|
||||||
import com.hfkj.common.utils.ResponseMsgUtil; |
|
||||||
import com.hfkj.config.hsg.UserDiscountService; |
|
||||||
import com.hfkj.entity.*; |
|
||||||
import com.hfkj.model.ResponseData; |
|
||||||
import com.hfkj.model.UserDiscount; |
|
||||||
import com.hfkj.model.UserInfoModel; |
|
||||||
import com.hfkj.openapi.v1.model.TradePreorderModel; |
|
||||||
import com.hfkj.service.*; |
|
||||||
import com.hfkj.sysenum.*; |
|
||||||
import io.swagger.annotations.Api; |
|
||||||
import io.swagger.annotations.ApiOperation; |
|
||||||
import org.apache.commons.lang3.StringUtils; |
|
||||||
import org.slf4j.Logger; |
|
||||||
import org.slf4j.LoggerFactory; |
|
||||||
import org.springframework.stereotype.Controller; |
|
||||||
import org.springframework.web.bind.annotation.*; |
|
||||||
|
|
||||||
import javax.annotation.Resource; |
|
||||||
import javax.servlet.http.HttpServletRequest; |
|
||||||
import java.math.BigDecimal; |
|
||||||
import java.util.HashMap; |
|
||||||
import java.util.Map; |
|
||||||
|
|
||||||
@Controller |
|
||||||
@Api(value = "交易订单") |
|
||||||
@RequestMapping(value = "/v1/trade") |
|
||||||
public class BsTradeController { |
|
||||||
|
|
||||||
private static Logger log = LoggerFactory.getLogger(BsTradeController.class); |
|
||||||
|
|
||||||
@RequestMapping(value="/preorder",method = RequestMethod.POST) |
|
||||||
@ResponseBody |
|
||||||
@ApiOperation(value = "聚合主扫") |
|
||||||
public ResponseData preorder(@RequestBody TradePreorderModel body, HttpServletRequest request) { |
|
||||||
try { |
|
||||||
if (body == null) { |
|
||||||
log.error("configStore error!", "参数错误"); |
|
||||||
throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, ""); |
|
||||||
} |
|
||||||
|
|
||||||
// 创建交易订单
|
|
||||||
return ResponseMsgUtil.success(null); |
|
||||||
|
|
||||||
} catch (Exception e) { |
|
||||||
log.error(e.getMessage(), e); |
|
||||||
return ResponseMsgUtil.exception(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -0,0 +1,183 @@ |
|||||||
|
package com.api.controller.v1; |
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject; |
||||||
|
import com.hfkj.common.exception.ErrorCode; |
||||||
|
import com.hfkj.common.exception.ErrorHelp; |
||||||
|
import com.hfkj.common.exception.SysCode; |
||||||
|
import com.hfkj.common.utils.ResponseMsgUtil; |
||||||
|
import com.hfkj.entity.BsMer; |
||||||
|
import com.hfkj.entity.BsTradeOrder; |
||||||
|
import com.hfkj.entity.BsTradeOrderRefund; |
||||||
|
import com.hfkj.model.ResponseData; |
||||||
|
import com.hfkj.openapi.v1.model.RequestQueryTradeModel; |
||||||
|
import com.hfkj.openapi.v1.model.RequestRefundTradeModel; |
||||||
|
import com.hfkj.openapi.v1.model.RequestTradePreorderModel; |
||||||
|
import com.hfkj.openapi.v1.model.ResponseQueryTradeModel; |
||||||
|
import com.hfkj.openapi.v1.service.OpenApiTradeOrderService; |
||||||
|
import com.hfkj.openapi.v1.utils.SignatureUtil; |
||||||
|
import com.hfkj.service.BsMerKeyService; |
||||||
|
import com.hfkj.service.BsMerService; |
||||||
|
import com.hfkj.sysenum.*; |
||||||
|
import io.swagger.annotations.Api; |
||||||
|
import io.swagger.annotations.ApiOperation; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
import org.springframework.stereotype.Controller; |
||||||
|
import org.springframework.validation.annotation.Validated; |
||||||
|
import org.springframework.web.bind.annotation.*; |
||||||
|
|
||||||
|
import javax.annotation.Resource; |
||||||
|
import java.math.BigDecimal; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
@Controller |
||||||
|
@Api(value = "交易订单") |
||||||
|
@RequestMapping(value = "/v1/trade") |
||||||
|
public class TradeController { |
||||||
|
|
||||||
|
private static Logger log = LoggerFactory.getLogger(TradeController.class); |
||||||
|
|
||||||
|
@Resource |
||||||
|
private BsMerKeyService merKeyService; |
||||||
|
|
||||||
|
@Resource |
||||||
|
private OpenApiTradeOrderService openApiTradeOrderService; |
||||||
|
|
||||||
|
@Resource |
||||||
|
private BsMerService merService; |
||||||
|
|
||||||
|
@RequestMapping(value="/preorder",method = RequestMethod.POST) |
||||||
|
@ResponseBody |
||||||
|
@ApiOperation(value = "聚合主扫") |
||||||
|
public ResponseData preorder(@Validated @RequestBody RequestTradePreorderModel body) { |
||||||
|
log.info("========= Start 聚合主扫接口 Start ==========="); |
||||||
|
log.info("请求参数:" + JSONObject.toJSONString(body)); |
||||||
|
try { |
||||||
|
// 验证签名
|
||||||
|
if (!SignatureUtil.checkSign(body.getSign(), body, merKeyService.getKeyByMerNo(body.getMerchantNo()))) { |
||||||
|
throw ErrorHelp.genException(SysCode.OpenApi, ErrorCode.OPEN_API_SIGN_ERR, ""); |
||||||
|
} |
||||||
|
if (!body.getTransType().equals("JSAPI")) { |
||||||
|
throw ErrorHelp.genException(SysCode.OpenApi, ErrorCode.OPEN_API_COMMON, "接入方式错误"); |
||||||
|
} |
||||||
|
// 查询支付方式
|
||||||
|
TradeOrderPayModeEnum payMode = TradeOrderPayModeEnum.getNameByCode(body.getPayMode()); |
||||||
|
if (payMode == null) { |
||||||
|
throw ErrorHelp.genException(SysCode.OpenApi, ErrorCode.OPEN_API_COMMON, "支付方式错误"); |
||||||
|
} |
||||||
|
// 查询商户
|
||||||
|
BsMer mer = merService.getMer(body.getMerchantNo()); |
||||||
|
if (mer == null) { |
||||||
|
throw ErrorHelp.genException(SysCode.OpenApi, ErrorCode.OPEN_API_COMMON, "未知的商户号"); |
||||||
|
} |
||||||
|
if (!mer.getMerStatus().equals(MerStatusEnum.status1.getNumber())) { |
||||||
|
throw ErrorHelp.genException(SysCode.OpenApi, ErrorCode.OPEN_API_COMMON, "商户状态异常"); |
||||||
|
} |
||||||
|
// 查询订单号是否存在
|
||||||
|
BsTradeOrder outTradeNo = openApiTradeOrderService.getOrderByOutTradeNo(body.getOutTradeNo()); |
||||||
|
if (outTradeNo != null) { |
||||||
|
throw ErrorHelp.genException(SysCode.OpenApi, ErrorCode.OPEN_API_COMMON, "商户交易流水重复"); |
||||||
|
} |
||||||
|
|
||||||
|
BsTradeOrder tradeOrder = new BsTradeOrder(); |
||||||
|
tradeOrder.setCompanyId(mer.getCompanyId()); |
||||||
|
tradeOrder.setAgentId(mer.getAgentId()); |
||||||
|
tradeOrder.setSalesmanId(mer.getSalesmanId()); |
||||||
|
tradeOrder.setSalesmanName(mer.getSalesmanName()); |
||||||
|
tradeOrder.setMerId(mer.getId()); |
||||||
|
tradeOrder.setMerName(mer.getMerName()); |
||||||
|
tradeOrder.setMerNo(mer.getMerNo()); |
||||||
|
tradeOrder.setOutTradeNo(body.getOutTradeNo()); |
||||||
|
tradeOrder.setTradeAmount(new BigDecimal(body.getTotalAmount())); |
||||||
|
tradeOrder.setTradeActualAmount(tradeOrder.getTradeAmount()); |
||||||
|
tradeOrder.setPayMode(payMode.getCode()); |
||||||
|
tradeOrder.setStatus(TradeOrderStatusEnum.status1.getNumber()); |
||||||
|
tradeOrder.setProfitSharingStatus(body.getProfitSharing().equals("0")?false:true); |
||||||
|
tradeOrder.setCreateType(TradeOrderCreateTypeEnum.type3.getCode()); |
||||||
|
tradeOrder.setPayAppid(body.getSubAppid()); |
||||||
|
tradeOrder.setPayUserId(body.getUserId()); |
||||||
|
tradeOrder.setTimeoutExpress(body.getTimeoutExpress()); |
||||||
|
|
||||||
|
// 创建交易订单
|
||||||
|
Map<String, Object> returnParam = openApiTradeOrderService.createOrder(tradeOrder); |
||||||
|
log.info("返回参数:" + JSONObject.toJSONString(returnParam)); |
||||||
|
return ResponseMsgUtil.success(returnParam); |
||||||
|
|
||||||
|
} catch (Exception e) { |
||||||
|
log.info("出现异常:", e); |
||||||
|
return ResponseMsgUtil.exception(e); |
||||||
|
} finally { |
||||||
|
log.info("========= END 聚合主扫接口 END ==========="); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@RequestMapping(value="/queryTrade",method = RequestMethod.POST) |
||||||
|
@ResponseBody |
||||||
|
@ApiOperation(value = "查询交易") |
||||||
|
public ResponseData queryTrade(@RequestBody RequestQueryTradeModel body) { |
||||||
|
log.info("========= Start 查询交易 Start ==========="); |
||||||
|
log.info("请求参数:" + JSONObject.toJSONString(body)); |
||||||
|
try { |
||||||
|
// 验证签名
|
||||||
|
if (!SignatureUtil.checkSign(body.getSign(), body, merKeyService.getKeyByMerNo(body.getMerchantNo()))) { |
||||||
|
throw ErrorHelp.genException(SysCode.OpenApi, ErrorCode.OPEN_API_SIGN_ERR, ""); |
||||||
|
} |
||||||
|
// 查询交易订单号
|
||||||
|
BsTradeOrder tradeOrder = openApiTradeOrderService.getOrderByOutTradeNo(body.getOutTradeNo()); |
||||||
|
if (tradeOrder == null) { |
||||||
|
throw ErrorHelp.genException(SysCode.OpenApi, ErrorCode.OPEN_API_COMMON, "未知的交易订单号"); |
||||||
|
} |
||||||
|
|
||||||
|
ResponseQueryTradeModel responseQueryTradeModel = new ResponseQueryTradeModel(); |
||||||
|
responseQueryTradeModel.setMerchantNo(tradeOrder.getMerNo()); |
||||||
|
responseQueryTradeModel.setOutTradeNo(tradeOrder.getOutTradeNo()); |
||||||
|
responseQueryTradeModel.setAccTradeNo(tradeOrder.getAccTradeNo()); |
||||||
|
responseQueryTradeModel.setUserId(tradeOrder.getPayUserId()); |
||||||
|
responseQueryTradeModel.setPayMode(tradeOrder.getPayMode()); |
||||||
|
responseQueryTradeModel.setTradeAmount(tradeOrder.getTradeAmount()); |
||||||
|
responseQueryTradeModel.setTradeActualAmount(tradeOrder.getTradeActualAmount()); |
||||||
|
responseQueryTradeModel.setStatus(tradeOrder.getStatus()); |
||||||
|
responseQueryTradeModel.setCreateTime(tradeOrder.getCreateTime()); |
||||||
|
responseQueryTradeModel.setPayTime(tradeOrder.getPayTime()); |
||||||
|
responseQueryTradeModel.setSign(SignatureUtil.createSign(responseQueryTradeModel, merKeyService.getKeyByMerNo(body.getMerchantNo()))); |
||||||
|
|
||||||
|
log.info("响应参数:" + JSONObject.toJSONString(responseQueryTradeModel)); |
||||||
|
return ResponseMsgUtil.success(responseQueryTradeModel); |
||||||
|
|
||||||
|
} catch (Exception e) { |
||||||
|
log.info("出现异常:", e); |
||||||
|
return ResponseMsgUtil.exception(e); |
||||||
|
} finally { |
||||||
|
log.info("========= END 查询交易 END ==========="); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@RequestMapping(value="/refund",method = RequestMethod.POST) |
||||||
|
@ResponseBody |
||||||
|
@ApiOperation(value = "退款交易") |
||||||
|
public ResponseData refund(@Validated @RequestBody RequestRefundTradeModel body) { |
||||||
|
log.info("========= Start 退款交易接口 Start ==========="); |
||||||
|
log.info("请求参数:" + JSONObject.toJSONString(body)); |
||||||
|
try { |
||||||
|
// 验证签名
|
||||||
|
if (!SignatureUtil.checkSign(body.getSign(), body, merKeyService.getKeyByMerNo(body.getMerchantNo()))) { |
||||||
|
throw ErrorHelp.genException(SysCode.OpenApi, ErrorCode.OPEN_API_SIGN_ERR, ""); |
||||||
|
} |
||||||
|
// 查询退款单号
|
||||||
|
BsTradeOrderRefund refund = openApiTradeOrderService.getRefundByNo(body.getRefundTradeNo()); |
||||||
|
if (refund != null) { |
||||||
|
throw ErrorHelp.genException(SysCode.OpenApi, ErrorCode.OPEN_API_COMMON, "退款流水重复"); |
||||||
|
} |
||||||
|
openApiTradeOrderService.refund(body); |
||||||
|
|
||||||
|
return ResponseMsgUtil.success(null); |
||||||
|
|
||||||
|
} catch (Exception e) { |
||||||
|
log.info("出现异常:", e); |
||||||
|
return ResponseMsgUtil.exception(e); |
||||||
|
} finally { |
||||||
|
log.info("========= END 退款交易接口 END ==========="); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -1,9 +0,0 @@ |
|||||||
package com.hfkj.common; |
|
||||||
|
|
||||||
/** |
|
||||||
* @className: StreamGobbler |
|
||||||
* @author: HuRui |
|
||||||
* @date: 2023/5/12 |
|
||||||
**/ |
|
||||||
public class StreamGobbler { |
|
||||||
} |
|
@ -0,0 +1,29 @@ |
|||||||
|
package com.hfkj.common.utils; |
||||||
|
|
||||||
|
import java.util.Random; |
||||||
|
|
||||||
|
/** |
||||||
|
* 生成工具类 |
||||||
|
* @className: GenerateUtil |
||||||
|
* @author: HuRui |
||||||
|
* @date: 2023/5/23 |
||||||
|
**/ |
||||||
|
public class GenerateUtil { |
||||||
|
|
||||||
|
/** |
||||||
|
* 生成随机字符串 |
||||||
|
* @param length 长度 |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static String generateRandomString(int length) { |
||||||
|
String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; |
||||||
|
StringBuilder sb = new StringBuilder(); |
||||||
|
Random random = new Random(); |
||||||
|
for (int i = 0; i < length; i++) { |
||||||
|
int index = random.nextInt(chars.length()); |
||||||
|
sb.append(chars.charAt(index)); |
||||||
|
} |
||||||
|
return sb.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -1,7 +1,19 @@ |
|||||||
package com.hfkj.dao; |
package com.hfkj.dao; |
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Param; |
||||||
|
import org.apache.ibatis.annotations.Select; |
||||||
|
|
||||||
|
import java.util.Map; |
||||||
|
|
||||||
/** |
/** |
||||||
* mapper扩展类 |
* mapper扩展类 |
||||||
*/ |
*/ |
||||||
public interface BsMerKeyMapperExt { |
public interface BsMerKeyMapperExt { |
||||||
} |
|
||||||
|
@Select({ |
||||||
|
" select mer_no merNo,b.`key` merKey from bs_mer a " + |
||||||
|
" LEFT JOIN bs_mer_key b on b.mer_id = a.id " + |
||||||
|
" where a.mer_no = #{merNo} and b.status = 1" |
||||||
|
}) |
||||||
|
Map<String, Object> queryKeyByMerNo(@Param("merNo") String merNo); |
||||||
|
} |
||||||
|
@ -0,0 +1,36 @@ |
|||||||
|
package com.hfkj.openapi.v1.model; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
import org.hibernate.validator.constraints.Length; |
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank; |
||||||
|
|
||||||
|
/** |
||||||
|
* 请求查询交易模型 |
||||||
|
* @className: TradePreorderModel |
||||||
|
* @author: HuRui |
||||||
|
* @date: 2023/5/23 |
||||||
|
**/ |
||||||
|
@Data |
||||||
|
public class RequestQueryTradeModel { |
||||||
|
|
||||||
|
/** |
||||||
|
* 商户号 |
||||||
|
*/ |
||||||
|
@NotBlank(message = "商户号必填项") |
||||||
|
private String merchantNo; |
||||||
|
|
||||||
|
/** |
||||||
|
* 商户交易单号 |
||||||
|
*/ |
||||||
|
@NotBlank(message = "商户交易单号必填项") |
||||||
|
@Length(min = 6, max = 50, message = "商户交易单号长度限制6至50位字符串长度") |
||||||
|
private String outTradeNo; |
||||||
|
|
||||||
|
/** |
||||||
|
* 签名参数 |
||||||
|
*/ |
||||||
|
@NotBlank(message = "签名必填项") |
||||||
|
private String sign; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,59 @@ |
|||||||
|
package com.hfkj.openapi.v1.model; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
import org.hibernate.validator.constraints.Length; |
||||||
|
|
||||||
|
import javax.validation.constraints.DecimalMax; |
||||||
|
import javax.validation.constraints.DecimalMin; |
||||||
|
import javax.validation.constraints.NotBlank; |
||||||
|
|
||||||
|
/** |
||||||
|
* 请求查询交易模型 |
||||||
|
* @className: TradePreorderModel |
||||||
|
* @author: HuRui |
||||||
|
* @date: 2023/5/23 |
||||||
|
**/ |
||||||
|
@Data |
||||||
|
public class RequestRefundTradeModel { |
||||||
|
|
||||||
|
/** |
||||||
|
* 商户号 |
||||||
|
*/ |
||||||
|
@NotBlank(message = "商户号必填项") |
||||||
|
private String merchantNo; |
||||||
|
|
||||||
|
/** |
||||||
|
* 商户交易单号 |
||||||
|
*/ |
||||||
|
@Length(min = 6, max = 50, message = "商户交易单号长度限制6至50位字符串长度") |
||||||
|
@NotBlank(message = "商户交易单号必填项") |
||||||
|
private String outTradeNo; |
||||||
|
|
||||||
|
/** |
||||||
|
* 退款单号 |
||||||
|
*/ |
||||||
|
@Length(min = 6, max = 50, message = "退款单号长度限制6至50位字符串长度") |
||||||
|
@NotBlank(message = "退款单号必填项") |
||||||
|
private String refundTradeNo; |
||||||
|
|
||||||
|
/** |
||||||
|
* 退款金额 |
||||||
|
*/ |
||||||
|
@DecimalMax(value = "99999999", message = "交易最大金额99999999元") |
||||||
|
@DecimalMin(value = "0.01", message = "交易最小金额0.01元") |
||||||
|
@NotBlank(message = "退款金额必填项") |
||||||
|
private String refundAmount; |
||||||
|
|
||||||
|
/** |
||||||
|
* 退款原因 |
||||||
|
*/ |
||||||
|
@Length(max = 30, message = "退款描述最多支持30位字符") |
||||||
|
private String refundReason; |
||||||
|
|
||||||
|
/** |
||||||
|
* 签名参数 |
||||||
|
*/ |
||||||
|
@NotBlank(message = "签名必填项") |
||||||
|
private String sign; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,97 @@ |
|||||||
|
package com.hfkj.openapi.v1.model; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
import org.hibernate.validator.constraints.Length; |
||||||
|
import org.hibernate.validator.constraints.Range; |
||||||
|
|
||||||
|
import javax.validation.constraints.*; |
||||||
|
import java.math.BigDecimal; |
||||||
|
|
||||||
|
/** |
||||||
|
* 请求交易聚合主扫模型 |
||||||
|
* @className: TradePreorderModel |
||||||
|
* @author: HuRui |
||||||
|
* @date: 2023/5/23 |
||||||
|
**/ |
||||||
|
@Data |
||||||
|
public class RequestTradePreorderModel { |
||||||
|
|
||||||
|
/** |
||||||
|
* 商户号 |
||||||
|
*/ |
||||||
|
@NotBlank(message = "商户号必填项") |
||||||
|
private String merchantNo; |
||||||
|
|
||||||
|
/** |
||||||
|
* 商户交易单号 |
||||||
|
*/ |
||||||
|
@NotBlank(message = "商户交易单号必填项") |
||||||
|
@Length(min = 6, max = 50, message = "商户交易单号长度限制6至50位字符串长度") |
||||||
|
private String outTradeNo; |
||||||
|
|
||||||
|
/** |
||||||
|
* 支付方式 |
||||||
|
*/ |
||||||
|
@NotBlank(message = "支付方式必填项") |
||||||
|
private String payMode; |
||||||
|
|
||||||
|
/** |
||||||
|
* 接入方式 |
||||||
|
*/ |
||||||
|
@NotBlank(message = "接入方式必填项") |
||||||
|
private String transType; |
||||||
|
|
||||||
|
/** |
||||||
|
* 交易金额 |
||||||
|
*/ |
||||||
|
@DecimalMax(value = "99999999", message = "交易最大金额99999999元") |
||||||
|
@DecimalMin(value = "0.01", message = "交易最小金额0.01元") |
||||||
|
@NotBlank(message = "交易金额必填项") |
||||||
|
private String totalAmount; |
||||||
|
|
||||||
|
/** |
||||||
|
* 订单标题 |
||||||
|
*/ |
||||||
|
private String subject; |
||||||
|
|
||||||
|
/** |
||||||
|
* 通知地址 |
||||||
|
*/ |
||||||
|
private String notifyUrl; |
||||||
|
|
||||||
|
/** |
||||||
|
* 用户id |
||||||
|
*/ |
||||||
|
@NotBlank(message = "用户标识必填项") |
||||||
|
private String userId; |
||||||
|
|
||||||
|
/** |
||||||
|
* 子商户公众账号ID |
||||||
|
*/ |
||||||
|
private String subAppid; |
||||||
|
|
||||||
|
/** |
||||||
|
* 预下单有效时间 |
||||||
|
*/ |
||||||
|
@Range(min = 1, max = 60,message = "预下单有效期可设置在1至60分钟之内") |
||||||
|
private Integer timeoutExpress; |
||||||
|
|
||||||
|
/** |
||||||
|
* 附加域 |
||||||
|
*/ |
||||||
|
private String attach; |
||||||
|
|
||||||
|
/** |
||||||
|
* 分账 0:不分账 1:需分账 |
||||||
|
*/ |
||||||
|
@Range(min = 0, max = 1,message = "分账类型错误") |
||||||
|
@NotBlank(message = "分账类型必填项") |
||||||
|
private String profitSharing; |
||||||
|
|
||||||
|
/** |
||||||
|
* 签名参数 |
||||||
|
*/ |
||||||
|
@NotBlank(message = "签名必填项") |
||||||
|
private String sign; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,74 @@ |
|||||||
|
package com.hfkj.openapi.v1.model; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
import org.hibernate.validator.constraints.Length; |
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank; |
||||||
|
import java.math.BigDecimal; |
||||||
|
import java.util.Date; |
||||||
|
|
||||||
|
/** |
||||||
|
* 响应查询交易模型 |
||||||
|
* @className: TradePreorderModel |
||||||
|
* @author: HuRui |
||||||
|
* @date: 2023/5/23 |
||||||
|
**/ |
||||||
|
@Data |
||||||
|
public class ResponseQueryTradeModel { |
||||||
|
|
||||||
|
/** |
||||||
|
* 商户号 |
||||||
|
*/ |
||||||
|
private String merchantNo; |
||||||
|
|
||||||
|
/** |
||||||
|
* 商户交易单号 |
||||||
|
*/ |
||||||
|
private String outTradeNo; |
||||||
|
|
||||||
|
/** |
||||||
|
* 账户端交易单号 |
||||||
|
*/ |
||||||
|
private String accTradeNo; |
||||||
|
|
||||||
|
/** |
||||||
|
* 用户标识 |
||||||
|
*/ |
||||||
|
private String userId; |
||||||
|
|
||||||
|
/** |
||||||
|
* 支付方式 |
||||||
|
*/ |
||||||
|
private String payMode; |
||||||
|
|
||||||
|
/** |
||||||
|
* 交易金额 |
||||||
|
*/ |
||||||
|
private BigDecimal tradeAmount; |
||||||
|
|
||||||
|
/** |
||||||
|
* 交易实付金额 |
||||||
|
*/ |
||||||
|
private BigDecimal tradeActualAmount; |
||||||
|
|
||||||
|
/** |
||||||
|
* 交易状态 |
||||||
|
*/ |
||||||
|
private Integer status; |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建时间 |
||||||
|
*/ |
||||||
|
private Date createTime; |
||||||
|
|
||||||
|
/** |
||||||
|
* 支付时间 |
||||||
|
*/ |
||||||
|
private Date payTime; |
||||||
|
|
||||||
|
/** |
||||||
|
* 签名参数 |
||||||
|
*/ |
||||||
|
private String sign; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,60 @@ |
|||||||
|
package com.hfkj.openapi.v1.model; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
import org.hibernate.validator.constraints.Length; |
||||||
|
|
||||||
|
import javax.validation.constraints.DecimalMax; |
||||||
|
import javax.validation.constraints.DecimalMin; |
||||||
|
import javax.validation.constraints.NotBlank; |
||||||
|
import java.util.Date; |
||||||
|
|
||||||
|
/** |
||||||
|
* 请求查询交易模型 |
||||||
|
* @className: TradePreorderModel |
||||||
|
* @author: HuRui |
||||||
|
* @date: 2023/5/23 |
||||||
|
**/ |
||||||
|
@Data |
||||||
|
public class ResponseRefundTradeModel { |
||||||
|
|
||||||
|
/** |
||||||
|
* 商户号 |
||||||
|
*/ |
||||||
|
private String merchantNo; |
||||||
|
|
||||||
|
/** |
||||||
|
* 商户交易单号 |
||||||
|
*/ |
||||||
|
private String outTradeNo; |
||||||
|
|
||||||
|
/** |
||||||
|
* 支付方式 |
||||||
|
*/ |
||||||
|
private String payMode; |
||||||
|
|
||||||
|
/** |
||||||
|
* 退款单号 |
||||||
|
*/ |
||||||
|
private String refundTradeNo; |
||||||
|
|
||||||
|
/** |
||||||
|
* 退款金额 |
||||||
|
*/ |
||||||
|
private String refundAmount; |
||||||
|
|
||||||
|
/** |
||||||
|
* 退款原因 |
||||||
|
*/ |
||||||
|
private String refundReason; |
||||||
|
|
||||||
|
/** |
||||||
|
* 退款时间 |
||||||
|
*/ |
||||||
|
private Date refundTime; |
||||||
|
|
||||||
|
/** |
||||||
|
* 签名参数 |
||||||
|
*/ |
||||||
|
private String sign; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,52 @@ |
|||||||
|
package com.hfkj.openapi.v1.model; |
||||||
|
|
||||||
|
import java.util.Objects; |
||||||
|
|
||||||
|
/** |
||||||
|
* toekn 授权类型 |
||||||
|
* @className: TokenGrantType |
||||||
|
* @author: HuRui |
||||||
|
* @date: 2023/5/23 |
||||||
|
**/ |
||||||
|
public enum TokenGrantType { |
||||||
|
CLIENT_CREDENTIALS("client_credentials", "客户访问凭证"), |
||||||
|
; |
||||||
|
|
||||||
|
private String code; |
||||||
|
|
||||||
|
private String name; |
||||||
|
|
||||||
|
|
||||||
|
TokenGrantType(String code, String name) { |
||||||
|
this.code = code; |
||||||
|
this.name = name; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static TokenGrantType getDataByCode(String code) { |
||||||
|
for (TokenGrantType ele : values()) { |
||||||
|
if (Objects.equals(code,ele.getCode())) { |
||||||
|
return ele; |
||||||
|
} |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public String getCode() { |
||||||
|
return code; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCode(String code) { |
||||||
|
this.code = code; |
||||||
|
} |
||||||
|
|
||||||
|
public String getName() { |
||||||
|
return name; |
||||||
|
} |
||||||
|
|
||||||
|
public void setName(String name) { |
||||||
|
this.name = name; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
package com.hfkj.openapi.v1.model; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* @className: TokenModel |
||||||
|
* @author: HuRui |
||||||
|
* @date: 2023/5/23 |
||||||
|
**/ |
||||||
|
@Data |
||||||
|
public class TokenModel { |
||||||
|
|
||||||
|
/** |
||||||
|
* 授权类型 |
||||||
|
*/ |
||||||
|
private String grantType; |
||||||
|
|
||||||
|
/** |
||||||
|
* token |
||||||
|
*/ |
||||||
|
private String token; |
||||||
|
|
||||||
|
/** |
||||||
|
* 有效期 |
||||||
|
*/ |
||||||
|
private Long expiresTime; |
||||||
|
|
||||||
|
public TokenModel(TokenGrantType grantType, String token, Long expiresTime) { |
||||||
|
this.grantType = grantType.getCode(); |
||||||
|
this.token = token; |
||||||
|
this.expiresTime = expiresTime; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} |
@ -1,15 +0,0 @@ |
|||||||
package com.hfkj.openapi.v1.model; |
|
||||||
|
|
||||||
import lombok.Data; |
|
||||||
|
|
||||||
/** |
|
||||||
* 交易聚合主扫模型 |
|
||||||
* @className: TradePreorderModel |
|
||||||
* @author: HuRui |
|
||||||
* @date: 2023/5/23 |
|
||||||
**/ |
|
||||||
@Data |
|
||||||
public class TradePreorderModel { |
|
||||||
|
|
||||||
|
|
||||||
} |
|
@ -0,0 +1,25 @@ |
|||||||
|
package com.hfkj.openapi.v1.service; |
||||||
|
|
||||||
|
import com.hfkj.openapi.v1.model.TokenModel; |
||||||
|
|
||||||
|
/** |
||||||
|
* @className: AuthTokenService |
||||||
|
* @author: HuRui |
||||||
|
* @date: 2023/5/23 |
||||||
|
**/ |
||||||
|
public interface AuthTokenService { |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建token |
||||||
|
* @param merNo |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
TokenModel createToken(String merNo); |
||||||
|
|
||||||
|
/** |
||||||
|
* 刷新token |
||||||
|
* @param merNo |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
TokenModel refresh(String merNo); |
||||||
|
} |
@ -0,0 +1,43 @@ |
|||||||
|
package com.hfkj.openapi.v1.service; |
||||||
|
|
||||||
|
import com.hfkj.entity.BsTradeOrder; |
||||||
|
import com.hfkj.entity.BsTradeOrderRefund; |
||||||
|
import com.hfkj.openapi.v1.model.RequestRefundTradeModel; |
||||||
|
import com.hfkj.openapi.v1.model.ResponseRefundTradeModel; |
||||||
|
|
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* @className: TradeOrder |
||||||
|
* @author: HuRui |
||||||
|
* @date: 2023/5/24 |
||||||
|
**/ |
||||||
|
public interface OpenApiTradeOrderService { |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建订单 |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
Map<String, Object> createOrder(BsTradeOrder tradeOrder) throws Exception; |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据交易流水查询订单 |
||||||
|
* @param outTradeNo |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
BsTradeOrder getOrderByOutTradeNo(String outTradeNo); |
||||||
|
|
||||||
|
/** |
||||||
|
* 退款接口 |
||||||
|
* @param refundTrade |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
ResponseRefundTradeModel refund(RequestRefundTradeModel refundTrade); |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据退款单号查询退款信息 |
||||||
|
* @param refundNo |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
BsTradeOrderRefund getRefundByNo(String refundNo); |
||||||
|
} |
@ -0,0 +1,49 @@ |
|||||||
|
package com.hfkj.openapi.v1.service.impl; |
||||||
|
|
||||||
|
import com.hfkj.common.exception.ErrorCode; |
||||||
|
import com.hfkj.common.exception.ErrorHelp; |
||||||
|
import com.hfkj.common.exception.SysCode; |
||||||
|
import com.hfkj.common.utils.GenerateUtil; |
||||||
|
import com.hfkj.common.utils.RedisUtil; |
||||||
|
import com.hfkj.openapi.v1.model.TokenGrantType; |
||||||
|
import com.hfkj.openapi.v1.model.TokenModel; |
||||||
|
import com.hfkj.openapi.v1.service.AuthTokenService; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
|
||||||
|
import javax.annotation.Resource; |
||||||
|
|
||||||
|
/** |
||||||
|
* @className: AuthTokenServiceImpl |
||||||
|
* @author: HuRui |
||||||
|
* @date: 2023/5/23 |
||||||
|
**/ |
||||||
|
@Service("authTokenService") |
||||||
|
public class AuthTokenServiceImpl implements AuthTokenService { |
||||||
|
|
||||||
|
public static String OPEN_API_TOKEN = "_OPEN_API_TOKEN"; |
||||||
|
|
||||||
|
private static Long expiresTime = 7200L; |
||||||
|
|
||||||
|
@Resource |
||||||
|
private RedisUtil redisUtil; |
||||||
|
|
||||||
|
@Override |
||||||
|
public TokenModel createToken(String merNo) { |
||||||
|
// 生成64位字符token;
|
||||||
|
String token = GenerateUtil.generateRandomString(64); |
||||||
|
redisUtil.set(merNo+OPEN_API_TOKEN, token, 7200); |
||||||
|
|
||||||
|
|
||||||
|
return new TokenModel(TokenGrantType.CLIENT_CREDENTIALS, token, expiresTime); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public TokenModel refresh(String merNo) { |
||||||
|
Object token = redisUtil.get(merNo+OPEN_API_TOKEN); |
||||||
|
if (token == null) { |
||||||
|
throw ErrorHelp.genException(SysCode.OpenApi, ErrorCode.OPEN_API_TOKEN_ERR, ""); |
||||||
|
} |
||||||
|
redisUtil.set(merNo+OPEN_API_TOKEN, token.toString(), 7200); |
||||||
|
return new TokenModel(TokenGrantType.CLIENT_CREDENTIALS, token.toString(), expiresTime); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,97 @@ |
|||||||
|
package com.hfkj.openapi.v1.service.impl; |
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject; |
||||||
|
import com.hfkj.channel.lakala.LaKaLaTradeService; |
||||||
|
import com.hfkj.entity.BsTradeOrder; |
||||||
|
import com.hfkj.entity.BsTradeOrderExample; |
||||||
|
import com.hfkj.entity.BsTradeOrderRefund; |
||||||
|
import com.hfkj.openapi.v1.model.RequestRefundTradeModel; |
||||||
|
import com.hfkj.openapi.v1.model.ResponseRefundTradeModel; |
||||||
|
import com.hfkj.openapi.v1.service.OpenApiTradeOrderService; |
||||||
|
import com.hfkj.openapi.v1.utils.SignatureUtil; |
||||||
|
import com.hfkj.service.BsMerKeyService; |
||||||
|
import com.hfkj.service.BsTradeOrderRefundService; |
||||||
|
import com.hfkj.service.BsTradeOrderService; |
||||||
|
import com.hfkj.sysenum.TradeOrderRefundStatusEnum; |
||||||
|
import org.apache.commons.collections4.MapUtils; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
import org.springframework.transaction.annotation.Propagation; |
||||||
|
import org.springframework.transaction.annotation.Transactional; |
||||||
|
|
||||||
|
import javax.annotation.Resource; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* @className: TradeOrderServiceImpl |
||||||
|
* @author: HuRui |
||||||
|
* @date: 2023/5/24 |
||||||
|
**/ |
||||||
|
@Service("openApiTradeOrderService") |
||||||
|
public class OpenApiTradeOrderServiceImpl implements OpenApiTradeOrderService { |
||||||
|
|
||||||
|
@Resource |
||||||
|
private BsTradeOrderService bsTradeOrderService; |
||||||
|
|
||||||
|
@Resource |
||||||
|
private BsTradeOrderRefundService bsTradeOrderRefundService; |
||||||
|
|
||||||
|
@Resource |
||||||
|
private BsMerKeyService merKeyService; |
||||||
|
|
||||||
|
@Resource |
||||||
|
private LaKaLaTradeService laKaLaTradeService; |
||||||
|
|
||||||
|
@Override |
||||||
|
@Transactional(propagation= Propagation.REQUIRES_NEW) |
||||||
|
public Map<String, Object> createOrder(BsTradeOrder tradeOrder) throws Exception { |
||||||
|
bsTradeOrderService.editOrder(tradeOrder); |
||||||
|
|
||||||
|
Map<String, Object> preorder = laKaLaTradeService.preorder(tradeOrder.getOutTradeNo()); |
||||||
|
preorder.put("merchantNo", tradeOrder.getMerNo()); |
||||||
|
preorder.put("outTradeNo", tradeOrder.getOutTradeNo()); |
||||||
|
|
||||||
|
// 取出支付参数
|
||||||
|
JSONObject payParam = JSONObject.parseObject(MapUtils.getString(preorder, "payParam")); |
||||||
|
preorder.put("payParam", payParam.getJSONObject("acc_resp_fields")); |
||||||
|
preorder.remove("platformType"); |
||||||
|
preorder.remove("order"); |
||||||
|
preorder.put("sign", SignatureUtil.createSign(preorder, merKeyService.getKeyByMerNo(tradeOrder.getMerNo()))); |
||||||
|
return preorder; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public BsTradeOrder getOrderByOutTradeNo(String outTradeNo) { |
||||||
|
return bsTradeOrderService.getOrderByOutTradeNo(outTradeNo); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ResponseRefundTradeModel refund(RequestRefundTradeModel refundTrade) { |
||||||
|
|
||||||
|
|
||||||
|
/* BsTradeOrderRefund orderRefund = new BsTradeOrderRefund(); |
||||||
|
orderRefund.setTradeOrderId(order.getId()); |
||||||
|
orderRefund.setOutTradeNo(order.getOutTradeNo()); |
||||||
|
orderRefund.setTradeOrderId(order.getId()); |
||||||
|
orderRefund.setAgentId(order.getAgentId()); |
||||||
|
orderRefund.setSalesmanId(order.getSalesmanId()); |
||||||
|
orderRefund.setMerId(order.getMerId()); |
||||||
|
orderRefund.setStoreId(order.getStoreId()); |
||||||
|
orderRefund.setPlatformType(order.getPlatformType()); |
||||||
|
orderRefund.setRefundNo(refundNo); |
||||||
|
orderRefund.setTotalAmount(order.getTradeAmount()); |
||||||
|
orderRefund.setRefundAmount(body.getBigDecimal("refundAmount")); |
||||||
|
orderRefund.setRefundReason(body.getString("refundReason")); |
||||||
|
orderRefund.setStatus(TradeOrderRefundStatusEnum.status1.getNumber()); |
||||||
|
orderRefund.setOperatorId(userInfoModel.getSecUser().getId()); |
||||||
|
orderRefund.setOperatorName(userInfoModel.getSecUser().getUserName()); |
||||||
|
|
||||||
|
bsTradeOrderRefundService.tradeOrderRefund()*/ |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public BsTradeOrderRefund getRefundByNo(String refundNo) { |
||||||
|
return bsTradeOrderRefundService.getRefundByRefundNo(refundNo); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -1,31 +0,0 @@ |
|||||||
package com.hfkj.openapi.v1.utils; |
|
||||||
|
|
||||||
import javax.xml.bind.annotation.adapters.HexBinaryAdapter; |
|
||||||
import java.security.MessageDigest; |
|
||||||
|
|
||||||
/** |
|
||||||
* MD5 加密 |
|
||||||
*/ |
|
||||||
public class MD5Util { |
|
||||||
|
|
||||||
/** |
|
||||||
* 加密 |
|
||||||
* @param data |
|
||||||
* @return |
|
||||||
* @throws Exception |
|
||||||
*/ |
|
||||||
public static String encode(byte[] data) throws Exception { |
|
||||||
// 初始化MessageDigest
|
|
||||||
MessageDigest md = MessageDigest.getInstance("MD5"); |
|
||||||
// 执行摘要信息
|
|
||||||
byte[] digest = md.digest(data); |
|
||||||
// 将摘要信息转换为32位的十六进制字符串
|
|
||||||
return new String(new HexBinaryAdapter().marshal(digest)); |
|
||||||
} |
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception { |
|
||||||
String str = "123456"; |
|
||||||
System.out.println(MD5Util.encode(str.getBytes("UTF-8"))); |
|
||||||
//String ee = "29AD0E3FD3DB681FB9F8091C756313F7";
|
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,89 @@ |
|||||||
|
package com.hfkj.openapi.v1.utils; |
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject; |
||||||
|
import org.apache.commons.lang3.StringUtils; |
||||||
|
|
||||||
|
import javax.xml.bind.annotation.adapters.HexBinaryAdapter; |
||||||
|
import java.security.MessageDigest; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.Set; |
||||||
|
|
||||||
|
/** |
||||||
|
* 签名工具类 |
||||||
|
*/ |
||||||
|
public class SignatureUtil { |
||||||
|
|
||||||
|
/** |
||||||
|
* 参数签名 |
||||||
|
* @param param 参数 |
||||||
|
* @param key 秘钥 |
||||||
|
* @return |
||||||
|
* @throws Exception |
||||||
|
*/ |
||||||
|
public static String createSign(Object param, String key) throws Exception { |
||||||
|
Map map = JSONObject.parseObject(JSONObject.toJSONString(param), Map.class); |
||||||
|
return md5Encode(paramSort(map, key).getBytes()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 验证签名 |
||||||
|
* @param checkSign 需验证的签名字符串 |
||||||
|
* @param param 参数 |
||||||
|
* @param key 秘钥 |
||||||
|
* @return |
||||||
|
* @throws Exception |
||||||
|
*/ |
||||||
|
public static Boolean checkSign(String checkSign,Object param, String key) throws Exception { |
||||||
|
Map map = JSONObject.parseObject(JSONObject.toJSONString(param), Map.class); |
||||||
|
// 去除签名
|
||||||
|
map.remove("sign"); |
||||||
|
if (checkSign.equals(md5Encode(paramSort(map, key).getBytes()))) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 参数排序 |
||||||
|
* @param param |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static String paramSort(final Map<String, Object> param, String key) { |
||||||
|
Set<String> keySet = param.keySet(); |
||||||
|
String[] keyArray = keySet.toArray(new String[keySet.size()]); |
||||||
|
StringBuilder sb = new StringBuilder(); |
||||||
|
for (String k : keyArray) { |
||||||
|
if (StringUtils.isBlank(sb.toString())) { |
||||||
|
sb.append(k).append("=").append(param.get(k)); |
||||||
|
} else { |
||||||
|
sb.append("&").append(k).append("=").append(param.get(k)); |
||||||
|
} |
||||||
|
} |
||||||
|
sb.append("&key=").append(key); |
||||||
|
return sb.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* MD5加密 |
||||||
|
* @param data |
||||||
|
* @return |
||||||
|
* @throws Exception |
||||||
|
*/ |
||||||
|
public static String md5Encode(byte[] data) throws Exception { |
||||||
|
// 初始化MessageDigest
|
||||||
|
MessageDigest md = MessageDigest.getInstance("MD5"); |
||||||
|
// 执行摘要信息
|
||||||
|
byte[] digest = md.digest(data); |
||||||
|
// 将摘要信息转换为32位的十六进制字符串
|
||||||
|
return new String(new HexBinaryAdapter().marshal(digest)); |
||||||
|
} |
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception { |
||||||
|
String paramStr = "{\n" + |
||||||
|
" \"merchantNo\": \"2023030909414450700\",\n" + |
||||||
|
" \"outTradeNo\": \"ZF1130202305051459532538978807\"" + |
||||||
|
"}"; |
||||||
|
String sign = createSign(JSONObject.parseObject(paramStr), "LRL9uflTQGeyp9yVWDD6orhBp2VhYDvP"); |
||||||
|
System.out.println(sign); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,24 @@ |
|||||||
|
package com.hfkj.service; |
||||||
|
|
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* @className: BsMerKeyService |
||||||
|
* @author: HuRui |
||||||
|
* @date: 2023/5/23 |
||||||
|
**/ |
||||||
|
public interface BsMerKeyService { |
||||||
|
|
||||||
|
/** |
||||||
|
* 查询详情 |
||||||
|
* @param merNo |
||||||
|
*/ |
||||||
|
Map<String,Object> getDetailByMerNo(String merNo); |
||||||
|
|
||||||
|
/** |
||||||
|
* 查询key |
||||||
|
* @param merNo |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
String getKeyByMerNo(String merNo); |
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
package com.hfkj.service.impl; |
||||||
|
|
||||||
|
import com.hfkj.common.exception.ErrorCode; |
||||||
|
import com.hfkj.common.exception.ErrorHelp; |
||||||
|
import com.hfkj.common.exception.SysCode; |
||||||
|
import com.hfkj.dao.BsMerKeyMapper; |
||||||
|
import com.hfkj.service.BsMerKeyService; |
||||||
|
import org.apache.commons.collections4.MapUtils; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
|
||||||
|
import javax.annotation.Resource; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* @className: BsMerKeyServiceImpl |
||||||
|
* @author: HuRui |
||||||
|
* @date: 2023/5/23 |
||||||
|
**/ |
||||||
|
@Service("merKeyService") |
||||||
|
public class BsMerKeyServiceImpl implements BsMerKeyService { |
||||||
|
|
||||||
|
@Resource |
||||||
|
private BsMerKeyMapper merKeyMapper; |
||||||
|
|
||||||
|
@Override |
||||||
|
public Map<String, Object> getDetailByMerNo(String merNo) { |
||||||
|
Map<String, Object> key = merKeyMapper.queryKeyByMerNo(merNo); |
||||||
|
if (key == null) { |
||||||
|
throw ErrorHelp.genException(SysCode.OpenApi, ErrorCode.OPEN_API_KEY_ERR, ""); |
||||||
|
} |
||||||
|
return key; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getKeyByMerNo(String merNo) { |
||||||
|
return MapUtils.getString(getDetailByMerNo(merNo), "merKey"); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,49 @@ |
|||||||
|
package com.hfkj.sysenum; |
||||||
|
|
||||||
|
import java.util.Objects; |
||||||
|
|
||||||
|
/** |
||||||
|
* 交易订单创建类型 |
||||||
|
* @className: TradeOrderCreateType |
||||||
|
* @author: HuRui |
||||||
|
* @date: 2023/5/24 |
||||||
|
**/ |
||||||
|
public enum TradeOrderCreateTypeEnum { |
||||||
|
type1(1, "扫一扫"), |
||||||
|
type2(2, "被扫"), |
||||||
|
type3(3, "API"); |
||||||
|
|
||||||
|
private Integer code; |
||||||
|
|
||||||
|
private String name; |
||||||
|
|
||||||
|
TradeOrderCreateTypeEnum(Integer code, String name) { |
||||||
|
this.code = code; |
||||||
|
this.name = name; |
||||||
|
} |
||||||
|
|
||||||
|
public static TradeOrderCreateTypeEnum getNameByCode(Integer code) { |
||||||
|
for (TradeOrderCreateTypeEnum ele : values()) { |
||||||
|
if (Objects.equals(code,ele.getCode())) { |
||||||
|
return ele; |
||||||
|
} |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public Integer getCode() { |
||||||
|
return code; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCode(Integer code) { |
||||||
|
this.code = code; |
||||||
|
} |
||||||
|
|
||||||
|
public String getName() { |
||||||
|
return name; |
||||||
|
} |
||||||
|
|
||||||
|
public void setName(String name) { |
||||||
|
this.name = name; |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue