123
This commit is contained in:
@@ -17,4 +17,8 @@ public class PayOrderInfoDTO {
|
|||||||
public String getPriceFenStr(){
|
public String getPriceFenStr(){
|
||||||
return NumberUtil.mul(price,100).longValue()+"";
|
return NumberUtil.mul(price,100).longValue()+"";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getPriceYuanStr(){
|
||||||
|
return price.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package com.ruoyi.cai.trdpay;
|
|||||||
|
|
||||||
import cn.hutool.crypto.digest.DigestUtil;
|
import cn.hutool.crypto.digest.DigestUtil;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
|
import org.springframework.util.MultiValueMap;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -9,6 +11,21 @@ import java.util.Map;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class PayMd5Util {
|
public class PayMd5Util {
|
||||||
|
public static MultiValueMap<String,String> createParamsOfMap(Map<String, String> params, String key) {
|
||||||
|
MultiValueMap<String, String> resp = new LinkedMultiValueMap<>();
|
||||||
|
List<String> url = new ArrayList<>();
|
||||||
|
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||||
|
url.add(entry.getKey() + "=" + entry.getValue());
|
||||||
|
resp.add(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
url = url.stream().sorted().collect(Collectors.toList());
|
||||||
|
String stringSignTemp = StringUtils.join(url, "&") + "&key=" + key;
|
||||||
|
String sign = DigestUtil.md5Hex(stringSignTemp).toUpperCase();
|
||||||
|
url.add("sign=" + sign);
|
||||||
|
resp.add("sign",sign);
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
|
|
||||||
public static String createParams(Map<String, String> params, String key) {
|
public static String createParams(Map<String, String> params, String key) {
|
||||||
List<String> url = new ArrayList<>();
|
List<String> url = new ArrayList<>();
|
||||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||||
|
|||||||
@@ -66,6 +66,24 @@ public enum TrdPayTypeEnum {
|
|||||||
* 通道编码:8010
|
* 通道编码:8010
|
||||||
*/
|
*/
|
||||||
V6("https://ydwg.blzf.cc","/api/pay/create_order","/api/pay/query_order","/api/pay/trd/notify/v6","success"),
|
V6("https://ydwg.blzf.cc","/api/pay/create_order","/api/pay/query_order","/api/pay/trd/notify/v6","success"),
|
||||||
|
/**
|
||||||
|
* [商户号]: M1736166248
|
||||||
|
* [用户名]: huaxiang
|
||||||
|
* [商户名称]: 花香
|
||||||
|
* [API密钥]: 17ddac0a588280c6b0e1220b87bf3575
|
||||||
|
* [默认密码]: Aa123456
|
||||||
|
*
|
||||||
|
* [通道编码]: 888
|
||||||
|
* [通道名称]: 支付宝
|
||||||
|
* [金额]: 10 - 1000
|
||||||
|
*
|
||||||
|
* [支付网关]: https://baihe.lhsifang.com/api/pay/create
|
||||||
|
* [查询地址]: https://baihe.lhsifang.com/api/pay/query
|
||||||
|
* [商户登录地址]: https://baihe.lhsifang.com/merchants
|
||||||
|
* [对接文档]: https://baihe.lhsifang.com/merchants/#/api-document
|
||||||
|
* [回调IP]: 142.171.122.90
|
||||||
|
*/
|
||||||
|
V7("https://baihe.lhsifang.com","/api/pay/create","/api/pay/query","/api/pay/trd/notify/v7","success"),
|
||||||
;
|
;
|
||||||
private final String gatewayUrl;
|
private final String gatewayUrl;
|
||||||
private final String createOrderUrl;
|
private final String createOrderUrl;
|
||||||
|
|||||||
@@ -0,0 +1,146 @@
|
|||||||
|
package com.ruoyi.cai.trdpay.handle;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.ruoyi.cai.domain.PayTrdConfig;
|
||||||
|
import com.ruoyi.cai.pay.PayManager;
|
||||||
|
import com.ruoyi.cai.pay.PayOrderInfoDTO;
|
||||||
|
import com.ruoyi.cai.pay.PayReturnResp;
|
||||||
|
import com.ruoyi.cai.service.OrderLogsService;
|
||||||
|
import com.ruoyi.cai.trdpay.PayMd5Util;
|
||||||
|
import com.ruoyi.cai.trdpay.PayTrdService;
|
||||||
|
import com.ruoyi.cai.trdpay.TrdPayTypeEnum;
|
||||||
|
import com.ruoyi.cai.trdpay.dto.NotifyResp;
|
||||||
|
import com.ruoyi.cai.util.RestTemplateUtil;
|
||||||
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
|
import com.ruoyi.common.utils.ServletUtils;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpEntity;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.MultiValueMap;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class PayTrdV7Service implements PayTrdService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private OrderLogsService orderLogsService;
|
||||||
|
@Autowired
|
||||||
|
private PayManager payManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TrdPayTypeEnum getType() {
|
||||||
|
return TrdPayTypeEnum.V7;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PayReturnResp createOrderAli(PayOrderInfoDTO payOrderInfoDTO, PayTrdConfig payTrdConfig) {
|
||||||
|
TrdPayTypeEnum type = getType();
|
||||||
|
RestTemplate rest = RestTemplateUtil.getNoSSLRest();
|
||||||
|
Map<String, String> params = new HashMap<>();
|
||||||
|
params.put("merchantCode", payTrdConfig.getMchId());
|
||||||
|
params.put("channelType", payTrdConfig.getAliProductId());
|
||||||
|
params.put("merchantOrderNo", payOrderInfoDTO.getOrderNo());
|
||||||
|
params.put("amount", payOrderInfoDTO.getPriceYuanStr());
|
||||||
|
String notifyUrl = payTrdConfig.getNotifyUrl() + type.getNotifyPath();
|
||||||
|
params.put("notifyUrl", notifyUrl);
|
||||||
|
params.put("ip", ServletUtils.getClientIP());
|
||||||
|
params.put("title", payOrderInfoDTO.getSubject());
|
||||||
|
params.put("describe", payOrderInfoDTO.getBody());
|
||||||
|
MultiValueMap<String, String> map = PayMd5Util.createParamsOfMap(params, payTrdConfig.getSign());
|
||||||
|
String gatewayUrl = type.getGatewayUrl();
|
||||||
|
if (StringUtils.isNotBlank(payTrdConfig.getGatewayUrl())) {
|
||||||
|
gatewayUrl = payTrdConfig.getGatewayUrl();
|
||||||
|
}
|
||||||
|
String createOrderUrl = gatewayUrl + type.getCreateOrderUrl();
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
|
||||||
|
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
|
||||||
|
String body = rest.postForObject(createOrderUrl, request, String.class);
|
||||||
|
JSONObject jsonObject = JSON.parseObject(body);
|
||||||
|
orderLogsService.createAliPayLogs(payOrderInfoDTO.getOrderNo(), createOrderUrl+JSON.toJSONString(map), jsonObject, type);
|
||||||
|
if(jsonObject == null){
|
||||||
|
log.error("第三方支付失败 V7 返回数据为空 url={} params={}",createOrderUrl,JSON.toJSONString(map));
|
||||||
|
throw new ServiceException("调用支付失败");
|
||||||
|
}
|
||||||
|
if(!"1".equals(jsonObject.getString("code"))){
|
||||||
|
log.info("第三方支付失败 V7 统一支付失败失败 url={} params={} body={}, payTrdConfig={}, typeEnum={}", createOrderUrl,JSON.toJSONString(map), body, JSON.toJSONString(payTrdConfig), JSON.toJSONString(jsonObject));
|
||||||
|
throw new ServiceException("调用支付失败");
|
||||||
|
}
|
||||||
|
String payUrl = jsonObject.getJSONObject("data").getString("payUrl");
|
||||||
|
return PayReturnResp.createH5(payUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NotifyResp getNotifyResp(Map<String, String> sourceData) {
|
||||||
|
String mchOrderNo = sourceData.get("order_no"); // 第三方订单号
|
||||||
|
String payOrderId = sourceData.get("merchant_order_no"); // 商户订单号
|
||||||
|
String status = sourceData.get("status");
|
||||||
|
NotifyResp resp = new NotifyResp();
|
||||||
|
resp.setOrderNo(mchOrderNo);
|
||||||
|
resp.setTrdOrderNo(payOrderId);
|
||||||
|
resp.setPayTypeEnum(getType());
|
||||||
|
resp.setSourceData(sourceData);
|
||||||
|
resp.setSuccess("1".equals(status));
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject queryOrder(String orderNo, PayTrdConfig payTrdConfig) {
|
||||||
|
throw new ServiceException("V7不支持订单查询");
|
||||||
|
/*TrdPayTypeEnum type = getType();
|
||||||
|
Map<String, String> params = new HashMap<>();
|
||||||
|
params.put("merchantId", payTrdConfig.getMchId());
|
||||||
|
params.put("merchantPayNo", orderNo);
|
||||||
|
String para = PayMd5Util.createParams(params,payTrdConfig.getSign());
|
||||||
|
String gatewayUrl = type.getGatewayUrl();
|
||||||
|
if(StringUtils.isNotBlank(payTrdConfig.getGatewayUrl())){
|
||||||
|
gatewayUrl = payTrdConfig.getGatewayUrl();
|
||||||
|
}
|
||||||
|
String queryOrderUrl = gatewayUrl + type.getQueryOrderUrl();
|
||||||
|
String url = queryOrderUrl + "?" + para;
|
||||||
|
String body = RestTemplateUtil.getRest().getForEntity(url, String.class).getBody();
|
||||||
|
JSONObject jsonObject = JSON.parseObject(body);
|
||||||
|
if(jsonObject == null){
|
||||||
|
log.error("第三方支付查询失败 返回数据为空 URL={}",url);
|
||||||
|
throw new ServiceException("调用支付失败");
|
||||||
|
}
|
||||||
|
log.info("第三方支付查询成功 V7 URL={}, body={}",url, body);
|
||||||
|
return jsonObject;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject resetOrder(String orderNo, PayTrdConfig payTrdConfig, boolean updateData) {
|
||||||
|
throw new ServiceException("V7不支持订单查询");
|
||||||
|
/*JSONObject jsonObject = this.queryOrder(orderNo,payTrdConfig);
|
||||||
|
if(!"SUCCESS".equals(jsonObject.getString("retCode"))){
|
||||||
|
log.info("第三方支付失败 V7统一支付失败失败 orderNo={}, payTrdConfig={}", orderNo, JSON.toJSONString(payTrdConfig));
|
||||||
|
throw new ServiceException("调用支付失败");
|
||||||
|
}
|
||||||
|
Integer status = jsonObject.getInteger("status");
|
||||||
|
if(status != null && status.equals(1)){
|
||||||
|
String mchOrderNo = jsonObject.getString("mchOrderNo");
|
||||||
|
String payOrderId = jsonObject.getString("payOrderId");
|
||||||
|
String productId = jsonObject.getString("productId");
|
||||||
|
Map<String,String> objectJson = new HashMap<>();
|
||||||
|
for (String key : jsonObject.keySet()) {
|
||||||
|
objectJson.put(key, jsonObject.getString(key));
|
||||||
|
}
|
||||||
|
if(updateData){
|
||||||
|
payManager.callBack(mchOrderNo,payOrderId,objectJson,"V7", PayTypeEnum.TRD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return jsonObject;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.ruoyi.cai.util;
|
||||||
|
|
||||||
|
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||||
|
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClients;
|
||||||
|
import org.apache.http.ssl.SSLContextBuilder;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
|
||||||
|
public class CustomHttpClient {
|
||||||
|
|
||||||
|
public static CloseableHttpClient createClient() throws Exception {
|
||||||
|
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (x509Certificates, s) -> true).build();
|
||||||
|
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
|
||||||
|
return HttpClients.custom().setSSLSocketFactory(sslSocketFactory).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
package com.ruoyi.cai.util;
|
package com.ruoyi.cai.util;
|
||||||
|
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.springframework.http.client.BufferingClientHttpRequestFactory;
|
import org.springframework.http.client.BufferingClientHttpRequestFactory;
|
||||||
|
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
||||||
import org.springframework.http.client.SimpleClientHttpRequestFactory;
|
import org.springframework.http.client.SimpleClientHttpRequestFactory;
|
||||||
import org.springframework.http.converter.HttpMessageConverter;
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||||
@@ -12,6 +14,7 @@ import java.util.List;
|
|||||||
public class RestTemplateUtil {
|
public class RestTemplateUtil {
|
||||||
|
|
||||||
public static RestTemplate restTemplate;
|
public static RestTemplate restTemplate;
|
||||||
|
public static RestTemplate NO_SSL_REST_TEMPLATE;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
|
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
|
||||||
@@ -26,10 +29,34 @@ public class RestTemplateUtil {
|
|||||||
converter.setDefaultCharset(StandardCharsets.UTF_8);
|
converter.setDefaultCharset(StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CloseableHttpClient httpClient = null;
|
||||||
|
try {
|
||||||
|
httpClient = CustomHttpClient.createClient();
|
||||||
|
HttpComponentsClientHttpRequestFactory requestFactoryNoSSL = new HttpComponentsClientHttpRequestFactory(httpClient);
|
||||||
|
requestFactoryNoSSL.setConnectTimeout(3000);
|
||||||
|
requestFactoryNoSSL.setReadTimeout(3000);
|
||||||
|
NO_SSL_REST_TEMPLATE = new RestTemplate(requestFactoryNoSSL);
|
||||||
|
List<HttpMessageConverter<?>> messageConvertersNoSSL = restTemplate.getMessageConverters();
|
||||||
|
for (HttpMessageConverter<?> messageConverter : messageConvertersNoSSL) {
|
||||||
|
if (messageConverter instanceof StringHttpMessageConverter) {
|
||||||
|
StringHttpMessageConverter converter = (StringHttpMessageConverter) messageConverter;
|
||||||
|
converter.setDefaultCharset(StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static RestTemplate getRest(){
|
public static RestTemplate getRest(){
|
||||||
return restTemplate;
|
return restTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static RestTemplate getNoSSLRest(){
|
||||||
|
return NO_SSL_REST_TEMPLATE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user