package com.nova.sankuai.service.impl;
|
|
import cn.hutool.core.util.StrUtil;
|
import com.alibaba.fastjson.JSONObject;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.fasterxml.jackson.databind.JsonNode;
|
import com.nova.sankuai.domain.api.jiniu.EncryptUtil;
|
import com.nova.sankuai.domain.api.shantai.ConfirmVo;
|
import com.nova.sankuai.domain.api.shantai.GetOrderStatusVo;
|
import com.nova.sankuai.domain.api.shantai.ShanTaiSelectOrderEnum;
|
import com.nova.sankuai.domain.entity.*;
|
import com.nova.sankuai.domain.enums.vipservice.VipCardOrderEnum;
|
import com.nova.sankuai.domain.vo.VipEffectiveTimeVo;
|
import com.nova.sankuai.domain.vo.huifubao.*;
|
import com.nova.sankuai.infra.config.CommonException;
|
import com.nova.sankuai.infra.constants.ResultCode;
|
import com.nova.sankuai.infra.mapper.CustomerMapper;
|
import com.nova.sankuai.infra.mapper.VipCardOrderMapper;
|
import com.nova.sankuai.infra.utils.IpUtil;
|
import com.nova.sankuai.infra.utils.ResultJson;
|
import com.nova.sankuai.infra.utils.UserUtil;
|
import com.nova.sankuai.infra.utils.huifubao.common.HttpUtil;
|
import com.nova.sankuai.infra.utils.huifubao.common.MyKey;
|
import com.nova.sankuai.infra.utils.huifubao.common.SignEncrypt;
|
import com.nova.sankuai.security.UserDetail;
|
import com.nova.sankuai.service.*;
|
import lombok.SneakyThrows;
|
import org.apache.http.client.methods.HttpPost;
|
import org.bouncycastle.util.encoders.Base64;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.http.HttpStatus;
|
import org.springframework.http.ResponseEntity;
|
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.w3c.dom.Document;
|
import org.w3c.dom.Element;
|
import org.w3c.dom.NodeList;
|
import org.xml.sax.InputSource;
|
|
import javax.annotation.Resource;
|
import javax.servlet.http.HttpServletRequest;
|
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
import java.io.StringReader;
|
import java.math.BigDecimal;
|
import java.net.URLDecoder;
|
import java.security.KeyFactory;
|
import java.security.PrivateKey;
|
import java.security.PublicKey;
|
import java.security.spec.PKCS8EncodedKeySpec;
|
import java.security.spec.X509EncodedKeySpec;
|
import java.text.SimpleDateFormat;
|
import java.time.Instant;
|
import java.time.LocalDateTime;
|
import java.time.ZoneId;
|
import java.time.format.DateTimeFormatter;
|
import java.util.Date;
|
import java.util.HashMap;
|
import java.util.Map;
|
import java.util.Objects;
|
|
@Service
|
public class HuiFuBaoPayServiceImpl implements IHuiFuBaoPayService {
|
|
private static final Logger logger = LoggerFactory.getLogger("huibaofu-pay");
|
|
@Value("${huifubao.merchId}")
|
private String merchId;
|
|
@Value("${huifubao.returnPayUrl}")
|
private String returnPayUrl;
|
|
@Value("${huifubao.domainUrl}")
|
private String domainUrl;
|
|
@Resource
|
private ICustomerUserService iCustomerUserService;
|
|
@Resource
|
private IPayRecordService iPayRecordService;
|
|
@Resource
|
private CustomerMapper customerMapper;
|
|
@Resource
|
private VipCardOrderMapper vipCardOrderMapper;
|
|
@Resource
|
private IVipCardService vipCardService;
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public HuiFuBaoSendPayInfo sendPaySMS(HuiFuBaoPayVo vo, UserDetail user) {
|
|
Customer customer = customerMapper.getLatestCustomerRecord(user.getPhone());
|
if (user == null || user.getId() == null) {
|
throw new CommonException("Token无效");
|
}
|
CustomerUser customerUser = iCustomerUserService.getById(user.getId());
|
if (customerUser == null) {
|
throw new CommonException("用户不存在");
|
}
|
|
//商户编号,(汇付宝商户内码:七位整数数字)
|
String agent_id = merchId;
|
|
//二级商户号,传了要参与签名(集团商户模式)
|
String ref_agent_id = vo.getRefAgentId();
|
//是否分润单,传了要参与签名(集团商户模式;分润单需要调分润接口,不然不会结算)
|
String is_guarantee = vo.getIsGuarantee();
|
|
//版本号,固定为1
|
String version = "1";
|
long tenDigitTimestamp = System.currentTimeMillis() / 1000;
|
//商户订单号
|
String agent_bill_id = String.valueOf(tenDigitTimestamp);
|
|
//商户订单时间,格式为"yyyyMMddhhmmss"
|
Date now = new Date();
|
SimpleDateFormat sd = new SimpleDateFormat("yyyyMMddHHmmss");
|
String agent_bill_time = sd.format(now);
|
|
//支付金额,单位:元,保留二位小数
|
String pay_amt = String.valueOf(vo.getPayAmt());
|
if (StrUtil.isEmpty(pay_amt)){
|
throw new RuntimeException("支付金额不能为空");
|
}
|
//商品名称,中文UTF-8处理
|
String goods_name = vo.getGoodsName();
|
if (StrUtil.isEmpty(goods_name)){
|
throw new RuntimeException("商品名称不能为空");
|
}
|
//授权码
|
String hy_auth_uid = vo.getHyAuthUid();
|
if (StrUtil.isEmpty(hy_auth_uid)){
|
throw new RuntimeException("授权码不能为空");
|
}
|
//用户IP地址
|
String user_ip = customer.getIpAddres();
|
//支付后返回的商户处理页面,URL参数是以http://或https://开头的完整URL地址(后台处理),提交的url地址必须外网能访问到,否则无法通知商户。值可以为空,但不可以为null。
|
String notify_url = domainUrl + "/api/v2/hfb/pay/callback";
|
//
|
|
//拼接待加密签名参数
|
|
String signStr = "agent_bill_id=" + agent_bill_id +
|
"&agent_bill_time=" + agent_bill_time +
|
"&agent_id=" + agent_id +
|
"&goods_name=" + goods_name +
|
"&hy_auth_uid=" + hy_auth_uid +
|
"&is_guarantee=" +is_guarantee +
|
"¬ify_url=" + notify_url +
|
"&return_url=" + returnPayUrl +
|
"&pay_amt=" + pay_amt +
|
"&ref_agent_id=" + ref_agent_id +
|
"&user_ip=" + user_ip +
|
"&version=" + version;
|
logger.info("待加密签名串:{}",signStr);
|
|
SignEncrypt signEncrypt = new SignEncrypt();
|
// 使用类名和常量名来访问常量
|
String publicKeystr = MyKey.publicKeystr;
|
String privateKeystr = MyKey.privateKeystr;
|
PublicKey heepayPublicKey = null;
|
PrivateKey privateKey = null;
|
String content = "";
|
try {
|
//密钥配置
|
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
byte[] publicKeyPath = Base64.decode(publicKeystr.getBytes());
|
byte[] privateKeyPath = Base64.decode(privateKeystr.getBytes());
|
heepayPublicKey = keyFactory.generatePublic(new X509EncodedKeySpec(publicKeyPath));
|
privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKeyPath));
|
//加密
|
content = signEncrypt.encrypt(signStr, heepayPublicKey);
|
}catch (Exception e){
|
throw new RuntimeException("加密有误");
|
}
|
|
//加签
|
String sign = signEncrypt.sign(signStr, privateKey);
|
Map<String, String> map = new HashMap<>();
|
map.put("encrypt_data", content);
|
map.put("agent_id",agent_id);
|
map.put("sign",sign);
|
|
logger.info("请求参数:{}",map);
|
|
String result = HttpUtil.sendPost("Https://Pay.Heepay.com/WithholdAuthPay/SendPaySMS.aspx",map);
|
|
logger.info("响应参数:{}", result);
|
|
//录入订单信息
|
PayRecord payRecord = new PayRecord();
|
payRecord.setTotalAmount(pay_amt);
|
payRecord.setUserId(customerUser.getId());
|
payRecord.setPayType("sd");
|
payRecord.setPayStatus(3);
|
payRecord.setOutTradeNo(agent_bill_id);
|
// 转换为LocalDateTime
|
Instant instant = now.toInstant();
|
ZoneId zoneId = ZoneId.systemDefault();
|
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zoneId);
|
payRecord.setPayDate(localDateTime);
|
HuiFuBaoSendPayInfo huiFuBaoSendPayInfo = null;
|
try {
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
DocumentBuilder builder = factory.newDocumentBuilder();
|
|
InputSource inputSource = new InputSource(new StringReader(result));
|
Document document = builder.parse(inputSource);
|
|
// 提取节点的值
|
String retMsg = getElementValue(document, "ret_msg");
|
String encryptData = getElementValue(document, "encrypt_data");
|
if (!Objects.equals("已经发送短信验证码",retMsg)){
|
logger.info("短信发送有误");
|
throw new RuntimeException("短信发送有误");
|
}
|
|
if (StrUtil.isEmpty(encryptData)){
|
throw new RuntimeException("发送支付短信失败");
|
}
|
|
String decrypt = signEncrypt.decrypt(encryptData,privateKey);
|
//继续解析解密后的值拿到sign_url
|
String replace = "{\""+decrypt.replace("=", "\":\"").replace("&", "\",\"")+"\"}";
|
huiFuBaoSendPayInfo = JSONObject.parseObject(replace, HuiFuBaoSendPayInfo.class);
|
payRecord.setMobileVerifyCode(huiFuBaoSendPayInfo.getHyTokenId());
|
} catch (Exception e) {
|
logger.error("系统异常,请联系管理人员。");
|
throw new RuntimeException(e);
|
}
|
iPayRecordService.saveOrUpdate(payRecord);
|
huiFuBaoSendPayInfo.setAgentBillId(agent_bill_id);
|
return huiFuBaoSendPayInfo;
|
}
|
|
@SneakyThrows
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public ConfirmVo confirmPay(HuiFuBaoPayVo vo, UserDetail user) {
|
ConfirmVo confirmVo = new ConfirmVo();
|
if (user == null || user.getId() == null) {
|
throw new CommonException("Token无效");
|
}
|
CustomerUser customerUser = iCustomerUserService.getById(user.getId());
|
VipCardOrder vipCardOrder = vipCardOrderMapper.selectOne(new LambdaQueryWrapper<VipCardOrder>()
|
.eq(VipCardOrder::getOrderId, vo.getAgentBillId()));
|
if (vipCardOrder == null) {
|
throw new CommonException("订单不存在");
|
}
|
VipCard card = vipCardService.getOne(new LambdaQueryWrapper<VipCard>()
|
.eq(VipCard::getCardId, vipCardOrder.getCardId()));
|
|
if (card == null) {
|
throw new CommonException("不存在此类会员卡");
|
}
|
|
if (customerUser == null) {
|
throw new CommonException("用户不存在");
|
}
|
|
//商户编号,(汇付宝商户内码:七位整数数字)
|
String agent_id = merchId;
|
//二级商户号,传了要参与签名(集团商户模式)
|
String ref_agent_id = "";
|
//版本号,固定为1
|
String version = "1.0";
|
//支付订单创建成功的标记(短信接口返回)
|
String hy_token_id = vo.getHyAuthUid();
|
if (StrUtil.isEmpty(hy_token_id)){
|
logger.error("授权码不能为空");
|
throw new RuntimeException("授权码不能为空");
|
}
|
//支付短信验证码
|
String verify_code = vo.getVerifyCode();
|
if (StrUtil.isEmpty(verify_code)){
|
logger.error("短信验证码不能为空");
|
throw new RuntimeException("短信验证码不能为空");
|
}
|
//拼接待加密签名参数
|
|
String signStr = "hy_token_id=" + hy_token_id +
|
"&ref_agent_id=" + ref_agent_id +
|
"&verify_code=" + verify_code +
|
"&version=" + version;
|
|
System.out.println("待加密签名串:--------->" + signStr);
|
logger.info("待加密签名串:{}",signStr);
|
|
SignEncrypt signEncrypt = new SignEncrypt();
|
// 使用类名和常量名来访问常量
|
String publicKeystr = MyKey.publicKeystr;
|
String privateKeystr = MyKey.privateKeystr;
|
//密钥配置
|
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
byte[] publicKeyPath = Base64.decode(publicKeystr.getBytes());
|
byte[] privateKeyPath = Base64.decode(privateKeystr.getBytes());
|
PublicKey heepayPublicKey = keyFactory.generatePublic(new X509EncodedKeySpec(publicKeyPath));
|
PrivateKey privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKeyPath));
|
//加密
|
String content = signEncrypt.encrypt(signStr, heepayPublicKey);
|
//加签
|
String sign = signEncrypt.sign(signStr, privateKey);
|
|
Map<String, String> map = new HashMap<>();
|
map.put("encrypt_data", content);
|
map.put("agent_id",agent_id);
|
map.put("sign",sign);
|
|
System.out.println("请求参数:--------->" + map);
|
logger.info("确认提交请求参数:{}",map);
|
|
LambdaQueryWrapper<PayRecord> payRecordLambdaQueryWrapper = Wrappers.lambdaQuery();
|
payRecordLambdaQueryWrapper.eq(PayRecord::getMobileVerifyCode,vo.getHyAuthUid());
|
payRecordLambdaQueryWrapper.eq(PayRecord::getUserId,customerUser.getId());
|
PayRecord payRecord = iPayRecordService.getOne(payRecordLambdaQueryWrapper);
|
|
if (payRecord == null){
|
throw new RuntimeException("订单不存在" );
|
}
|
|
String result = HttpUtil.sendPost("Https://Pay.Heepay.com/WithholdAuthPay/ConfirmPay.aspx",map);
|
System.out.println("响应参数:--------->" + result);
|
logger.info("确认提交响应参数:{}",result);
|
if (StrUtil.isEmpty(result)){
|
logger.error("支付失败 请求操作的资源不存在");
|
payRecord.setPayStatus(2);
|
payRecord.setPayError(ResultCode.ORDER_ERROR.getMsg());
|
payRecord.setPayErrorCode(String.valueOf(ResultCode.ORDER_ERROR.getCode()));
|
confirmVo.setResult(false);
|
}
|
|
try {
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
DocumentBuilder builder = factory.newDocumentBuilder();
|
|
InputSource inputSource = new InputSource(new StringReader(result));
|
Document document = builder.parse(inputSource);
|
confirmVo.setResult(true);
|
// 提取节点的值
|
String retMsg = getElementValue(document, "ret_msg");
|
String encryptData = getElementValue(document, "encrypt_data");
|
String retCode = getElementValue(document, "ret_code");
|
if (!Objects.equals("0000",retCode)){
|
logger.info(retMsg);
|
payRecord.setPayError(retMsg);
|
payRecord.setPayErrorCode(retCode);
|
confirmVo.setResult(false);
|
}
|
|
String decrypt = signEncrypt.decrypt(encryptData,privateKey);
|
//继续解析解密后的值拿到sign_url
|
String replace = "{\""+decrypt.replace("=", "\":\"").replace("&", "\",\"")+"\"}";
|
Map<String,String> objectMap = JSONObject.parseObject(replace, Map.class);
|
String hyTokenId = objectMap.get("hy_bill_no");
|
payRecord.setTradeNo(hyTokenId);
|
} catch (Exception e) {
|
logger.error("系统异常,请联系管理人员。");
|
e.printStackTrace();
|
confirmVo.setResult(false);
|
}
|
|
iPayRecordService.saveOrUpdate(payRecord);
|
return confirmVo;
|
}
|
|
@SneakyThrows
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public HuiFuBaoPayInfo submitPay(HuiFuBaoPayVo vo, UserDetail user) {
|
Customer customer = customerMapper.getLatestCustomerRecord(user.getPhone());
|
if (user.getId() == null) {
|
throw new CommonException("登陆用户不存在");
|
}
|
CustomerUser customerUser = iCustomerUserService.getById(user.getId());
|
if (customerUser == null) {
|
throw new CommonException("用户不存在");
|
}
|
|
Date now = new Date();
|
|
//商户编号,(汇付宝商户内码:七位整数数字)
|
String agent_id = merchId;
|
|
//二级商户号,传了要参与签名(集团商户模式)
|
String ref_agent_id = vo.getRefAgentId();
|
//是否分润单,传了要参与签名(集团商户模式;分润单需要调分润接口,不然不会结算)
|
String is_guarantee = vo.getIsGuarantee();
|
|
//版本号,固定为1
|
String version = "1";
|
|
|
long tenDigitTimestamp = System.currentTimeMillis() / 1000;
|
//商户订单号
|
String agent_bill_id = String.valueOf(tenDigitTimestamp);
|
|
//商户订单时间,格式为"yyyyMMddhhmmss"
|
SimpleDateFormat sd = new SimpleDateFormat("yyyyMMddHHmmss");
|
String agent_bill_time = sd.format(now);
|
|
//支付金额,单位:元,保留二位小数
|
String pay_amt = String.valueOf(vo.getPayAmt());
|
if (StrUtil.isEmpty(pay_amt)){
|
throw new RuntimeException("支付金额不能为空");
|
}
|
//商品名称,中文UTF-8处理
|
String goods_name = vo.getGoodsName();
|
if (StrUtil.isEmpty(goods_name)){
|
throw new RuntimeException("商品名称不能为空");
|
}
|
//授权码
|
// String hy_auth_uid = "1af7fa0e3f496281398fda48b4bdf5bb";
|
String hy_auth_uid = vo.getHyAuthUid();
|
if (StrUtil.isEmpty(hy_auth_uid)){
|
throw new RuntimeException("授权码不能为空");
|
}
|
|
//用户IP地址
|
String user_ip = customer.getIpAddres();
|
//支付后返回的商户处理页面,URL参数是以http://或https://开头的完整URL地址(后台处理),提交的url地址必须外网能访问到,否则无法通知商户。值可以为空,但不可以为null。
|
String notify_url = domainUrl + "/test/testreceive.aspx";
|
String return_url = returnPayUrl;
|
//拼接待加密签名参数
|
|
String signStr = "agent_bill_id=" + agent_bill_id +
|
"&agent_bill_time=" + agent_bill_time +
|
"&agent_id=" + agent_id +
|
"&goods_name=" + goods_name +
|
"&hy_auth_uid=" + hy_auth_uid +
|
"&is_guarantee=" +is_guarantee +
|
"¬ify_url=" + notify_url +
|
"&return_url=" + return_url +
|
"&pay_amt=" + pay_amt +
|
"&ref_agent_id=" + ref_agent_id +
|
"&user_ip=" + user_ip +
|
"&version=" + version;
|
|
logger.info("待加密签名串:{}",signStr);
|
System.out.println("待加密签名串:--------->" + signStr);
|
|
SignEncrypt signEncrypt = new SignEncrypt();
|
// 使用类名和常量名来访问常量
|
String publicKeystr = MyKey.publicKeystr;
|
String privateKeystr = MyKey.privateKeystr;
|
//密钥配置
|
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
byte[] publicKeyPath = Base64.decode(publicKeystr.getBytes());
|
byte[] privateKeyPath = Base64.decode(privateKeystr.getBytes());
|
PublicKey heepayPublicKey = keyFactory.generatePublic(new X509EncodedKeySpec(publicKeyPath));
|
PrivateKey privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKeyPath));
|
//加密
|
String content = signEncrypt.encrypt(signStr, heepayPublicKey);
|
//加签
|
String sign = signEncrypt.sign(signStr, privateKey);
|
|
Map<String, String> map = new HashMap<>();
|
map.put("encrypt_data", content);
|
map.put("agent_id",agent_id);
|
map.put("sign",sign);
|
|
System.out.println("请求参数:--------->" + map);
|
logger.info("请求参数 :{}",map);
|
|
String result = HttpUtil.sendPost("https://Pay.Heepay.com/WithholdAuthPay/SubmitPay.aspx",map);
|
System.out.println("响应参数:--------->" + result);
|
logger.info("响应参数 :{}",result);
|
|
JsonNode jsonNode = null;
|
try {
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
DocumentBuilder builder = factory.newDocumentBuilder();
|
|
InputSource inputSource = new InputSource(new StringReader(result));
|
Document document = builder.parse(inputSource);
|
|
// 提取节点的值
|
String retCode = getElementValue(document, "ret_code");
|
String retMsg = getElementValue(document, "ret_msg");
|
// String encryptData = getElementValue(document, "encrypt_data");
|
if (!Objects.equals("0000",retCode)){
|
logger.info(retMsg);
|
throw new RuntimeException(retMsg);
|
}
|
} catch (Exception e) {
|
logger.error("系统异常,请联系管理人员。");
|
throw new RuntimeException(e);
|
}
|
//继续解析解密后的值拿到sign_url
|
|
HuiFuBaoPayInfo huiFuBaoPayInfo = queryPay(vo);
|
|
|
//录入订单信息
|
PayRecord payRecord = new PayRecord();
|
payRecord.setTotalAmount(huiFuBaoPayInfo.getPayAmt());
|
payRecord.setTradeNo(huiFuBaoPayInfo.getJnetBillNo());
|
payRecord.setUserId(customerUser.getId());
|
payRecord.setPayType("sd");
|
payRecord.setPayStatus(1);
|
payRecord.setOutTradeNo(agent_bill_id);
|
// 转换为LocalDateTime
|
Instant instant = now.toInstant();
|
ZoneId zoneId = ZoneId.systemDefault();
|
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zoneId);
|
payRecord.setPayDate(localDateTime);
|
if (!Objects.equals("1",huiFuBaoPayInfo.getResult())){
|
payRecord.setPayStatus(2);
|
payRecord.setPayErrorCode(huiFuBaoPayInfo.getDetailErrorCode());
|
payRecord.setPayError(huiFuBaoPayInfo.getDetailErrorMessage());
|
iPayRecordService.saveOrUpdate(payRecord);
|
throw new RuntimeException(huiFuBaoPayInfo.getDetailErrorMessage());
|
}
|
iPayRecordService.saveOrUpdate(payRecord);
|
return huiFuBaoPayInfo;
|
}
|
|
@Override
|
public HuiFuBaoPayInfo queryPay(HuiFuBaoPayVo vo) {
|
//请求公用参数
|
String param = "version=" + "1"
|
+ "&agent_id=" + merchId
|
+ "&agent_bill_id=" + vo.getAgentBillId()
|
+ "&agent_bill_time=" + vo.getAgentBillTime()
|
+ "&return_mode=" + "1";
|
|
//签名前
|
String oldSign = param + "&key=" + "5B94631C49B64949B687803E";
|
logger.info("签名串:{}",oldSign);
|
System.out.println("签名串:--------->"+oldSign);
|
|
String sign = EncryptUtil.md5(oldSign);
|
logger.info("签名后:{}", sign);
|
|
|
String url = "version=" + "1"
|
+ "&agent_id=" + merchId
|
+ "&agent_bill_id=" + vo.getAgentBillId()
|
+ "&agent_bill_time=" + vo.getAgentBillTime()
|
+ "&return_mode=" + "1"
|
+ "&sign=" + sign;
|
|
logger.info("url参数:{}", url);
|
|
HttpUtil httpUtil = new HttpUtil();
|
String result = httpUtil.sendHttpPost(new HttpPost("https://query.heepay.com/Payment/Query.aspx?" + url));
|
logger.info("响应结果:{}",result);
|
|
if (Objects.equals("无效的签名数据",result) || Objects.equals("version参数错误",result)){
|
throw new RuntimeException(result);
|
}
|
String replace = "{\""+result.replace("=", "\":\"").replace("|", "\",\"")+"\"}";
|
HuiFuBaoPayInfo huiFuBaoPayInfo = JSONObject.parseObject(replace, HuiFuBaoPayInfo.class);
|
if (huiFuBaoPayInfo == null){
|
throw new RuntimeException("订单有误,请联系管理人员。");
|
}
|
|
return huiFuBaoPayInfo;
|
}
|
|
@Override
|
public GetOrderStatusVo getOrderStatus(String payOrderId) {
|
GetOrderStatusVo getOrderStatusVo = new GetOrderStatusVo();
|
getOrderStatusVo.setValue("END");
|
LambdaQueryWrapper<PayRecord> lambdaQueryWrapper = Wrappers.lambdaQuery();
|
lambdaQueryWrapper.eq(PayRecord::getOutTradeNo,payOrderId);
|
PayRecord payRecord = iPayRecordService.getOne(lambdaQueryWrapper);
|
if (payRecord == null){
|
getOrderStatusVo.setValue("INVALID");
|
return getOrderStatusVo;
|
}
|
// 创建一个DateTimeFormatter对象,定义日期和时间的格式
|
HuiFuBaoPayVo huiFuBaoPayVo = new HuiFuBaoPayVo();
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
|
// 使用formatter将LocalDateTime转换为字符串
|
String formattedDateTime = payRecord.getPayDate().format(formatter);
|
huiFuBaoPayVo.setAgentBillId(payOrderId);
|
huiFuBaoPayVo.setAgentBillTime(formattedDateTime);
|
HuiFuBaoPayInfo huiFuBaoPayInfo = queryPay(huiFuBaoPayVo);
|
if (huiFuBaoPayInfo == null){
|
getOrderStatusVo.setValue("INVALID");
|
return getOrderStatusVo;
|
}
|
if (!Objects.equals("1",huiFuBaoPayInfo.getResult())){
|
getOrderStatusVo.setValue("INVALID");
|
}
|
return getOrderStatusVo;
|
}
|
|
@SneakyThrows
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public ResponseEntity callBack(PayCallBackVo vo) {
|
if (StrUtil.isEmpty(vo.getEncrypt_data())){
|
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("回调参数不能为空");
|
}
|
|
SignEncrypt signEncrypt = new SignEncrypt();
|
// 使用类名和常量名来访问常量
|
String privateKeystr = MyKey.privateKeystr;
|
//密钥配置
|
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
byte[] privateKeyPath = Base64.decode(privateKeystr.getBytes());
|
PrivateKey privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKeyPath));
|
String decrypt = signEncrypt.decrypt(vo.getEncrypt_data(),privateKey);
|
//继续解析解密后的值拿到sign_url
|
String replace = "{\""+decrypt.replace("=", "\":\"").replace("&", "\",\"")+"\"}";
|
PayCallBackInfo payCallBackInfo = JSONObject.parseObject(replace, PayCallBackInfo.class);
|
|
LambdaQueryWrapper<PayRecord> payRecordLambdaQueryWrapper = Wrappers.lambdaQuery();
|
payRecordLambdaQueryWrapper.eq(PayRecord::getOutTradeNo,payCallBackInfo.getAgentBillId());
|
PayRecord payRecord = iPayRecordService.getOne(payRecordLambdaQueryWrapper);
|
if (payRecord == null){
|
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("支付单不能为空");
|
}
|
|
LambdaQueryWrapper<VipCardOrder> vipCardOrderLambdaQueryWrapper = Wrappers.lambdaQuery();
|
vipCardOrderLambdaQueryWrapper.eq(VipCardOrder::getOrderId,payCallBackInfo.getAgentBillId());
|
VipCardOrder vipCardOrder = vipCardOrderMapper.selectOne(vipCardOrderLambdaQueryWrapper);
|
if (vipCardOrder == null){
|
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("vip支付单不能为空");
|
}
|
|
VipCard card = vipCardService.getOne(new LambdaQueryWrapper<VipCard>()
|
.eq(VipCard::getCardId, vipCardOrder.getCardId()));
|
if (card == null) {
|
throw new CommonException("不存在此类会员卡!");
|
}
|
|
//修改订单信息
|
payRecord.setTradeNo(payCallBackInfo.getHyBillNo());
|
payRecord.setPayDate(LocalDateTime.now());
|
payRecord.setPayStatus(1);
|
String vipOrderStatus = VipCardOrderEnum.STATUS_END.getCode();
|
if (!Objects.equals(ShanTaiSelectOrderEnum.SUCCESS.getCode(),payCallBackInfo.getStatus())){
|
payRecord.setPayStatus(2);
|
payRecord.setPayErrorCode(payCallBackInfo.getStatus());
|
payRecord.setPayError(payCallBackInfo.getDealNote());
|
vipOrderStatus = VipCardOrderEnum.STATUS_INVALID.getCode();
|
}
|
iPayRecordService.saveOrUpdate(payRecord);
|
vipCardOrderMapper.update(null, Wrappers.<VipCardOrder>lambdaUpdate()
|
.set(VipCardOrder::getStatus, vipOrderStatus)
|
.eq(VipCardOrder::getId, vipCardOrder.getId()));
|
vipCardOrder.setStatus(vipOrderStatus);
|
VipEffectiveTimeVo vipEffectiveTimeVo = iCustomerUserService.calculateExpiredDate(vipCardOrder.getUserId(), card.getValidDate(), null, null);
|
iCustomerUserService.updateVipEffectiveTime(vipCardOrder, vipEffectiveTimeVo);
|
return ResponseEntity.ok("ok");
|
}
|
|
private static String getElementValue(Document document, String tagName) {
|
NodeList nodeList = document.getElementsByTagName(tagName);
|
if (nodeList.getLength() > 0) {
|
Element element = (Element) nodeList.item(0);
|
return element.getTextContent();
|
}
|
return null;
|
}
|
}
|