Commit c03f74ef authored by Administrator's avatar Administrator

创建项目

parent 01085b7a
...@@ -24,7 +24,9 @@ public class Constant { ...@@ -24,7 +24,9 @@ public class Constant {
@Deprecated @Deprecated
public static final Duration PAY_DUE_TIME = Duration.ofMinutes(30); public static final Duration PAY_DUE_TIME = Duration.ofMinutes(30);
public final static String DICT_TYPE_PAY= "PAY"; public final static String DICT_TYPE_PAY = "PAY";
public final static String DICT_CODE_WXP= "WXP"; public final static String DICT_CODE_WXP = "WXP";
public final static String DICT_TYPE_WXP_CALLBACK_URL = "WXP_CALLBACK_URL"; public final static String DICT_TYPE_WXP_CALLBACK_URL = "WXP_CALLBACK_URL";
public final static String HTTP_OK_CODE = "SUCC";
} }
...@@ -14,5 +14,4 @@ public interface Acquirer { ...@@ -14,5 +14,4 @@ public interface Acquirer {
ChannelResponse checkPay(CheckPayRequestData request) throws Exception; ChannelResponse checkPay(CheckPayRequestData request) throws Exception;
ChannelResponse checkRefund(CheckRefundRequestData request) throws Exception; ChannelResponse checkRefund(CheckRefundRequestData request) throws Exception;
ChannelResponse close(CloseRequestData request) throws Exception; ChannelResponse close(CloseRequestData request) throws Exception;
void callback(CallbackRequestData request) throws Exception;
} }
...@@ -5,6 +5,7 @@ package cn.quant.baa.pay.acquirer; ...@@ -5,6 +5,7 @@ package cn.quant.baa.pay.acquirer;
*/ */
public abstract class AcquirerConstant { public abstract class AcquirerConstant {
public final static String HTTP_STATUS_TYPE= "HTTP_STAT"; public final static String HTTP_STATUS_TYPE= "HTTP_STAT";
public final static String COMMON_ERROR_CODE = "ERROR"; public final static String COMMON_ERROR_CODE = "ERROR";
public final static String COMMON_ERROR_MESSAGE = "ERROR"; public final static String COMMON_ERROR_MESSAGE = "ERROR";
public final static String EXECUTE_PAY = "Pay"; public final static String EXECUTE_PAY = "Pay";
......
...@@ -17,7 +17,7 @@ public class AcquirerProperties implements Serializable{ ...@@ -17,7 +17,7 @@ public class AcquirerProperties implements Serializable{
private Long mchChanId; private Long mchChanId;
//account //Account
private String payChanCode; private String payChanCode;
private String payAcctId; private String payAcctId;
...@@ -46,10 +46,7 @@ public class AcquirerProperties implements Serializable{ ...@@ -46,10 +46,7 @@ public class AcquirerProperties implements Serializable{
private String payRootCertKey; private String payRootCertKey;
private String productCode;
//feature //feature
private AccessCode accessCode; private AccessCode accessCode;
private AccessType accessType; private AccessType accessType;
private String accessMethod; private String accessMethod;
...@@ -58,9 +55,9 @@ public class AcquirerProperties implements Serializable{ ...@@ -58,9 +55,9 @@ public class AcquirerProperties implements Serializable{
private String refundAccess; private String refundAccess;
private String checkAccess; private String checkAccess;
private String descText; private String descText;
private String productCode;
//APP //APP
private String institutionId; private String institutionId;
private String productId; private String productId;
......
...@@ -54,7 +54,7 @@ public class MerchantAcquirer implements Acquirer { ...@@ -54,7 +54,7 @@ public class MerchantAcquirer implements Acquirer {
return this; return this;
} }
public void register(Acquirer acquirer) { public final void register(Acquirer acquirer) {
acquirers.put(acquirer.code(), acquirer); acquirers.put(acquirer.code(), acquirer);
} }
...@@ -89,9 +89,4 @@ public class MerchantAcquirer implements Acquirer { ...@@ -89,9 +89,4 @@ public class MerchantAcquirer implements Acquirer {
public ChannelResponse close(CloseRequestData request) throws Exception { public ChannelResponse close(CloseRequestData request) throws Exception {
return acquirers.get(request.getChanId()).close(request); return acquirers.get(request.getChanId()).close(request);
} }
@Override
public void callback(CallbackRequestData request) throws Exception {
acquirers.get(request.getChanId()).callback(request);
}
} }
...@@ -50,24 +50,24 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer { ...@@ -50,24 +50,24 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer {
/** /**
* 微信签名格式定义 * 微信签名格式定义
*/ */
String TOKEN_PATTERN = "mchid=\"%s\",nonce_str=\"%s\",timestamp=\"%d\",serial_no=\"%s\",signature=\"%s\""; private static final String TOKEN_PATTERN = "mchid=\"%s\",nonce_str=\"%s\",timestamp=\"%d\",serial_no=\"%s\",signature=\"%s\"";
/** /**
* 微信签名前缀 * 微信签名前缀
*/ */
String SCHEMA = "WECHATPAY2-SHA256-RSA2048 "; private static final String SCHEMA = "WECHATPAY2-SHA256-RSA2048 ";
/** /**
* 商户私钥 * 商户私钥
*/ */
PrivateKey privateKey; private PrivateKey privateKey;
/** /**
* 平台证书 * 平台证书
*/ */
X509Certificate payCerKey; private X509Certificate payCerKey;
ObjectMapper objectMapper = new ObjectMapper(); private static final ObjectMapper objectMapper = new ObjectMapper();
/** /**
* 支付初始化 * 支付初始化
...@@ -114,7 +114,8 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer { ...@@ -114,7 +114,8 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer {
.put("appid", properties.getPayAppId()) .put("appid", properties.getPayAppId())
.put("attach", request.getAttach()) .put("attach", request.getAttach())
.put("description", request.getSubject()) .put("description", request.getSubject())
.put("notify_url", callback.getValue() + request.getChanId()) .put("notify_url", String.join("/", callback.getValue(), Long.toHexString(Long.valueOf(request.getChanId()))
, Long.toHexString(transaction.getAccountId()), transaction.getExternalOrderNo()))
.put("out_trade_no", transaction.getTransactionId().toString()); .put("out_trade_no", transaction.getTransactionId().toString());
bodyNode.putObject("amount") bodyNode.putObject("amount")
.put("total", amount); .put("total", amount);
...@@ -268,7 +269,7 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer { ...@@ -268,7 +269,7 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer {
if (response.getSuccess()) { if (response.getSuccess()) {
} else { } else {
DictionaryItemDTO itemDTO = DictionaryViewer.get(HTTP_STATUS_TYPE, response.getCode()); DictionaryItemDTO itemDTO = DictionaryViewer.get("WXP_HTTP_STAT", response.getCode());
if (itemDTO == null) { if (itemDTO == null) {
response.setCode(COMMON_ERROR_CODE); response.setCode(COMMON_ERROR_CODE);
response.setMessage(COMMON_ERROR_CODE); response.setMessage(COMMON_ERROR_CODE);
......
...@@ -3,6 +3,7 @@ package cn.quant.baa.pay.context; ...@@ -3,6 +3,7 @@ package cn.quant.baa.pay.context;
import cn.quant.baa.pay.component.Sequencer; import cn.quant.baa.pay.component.Sequencer;
import cn.quant.baa.pay.jpa.entity.AccountEntity; import cn.quant.baa.pay.jpa.entity.AccountEntity;
import cn.quant.baa.pay.model.BusinessRequest; import cn.quant.baa.pay.model.BusinessRequest;
import cn.quant.spring.NullException;
import cn.quant.spring.context.BusinessSession; import cn.quant.spring.context.BusinessSession;
import cn.quant.spring.context.ServerApplicationContext; import cn.quant.spring.context.ServerApplicationContext;
import cn.quant.spring.data.jpa.entity.OptimisticEntity; import cn.quant.spring.data.jpa.entity.OptimisticEntity;
...@@ -126,7 +127,11 @@ public class TransactionSession extends BusinessSession { ...@@ -126,7 +127,11 @@ public class TransactionSession extends BusinessSession {
} }
public JpaRepository getRepository(Class cls) { public JpaRepository getRepository(Class cls) {
return repositoryProxy.getRepository(cls); JpaRepository repository = repositoryProxy.getRepository(cls);
if (repository == null) {
throw new NullException("Repository not found : {}", cls);
}
return repository;
} }
public <T> T findOne(Class<T> cls, Object key) { public <T> T findOne(Class<T> cls, Object key) {
......
package cn.quant.baa.pay.jpa.repository; package cn.quant.baa.pay.jpa.repository;
import cn.quant.baa.pay.dict.StatusCode;
import cn.quant.baa.pay.jpa.entity.BatchCycleTriggerEntity; import cn.quant.baa.pay.jpa.entity.BatchCycleTriggerEntity;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
/** /**
...@@ -10,4 +13,6 @@ import org.springframework.stereotype.Repository; ...@@ -10,4 +13,6 @@ import org.springframework.stereotype.Repository;
@Repository @Repository
public interface BatchCycleTriggerRepository extends JpaRepository<BatchCycleTriggerEntity, Long> { public interface BatchCycleTriggerRepository extends JpaRepository<BatchCycleTriggerEntity, Long> {
@Query("SELECT trigger FROM BatchCycleTriggerEntity trigger WHERE trigger.targetId=:targetId AND trigger.entityCode=:entityCode")
BatchCycleTriggerEntity findOne(@Param("targetId") Long targetId, @Param("entityCode") String entityCode);
} }
package cn.quant.baa.pay.model.web; package cn.quant.baa.pay.model.web;
import java.time.LocalDateTime;
/** /**
* Created by Administrator on 2021/9/27 0027. * Created by Administrator on 2021/9/27 0027.
*/ */
public class CallbackRequestData { public class CallbackRequestData {
private String chanId; private Long chanId;
private Long accountId;
private String orderNo;
private LocalDateTime successTime;
private String chanTransactionId;
public String getChanId() { private String tradeState;
private String tradeStateDesc;
private String checkCode;
public Long getChanId() {
return chanId; return chanId;
} }
public void setChanId(String chanId) { public void setChanId(Long chanId) {
this.chanId = chanId; this.chanId = chanId;
} }
public Long getAccountId() {
return accountId;
}
public void setAccountId(Long accountId) {
this.accountId = accountId;
}
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
public LocalDateTime getSuccessTime() {
return successTime;
}
public void setSuccessTime(LocalDateTime successTime) {
this.successTime = successTime;
}
public String getChanTransactionId() {
return chanTransactionId;
}
public void setChanTransactionId(String chanTransactionId) {
this.chanTransactionId = chanTransactionId;
}
public String getTradeState() {
return tradeState;
}
public void setTradeState(String tradeState) {
this.tradeState = tradeState;
}
public String getTradeStateDesc() {
return tradeStateDesc;
}
public void setTradeStateDesc(String tradeStateDesc) {
this.tradeStateDesc = tradeStateDesc;
}
public String getCheckCode() {
return checkCode;
}
public void setCheckCode(String checkCode) {
this.checkCode = checkCode;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("CallbackRequestData{");
sb.append("chanId=").append(chanId);
sb.append(", accountId=").append(accountId);
sb.append(", orderNo='").append(orderNo).append('\'');
sb.append(", successTime=").append(successTime);
sb.append(", chanTransactionId='").append(chanTransactionId).append('\'');
sb.append(", tradeState='").append(tradeState).append('\'');
sb.append(", tradeStateDesc='").append(tradeStateDesc).append('\'');
sb.append(", checkCode='").append(checkCode).append('\'');
sb.append('}');
return sb.toString();
}
} }
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
</encoder> </encoder>
</appender> </appender>
<logger name="cn.quant.baa.pay" level="DEBUG"/> <logger name="cn.quant.baa.pay" level="INFO"/>
<logger name="javax.activation" level="ERROR"/> <logger name="javax.activation" level="ERROR"/>
<logger name="org.quartz.core" level="ERROR"/> <logger name="org.quartz.core" level="ERROR"/>
<logger name="org.quartz.simpl" level="ERROR"/> <logger name="org.quartz.simpl" level="ERROR"/>
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
<logger name="org.hibernate.engine.QueryParameters" level="ERROR"/> <logger name="org.hibernate.engine.QueryParameters" level="ERROR"/>
<logger name="org.hibernate.SQL" level="ERROR" /> <logger name="org.hibernate.SQL" level="ERROR" />
<root level="DEBUG"> <root level="INFO">
<appender-ref ref="STDOUT"/> <appender-ref ref="STDOUT"/>
<appender-ref ref="ROLLINGFILE"/> <appender-ref ref="ROLLINGFILE"/>
</root> </root>
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
</encoder> </encoder>
</appender> </appender>
<logger name="cn.quant.baa.pay" level="DEBUG"/> <logger name="cn.quant.baa.pay" level="INFO"/>
<logger name="javax.activation" level="ERROR"/> <logger name="javax.activation" level="ERROR"/>
<logger name="org.quartz.core" level="ERROR"/> <logger name="org.quartz.core" level="ERROR"/>
<logger name="org.quartz.simpl" level="ERROR"/> <logger name="org.quartz.simpl" level="ERROR"/>
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
<logger name="org.hibernate.engine.QueryParameters" level="ERROR"/> <logger name="org.hibernate.engine.QueryParameters" level="ERROR"/>
<logger name="org.hibernate.SQL" level="ERROR" /> <logger name="org.hibernate.SQL" level="ERROR" />
<root level="DEBUG"> <root level="INFO">
<appender-ref ref="STDOUT"/> <appender-ref ref="STDOUT"/>
<appender-ref ref="ROLLINGFILE"/> <appender-ref ref="ROLLINGFILE"/>
</root> </root>
......
...@@ -5,53 +5,78 @@ import cn.quant.baa.pay.acquirer.AcquirerPropertiesSource; ...@@ -5,53 +5,78 @@ import cn.quant.baa.pay.acquirer.AcquirerPropertiesSource;
import cn.quant.baa.pay.annotation.BusinessMapping; import cn.quant.baa.pay.annotation.BusinessMapping;
import cn.quant.baa.pay.config.DictionaryViewer; import cn.quant.baa.pay.config.DictionaryViewer;
import cn.quant.baa.pay.model.dto.DictionaryItemDTO; import cn.quant.baa.pay.model.dto.DictionaryItemDTO;
import cn.quant.baa.pay.model.web.CallbackRequestData;
import cn.quant.baa.pay.service.CallbackService;
import cn.quant.spring.ProfileException; import cn.quant.spring.ProfileException;
import cn.quant.spring.util.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.Map; import java.util.Map;
import static cn.quant.baa.pay.Constant.DICT_CODE_WXP; import static cn.quant.baa.pay.Constant.*;
import static cn.quant.baa.pay.Constant.DICT_TYPE_PAY;
/** /**
* Created by Administrator on 2021/9/26 0026. * Created by Administrator on 2021/9/26 0026.
*/ */
@RestController @RestController
@RequestMapping("/transaction") @RequestMapping("/callback")
public class TransactionController extends BusinessController { public class CallbackController extends BusinessController {
private static final Logger logger = LoggerFactory.getLogger(TransactionController.class); private static final Logger logger = LoggerFactory.getLogger(TransactionController.class);
@Autowired @Autowired
private AcquirerPropertiesSource acquirerPropertiesSource; private AcquirerPropertiesSource acquirerPropertiesSource;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Autowired
private CallbackService callbackService;
@ResponseBody @ResponseBody
@BusinessMapping @BusinessMapping
@PostMapping("/pay/callback/wx/{chanId}") @PostMapping("/pay/wx/{chanId}/{acctId}/{orderNo}")
public ResponseEntity pay(@PathVariable("chanId") String chanId, @RequestBody Map request) throws Exception { public ResponseEntity pay(@PathVariable("chanId") String chanId, @PathVariable("acctId") String acctId
, @PathVariable("orderNo") String orderNo
, @RequestBody Map request) throws Exception {
logger.info(request.toString()); logger.info(request.toString());
Long channelId = Long.parseLong(chanId, 16);
Long accountId = Long.parseLong(acctId, 16);
DictionaryItemDTO dict = DictionaryViewer.get(DICT_TYPE_PAY, DICT_CODE_WXP); DictionaryItemDTO dict = DictionaryViewer.get(DICT_TYPE_PAY, DICT_CODE_WXP);
if (dict == null) { if (dict == null) {
throw new ProfileException("Configuration not found in dictionary : {}; {}; {}; {};", DICT_TYPE_PAY, DICT_CODE_WXP, chanId, request); throw new ProfileException("Configuration not found in dictionary : {}; {}; {}; {};", DICT_TYPE_PAY, DICT_CODE_WXP, channelId, request);
} }
AcquirerProperties properties = acquirerPropertiesSource.get(Long.valueOf(chanId)); AcquirerProperties properties = acquirerPropertiesSource.get(channelId);
if (properties == null || !dict.getCode().equals(properties.getPayChanCode())) { if (properties == null || !dict.getCode().equals(properties.getPayChanCode())) {
throw new ProfileException("Acquirer not found : {}; {}; {}; {};", DICT_TYPE_PAY, DICT_CODE_WXP, chanId, request); throw new ProfileException("Acquirer not found : {}; {}; {}; {};", DICT_TYPE_PAY, DICT_CODE_WXP, channelId, request);
} }
CallbackRequestData requestData = new CallbackRequestData();
requestData.setChanId(properties.getMchChanId());
requestData.setAccountId(accountId);
requestData.setOrderNo("75774627146563586");
requestData.setChanTransactionId("1217752501201407033233368018");
requestData.setCheckCode("3ffe82f6731f6e09255bc258d1131a75");
//TODO:状态转码
requestData.setTradeState("SUCC");
requestData.setTradeStateDesc("支付成功");
requestData.setSuccessTime(LocalDateTime.now());
String redisKey = StringUtils.toDelimitedString(REDIS_NAMESPACE_PAY, properties.getInstitutionId(), properties.getProductId(), orderNo);
// CallbackRequestData requestData = new CallbackRequestData();
// requestData.setChanId(chanId);
// transactionService.callback(requestData); callbackService.callback(requestData);
return null; return null;
} }
} }
package cn.quant.baa.pay.service;
import cn.quant.baa.pay.context.TransactionSession;
import cn.quant.baa.pay.dict.StatusCode;
import cn.quant.baa.pay.jpa.entity.BatchCycleTriggerEntity;
import cn.quant.baa.pay.jpa.entity.TransactionSummaryEntity;
import cn.quant.baa.pay.jpa.repository.BatchCycleTriggerRepository;
import cn.quant.baa.pay.model.web.CallbackRequestData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
/**
* Created by Administrator on 2021/8/24 0024.
*/
@Service
public class CallbackService extends BusinessService {
private static final Logger logger = LoggerFactory.getLogger(TransactionService.class);
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void callback(CallbackRequestData request) throws Exception {
update(request);
System.currentTimeMillis();
}
@Transactional(propagation = Propagation.REQUIRED)
public void update(CallbackRequestData request) throws Exception {
TransactionSession session = TransactionSession.session();
Long orderNo = Long.valueOf(request.getOrderNo());
String checkCode = request.getCheckCode();
// session.getRepository();
TransactionSummaryEntity summaryEntity = session.findOne(TransactionSummaryEntity.class, checkCode);
if (summaryEntity == null) {
throw new Exception("ERROR");
}
BatchCycleTriggerRepository repository = (BatchCycleTriggerRepository) session.getRepository(BatchCycleTriggerEntity.class);
BatchCycleTriggerEntity triggerEntity = repository.findOne(summaryEntity.getTransactionId(), summaryEntity.getTxnType());
if (triggerEntity == null) {
throw new Exception("ERROR");
}
String tradeState = request.getTradeState();
if (StatusCode.SUCC.name().equals(tradeState)) {
} else {
}
new Integer(null);
}
}
...@@ -134,9 +134,4 @@ public class TransactionService extends BusinessService { ...@@ -134,9 +134,4 @@ public class TransactionService extends BusinessService {
return acquirer.refund(data); return acquirer.refund(data);
} }
@Transactional(propagation = Propagation.REQUIRED)
public void callback(CallbackRequestData data) throws Exception {
acquirer.callback(data);
}
} }
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment