提交修改
This commit is contained in:
parent
4417f5fb27
commit
6551a43f40
@ -3,20 +3,28 @@ package com.heyu.api.jsapi.dto.pay;
|
|||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信支付商品详情
|
||||||
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class GoodsDetail {
|
public class GoodsDetail {
|
||||||
|
/** 商户侧商品编码 */
|
||||||
@SerializedName("merchant_goods_id")
|
@SerializedName("merchant_goods_id")
|
||||||
private String merchantGoodsId;
|
private String merchantGoodsId;
|
||||||
|
|
||||||
|
/** 微信支付商品编码 */
|
||||||
@SerializedName("wechatpay_goods_id")
|
@SerializedName("wechatpay_goods_id")
|
||||||
private String wechatpayGoodsId;
|
private String wechatpayGoodsId;
|
||||||
|
|
||||||
|
/** 商品名称 */
|
||||||
@SerializedName("goods_name")
|
@SerializedName("goods_name")
|
||||||
private String goodsName;
|
private String goodsName;
|
||||||
|
|
||||||
|
/** 商品数量 */
|
||||||
@SerializedName("quantity")
|
@SerializedName("quantity")
|
||||||
private Long quantity;
|
private Long quantity;
|
||||||
|
|
||||||
|
/** 商品单价,单位为分 */
|
||||||
@SerializedName("unit_price")
|
@SerializedName("unit_price")
|
||||||
private Long unitPrice;
|
private Long unitPrice;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,8 +3,15 @@ package com.heyu.api.jsapi.dto.pay;
|
|||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JSAPI下单 - 支付者信息
|
||||||
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class JsapiReqPayerInfo {
|
public class JsapiReqPayerInfo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户在直连商户appid下的唯一标识
|
||||||
|
*/
|
||||||
@SerializedName("openid")
|
@SerializedName("openid")
|
||||||
private String openid;
|
private String openid;
|
||||||
}
|
}
|
||||||
@ -620,19 +620,25 @@ public class AppOrderController {
|
|||||||
vo.setPaySign(sign);
|
vo.setPaySign(sign);
|
||||||
vo.setPrepayId("prepay_id=" + prepay_id);
|
vo.setPrepayId("prepay_id=" + prepay_id);
|
||||||
|
|
||||||
|
log.info("[添加订单] 订单创建完成, tradeOrderId={}, outTradeNo={}, payAmount={}",
|
||||||
|
vvTradeOrderEntity.getId(), vvTradeOrderEntity.getOutTradeNo(), vvTradeOrderEntity.getPayAmount());
|
||||||
|
|
||||||
return R.ok().setData(vo);
|
return R.ok().setData(vo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
/***
|
* 订单再次支付
|
||||||
* 订单 再次支付
|
* 当订单支付失败或超时后,用户可以再次发起支付
|
||||||
*
|
*
|
||||||
* http://localhost:8888/app/order/to/pay
|
* @param vvOrderRequest 支付请求参数
|
||||||
|
* @return 微信支付参数
|
||||||
*/
|
*/
|
||||||
@Describe("添加订单")
|
@Describe("订单再次支付")
|
||||||
@RequestMapping("/to/pay")
|
@RequestMapping("/to/pay")
|
||||||
@AppRealyLogin
|
@AppRealyLogin
|
||||||
public R toPay(@RequestBody VvTradeOrderToPayDTO vvOrderRequest) {
|
public R toPay(@RequestBody VvTradeOrderToPayDTO vvOrderRequest) {
|
||||||
|
log.info("[订单再次支付] 开始处理, tradeOrderId={}, buyerId={}",
|
||||||
|
vvOrderRequest.getTradeOrderId(), vvOrderRequest.getBuyerId());
|
||||||
VvTradeOrderEntity vvTradeOrderEntity = vvTradeOrderDao.selectVvTradeOrderById(vvOrderRequest.getTradeOrderId());
|
VvTradeOrderEntity vvTradeOrderEntity = vvTradeOrderDao.selectVvTradeOrderById(vvOrderRequest.getTradeOrderId());
|
||||||
|
|
||||||
VvBuyerEntity vvBuyerEntity = vvBuyerDao.selectVvBuyerById(vvOrderRequest.getBuyerId());
|
VvBuyerEntity vvBuyerEntity = vvBuyerDao.selectVvBuyerById(vvOrderRequest.getBuyerId());
|
||||||
@ -682,11 +688,19 @@ public class AppOrderController {
|
|||||||
return R.ok().setData(vo);
|
return R.ok().setData(vo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// /app/order/delete
|
/**
|
||||||
|
* 删除订单
|
||||||
|
* 将订单状态更新为已删除,仅在特定状态下允许删除
|
||||||
|
*
|
||||||
|
* @param vvOrderRequest 删除请求参数
|
||||||
|
* @return 删除结果
|
||||||
|
*/
|
||||||
@Describe("删除订单")
|
@Describe("删除订单")
|
||||||
@RequestMapping("/delete")
|
@RequestMapping("/delete")
|
||||||
@AppRealyLogin
|
@AppRealyLogin
|
||||||
public R delete(@RequestBody VvTradeOrderDeleteDTO vvOrderRequest) {
|
public R delete(@RequestBody VvTradeOrderDeleteDTO vvOrderRequest) {
|
||||||
|
log.info("[删除订单] 开始处理, tradeOrderId={}, trackNumber={}, buyerId={}",
|
||||||
|
vvOrderRequest.getTradeOrderId(), vvOrderRequest.getTrackNumber(), vvOrderRequest.getBuyerId());
|
||||||
List<VvTradeOrderLineEntity> vvTradeOrderLineEntityList = null;
|
List<VvTradeOrderLineEntity> vvTradeOrderLineEntityList = null;
|
||||||
if (StringUtils.isNotEmpty(vvOrderRequest.getTrackNumber())) {
|
if (StringUtils.isNotEmpty(vvOrderRequest.getTrackNumber())) {
|
||||||
vvTradeOrderLineEntityList = vvTradeOrderLineDao.selectVvTradeOrderLineByTrackNumberBuyerId(vvOrderRequest.getTrackNumber(), vvOrderRequest.getBuyerId());
|
vvTradeOrderLineEntityList = vvTradeOrderLineDao.selectVvTradeOrderLineByTrackNumberBuyerId(vvOrderRequest.getTrackNumber(), vvOrderRequest.getBuyerId());
|
||||||
|
|||||||
@ -29,30 +29,70 @@ import java.util.Base64;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信支付回调通知控制器
|
||||||
|
* <p>
|
||||||
|
* 用于处理微信支付的异步通知回调,接收微信支付平台发送的支付结果通知,
|
||||||
|
* 并根据通知内容更新订单状态。
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author heyu
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/app/weixin")
|
@RequestMapping("/app/weixin")
|
||||||
public class AppWeiXinPayNotifyController {
|
public class AppWeiXinPayNotifyController {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 交易订单明细数据访问对象
|
||||||
|
*/
|
||||||
@Autowired
|
@Autowired
|
||||||
private VvTradeOrderLineDao vvTradeOrderLineDao;
|
private VvTradeOrderLineDao vvTradeOrderLineDao;
|
||||||
|
|
||||||
|
/**
|
||||||
// 微信支付APIv3密钥
|
* 微信支付APIv3密钥,用于解密回调通知中的加密数据
|
||||||
|
*/
|
||||||
@Value("${eb.config.weixin.pay.apiv3key}")
|
@Value("${eb.config.weixin.pay.apiv3key}")
|
||||||
private String apiv3key;
|
private String apiv3key;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 交易订单数据访问对象
|
||||||
|
*/
|
||||||
@Autowired
|
@Autowired
|
||||||
private VvTradeOrderDao tradeOrderDao;
|
private VvTradeOrderDao tradeOrderDao;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信支付商户号
|
||||||
|
*/
|
||||||
@Value("${eb.config.weixin.pay.mchid}")
|
@Value("${eb.config.weixin.pay.mchid}")
|
||||||
private String mchid;
|
private String mchid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JSAPI预支付服务
|
||||||
|
*/
|
||||||
@Autowired
|
@Autowired
|
||||||
private JsapiPrepay jsapiPrepay;
|
private JsapiPrepay jsapiPrepay;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理微信支付回调通知
|
||||||
|
* <p>
|
||||||
|
* 接收微信支付平台发送的异步通知,解密通知内容,验证支付结果,并更新订单状态。
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>处理流程:</p>
|
||||||
|
* <ol>
|
||||||
|
* <li>解析微信支付回调通知的JSON数据</li>
|
||||||
|
* <li>提取加密字段(ciphertext、associated_data、nonce)</li>
|
||||||
|
* <li>使用AES-GCM算法解密数据</li>
|
||||||
|
* <li>解析解密后的支付结果数据</li>
|
||||||
|
* <li>如果支付成功,更新商户订单状态</li>
|
||||||
|
* <li>返回处理结果给微信支付平台</li>
|
||||||
|
* </ol>
|
||||||
|
*
|
||||||
|
* @param requestBody 微信支付回调通知的原始JSON数据
|
||||||
|
* @return 处理结果的JSON字符串,成功返回 {"code":"SUCCESS","message":"OK"},失败返回 {"code":"FAIL","message":"Server Error"}
|
||||||
|
*/
|
||||||
@Describe("微信支付回调")
|
@Describe("微信支付回调")
|
||||||
@PostMapping("/payNotify")
|
@PostMapping("/payNotify")
|
||||||
public String handleWeChatPayCallback(@RequestBody String requestBody) {
|
public String handleWeChatPayCallback(@RequestBody String requestBody) {
|
||||||
@ -86,7 +126,19 @@ public class AppWeiXinPayNotifyController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AES-GCM解密方法
|
/**
|
||||||
|
* AES-GCM解密方法
|
||||||
|
* <p>
|
||||||
|
* 使用微信支付APIv3密钥对回调通知中的加密数据进行解密。
|
||||||
|
* 采用AES-GCM算法,密钥长度为256位,GCM标签长度为128位。
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param ciphertext 加密后的密文(Base64编码)
|
||||||
|
* @param associatedData 附加数据,用于GCM认证
|
||||||
|
* @param nonce 随机数,用作GCM初始化向量
|
||||||
|
* @return 解密后的明文字符串
|
||||||
|
* @throws Exception 解密过程中发生的异常
|
||||||
|
*/
|
||||||
private String decrypt(String ciphertext, String associatedData, String nonce) throws Exception {
|
private String decrypt(String ciphertext, String associatedData, String nonce) throws Exception {
|
||||||
// 将APIv3密钥转为字节数组
|
// 将APIv3密钥转为字节数组
|
||||||
byte[] key = apiv3key.getBytes(StandardCharsets.UTF_8);
|
byte[] key = apiv3key.getBytes(StandardCharsets.UTF_8);
|
||||||
@ -103,6 +155,23 @@ public class AppWeiXinPayNotifyController {
|
|||||||
return new String(decryptedData, StandardCharsets.UTF_8);
|
return new String(decryptedData, StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新订单状态
|
||||||
|
* <p>
|
||||||
|
* 根据微信支付回调通知的结果,更新商户订单及子订单的支付状态。
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>更新内容:</p>
|
||||||
|
* <ul>
|
||||||
|
* <li>查询微信支付订单详情并保存到主订单的交易信息字段</li>
|
||||||
|
* <li>更新主订单的微信支付交易号</li>
|
||||||
|
* <li>将所有子订单的状态更新为"待发货"</li>
|
||||||
|
* <li>记录子订单的支付时间和微信支付交易号</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param outTradeNo 商户订单号
|
||||||
|
* @param transactionId 微信支付交易号
|
||||||
|
*/
|
||||||
private void updateOrderStatus(String outTradeNo, String transactionId) {
|
private void updateOrderStatus(String outTradeNo, String transactionId) {
|
||||||
try {
|
try {
|
||||||
DirectAPIv3QueryResponse response = jsapiPrepay.queryOrder(transactionId);
|
DirectAPIv3QueryResponse response = jsapiPrepay.queryOrder(transactionId);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user