支付模块-下单接口修改以及支付结果回溯接口修改

This commit is contained in:
2024-12-26 10:20:18 +08:00
parent 4760dba312
commit efd0fa1e44
18 changed files with 498 additions and 222 deletions

View File

@ -4,10 +4,10 @@ import lombok.Data;
@Data
public class WeChatRechargeBacktracking {
private String id;
private String create_time;
private String resource_type;
private String event_type;
private String summary;
private WeChatRechargeBacktrackingResource resource;
private String id;//回调通知唯一编号
private String create_time;//通知创建时间
private String resource_type;//资源数据类型
private String event_type;//回调通知类型TRANSACTION.SUCCESS
private String summary;//备注
private WeChatRechargeBacktrackingResource resource;//通知资源数据
}

View File

@ -4,10 +4,10 @@ import lombok.Data;
@Data
public class WeChatRechargeBacktrackingResource{
private String original_type;
private String algorithm;
private String cliphertext;
private String associated_data;
private String nonce;
private String original_type;//加密前的对象类型transaction
private String algorithm;//加密算法类型
private String ciphertext;//回调数据密文ciphertext
private String associated_data;//附加数据
private String nonce;//随机串
}

View File

@ -34,6 +34,7 @@ public interface NgUserRechargeRecordsMapper
* @param rechargeCode
* @return
*/
@Select("select * from ng_user_recharge_records where recharge_code=#{rechargeCode}")
public NgUserRechargeRecords selectNgUserRechargeRecordsByRechargeCode(String rechargeCode);
/**

View File

@ -4,6 +4,7 @@ import java.util.List;
import com.fastbee.rechargecard.domain.UserRechargeCards;
import com.github.yulichang.base.MPJBaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
/**
@ -34,6 +35,7 @@ public interface UserRechargeCardsMapper extends MPJBaseMapper<UserRechargeCards
* @param cardNumber
* @return 用户充值卡
*/
@Select("select * from user_recharge_cards where card_number=#{cardNumber}")
public UserRechargeCards selectUserRechargeCardsByCardNumber(String cardNumber);
/**

View File

@ -53,7 +53,7 @@ public interface IUserRechargeCardsService
* @param rechargeCode
* @return
*/
public int updateUserRechargeWechat(String rechargeCode);
public int updateUserRechargeWechat(String rechargeCode,BigDecimal payer_total) throws Exception;
/**
* 批量删除用户充值卡

View File

@ -0,0 +1,19 @@
package com.fastbee.rechargecard.service;
import com.fastbee.rechargecard.domain.UserRechargeCards;
import com.fastbee.rechargecard.domain.dto.WeChatRecharge;
import java.io.IOException;
import java.util.Map;
/**
* 用户微信支付Service接口
*/
public interface IUserWechatPayService {
/**
* 生成订单
* @param recharge
* @return
*/
public Map<String,String> CreateOrder(WeChatRecharge recharge) throws Exception;
}

View File

@ -32,11 +32,13 @@ public class NgUserRechargeRecordsServiceImpl implements INgUserRechargeRecordsS
NgUserRechargeRecords ngUserRechargeRecords=new NgUserRechargeRecords();
ngUserRechargeRecords.setRechargeTime(DateUtils.getNowDate());
ngUserRechargeRecords.setBalance(rechargecardUser.getAmount());
ngUserRechargeRecords.setAmount(rechargecardUser.getAmount());
ngUserRechargeRecords.setType(1);//微信
ngUserRechargeRecords.setStatus(0);//生成订单
ngUserRechargeRecords.setAreaCode(String.valueOf(rechargecardUser.getAreacode()));
ngUserRechargeRecords.setCardNumber(String.valueOf(rechargecardUser.getCardnumber()));
ngUserRechargeRecords.setRechargeCode(rechargecardUser.getRechargeCode());
ngUserRechargeRecords.setSerialNumber(rechargecardUser.getDeviceNumber());
return ngUserRechargeRecordsMapper.insertNgUserRechargeRecords(ngUserRechargeRecords);
}

View File

@ -214,8 +214,9 @@ public class UserConsumptionDetailsServiceImpl implements IUserConsumptionDetail
userConsumptionDetails.setPaymentStatus(0);
userConsumptionDetails.setPaymentMethod(recharge.getType());
userConsumptionDetails.setPaymentTime(DateUtils.getNowDate());
userConsumptionDetails.setStatus(0);
userConsumptionDetails.setStatus(2);
userConsumptionDetails.setCreateTime(DateUtils.getNowDate());
userConsumptionDetails.setDeviceNumber(recharge.getDeviceNumber());
return userConsumptionDetailsMapper.insertUserConsumptionDetails(userConsumptionDetails);
}

View File

@ -106,48 +106,73 @@ public class UserRechargeCardsServiceImpl implements IUserRechargeCardsService
* @return
*/
@Override
public int updateUserRechargeWechat(String rechargeCode) {
public int updateUserRechargeWechat(String rechargeCode,BigDecimal payer_total) throws Exception {
//用户充值记录中订单信息状态更改为已支付
NgUserRechargeRecords ngUserRechargeRecords=new NgUserRechargeRecords();
if(rechargeCode==null)
{
throw new Exception("订单编号为空");
}
if(userRechargeRecordsMapper.selectNgUserRechargeRecordsByRechargeCode(rechargeCode)==null)
{
throw new Exception("订单信息不存在");
}
ngUserRechargeRecords=userRechargeRecordsMapper.selectNgUserRechargeRecordsByRechargeCode(rechargeCode);//查询订单信息
ngUserRechargeRecords.setStatus(1);//状态更改为已支付
ngUserRechargeRecords.setRechargeCode(rechargeCode);
userRechargeRecordsMapper.updateNgUserRechargeRecords(ngUserRechargeRecords);
/* userConsumptionDetails.setCreateTime(DateUtils.getNowDate());
NgUserRechargeRecords ngUserRechargeRecords = NgUserRechargeRecords.builder()
.userId(info.getUserId()).userName(info.getUserName())
.cardNumber(info.getCardNumber()).areaCode(rechargecardUser.getAreacode())
.type(rechargecardUser.getStatus()).amount(rechargecardUser.getNumber())
.balance(info.getBalance()).rechargeTime(DateUtils.getNowDate())
.rechargeCode(null).status(0).serialNumber(null).deviceNumber(null).projectId(null)
.deptId(null)
.areaCode(rechargecardUser.getAreacode())
.build();*/
userRechargeRecordsMapper.updateNgUserRechargeRecordsWechat(ngUserRechargeRecords);
/*RechargecardUser rechargecardUser=new RechargecardUser();
// 计算新的余额
BigDecimal newBalance = rechargecardUser.getAmount().add(info.getBalance());*/
// 更新用户充值卡信息,包括新的余额
// info.setBalance(newBalance);
// info.setUpdateTime(DateUtils.getNowDate());
// info.setAreaCode(String.valueOf(rechargecardUser.getAreaCode()));
//用户充值卡中的余额更改
String cardNumber=ngUserRechargeRecords.getCardNumber();//卡号
BigDecimal balance=ngUserRechargeRecords.getAmount();//充值金额
if(!cardNumber.isEmpty())
{
if(userRechargeCardsMapper.selectUserRechargeCardsByCardNumber(cardNumber)==null)
{
throw new Exception("用户信息不存在");
}
UserRechargeCards rechargeCards=userRechargeCardsMapper.selectUserRechargeCardsByCardNumber(ngUserRechargeRecords.getCardNumber());
BigDecimal newBalance = rechargeCards.getBalance().add(balance);
System.out.println(cardNumber+"的余额从"+rechargeCards.getBalance()+"变成了"+newBalance);
rechargeCards.setBalance(newBalance);
userRechargeCardsMapper.updateUserRechargeCards(rechargeCards);
}else{
throw new Exception("卡号为空");
}
/*//构建主题
String topic ="hzlink/147/"+rechargecardUser.getDeviceNumber()+"/cmd/down";
//用户消费明细记录中状态更改为已支付
/*UserConsumptionDetails userConsumptionDetails=userConsumptionDetailsMapper.selectUserConsumptionDetailsBy();
userConsumptionDetails.setStatus(0);//更改为已支付
userConsumptionDetails.setPaymentStatus(2);//账单状态更改为已支付*/
String areaCode=ngUserRechargeRecords.getAreaCode();
//构建主题
String topic ="hzlink/147/"+ngUserRechargeRecords.getSerialNumber()+"/cmd/down";
//构建消息
Map<String,Object> param = new HashMap<>();
//远程阀控
param.put("cmd",1000);
Map<String,Object> data = new HashMap<>();
data.put("orderNum", ngUserRechargeRecords.getId());
data.put("cardNum",rechargecardUser.getCardnumber());
data.put("areaCode",rechargecardUser.getAreacode());
data.put("investBalance",rechargecardUser.getAmount().doubleValue());
data.put("investWater",rechargecardUser.getWater());
data.put("orderNum", rechargeCode);//订单号
data.put("cardNum",cardNumber);//卡号
data.put("areaCode",areaCode);//区域号
data.put("investBalance",balance);//充值的金额
data.put("investWater",100);//充值的水量
param.put("data",data);
pubMqttClient.publish(1,true,topic, JSONUtil.toJsonStr(param));*/
try{
//pubMqttClient.publish(1,true,topic, JSONUtil.toJsonStr(param));
}catch (Exception e)
{
throw new Exception("消息发布失败");
}
// int i = userRechargeCardsMapper.updateUserRechargeCards(info);
return 1;
}

View File

@ -0,0 +1,195 @@
package com.fastbee.rechargecard.service.impl;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fastbee.common.utils.pay.wxPayConfig;
import com.fastbee.rechargecard.domain.dto.WeChatRecharge;
import com.fastbee.rechargecard.service.INgUserRechargeRecordsService;
import com.fastbee.rechargecard.service.IUserConsumptionDetailsService;
import com.fastbee.rechargecard.service.IUserRechargeCardsService;
import com.fastbee.rechargecard.service.IUserWechatPayService;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@Service
public class UserWechatPayServiceImpl implements IUserWechatPayService {
/** 商户号 */
public static String mchId = "1531795301";
/** 商户API私钥文件路径 */
public static String privateKeyPath = "fastbee-common/src/main/java/com/fastbee/common/utils/pay/apiclient_key.pem";
/** 商户API证书序列号 */
public static String serial_no = "3075B63EF52666EDC3EAFC5D4FB35C02CE123A9C";
/** 商户APIV3密钥 */
public static String apiV3Key = "e85a203e8ca146102f5cd7ecff912580";
//微信小程序appid
public static String appId="wx308612d2a8423311";
//微信支付公钥地址
public static String publicKeyPath="fastbee-common/src/main/java/com/fastbee/common/utils/pay/wechat_public_key.pem";
@Override
/**
* 创建订单获取prepay_id和paySign
* @param recharge
* @return
* @throws Exception
*/
public Map<String, String> CreateOrder(WeChatRecharge recharge) throws Exception {
System.out.println("CreateOrder");
//请求URL
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi");
Map<String,String> result=new HashMap<>();
Map<String,Object> reqdata=new HashMap<String,Object>();
Map<String,Object> amount=new HashMap<>();
Map<String,Object> payer=new HashMap<>();
amount.put("total",recharge.getTotal());
System.out.print(recharge.getTotal());
amount.put("currency",recharge.getCurrency());
payer.put("openid",recharge.getOpenId());
reqdata.put("amount",amount);
reqdata.put("appid",appId);
reqdata.put("mchid",mchId);
reqdata.put("description",recharge.getCardnumber()+recharge.getAmount().toString());
reqdata.put("out_trade_no",recharge.getRechargeCode());
reqdata.put("notify_url","https://46b411f6.r3.cpolar.cn/pay/getresult");//"\t\n" +
reqdata.put("payer",payer);
//String Signature=getSign(reqdata);
Map<String,String> info=getSign(reqdata);
String timeStamp=info.get("timeStamp");
String nonce_str=info.get("nonce_str");
result.put("timeStamp",timeStamp);
result.put("mchid",mchId);
result.put("signType","RSA");
result.put("nonceStr",nonce_str);
result.put("partnerid",mchId);
String Signature=info.get("sign");
String Authorization="WECHATPAY2-SHA256-RSA2048 mchid=\""+mchId+"\",nonce_str=\""+nonce_str+"\",signature=\""+Signature+"\",timestamp=\""+timeStamp+"\",serial_no=\""+serial_no+"\"";
StringEntity entity = new StringEntity(JSONUtil.toJsonStr(reqdata), "utf-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Authorization",Authorization);
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
//完成签名并执行请求
CloseableHttpResponse response = httpClient.execute(httpPost);
try {
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
// 假设responseEntity是包含JSON响应的字符串
String responseEntity = EntityUtils.toString(response.getEntity());
// 使用Hutool的JSONUtil解析JSON字符串
JSONObject jsonObject = JSONUtil.parseObj(responseEntity);
// 安全地获取prepay_id的值
String prepayId = jsonObject.getStr("prepay_id");
System.out.println("Prepay ID: " + prepayId);
result.put("prepay_id",prepayId);
result.put("paySign",getPaySign(prepayId,timeStamp,nonce_str));
System.out.println("success,return body = " + prepayId);
return result;
} else if (statusCode == 204) {
return null;
} else {
System.out.println("failed,resp code = " + statusCode + ",return body = " + EntityUtils.toString(response.getEntity()));
throw new IOException("request failed");
}
} catch (IOException e) {
response.close();
httpClient.close();
throw new RuntimeException(e);
} finally {
response.close();
httpClient.close();
}
}
/**
* 生成签名
*/
private Map<String,String> getSign(Map<String,Object> reqBody) throws Exception {
//获取时间戳
String reqMethod="POST";
String url="/v3/pay/transactions/jsapi";
/*String reqMethod="GET";
String url="/v3/refund/domestic/refunds/123123123123";*/
String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
//timeStamp="1554208460";
String nonce_str= UUID.randomUUID().toString();
//nonce_str="593BEC0C930BF1AFEB40B4A08C8FB242";
String reqParam= JSONUtil.toJsonStr(reqBody);
/*HTTP请求方法\n
URL\n
请求时间戳\n
请求随机串\n
请求报文主体\n
*/
String signStr=reqMethod+"\n"+url+"\n"+timeStamp+"\n"+nonce_str+"\n"+reqParam +"\n";
//String signStr=reqMethod+"\n"+url+"\n"+timeStamp+"\n"+nonce_str+"\n\n";
String sign=sign(signStr.getBytes("utf-8"));
Map<String,String> info=new HashMap<>();
info.put("timeStamp",timeStamp);
info.put("nonce_str",nonce_str);
info.put("sign",sign);
/*//进行sha256
String sha256HexSignStr = DigestUtil.sha256Hex(signStr);
//在进行base64
String base64SignStr = Base64.getEncoder().encodeToString(sha256HexSignStr.getBytes());
*/
return info;
}
/**
* 生成前端所需签名
*/
private String getPaySign(String prepayId,String timeStamp,String nonce_str) throws Exception {
/**
* 使用字段appId、timeStamp、nonceStr、package
*/
String signStr=appId+"\n"+timeStamp+"\n"+nonce_str+"\n"+"prepay_id="+prepayId+"\n";
String sign=sign(signStr.getBytes("utf-8"));
return sign;
}
/**
* 生成签名方法
* @param message
* @return
* @throws Exception
*/
private String sign(byte[] message) throws Exception{
Signature sign;
sign = Signature.getInstance("SHA256withRSA");
//这里需要一个PrivateKey类型的参数就是商户的私钥。
//获取商户私钥——传商户私钥位置
PrivateKey privateKey = wxPayConfig.getPrivateKey(privateKeyPath);
sign.initSign(privateKey);
sign.update(message);
return Base64.getEncoder().encodeToString(sign.sign());
}
}

View File

@ -76,10 +76,10 @@
</where>
</select>
<select id="selectNgUserRechargeRecordsByRechargeCode" parameterType="String" resultMap="NgUserRechargeRecordsResult">
<!--<select id="selectNgUserRechargeRecordsByRechargeCode" parameterType="String" resultMap="NgUserRechargeRecordsResult">
<include refid="selectNgUserRechargeRecordsVo"/>
<where>
recharge_code = #{rechargeCode}
<if test="cardNumber != null and cardNumber != ''"> card_number = #{cardNumber}</if>
<if test="userId != null "> and user_id = #{userId}</if>
<if test="userName != null and userName != ''"> and user_name like concat('%', #{userName}, '%')</if>
@ -88,14 +88,13 @@
<if test="amount != null "> and amount = #{amount}</if>
<if test="balance != null "> and balance = #{balance}</if>
<if test="rechargeTime != null "> and recharge_time = #{rechargeTime}</if>
<if test="rechargeCode != null and rechargeCode != ''"> and recharge_code = #{rechargeCode}</if>
<if test="status != null "> and status = #{status}</if>
<if test="serialNumber != null and serialNumber != ''"> and serial_number = #{serialNumber}</if>
<if test="deviceNumber != null and deviceNumber != ''"> and device_number = #{deviceNumber}</if>
<if test="projectId != null "> and project_id = #{projectId}</if>
<if test="deptId != null "> and dept_id = #{deptId}</if>
</where>
</select>
</select>-->
<select id="selectNgUserRechargeRecordsBySerialNumber" parameterType="NgUserRechargeRecords" resultMap="NgUserRechargeRecordsResult">
<include refid="selectNgUserRechargeRecordsVo"/>

View File

@ -58,10 +58,10 @@
<include refid="selectUserRechargeCardsVo"/>
where card_number= #{cardnumber}
</select>
<select id="selectUserRechargeCardsByCardNumber" parameterType="String" resultMap="UserRechargeCardsResult">
<!--<select id="selectUserRechargeCardsByCardNumber" parameterType="String" resultMap="UserRechargeCardsResult">
<include refid="selectUserRechargeCardsVo"/>
where cardNumber = #{cardNumber}
</select>
</select>-->
<insert id="insertUserRechargeCards" parameterType="UserRechargeCards" useGeneratedKeys="true" keyProperty="id">
insert into user_recharge_cards