nnnn
This commit is contained in:
222
ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/V14Manager.java
Normal file
222
ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/V14Manager.java
Normal file
@@ -0,0 +1,222 @@
|
||||
package com.ruoyi.cai.trdpay;
|
||||
|
||||
import cn.hutool.core.lang.UUID;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.ruoyi.cai.domain.PayTrdConfig;
|
||||
import com.ruoyi.cai.enums.SystemConfigEnum;
|
||||
import com.ruoyi.cai.manager.SystemConfigManager;
|
||||
import com.ruoyi.cai.pay.PayManager;
|
||||
import com.ruoyi.cai.pay.PayOrderInfoDTO;
|
||||
import com.ruoyi.cai.pay.PayTypeEnum;
|
||||
import com.ruoyi.cai.service.OrderLogsService;
|
||||
import com.ruoyi.cai.service.PayTrdConfigService;
|
||||
import com.ruoyi.cai.trdpay.dto.NotifyResp;
|
||||
import com.ruoyi.cai.trdpay.dto.extend.V14ExtendMapDTO;
|
||||
import com.ruoyi.cai.trdpay.dto.v14.NotifyContent;
|
||||
import com.ruoyi.cai.trdpay.dto.v14.V14Token;
|
||||
import com.ruoyi.cai.trdpay.dto.v14.wechatJSAPI.WechatJSAPIRequest;
|
||||
import com.ruoyi.cai.trdpay.dto.v14.wechatJSAPI.WechatJSAPIResponse;
|
||||
import com.ruoyi.cai.trdpay.dto.v14.wechatJSAPI.WxJsOrderGoods;
|
||||
import com.ruoyi.cai.trdpay.dto.v14.wechatJSAPI.WxJsOrderInfo;
|
||||
import com.ruoyi.cai.trdpay.handle.v12new.enums.AsymmetricTypeEnum;
|
||||
import com.ruoyi.cai.trdpay.handle.v12new.utils.AESUtil;
|
||||
import com.ruoyi.cai.trdpay.handle.v12new.utils.JacksonUtil;
|
||||
import com.ruoyi.cai.trdpay.handle.v12new.utils.RSAUtil;
|
||||
import com.ruoyi.cai.util.OkHttp3Util;
|
||||
import com.ruoyi.cai.util.RestTemplateUtil;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.redisson.api.RBucket;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.math.BigDecimal;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class V14Manager {
|
||||
|
||||
@Autowired
|
||||
private SystemConfigManager systemConfigManager;
|
||||
@Autowired
|
||||
private PayTrdConfigService payTrdConfigService;
|
||||
@Autowired
|
||||
private OrderLogsService orderLogsService;
|
||||
@Autowired
|
||||
private RedissonClient redissonClient;
|
||||
@Autowired
|
||||
private PayManager payManager;
|
||||
private static final String PUBLIC_KEY_PATH = "/home/server/api/sign/v14/EFPS-PublicKey.cer";
|
||||
|
||||
private boolean init = false;
|
||||
private static PrivateKey merchantPrivateKey = null;
|
||||
|
||||
|
||||
public synchronized void init(String privateKeyPath,String privateKeyPassword){
|
||||
if(!init){
|
||||
log.info("初始化ETSP SDK privateKeyPath:{} privateKeyPassword:{}", privateKeyPath, privateKeyPassword);
|
||||
merchantPrivateKey = RSAUtil.getPrivateKeyByPath(privateKeyPath, privateKeyPassword);
|
||||
init = true;
|
||||
}
|
||||
}
|
||||
|
||||
public WechatJSAPIResponse pay(PayOrderInfoDTO payOrderInfoDTO, PayTrdConfig payTrdConfig){
|
||||
String extendData = payTrdConfig.getExtendData();
|
||||
if(StringUtils.isBlank(extendData)){
|
||||
throw new ServiceException("参数异常");
|
||||
}
|
||||
V14ExtendMapDTO extendMap = JSON.parseObject(extendData, V14ExtendMapDTO.class);
|
||||
String privateKeyPath = extendMap.getPrivateKeyPath();
|
||||
String privateKeyPassword = extendMap.getPrivateKeyPassword();
|
||||
this.init(privateKeyPath, privateKeyPassword);
|
||||
TrdPayTypeEnum type = TrdPayTypeEnum.V14;
|
||||
String version = "3.0"; // 版本号
|
||||
String outTradeNo = payOrderInfoDTO.getOrderNo(); // 交易编号,商户侧唯一
|
||||
String customerCode = payTrdConfig.getMchId();
|
||||
long payAmount = payOrderInfoDTO.getPriceFen(); // 支付金额,分为单位
|
||||
String payCurrency = "CNY"; // 币种,写死
|
||||
String notifyUrl = type.getNotifyUrl(payTrdConfig.getNotifyUrl(), true);
|
||||
String transactionStartTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")); // 交易开始时间
|
||||
// String transactionEndTime = ""; // 交易结束时间
|
||||
WxJsOrderInfo orderInfo = new WxJsOrderInfo();
|
||||
orderInfo.setId(payOrderInfoDTO.getSubjectId());
|
||||
orderInfo.setBusinessType("100007");
|
||||
orderInfo.addGood(new WxJsOrderGoods(payOrderInfoDTO.getSubject(), payOrderInfoDTO.getBody(), payOrderInfoDTO.getPriceFen()));// 填写真实的订单信息如new
|
||||
WechatJSAPIRequest order = new WechatJSAPIRequest(outTradeNo, customerCode, orderInfo, payAmount, payCurrency,
|
||||
notifyUrl, transactionStartTime, null);
|
||||
order.setAppId(extendMap.getMinAppId());
|
||||
order.setOpenId(payOrderInfoDTO.getOpenId());
|
||||
order.setNonceStr(RandomUtil.randomString(16));
|
||||
order.setPayMethod("35");
|
||||
order.setVersion(version);
|
||||
order.setChannelMchtNo(extendMap.getLastMchId());
|
||||
order.setAreaInfo("420100");
|
||||
Map<String,String> header = new HashMap<>();
|
||||
header.put("x-efps-sign-no",extendMap.getSignNo());
|
||||
header.put("x-efps-sign-type","SHA256withRSA");
|
||||
String requestJson = JacksonUtil.objToJson(order);
|
||||
String sign = RSAUtil.sign(requestJson, merchantPrivateKey, AsymmetricTypeEnum.RSA);
|
||||
header.put("x-efps-sign",sign);
|
||||
header.put("x-efps-timestamp",LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
|
||||
String gatewayUrl = getGatewayUrl(payTrdConfig);
|
||||
String createOrderUrl = gatewayUrl + "/api/txs/pay/WxJSAPIPayment";
|
||||
String body = RestTemplateUtil.postJsonData(createOrderUrl, JacksonUtil.objToJson(order), header);
|
||||
log.info("v14调用支付日志 url:{} body:{} header:{} response:{}", createOrderUrl,JacksonUtil.objToJson(order),JacksonUtil.objToJson(header),body);
|
||||
WechatJSAPIResponse response = JacksonUtil.jsonToObj(body, WechatJSAPIResponse.class);
|
||||
if(!response.isSuccess()){
|
||||
orderLogsService.createAliPayLogs(payOrderInfoDTO.getOrderNo(), createOrderUrl,
|
||||
JacksonUtil.objToJson(order), body, false, type, "四方微信支付");
|
||||
throw new ServiceException("调用支付失败");
|
||||
}
|
||||
orderLogsService.createAliPayLogs(payOrderInfoDTO.getOrderNo(), createOrderUrl,
|
||||
JacksonUtil.objToJson(order), body, true, type, "四方微信支付");
|
||||
return response;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
V14Manager v14Manager = new V14Manager();
|
||||
PayOrderInfoDTO payOrderInfoDTO = new PayOrderInfoDTO();
|
||||
payOrderInfoDTO.setBody("15钻石");
|
||||
payOrderInfoDTO.setSubject("15钻石");
|
||||
payOrderInfoDTO.setSubjectId("1");
|
||||
payOrderInfoDTO.setPrice(BigDecimal.valueOf(200));
|
||||
payOrderInfoDTO.setOrderNo("OJSKDJKASDLWBJ22EQKWL123");
|
||||
payOrderInfoDTO.setOpenId("wx0ca162500b16e82321");
|
||||
PayTrdConfig config = new PayTrdConfig();
|
||||
config.setNotifyUrl("https://wewqw.wwiwi.com/ds/asd");
|
||||
v14Manager.pay(payOrderInfoDTO,config);
|
||||
}
|
||||
|
||||
|
||||
public String getGatewayUrl(PayTrdConfig payTrdConfig){
|
||||
TrdPayTypeEnum type = TrdPayTypeEnum.V14;
|
||||
String gatewayUrl = type.getGatewayUrl();
|
||||
if (StringUtils.isNotBlank(payTrdConfig.getGatewayUrl())) {
|
||||
gatewayUrl = payTrdConfig.getGatewayUrl();
|
||||
}
|
||||
return gatewayUrl;
|
||||
}
|
||||
|
||||
public String createToken(String orderNo,Long payTrdConfigId,String appId,String secret){
|
||||
V14Token token = new V14Token();
|
||||
token.setPayTrdConfigId(payTrdConfigId);
|
||||
token.setOrderNo(orderNo);
|
||||
token.setAppId(appId);
|
||||
token.setSecret(secret);
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
RBucket<V14Token> bucket = redissonClient.getBucket(uuid);
|
||||
bucket.set(token, 40, TimeUnit.MINUTES);
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public V14Token checkToken(String token){
|
||||
RBucket<V14Token> bucket = redissonClient.getBucket(token);
|
||||
return bucket.get();
|
||||
}
|
||||
|
||||
|
||||
public JSONObject notifyDeal(HttpServletRequest request) throws IOException {
|
||||
String sign = request.getHeader("x-efps-sign");
|
||||
BufferedReader br = request.getReader();
|
||||
String str = "";
|
||||
StringBuilder wholeStr = new StringBuilder();
|
||||
while ((str = br.readLine()) != null) {
|
||||
wholeStr.append(str);
|
||||
}
|
||||
String body = wholeStr.toString();
|
||||
log.info("收到第三方微信支付回调 sign={} {}:{}","V14", sign, wholeStr);
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
if (StringUtils.isNotBlank(body) && StringUtils.isNotBlank(sign)) {
|
||||
boolean verifySign = RSAUtil.verifySign(body, sign, RSAUtil.getPublicKeyByPath(PUBLIC_KEY_PATH), AsymmetricTypeEnum.RSA);
|
||||
if(!verifySign) {
|
||||
log.info("v14回调处理失败 验签失败! body={} sign={}", body, sign);
|
||||
jsonObject.put("returnCode", "0001");
|
||||
return jsonObject;
|
||||
}
|
||||
NotifyContent notify = JSONObject.parseObject(body, NotifyContent.class);
|
||||
String payState = notify.getPayState();
|
||||
NotifyResp notifyResp = new NotifyResp();
|
||||
notifyResp.setOrderNo(notify.getOutTradeNo()); // 商户订单号
|
||||
notifyResp.setTrdOrderNo(notify.getTransactionNo()); // 平台订单号
|
||||
notifyResp.setPayTypeEnum(TrdPayTypeEnum.V14);
|
||||
notifyResp.setSuccess("00".equals(payState));
|
||||
if(notifyResp.isSuccess()){
|
||||
JSONObject parse = JSONObject.parse(body);
|
||||
Map<String,String> javaObject = JsonToMap(parse);
|
||||
payManager.callBack(notifyResp.getOrderNo(),notifyResp.getTrdOrderNo(),javaObject,notifyResp.getPayTypeEnum().name(), PayTypeEnum.WX);
|
||||
}
|
||||
jsonObject.put("returnCode", "0000");
|
||||
jsonObject.put("returnMsg", "");
|
||||
return jsonObject;
|
||||
}
|
||||
jsonObject.put("returnCode", "0001");
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
public static Map<String,String> JsonToMap(JSONObject j){
|
||||
Map<String,String> map = new HashMap<>();
|
||||
Set<String> strings = j.keySet();
|
||||
for (String key : strings) {
|
||||
Object o = j.get(key);
|
||||
if(o instanceof String){
|
||||
map.put(key,(String)o);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user