保存交易信息

This commit is contained in:
quyixiao 2025-11-08 08:23:02 +08:00
parent 6376edf6b8
commit 7ae997f07c
9 changed files with 120 additions and 17 deletions

View File

@ -1,16 +1,16 @@
package com.heyu.api.data.entity.vv;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import com.lz.mybatis.plugin.annotations.AS;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Date;import java.util.Date;
/**
*购物车
* @author quyixiao
* @since 2025-10-25
* @since 2025-11-08
*/
@Data
@ -45,6 +45,7 @@ private static final long serialVersionUID = 1L;
public final static String app_name = CLASS_NAME + "app_name"; // app 来源
public final static String channel_ = CLASS_NAME + "channel"; // 渠道如抖音微信小程序朋友圈bilibili
public final static String promoter_id = CLASS_NAME + "promoter_id"; // 推广者买家id
public final static String trade_info = CLASS_NAME + "trade_info"; // 交易信息
//
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@ -94,6 +95,8 @@ private static final long serialVersionUID = 1L;
private String channel;
//推广者买家id
private String promoterId;
//交易信息
private String tradeInfo;
/**
*
* @return
@ -454,6 +457,21 @@ private static final long serialVersionUID = 1L;
this.promoterId = promoterId;
}
/**
* 交易信息
* @return
*/
public String getTradeInfo() {
return tradeInfo;
}
/**
* 交易信息
* @param tradeInfo
*/
public void setTradeInfo(String tradeInfo) {
this.tradeInfo = tradeInfo;
}
@Override
public String toString() {
return "VvTradeOrderEntity{" +
@ -481,6 +499,7 @@ private static final long serialVersionUID = 1L;
",appName=" + appName +
",channel=" + channel +
",promoterId=" + promoterId +
",tradeInfo=" + tradeInfo +
"}";
}
}

View File

@ -10,7 +10,7 @@ import java.util.Date;import java.util.Date;
/**
*购物车
* @author quyixiao
* @since 2025-11-07
* @since 2025-11-08
*/
@Data
@ -76,6 +76,7 @@ private static final long serialVersionUID = 1L;
public final static String pay_type = CLASS_NAME + "pay_type"; // 支付方式weixin
public final static String gmt_pre_pay = CLASS_NAME + "gmt_pre_pay"; // 预支付时间
public final static String gmt_close = CLASS_NAME + "gmt_close"; // 订单关闭时间
public final static String prepay_id = CLASS_NAME + "prepay_id"; // 预支付id
//
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@ -187,6 +188,8 @@ private static final long serialVersionUID = 1L;
private Date gmtPrePay;
//订单关闭时间
private Date gmtClose;
//预支付id
private String prepayId;
/**
*
* @return
@ -1012,6 +1015,21 @@ private static final long serialVersionUID = 1L;
this.gmtClose = gmtClose;
}
/**
* 预支付id
* @return
*/
public String getPrepayId() {
return prepayId;
}
/**
* 预支付id
* @param prepayId
*/
public void setPrepayId(String prepayId) {
this.prepayId = prepayId;
}
@Override
public String toString() {
return "VvTradeOrderLineEntity{" +
@ -1070,6 +1088,7 @@ private static final long serialVersionUID = 1L;
",payType=" + payType +
",gmtPrePay=" + gmtPrePay +
",gmtClose=" + gmtClose +
",prepayId=" + prepayId +
"}";
}
}

View File

@ -48,7 +48,8 @@ public class MysqlMain_update {
}
List<TablesBean> list = new ArrayList<TablesBean>();
list.add(new TablesBean("vv_app_category"));
list.add(new TablesBean("vv_trade_order"));
list.add(new TablesBean("vv_trade_order_line"));
Map<String, String> map = MysqlUtil2ShowCreateTable.getComments();

View File

@ -41,14 +41,16 @@ public class JsapiPrepay {
@Value("${eb.config.weixin.pay.mchid}")
private String mchid;
@Value("${eb.config.weixin.pay.certificateSerialNo}")
private String certificateSerialNo;
private PrivateKey privateKey;
private String wechatPayPublicKeyId;
private PublicKey wechatPayPublicKey;
@Value("${eb.config.weixin.pay.notifyUrl}")
private String notifyUrl;
@ -56,6 +58,7 @@ public class JsapiPrepay {
public JsapiPrepay() {
}
public JsapiPrepay(String mchid, String certificateSerialNo, String privateKeyFilePath, String wechatPayPublicKeyId, String wechatPayPublicKeyFilePath) {
this.mchid = mchid;
this.certificateSerialNo = certificateSerialNo;

View File

@ -3,9 +3,11 @@ package com.heyu.api.jsapi;
import com.heyu.api.jsapi.dto.DirectAPIv3QueryResponse;
import com.heyu.api.jsapi.dto.QueryByWxTradeNoRequest;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.UncheckedIOException;
@ -17,18 +19,28 @@ import java.util.Map;
/**
* 微信支付订单号查询订单
*/
@Slf4j
@Component
public class QueryByWxTradeNo {
private static String HOST = "https://api.mch.weixin.qq.com";
private static String METHOD = "GET";
private static String PATH = "/v3/pay/transactions/id/{transaction_id}";
private final String mchid;
private final String certificateSerialNo;
private final PrivateKey privateKey;
private final String wechatPayPublicKeyId;
private final PublicKey wechatPayPublicKey;
private String mchid;
private String certificateSerialNo;
private PrivateKey privateKey;
private String wechatPayPublicKeyId;
private PublicKey wechatPayPublicKey;
public QueryByWxTradeNo() {
}
public QueryByWxTradeNo(String mchid, String certificateSerialNo, String privateKeyFilePath, String wechatPayPublicKeyId, String wechatPayPublicKeyFilePath) {
this.mchid = mchid;
@ -60,7 +72,7 @@ public class QueryByWxTradeNo {
OkHttpClient client = new OkHttpClient.Builder().build();
try (Response httpResponse = client.newCall(httpRequest).execute()) {
String respBody = WXPayUtility.extractBody(httpResponse);
System.out.println("respBody = " + respBody);
log.info("QueryByWxTradeNo respBody = " + respBody);
if (httpResponse.code() >= 200 && httpResponse.code() < 300) {
// 2XX 成功验证应答签名
WXPayUtility.validateResponse(this.wechatPayPublicKeyId, this.wechatPayPublicKey,

View File

@ -1,6 +1,7 @@
package com.heyu.api.config;
import com.heyu.api.jsapi.JsapiPrepay;
import com.heyu.api.jsapi.QueryByWxTradeNo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
@ -27,4 +28,24 @@ public class JSAPIConfig {
}
@Bean
public QueryByWxTradeNo queryByWxTradeNo(@Value("${eb.config.weixin.pay.mchid}") String mchid,
@Value("${eb.config.weixin.pay.certificateSerialNo}") String certificateSerialNo,
@Value("${eb.config.weixin.pay.privateKeyFilePath}") String privateKeyFilePath,
@Value("${eb.config.weixin.pay.wechatPayPublicKeyId}") String wechatPayPublicKeyId,
@Value("${eb.config.weixin.pay.wechatPayPublicKeyFilePath}") String wechatPayPublicKeyFilePath) {
log.info("JSAPIConfig QueryByWxTradeNo init mchid:{}," +
"certificateSerialNo:{}," +
"privateKeyFilePath:{}," +
"wechatPayPublicKeyId:{}," +
"wechatPayPublicKeyFilePath:{}",
mchid, certificateSerialNo, privateKeyFilePath, wechatPayPublicKeyId, wechatPayPublicKeyFilePath);
return new QueryByWxTradeNo(mchid, certificateSerialNo, privateKeyFilePath, wechatPayPublicKeyId, wechatPayPublicKeyFilePath);
}
}

View File

@ -346,14 +346,14 @@ public class AppOrderController {
BigDecimalUtil.multiply(vvTradeOrderEntity.getAllPrice(), new BigDecimal(100)).longValue(),
vvBuyerEntity.getOpenid()
);
String prepay_id = jsapiPrepayResponse.getPrepayId();
if (jsapiPrepayResponse != null && jsapiPrepayResponse.getPrepayId() != null) {
List<VvTradeOrderLineEntity> vvTradeOrderLineEntities = vvTradeOrderLineDao.selectVvTradeOrderLineByTradeOrderId(vvTradeOrderEntity.getId());
for (VvTradeOrderLineEntity vvTradeOrderLineEntity : vvTradeOrderLineEntities) {
vvTradeOrderLineEntity.setPayType("weixin");
vvTradeOrderLineEntity.setStatus(OrderStatusEnums.wait_pay.getStatus());
vvTradeOrderLineEntity.setTransactionId(jsapiPrepayResponse.getPrepayId());
vvTradeOrderLineEntity.setPrepayId(jsapiPrepayResponse.getPrepayId());
vvTradeOrderLineEntity.setGmtPrePay(new Date());
vvTradeOrderLineDao.updateVvTradeOrderLineById(vvTradeOrderLineEntity);
}
@ -387,6 +387,8 @@ public class AppOrderController {
// "package": "prepay_id=wx201410272009395522657a690389285100",
// "signType": "RSA",
// "paySign": "oR9d",
String sign = JsapiPrepay.getSign(signatureStr, privateKey);
vo.setNonceStr(nonceStr);
vo.setTimeStamp(timeStamp);

View File

@ -1,13 +1,19 @@
package com.heyu.api.controller.vv;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.heyu.api.alibaba.request.mm.enums.OrderStatusEnums;
import com.heyu.api.common.annotation.Describe;
import com.heyu.api.data.dao.vv.VvTradeOrderDao;
import com.heyu.api.data.dao.vv.VvTradeOrderLineDao;
import com.heyu.api.data.entity.vv.VvTradeOrderEntity;
import com.heyu.api.data.entity.vv.VvTradeOrderLineEntity;
import com.heyu.api.data.utils.NumberUtil;
import com.heyu.api.jsapi.QueryByWxTradeNo;
import com.heyu.api.jsapi.dto.DirectAPIv3QueryResponse;
import com.heyu.api.jsapi.dto.QueryByWxTradeNoRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@ -39,6 +45,15 @@ public class AppWeiXinPayNotifyController {
@Value("${eb.config.weixin.pay.apiv3key}")
private String apiv3key;
@Autowired
private QueryByWxTradeNo queryByWxTradeNo;
@Autowired
private VvTradeOrderDao tradeOrderDao;
@Value("${eb.config.weixin.pay.mchid}")
private String mchid;
@Describe("微信支付回调")
@PostMapping("/payNotify")
public String handleWeChatPayCallback(@RequestBody String requestBody) {
@ -89,14 +104,25 @@ public class AppWeiXinPayNotifyController {
return new String(decryptedData, StandardCharsets.UTF_8);
}
private void updateOrderStatus(String outTradeNo, String transactionId) {
try {
QueryByWxTradeNoRequest request = new QueryByWxTradeNoRequest();
request.transactionId = transactionId;
request.mchid = mchid;
DirectAPIv3QueryResponse response = queryByWxTradeNo.run(request);
VvTradeOrderEntity tradeOrderEntity = tradeOrderDao.selectVvTradeOrderById(NumberUtil.objToLong(outTradeNo));
tradeOrderEntity.setTradeInfo(JSON.toJSONString(response));
}catch ( Exception e ){
log.error("AppWeiXinPayNotifyController updateOrderStatus error:{}",e.getMessage());
}
// 这里是更新商户订单状态的逻辑例如标记订单已支付
log.info("handleWeChatPayCallback 订单 " + outTradeNo + " 已支付,交易号:" + transactionId + "开始更新子订单信息");
List<VvTradeOrderLineEntity> vvTradeOrderLineEntityList = vvTradeOrderLineDao.selectVvTradeOrderLineByTradeOrderId(NumberUtil.objToLong(outTradeNo));
for (VvTradeOrderLineEntity vvTradeOrderLineEntity : vvTradeOrderLineEntityList) {
vvTradeOrderLineEntity.setStatus(OrderStatusEnums.wait_shipping.getStatus());
vvTradeOrderLineEntity.setGmtPay(new Date());
vvTradeOrderLineEntity.setTransactionId(transactionId);
vvTradeOrderLineDao.updateVvTradeOrderLineById(vvTradeOrderLineEntity);
}
}

View File

@ -19,7 +19,7 @@ public class JSAPIQueryTest {
);
QueryByWxTradeNoRequest request = new QueryByWxTradeNoRequest();
request.transactionId = "wx07124718921276a55b1abd623f48690001";
request.transactionId = "4200002963202511079867655660";
request.mchid = TestJSAPI.mchid;
try {
DirectAPIv3QueryResponse response = client.run(request);