package org.example.ssmico.demos.web.controller.pay;
|
|
import cn.hutool.core.bean.BeanUtil;
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.serializer.SerializerFeature;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.google.gson.JsonObject;
|
import com.google.gson.JsonParser;
|
import lombok.extern.slf4j.Slf4j;
|
import org.example.ssmico.demos.web.mapper.*;
|
import org.example.ssmico.demos.web.util.*;
|
import org.example.ssmico.demos.web.dto.AddressJsonList;
|
import org.example.ssmico.demos.web.dto.PayResDataDto;
|
import org.example.ssmico.demos.web.dto.PaymentCallbackDto;
|
import org.example.ssmico.demos.web.entity.*;
|
import org.example.ssmico.demos.web.out.PaymentCallbackOut;
|
import org.example.ssmico.demos.web.service.TWalletService;
|
import org.example.ssmico.demos.web.service.impl.UserPayServiceImpl;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.stereotype.Controller;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.web.bind.annotation.CrossOrigin;
|
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
import project.party.model.Party;
|
import project.wallet.Wallet;
|
import project.wallet.WalletExtend;
|
|
import java.math.BigDecimal;
|
import java.util.*;
|
|
/**
|
* @program: ssm-ico
|
* @description: 火币支付回调
|
* @create: 2024-04-16 17:20
|
**/
|
@Controller
|
@RequestMapping({"/wap/api/paymentCallback"})
|
@CrossOrigin
|
@Slf4j
|
public class PaymentCallbackApi {
|
@Autowired
|
private UserPayServiceImpl userPayService;
|
@Autowired
|
private TWalletService tWalletService;
|
@Autowired
|
private TMoneyLogMapper tMoneyLogMapper;
|
@Autowired
|
private RechargeBlockchainMapper rechargeBlockchainMapperf;
|
@Autowired
|
private PartyMapper partyMapper;
|
@Autowired
|
private LogMapper logMapper;
|
@Value("${HB_PUBKEY}")
|
private String pubKey;
|
|
private static final Object lock = new Object();
|
|
@Autowired
|
private TUserPayAddressMapper tUserPayAddressMapper;
|
|
@Autowired
|
private WalletExtendMapper walletExtendMapper;
|
|
@ResponseBody
|
@RequestMapping(value = "/topUp")
|
@Transactional
|
public PaymentCallbackOut topUp(@RequestBody PaymentCallbackDto res) {
|
PaymentCallbackOut.DataOut dataOut = new PaymentCallbackOut.DataOut();
|
PaymentCallbackOut out = new PaymentCallbackOut();
|
String userId = null;
|
try {
|
Long count = rechargeBlockchainMapperf.selectCount(new LambdaQueryWrapper<RechargeBlockchain>()
|
.eq(RechargeBlockchain::getTx,res.getData().getTxid()));
|
if(count > 0){
|
System.out.println("------"+count);
|
out.setStatus(200);
|
dataOut.setSuccess_data("success");
|
return out;
|
}
|
log.info("充值回调参数--->" + res);
|
TUserPayAddress payAddress = tUserPayAddressMapper.selectOne(new LambdaQueryWrapper<TUserPayAddress>()
|
.eq(TUserPayAddress::getAddress, res.getData().getAddress())
|
.eq(TUserPayAddress::getType, res.getData().getChain().contains("bnb_bsc")?"eth":res.getData().getChain()));
|
if(null != payAddress && StringUtils.isNotBlank(payAddress.getPartyUuid())){
|
userId = payAddress.getPartyUuid();
|
}else{
|
ResultObject bindingState = userPayService.getBindingState( res.getData().getChain().contains("bnb_bsc")?"eth":res.getData().getChain(), res.getData().getAddress());
|
AddressJsonList jsonList = BeanUtil.toBean(bindingState.getData(), AddressJsonList.class);
|
if(null == jsonList){
|
out.setStatus(500);
|
dataOut.setSuccess_data("该用户没有绑定地址: " + userId+"地址:"+res.getData().getAddress());
|
}
|
userId = jsonList.getUser_id();
|
}
|
|
// boolean isValid = verifySignature(res);
|
boolean isValid = true;
|
log.info("签名验证结果: " + isValid);
|
if (!isValid) {
|
out.setStatus(500);
|
dataOut.setSuccess_data("签名验证失败");
|
out.setData(dataOut);
|
} else {
|
synchronized (lock) {
|
processTopUp(res, out, dataOut, userId);
|
saveLog(res.getData(),userId,out.getData().getSuccess_data());
|
return out;
|
}
|
}
|
} catch (Exception e) {
|
log.error("充值回调异常", e);
|
out.setData(dataOut);
|
return out;
|
}
|
saveLog(res.getData(),userId,out.getData().getSuccess_data());
|
return out;
|
|
}
|
|
private void processTopUp(PaymentCallbackDto res, PaymentCallbackOut out, PaymentCallbackOut.DataOut dataOut,String userId) {
|
if(res.getData().getCoin().startsWith("usdt")){
|
Wallet tWallet = tWalletService.getOne(new LambdaQueryWrapper<Wallet>().eq(Wallet::getPartyId, userId));
|
if (tWallet == null) {
|
out.setStatus(500);
|
dataOut.setSuccess_data("充值用户不存在: " + userId);
|
} else {
|
BigDecimal money = new BigDecimal(tWallet.getMoney());
|
BigDecimal total = new BigDecimal(res.getData().getTotal());
|
double ultimatelyMoney = money.add(total).doubleValue();
|
res.getData().setChain("USDT");
|
addLog(res.getData(), tWallet.getPartyId(),tWallet.getMoney(), ultimatelyMoney);
|
tWallet.setMoney(ultimatelyMoney);
|
tWalletService.update(tWallet, new LambdaUpdateWrapper<Wallet>()
|
.eq(Wallet::getPartyId, tWallet.getPartyId()));
|
String jsonString = JSON.toJSONString(tWallet, SerializerFeature.WriteClassName);
|
RedisShardedPoolUtils.set( WalletRedisKeys.WALLET_PARTY_ID + tWallet.getPartyId().toString(),jsonString);
|
out.setStatus(200);
|
dataOut.setSuccess_data("success");
|
}
|
out.setData(dataOut);
|
}else{
|
if(res.getData().getCoin().contains("bnb_bsc")){
|
res.getData().setChain("bnb");
|
}else{
|
res.getData().setChain(res.getData().getCoin());
|
}
|
WalletExtend walletExtend = walletExtendMapper.selectOne(new LambdaQueryWrapper<WalletExtend>()
|
.eq(WalletExtend::getWallettype, res.getData().getChain()).eq(WalletExtend::getPartyId,userId));
|
if(null == walletExtend){
|
walletExtend = new WalletExtend();
|
walletExtend.setUuid(ApplicationUtil.getCurrentTimeUUID());
|
walletExtend.setPartyId(userId);
|
walletExtend.setAmount(Double.parseDouble(res.getData().getTotal()));
|
walletExtend.setWallettype(res.getData().getChain());
|
walletExtendMapper.insert(walletExtend);
|
addLog(res.getData(), userId,Double.parseDouble(res.getData().getTotal()), walletExtend.getAmount());
|
out.setStatus(200);
|
dataOut.setSuccess_data("success");
|
String json = JSON.toJSONString(walletExtend, SerializerFeature.WriteClassName);
|
RedisShardedPoolUtils.set(WalletRedisKeys.WALLET_EXTEND_PARTY_ID + walletExtend.getPartyId() + walletExtend.getWallettype(), json);
|
return;
|
}
|
walletExtend.setPartyId(userId);
|
walletExtend.setAmount(walletExtend.getAmount()+Double.parseDouble(res.getData().getTotal()));
|
walletExtendMapper.update(walletExtend,new LambdaUpdateWrapper<WalletExtend>().eq(WalletExtend::getUuid,walletExtend.getUuid()));
|
out.setStatus(200);
|
dataOut.setSuccess_data("success");
|
addLog(res.getData(), userId,Double.parseDouble(res.getData().getTotal()), walletExtend.getAmount());
|
String json = JSON.toJSONString(walletExtend, SerializerFeature.WriteClassName);
|
RedisShardedPoolUtils.set(WalletRedisKeys.WALLET_EXTEND_PARTY_ID + walletExtend.getPartyId() + walletExtend.getWallettype(), json);
|
}
|
|
}
|
|
@Transactional
|
public void addLog(PayResDataDto data, String partyId,Double money, double amountAfterRecharge) {
|
saveRechargeBlockchain(data, partyId);
|
saveMoneyLog(data, partyId,money, amountAfterRecharge);
|
}
|
|
// 存储充值申请订单记录
|
private void saveRechargeBlockchain(PayResDataDto data, String paryId) {
|
RechargeBlockchain recharge = new RechargeBlockchain();
|
recharge.setUuid(UUID.randomUUID().toString().replace("-", ""));
|
recharge.setOrder_no(data.getOrder_id());
|
recharge.setBlockchain_name(data.getChain());
|
recharge.setVolume(Double.parseDouble(data.getTotal()));
|
recharge.setSymbol(data.getCoin());
|
recharge.setPartyId(paryId);
|
recharge.setSucceeded(data.getStatus()==0?1:data.getStatus());
|
recharge.setChannel_address(data.getAddress());
|
recharge.setTx(data.getTxid());
|
recharge.setCreated(new Date());
|
rechargeBlockchainMapperf.insert(recharge);
|
System.out.println("存储充值申请订单记录");
|
}
|
|
// 记录日志
|
private void saveLog(PayResDataDto data,String partyId,String msg) {
|
Log log = new Log();
|
log.setUuid(UUID.randomUUID().toString().replace("-", ""));
|
Party party = partyMapper.selectOne(new LambdaQueryWrapper<Party>().eq(Party::getUuid, partyId));
|
log.setCategory(Constants.LOG_CATEGORY_SECURITY);
|
log.setLog("用户充值申请,订单号[" + data.getOrder_id()+"]"+"币种:"+data.getChain()+"日志信息"+msg);
|
log.setPartyId(partyId);
|
log.setUsername(party.getUsername());
|
log.setCreateTime(new Date());
|
logMapper.insert(log);
|
}
|
|
// 记录资金变动日志
|
private void saveMoneyLog(PayResDataDto data, String partyId,Double money, double amountAfterRecharge) {
|
TMoneyLog tMoneyLog = new TMoneyLog();
|
String msg = "充币,订单id:" + data.getOrder_id() + ",状态:" + (data.getStatus()==0?1:data.getStatus()) + "--(1确认成功 5失败 8等待退款 10退款中 20已退款)" + (StringUtils.isNotBlank(data.getReject_reason()) ? data.getReject_reason() : "");
|
tMoneyLog.setUuid(UUID.randomUUID().toString().replace("-", ""));
|
tMoneyLog.setLog(msg);
|
tMoneyLog.setWallettype(data.getChain());
|
tMoneyLog.setPartyId(partyId);
|
tMoneyLog.setAmount(Double.valueOf(data.getTotal()));
|
tMoneyLog.setAmountBefore(money);
|
tMoneyLog.setAmountAfter(amountAfterRecharge);
|
tMoneyLog.setContentType("支付");
|
tMoneyLog.setCategory("充币");
|
tMoneyLog.setCreateTime(new Date());
|
tMoneyLogMapper.insert(tMoneyLog);
|
}
|
|
|
public boolean verifySignature(PaymentCallbackDto res) {
|
try {
|
ObjectMapper objectMapper = new ObjectMapper();
|
String data = objectMapper.writeValueAsString(res.getData());
|
RsaSigner signer = new RsaSigner();
|
JsonParser jp = new JsonParser();
|
JsonObject resEle = jp.parse(data).getAsJsonObject();
|
boolean retSignOK = signer.verifySign(resEle, res.getSign(), pubKey);
|
return retSignOK;
|
} catch (Exception e) {
|
log.error("验证签名异常", e);
|
}
|
return false;
|
}
|
|
}
|