Commit ec71758a authored by 刘李鹏's avatar 刘李鹏

微信支持GET请求加签名、实现支付宝、微信的订单查询

parent 250cfbb8
package cn.quant.baa.pay.acquirer;
import cn.quant.baa.pay.jpa.entity.PayHistoryEntity;
import cn.quant.baa.pay.model.web.CheckPayRequestData;
import cn.quant.baa.pay.model.web.PayRequestData;
import com.fasterxml.jackson.databind.JsonNode;
......@@ -12,6 +13,7 @@ public interface Acquirer {
JsonNode pay(PayRequestData payRequestData, PayHistoryEntity payHistoryEntity);
JsonNode refund();
JsonNode check();
JsonNode checkPay(CheckPayRequestData checkPayRequestData);
JsonNode checkRefund();
JsonNode close();
}
package cn.quant.baa.pay.acquirer;
import cn.quant.baa.pay.jpa.entity.PayHistoryEntity;
import cn.quant.baa.pay.model.web.CheckPayRequestData;
import cn.quant.baa.pay.model.web.PayRequestData;
import cn.quant.spring.NotSupportedException;
import cn.quant.spring.security.Base64Cipher;
......@@ -75,8 +76,13 @@ public class MerchantAcquirer implements Acquirer {
}
@Override
public JsonNode check() {
throw new NotSupportedException();
public JsonNode checkPay(CheckPayRequestData checkPayRequestData) {
return acquirers.get(checkPayRequestData.getChanId()).checkPay(checkPayRequestData);
}
@Override
public JsonNode checkRefund() {
return null;
}
@Override
......
......@@ -2,7 +2,9 @@ package cn.quant.baa.pay.acquirer.weixin;
import cn.quant.baa.pay.acquirer.AcquirerProperties;
import cn.quant.baa.pay.acquirer.MerchantAcquirer;
import cn.quant.baa.pay.dict.AccessCode;
import cn.quant.baa.pay.jpa.entity.PayHistoryEntity;
import cn.quant.baa.pay.model.web.CheckPayRequestData;
import cn.quant.baa.pay.model.web.PayRequestData;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
......@@ -120,11 +122,23 @@ public class AlipayMerchantAcquirer extends MerchantAcquirer {
bodyNode.put("subject", payRequestData.getSubject());
bodyNode.put("body", payRequestData.getSubject());
bodyNode.put("product_code", properties.getProductCode());
return doWebExecute(bodyNode);
switch (properties.getAccessCode()) {
case APP:
return doAppExecute(bodyNode);
case H5:
case WEB:
return doWebExecute(bodyNode);
default:
}
return doExecute(bodyNode);
}
@Override
public JsonNode checkPay(CheckPayRequestData checkPayRequestData) {
// String outTradeNo = "11111111218";
// bodyNode.put("out_trade_no", outTradeNo);
// return doExecute(bodyNode);
ObjectNode bodyNode = objectMapper.createObjectNode();
bodyNode.put("out_trade_no", checkPayRequestData.getOutTradeNo());
return doExecute(bodyNode);
}
/**
......@@ -184,7 +198,7 @@ public class AlipayMerchantAcquirer extends MerchantAcquirer {
if (response != null) {
Mono<String> resultMono = response.bodyToMono(String.class);
String bodyRes = resultMono.block();
Pattern pattern = Pattern.compile("[a-zA-Z_0-9]*_response"); //去掉空格符合换行符
Pattern pattern = Pattern.compile("[a-zA-Z_0-9]*_response"); //处理支付宝不同的返回格式,统一为response
Matcher matcher = pattern.matcher(bodyRes);
String body = matcher.replaceAll("response");
try {
......
......@@ -3,14 +3,17 @@ package cn.quant.baa.pay.acquirer.weixin;
import cn.quant.baa.pay.acquirer.AcquirerProperties;
import cn.quant.baa.pay.acquirer.MerchantAcquirer;
import cn.quant.baa.pay.jpa.entity.PayHistoryEntity;
import cn.quant.baa.pay.model.web.CheckPayRequestData;
import cn.quant.baa.pay.model.web.PayRequestData;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;
import java.io.ByteArrayInputStream;
......@@ -85,7 +88,6 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer {
@Override
public JsonNode pay(PayRequestData payRequestData, PayHistoryEntity payHistoryEntity) {
String outTradeNo = UUID.randomUUID().toString().replace("-", "");
ObjectNode bodyNode = objectMapper.createObjectNode();
// 转换金额为分
BigInteger amount = new BigDecimal(payRequestData.getAmount()).multiply(new BigDecimal(100)).toBigInteger();
......@@ -111,29 +113,50 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer {
default:
}
bodyNode.set("scene_info", sceneInfo);
return doExecute(bodyNode);
String payAccess = properties.getPayAccess();
return doExecute(payAccess, bodyNode);
}
@Override
public JsonNode checkPay(CheckPayRequestData checkPayRequestData) {
ObjectNode bodyNode = objectMapper.createObjectNode();
bodyNode.put("mchid", properties.getPayAcctId());
String payAccess = properties.getPayAccess().replace("{out_trade_no}", checkPayRequestData.getOutTradeNo());
return doExecute(payAccess, bodyNode);
}
/**
* 发起请求
*
* @param requestNode
* @param payAccess
* @param bodyNode
* @return
*/
private JsonNode doExecute(ObjectNode requestNode) {
private JsonNode doExecute(String payAccess, ObjectNode bodyNode) {
String method = properties.getAccessMethod();
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(payAccess);
String requestBody = "";
try {
requestBody = objectMapper.writeValueAsString(requestNode);
} catch (JsonProcessingException e) {
e.printStackTrace();
// 处理GET请求
if (HttpMethod.GET.name().equals(method)) {
bodyNode.fields().forEachRemaining((entry) -> {
uriComponentsBuilder.queryParam(entry.getKey(), entry.getValue().asText());
});
} else {
// 非GET请求的时候处理requestBody
try {
requestBody = objectMapper.writeValueAsString(bodyNode);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
String uri = uriComponentsBuilder.build().toString();
long timestamp = System.currentTimeMillis() / 1000;
String nonceStr = UUID.randomUUID().toString().replace("-", "");
String signText = joining("\n", "POST", properties.getPayAccess(), String.valueOf(timestamp), nonceStr, requestBody);
// 代签名字符串
String signText = joining("\n", method, uri, String.valueOf(timestamp), nonceStr, requestBody);
String sign = sign(signText);
String token = String.format(TOKEN_PATTERN, properties.getPayAcctId(), nonceStr, timestamp, properties.getPayCertNo(), sign);
Mono<ClientResponse> mono = webClient.post()
.uri(properties.getPayAccess())
Mono<ClientResponse> mono = webClient.method(HttpMethod.resolve(method))
.uri(uri)
.header("Authorization", SCHEMA.concat(token))
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(requestBody)
......@@ -160,15 +183,16 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer {
String signature = response.headers().asHttpHeaders().getFirst("Wechatpay-Signature");
//签名信息
String wsSignText = joining("\n", wxTimestamp, nonce, resultMono.block());
String wsSignText = joining("\n", wxTimestamp, nonce, body);
if (verify(wsSignText, signature)) {
return bodyJsonNode;
}
// TODO: 签名校验失败,做异常处理
throw new RuntimeException("签名校验失败");
} else {
return bodyJsonNode;
// TODO: 返回异常,做异常处理
throw new RuntimeException("返回异常,做异常处理");
// throw new RuntimeException("返回异常,做异常处理");
}
}
return bodyJsonNode;
......@@ -295,9 +319,6 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer {
public String joining(String separator, String... str) {
StringBuilder builder = new StringBuilder();
for (String s : str) {
if (s == null || s.length() == 0) {
continue;
}
builder.append(s).append(separator);
}
return builder.toString();
......
......@@ -6,7 +6,8 @@ package cn.quant.baa.pay.dict;
public enum AccessCode {
REFUND("退款"),
CHECK("订单查询"),
CHKRFD("退款查询"),
CHKPAY("支付查询"),
CLOSE("关闭订单"),
WEB("电脑网站支付"),
APP("应用支付"),
......
......@@ -5,6 +5,7 @@ import cn.quant.baa.pay.acquirer.AcquirerConfiguration;
import cn.quant.baa.pay.acquirer.MerchantAcquirer;
import cn.quant.baa.pay.context.TransactionSession;
import cn.quant.baa.pay.jpa.entity.*;
import cn.quant.baa.pay.model.web.CheckPayRequestData;
import cn.quant.baa.pay.util.AssertUtils;
import cn.quant.baa.pay.model.web.GoodsDetail;
import cn.quant.baa.pay.acquirer.AcquirerProperties;
......@@ -114,4 +115,10 @@ public class TransactionService extends BusinessService {
System.currentTimeMillis();
return acquirer.pay(data, payHistoryEntity);
}
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public JsonNode checkPay(CheckPayRequestData data) {
return acquirer.checkPay(data);
}
}
......@@ -3,6 +3,7 @@ package cn.quant.baa.pay.rest;
import cn.quant.baa.pay.annotation.BusinessMapping;
import cn.quant.baa.pay.jpa.entity.PayHistoryEntity;
import cn.quant.baa.pay.model.BusinessRequest;
import cn.quant.baa.pay.model.web.CheckPayRequestData;
import cn.quant.baa.pay.model.web.PayRequestData;
import cn.quant.baa.pay.service.TransactionService;
import com.fasterxml.jackson.databind.JsonNode;
......@@ -31,4 +32,17 @@ public class TransactionController extends BusinessController {
System.currentTimeMillis();
return res;
}
@ResponseBody
@BusinessMapping(session = 1)
@PostMapping("/checkPay")
public JsonNode checkPay(@RequestBody BusinessRequest<CheckPayRequestData> request) {
CheckPayRequestData data = request.getData();
JsonNode res = transactionService.checkPay(data);
System.currentTimeMillis();
return res;
}
}
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