Commit 2265a9ed authored by Administrator's avatar Administrator

创建项目

parent db9a6484
...@@ -23,4 +23,9 @@ public class Constant { ...@@ -23,4 +23,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_CODE_WXP= "WXP";
public final static String DICT_TYPE_APP_CONFIG= "APP_CONFIG";
public final static String DICT_CODE_CALLBACK_URL= "CALLBACK_URL";
} }
...@@ -9,9 +9,10 @@ import cn.quant.baa.pay.model.web.*; ...@@ -9,9 +9,10 @@ import cn.quant.baa.pay.model.web.*;
public interface Acquirer { public interface Acquirer {
Object code(); Object code();
ChannelResponse pay(PayRequestData payRequestData, TransactionSummaryEntity payHistoryEntity) throws Exception; ChannelResponse pay(PayRequestData request, TransactionSummaryEntity transaction) throws Exception;
ChannelResponse refund(RefundRequestData refundRequestData) throws Exception; ChannelResponse refund(RefundRequestData request) throws Exception;
ChannelResponse checkPay(CheckPayRequestData checkPayRequestData) throws Exception; ChannelResponse checkPay(CheckPayRequestData request) throws Exception;
ChannelResponse checkRefund(CheckRefundRequestData checkRefundRequestData) throws Exception; ChannelResponse checkRefund(CheckRefundRequestData request) throws Exception;
ChannelResponse close(CloseRequestData closeRequestData) throws Exception; ChannelResponse close(CloseRequestData request) throws Exception;
void callback(CallbackRequestData request) throws Exception;
} }
...@@ -64,9 +64,9 @@ public class MerchantAcquirer implements Acquirer { ...@@ -64,9 +64,9 @@ public class MerchantAcquirer implements Acquirer {
} }
@Override @Override
public ChannelResponse pay(PayRequestData request, TransactionSummaryEntity history) throws Exception { public ChannelResponse pay(PayRequestData request, TransactionSummaryEntity transaction) throws Exception {
ChannelResponse response = acquirers.get(request.getChanId()).pay(request, history); ChannelResponse response = acquirers.get(request.getChanId()).pay(request, transaction);
response.setOrderNo(String.valueOf(history.getTransactionId())); response.setOrderNo(String.valueOf(transaction.getTransactionId()));
return response; return response;
} }
...@@ -89,4 +89,9 @@ public class MerchantAcquirer implements Acquirer { ...@@ -89,4 +89,9 @@ 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);
}
} }
...@@ -8,6 +8,7 @@ import cn.quant.baa.pay.jpa.entity.TransactionSummaryEntity; ...@@ -8,6 +8,7 @@ import cn.quant.baa.pay.jpa.entity.TransactionSummaryEntity;
import cn.quant.baa.pay.model.dto.DictionaryItemDTO; import cn.quant.baa.pay.model.dto.DictionaryItemDTO;
import cn.quant.baa.pay.model.web.*; import cn.quant.baa.pay.model.web.*;
import cn.quant.spring.NullException; import cn.quant.spring.NullException;
import cn.quant.spring.ProfileException;
import cn.quant.spring.util.StringUtils; import cn.quant.spring.util.StringUtils;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
...@@ -35,6 +36,7 @@ import java.security.spec.X509EncodedKeySpec; ...@@ -35,6 +36,7 @@ import java.security.spec.X509EncodedKeySpec;
import java.util.Base64; import java.util.Base64;
import java.util.UUID; import java.util.UUID;
import static cn.quant.baa.pay.Constant.*;
import static cn.quant.baa.pay.acquirer.AcquirerConstant.*; import static cn.quant.baa.pay.acquirer.AcquirerConstant.*;
/** /**
...@@ -102,12 +104,18 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer { ...@@ -102,12 +104,18 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer {
public ChannelResponse pay(PayRequestData request, TransactionSummaryEntity history) throws Exception { public ChannelResponse pay(PayRequestData request, TransactionSummaryEntity history) throws Exception {
ObjectNode bodyNode = objectMapper.createObjectNode(); ObjectNode bodyNode = objectMapper.createObjectNode();
// 转换金额为分 // 转换金额为分
DictionaryItemDTO callback = DictionaryViewer.get(DICT_TYPE_APP_CONFIG, DICT_CODE_CALLBACK_URL);
if (callback == null) {
throw new ProfileException("Configuration not found in dictionary : {}; {}; {};", DICT_TYPE_APP_CONFIG, DICT_CODE_CALLBACK_URL, request);
}
BigInteger amount = new BigDecimal(request.getAmount()).multiply(new BigDecimal(100)).toBigInteger(); BigInteger amount = new BigDecimal(request.getAmount()).multiply(new BigDecimal(100)).toBigInteger();
bodyNode.put("mchid", properties.getPayAcctId()) bodyNode.put("mchid", properties.getPayAcctId())
.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", request.getNotifyUrl()) .put("notify_url", callback.getValue() + request.getChanId())
.put("out_trade_no", history.getTransactionId().toString()); .put("out_trade_no", history.getTransactionId().toString());
bodyNode.putObject("amount") bodyNode.putObject("amount")
.put("total", amount); .put("total", amount);
...@@ -276,7 +284,7 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer { ...@@ -276,7 +284,7 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer {
private ChannelResponse response(String execute, String access, Object request, ClientResponse response) { private ChannelResponse response(String execute, String access, Object request, ClientResponse response) {
if (response == null) { if (response == null) {
throw new NullException(StringUtils.format("Client response is null : {}; {}; {};", execute, access, request)); throw new NullException("Client response is null : {}; {}; {};", execute, access, request);
} }
ChannelResponse responseData = new ChannelResponse(); ChannelResponse responseData = new ChannelResponse();
......
...@@ -27,11 +27,9 @@ import java.lang.reflect.Method; ...@@ -27,11 +27,9 @@ import java.lang.reflect.Method;
@Component @Component
public class BusinessMappingAspect { public class BusinessMappingAspect {
@Autowired @Autowired
private Sequencer sequencer; private Sequencer sequencer;
@Autowired @Autowired
private ServerApplicationContext serverApplicationContext; private ServerApplicationContext serverApplicationContext;
......
...@@ -2,7 +2,6 @@ package cn.quant.baa.pay.component; ...@@ -2,7 +2,6 @@ package cn.quant.baa.pay.component;
import cn.quant.baa.pay.acquirer.AcquirerProperties; import cn.quant.baa.pay.acquirer.AcquirerProperties;
import cn.quant.baa.pay.config.DictionaryViewer; import cn.quant.baa.pay.config.DictionaryViewer;
import cn.quant.baa.pay.dict.DictType;
import cn.quant.baa.pay.model.dto.DictionaryItemDTO; import cn.quant.baa.pay.model.dto.DictionaryItemDTO;
import cn.quant.baa.pay.model.web.MerchantAcquirerProperties; import cn.quant.baa.pay.model.web.MerchantAcquirerProperties;
import cn.quant.baa.pay.model.web.MerchantChannelResponseData; import cn.quant.baa.pay.model.web.MerchantChannelResponseData;
...@@ -16,6 +15,8 @@ import java.util.HashMap; ...@@ -16,6 +15,8 @@ import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Map; import java.util.Map;
import static cn.quant.baa.pay.Constant.DICT_TYPE_PAY;
/** /**
* Created by Administrator on 2021/8/23 0023. * Created by Administrator on 2021/8/23 0023.
*/ */
...@@ -49,9 +50,9 @@ public class ModelBuilder { ...@@ -49,9 +50,9 @@ public class ModelBuilder {
public Map<String, MerchantChannelResponseData> toModel(Map<String, Collection<AcquirerProperties>> profiles, String access) { public Map<String, MerchantChannelResponseData> toModel(Map<String, Collection<AcquirerProperties>> profiles, String access) {
Map<String, MerchantChannelResponseData> models = new HashMap<>(); Map<String, MerchantChannelResponseData> models = new HashMap<>();
for (String code : profiles.keySet()) { for (String code : profiles.keySet()) {
DictionaryItemDTO item = dictionaryViewer.get(DictType.PAY, code); DictionaryItemDTO item = dictionaryViewer.get(DICT_TYPE_PAY, code);
if (item == null) { if (item == null) {
throw new NotSupportedException(StringUtils.format("Dictionary item is null({}, {}).", DictType.PAY, code)); throw new NotSupportedException(StringUtils.format("Dictionary item is null({}, {}).", DICT_TYPE_PAY, code));
} }
Collection<AcquirerProperties> collection = profiles.get(code); Collection<AcquirerProperties> collection = profiles.get(code);
MerchantChannelResponseData book = new MerchantChannelResponseData(); MerchantChannelResponseData book = new MerchantChannelResponseData();
......
...@@ -36,5 +36,4 @@ public class DictionaryViewer { ...@@ -36,5 +36,4 @@ public class DictionaryViewer {
return viewer.bigTable.get(type, code); return viewer.bigTable.get(type, code);
} }
} }
package cn.quant.baa.pay.dict;
/**
* Created by Administrator on 2021/8/23 0023.
*/
public class DictType {
public final static String PAY = "PAY";
}
package cn.quant.baa.pay.model.web;
/**
* Created by Administrator on 2021/9/27 0027.
*/
public class CallbackRequestData {
private String chanId;
public String getChanId() {
return chanId;
}
public void setChanId(String chanId) {
this.chanId = chanId;
}
}
...@@ -50,7 +50,7 @@ public abstract class BusinessController extends AbstractController { ...@@ -50,7 +50,7 @@ public abstract class BusinessController extends AbstractController {
return objectMapper.readValue(value.getBytes(), Map.class); return objectMapper.readValue(value.getBytes(), Map.class);
} }
public String serialize(HttpResponseData value) throws JsonProcessingException { public String serialize(Object value) throws JsonProcessingException {
return objectMapper.writeValueAsString(value); return objectMapper.writeValueAsString(value);
} }
......
...@@ -16,7 +16,6 @@ public class WebMvcConfiguration extends WebMessageConfigurer { ...@@ -16,7 +16,6 @@ public class WebMvcConfiguration extends WebMessageConfigurer {
@Bean @Bean
public MappingJackson2HttpMessageConverter httpMessageConverter() { public MappingJackson2HttpMessageConverter httpMessageConverter() {
MappingJackson2HttpMessageConverter converter = super.httpMessageConverter(); MappingJackson2HttpMessageConverter converter = super.httpMessageConverter();
ObjectMapper objectMapper = converter.getObjectMapper(); ObjectMapper objectMapper = converter.getObjectMapper();
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
......
/**
* application controller dto
*/
package cn.quant.baa.pay.http;
/**
* jpa entity
*/
package cn.quant.baa.pay.jpa.entity;
/**
* jpa repository
*/
package cn.quant.baa.pay.jpa.repository;
package cn.quant.baa.pay.model.web;
import java.io.Serializable;
import java.time.LocalDate;
/**
* Created by Administrator on 2021/9/27 0027.
*/
public class WeiXinCallbackRequestData implements Serializable{
private static final long serialVersionUID = 8252843404761981034L;
private String id;
private LocalDate createTime;
private String eventType;
private String resourceType;
private WeiXinCallbackResource resource;
private String summary;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public LocalDate getCreateTime() {
return createTime;
}
public void setCreateTime(LocalDate createTime) {
this.createTime = createTime;
}
public String getEventType() {
return eventType;
}
public void setEventType(String eventType) {
this.eventType = eventType;
}
public String getResourceType() {
return resourceType;
}
public void setResourceType(String resourceType) {
this.resourceType = resourceType;
}
public WeiXinCallbackResource getResource() {
return resource;
}
public void setResource(WeiXinCallbackResource resource) {
this.resource = resource;
}
public String getSummary() {
return summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("WeiXinCallbackRequestData{");
sb.append("id='").append(id).append('\'');
sb.append(", createTime=").append(createTime);
sb.append(", eventType='").append(eventType).append('\'');
sb.append(", resourceType='").append(resourceType).append('\'');
sb.append(", resource='").append(resource).append('\'');
sb.append(", summary='").append(summary).append('\'');
sb.append('}');
return sb.toString();
}
}
package cn.quant.baa.pay.model.web;
import java.io.Serializable;
/**
* Created by Administrator on 2021/9/27 0027.
*/
public class WeiXinCallbackResource implements Serializable{
private static final long serialVersionUID = -8312044396842852528L;
private String algorithm;
private String ciphertext;
private String associatedData;
private String originalType;
private String nonce;
public String getAlgorithm() {
return algorithm;
}
public void setAlgorithm(String algorithm) {
this.algorithm = algorithm;
}
public String getCiphertext() {
return ciphertext;
}
public void setCiphertext(String ciphertext) {
this.ciphertext = ciphertext;
}
public String getAssociatedData() {
return associatedData;
}
public void setAssociatedData(String associatedData) {
this.associatedData = associatedData;
}
public String getOriginalType() {
return originalType;
}
public void setOriginalType(String originalType) {
this.originalType = originalType;
}
public String getNonce() {
return nonce;
}
public void setNonce(String nonce) {
this.nonce = nonce;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("WeiXinCallbackResource{");
sb.append("algorithm='").append(algorithm).append('\'');
sb.append(", ciphertext='").append(ciphertext).append('\'');
sb.append(", associatedData='").append(associatedData).append('\'');
sb.append(", originalType='").append(originalType).append('\'');
sb.append(", nonce='").append(nonce).append('\'');
sb.append('}');
return sb.toString();
}
}
/**
* mybatis mapper, entity
*/
package cn.quant.baa.pay.mybatis;
package cn.quant.baa.pay.rest; package cn.quant.baa.pay.rest;
import cn.quant.baa.pay.acquirer.AcquirerProperties;
import cn.quant.baa.pay.acquirer.AcquirerPropertiesSource;
import cn.quant.baa.pay.annotation.BusinessMapping;
import cn.quant.baa.pay.config.DictionaryViewer;
import cn.quant.baa.pay.model.dto.DictionaryItemDTO;
import cn.quant.baa.pay.service.TransactionService;
import cn.quant.spring.ProfileException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.netty.http.server.HttpServerRequest;
import java.util.Map;
import static cn.quant.baa.pay.Constant.DICT_CODE_WXP;
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.
*/ */
public class TransactionController extends BusinessController{ @RestController
@RequestMapping("/transaction")
public class TransactionController extends BusinessController {
private static final Logger logger = LoggerFactory.getLogger(TransactionController.class);
@Autowired
private TransactionService transactionService;
@Autowired
private AcquirerPropertiesSource acquirerPropertiesSource;
@ResponseBody
@BusinessMapping
@PostMapping("/pay/callback/wx/{chanId}")
public ResponseEntity pay(@PathVariable("chanId") String chanId, @RequestBody Map request) throws Exception {
DictionaryItemDTO dict = DictionaryViewer.get(DICT_TYPE_PAY, DICT_CODE_WXP);
if (dict == null) {
throw new ProfileException("Configuration not found in dictionary : {}; {}; {}; {};", DICT_TYPE_PAY, DICT_CODE_WXP, chanId, request);
}
AcquirerProperties properties = acquirerPropertiesSource.get(Long.valueOf(chanId));
if (properties == null || !dict.getCode().equals(properties.getPayChanCode())) {
throw new ProfileException("Acquirer not found : {}; {}; {}; {};", DICT_TYPE_PAY, DICT_CODE_WXP, chanId, request);
}
// CallbackRequestData requestData = new CallbackRequestData();
// requestData.setChanId(chanId);
// transactionService.callback(requestData);
return null;
}
} }
...@@ -7,7 +7,7 @@ spring.devtools.restart.enabled=true ...@@ -7,7 +7,7 @@ spring.devtools.restart.enabled=true
spring.devtools.livereload.enabled=true spring.devtools.livereload.enabled=true
#Server #Server
server.port=8080 server.port=8090
server.servlet.context-path=/ server.servlet.context-path=/
#quant #quant
quant.server.number=1 quant.server.number=1
......
...@@ -35,7 +35,6 @@ public class TransactionService extends BusinessService { ...@@ -35,7 +35,6 @@ public class TransactionService extends BusinessService {
private static final Logger logger = LoggerFactory.getLogger(TransactionService.class); private static final Logger logger = LoggerFactory.getLogger(TransactionService.class);
@Autowired @Autowired
private MerchantAcquirer acquirer; private MerchantAcquirer acquirer;
...@@ -49,7 +48,7 @@ public class TransactionService extends BusinessService { ...@@ -49,7 +48,7 @@ public class TransactionService extends BusinessService {
return md5; return md5;
} }
@Transactional(propagation = Propagation.REQUIRES_NEW) @Transactional(propagation = Propagation.REQUIRED)
public ChannelResponse pay(AcquirerProperties properties, PayRequestData data) throws Exception { public ChannelResponse pay(AcquirerProperties properties, PayRequestData data) throws Exception {
validate(data); validate(data);
...@@ -121,24 +120,29 @@ public class TransactionService extends BusinessService { ...@@ -121,24 +120,29 @@ public class TransactionService extends BusinessService {
// return acquirer.pay(data, payHistoryEntity); // return acquirer.pay(data, payHistoryEntity);
// } // }
@Transactional(propagation = Propagation.NOT_SUPPORTED) @Transactional(propagation = Propagation.REQUIRED)
public ChannelResponse checkPay(CheckPayRequestData data) throws Exception { public ChannelResponse checkPay(CheckPayRequestData data) throws Exception {
return acquirer.checkPay(data); return acquirer.checkPay(data);
} }
@Transactional(propagation = Propagation.NOT_SUPPORTED) @Transactional(propagation = Propagation.REQUIRED)
public ChannelResponse checkRefund(CheckRefundRequestData data) throws Exception { public ChannelResponse checkRefund(CheckRefundRequestData data) throws Exception {
return acquirer.checkRefund(data); return acquirer.checkRefund(data);
} }
@Transactional(propagation = Propagation.NOT_SUPPORTED) @Transactional(propagation = Propagation.REQUIRED)
public ChannelResponse close(CloseRequestData data) throws Exception { public ChannelResponse close(CloseRequestData data) throws Exception {
return acquirer.close(data); return acquirer.close(data);
} }
@Transactional(propagation = Propagation.NOT_SUPPORTED) @Transactional(propagation = Propagation.REQUIRED)
public ChannelResponse refund(RefundRequestData data) throws Exception { public ChannelResponse refund(RefundRequestData data) throws Exception {
return acquirer.refund(data); return acquirer.refund(data);
} }
@Transactional(propagation = Propagation.REQUIRED)
public void callback(CallbackRequestData data) throws Exception {
acquirer.callback(data);
}
} }
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