2025-11-17 14:11:46 +08:00
|
|
|
package handler
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"dianshang/internal/service"
|
|
|
|
|
"dianshang/pkg/response"
|
2025-11-28 15:18:10 +08:00
|
|
|
"log"
|
2025-11-17 14:11:46 +08:00
|
|
|
"strconv"
|
|
|
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// PaymentHandler 支付处理器
|
|
|
|
|
type PaymentHandler struct {
|
|
|
|
|
orderService *service.OrderService
|
|
|
|
|
wechatPayService *service.WeChatPayService
|
|
|
|
|
userService *service.UserService
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NewPaymentHandler 创建支付处理器
|
|
|
|
|
func NewPaymentHandler(orderService *service.OrderService, wechatPayService *service.WeChatPayService, userService *service.UserService) *PaymentHandler {
|
|
|
|
|
return &PaymentHandler{
|
|
|
|
|
orderService: orderService,
|
|
|
|
|
wechatPayService: wechatPayService,
|
|
|
|
|
userService: userService,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CreatePaymentRequest 创建支付请求
|
|
|
|
|
type CreatePaymentRequest struct {
|
|
|
|
|
OrderNo string `json:"orderNo" binding:"required"`
|
|
|
|
|
PaymentMethod string `json:"paymentMethod" binding:"required"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CreatePayment 创建支付订单
|
|
|
|
|
func (h *PaymentHandler) CreatePayment(c *gin.Context) {
|
|
|
|
|
var req CreatePaymentRequest
|
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
|
|
|
response.ErrorWithMessage(c, response.ERROR, "参数错误: "+err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取用户ID
|
|
|
|
|
userIDValue, exists := c.Get("user_id")
|
|
|
|
|
if !exists {
|
|
|
|
|
response.ErrorWithMessage(c, response.ERROR, "用户未登录")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
userID := userIDValue.(uint)
|
|
|
|
|
|
|
|
|
|
// 获取用户信息
|
|
|
|
|
user, err := h.userService.GetUserByID(userID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
response.ErrorWithMessage(c, response.ERROR, "获取用户信息失败")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询订单
|
|
|
|
|
order, err := h.orderService.GetOrderByOrderNo(req.OrderNo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
response.ErrorWithMessage(c, response.ERROR, "订单不存在")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 验证订单归属
|
|
|
|
|
if order.UserID != userID {
|
|
|
|
|
response.ErrorWithMessage(c, response.ERROR, "无权限操作此订单")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 验证订单状态
|
|
|
|
|
if order.Status != 1 { // 1 = 待付款
|
|
|
|
|
response.ErrorWithMessage(c, response.ERROR, "订单状态不允许支付")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 创建微信支付订单
|
|
|
|
|
if req.PaymentMethod == "wechat" {
|
|
|
|
|
paymentResp, err := h.wechatPayService.CreateOrder(c.Request.Context(), order, user.OpenID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
response.ErrorWithMessage(c, response.ERROR, "创建支付订单失败: "+err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
response.Success(c, paymentResp.Data)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
response.ErrorWithMessage(c, response.ERROR, "不支持的支付方式")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// QueryPayment 查询支付状态
|
|
|
|
|
func (h *PaymentHandler) QueryPayment(c *gin.Context) {
|
|
|
|
|
orderIDStr := c.Param("orderId")
|
|
|
|
|
orderID, err := strconv.ParseUint(orderIDStr, 10, 32)
|
|
|
|
|
if err != nil {
|
|
|
|
|
response.ErrorWithMessage(c, response.ERROR, "订单ID格式错误")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取用户ID
|
|
|
|
|
userIDValue, exists := c.Get("user_id")
|
|
|
|
|
if !exists {
|
|
|
|
|
response.ErrorWithMessage(c, response.ERROR, "用户未登录")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
userID := userIDValue.(uint)
|
|
|
|
|
|
|
|
|
|
// 查询订单
|
|
|
|
|
order, err := h.orderService.GetOrderDetail(userID, uint(orderID))
|
|
|
|
|
if err != nil {
|
|
|
|
|
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询微信支付状态
|
|
|
|
|
wechatOrder, err := h.wechatPayService.QueryOrder(c.Request.Context(), order.OrderNo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
response.ErrorWithMessage(c, response.ERROR, "查询支付状态失败: "+err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
response.Success(c, gin.H{
|
|
|
|
|
"orderNo": wechatOrder.OrderNo,
|
|
|
|
|
"totalAmount": wechatOrder.TotalAmount,
|
|
|
|
|
"status": wechatOrder.Status,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CancelPayment 取消支付
|
|
|
|
|
func (h *PaymentHandler) CancelPayment(c *gin.Context) {
|
|
|
|
|
orderIDStr := c.Param("orderId")
|
|
|
|
|
orderID, err := strconv.ParseUint(orderIDStr, 10, 32)
|
|
|
|
|
if err != nil {
|
|
|
|
|
response.ErrorWithMessage(c, response.ERROR, "订单ID格式错误")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取用户ID
|
|
|
|
|
userIDValue, exists := c.Get("user_id")
|
|
|
|
|
if !exists {
|
|
|
|
|
response.ErrorWithMessage(c, response.ERROR, "用户未登录")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
userID := userIDValue.(uint)
|
|
|
|
|
|
|
|
|
|
// 查询订单
|
|
|
|
|
order, err := h.orderService.GetOrderDetail(userID, uint(orderID))
|
|
|
|
|
if err != nil {
|
|
|
|
|
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 验证订单状态
|
|
|
|
|
if order.Status != 1 { // 1 = 待付款
|
|
|
|
|
response.ErrorWithMessage(c, response.ERROR, "订单状态不允许取消支付")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新订单状态为已取消
|
|
|
|
|
err = h.orderService.UpdateOrderStatus(order.ID, 7, userID) // 7 = 已取消
|
|
|
|
|
if err != nil {
|
|
|
|
|
response.ErrorWithMessage(c, response.ERROR, "取消支付失败")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
response.Success(c, gin.H{
|
|
|
|
|
"message": "支付已取消",
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// PaymentNotify 支付回调通知
|
|
|
|
|
func (h *PaymentHandler) PaymentNotify(c *gin.Context) {
|
2025-11-28 15:18:10 +08:00
|
|
|
log.Printf("[=== 微信支付回调 ===] 收到回调请求")
|
|
|
|
|
log.Printf("[回调请求] 请求方法: %s", c.Request.Method)
|
|
|
|
|
log.Printf("[回调请求] 请求路径: %s", c.Request.URL.Path)
|
|
|
|
|
log.Printf("[回调请求] 客户端IP: %s", c.ClientIP())
|
|
|
|
|
|
2025-11-17 14:11:46 +08:00
|
|
|
// 读取回调数据
|
|
|
|
|
body, err := c.GetRawData()
|
|
|
|
|
if err != nil {
|
2025-11-28 15:18:10 +08:00
|
|
|
log.Printf("[回调错误] 读取回调数据失败: %v", err)
|
2025-11-17 14:11:46 +08:00
|
|
|
response.ErrorWithMessage(c, response.ERROR, "读取回调数据失败")
|
|
|
|
|
return
|
|
|
|
|
}
|
2025-11-28 15:18:10 +08:00
|
|
|
log.Printf("[回调数据] 数据长度: %d bytes", len(body))
|
2025-11-17 14:11:46 +08:00
|
|
|
|
|
|
|
|
// 获取请求头
|
|
|
|
|
headers := make(map[string]string)
|
|
|
|
|
for key, values := range c.Request.Header {
|
|
|
|
|
if len(values) > 0 {
|
|
|
|
|
headers[key] = values[0]
|
2025-11-28 15:18:10 +08:00
|
|
|
log.Printf("[回调请求头] %s: %s", key, values[0])
|
2025-11-17 14:11:46 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理微信支付回调
|
2025-11-28 15:18:10 +08:00
|
|
|
log.Printf("[回调处理] 开始验证签名并解析数据...")
|
2025-11-17 14:11:46 +08:00
|
|
|
notify, err := h.wechatPayService.HandleNotify(c.Request.Context(), body, headers)
|
|
|
|
|
if err != nil {
|
2025-11-28 15:18:10 +08:00
|
|
|
log.Printf("[回调错误] 处理支付回调失败: %v", err)
|
2025-11-17 14:11:46 +08:00
|
|
|
response.ErrorWithMessage(c, response.ERROR, "处理支付回调失败: "+err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
2025-11-28 15:18:10 +08:00
|
|
|
log.Printf("[回调数据] 事件类型: %s", notify.EventType)
|
2025-11-17 14:11:46 +08:00
|
|
|
|
|
|
|
|
// 根据回调类型处理
|
|
|
|
|
if notify.EventType == "TRANSACTION.SUCCESS" {
|
2025-11-28 15:18:10 +08:00
|
|
|
log.Printf("[支付成功] 开始处理支付成功回调...")
|
2025-11-17 14:11:46 +08:00
|
|
|
// 支付成功,更新订单状态
|
|
|
|
|
err = h.wechatPayService.ProcessPaymentSuccess(c.Request.Context(), notify)
|
|
|
|
|
if err != nil {
|
2025-11-28 15:18:10 +08:00
|
|
|
log.Printf("[回调错误] 处理支付成功回调失败: %v", err)
|
2025-11-17 14:11:46 +08:00
|
|
|
response.ErrorWithMessage(c, response.ERROR, "处理支付成功回调失败: "+err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-28 15:18:10 +08:00
|
|
|
log.Printf("[支付成功] 订单状态更新成功")
|
2025-11-17 14:11:46 +08:00
|
|
|
response.Success(c, gin.H{
|
|
|
|
|
"code": "SUCCESS",
|
|
|
|
|
"message": "处理成功",
|
|
|
|
|
})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-28 15:18:10 +08:00
|
|
|
log.Printf("[回调处理] 非支付成功事件,仅记录")
|
2025-11-17 14:11:46 +08:00
|
|
|
response.Success(c, gin.H{
|
|
|
|
|
"code": "SUCCESS",
|
|
|
|
|
"message": "回调已接收",
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TestPaymentSuccess 测试支付成功处理(手动触发)
|
|
|
|
|
func (h *PaymentHandler) TestPaymentSuccess(c *gin.Context) {
|
|
|
|
|
orderNo := c.Query("order_no")
|
|
|
|
|
if orderNo == "" {
|
|
|
|
|
response.ErrorWithMessage(c, response.ERROR, "订单号不能为空")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err := h.wechatPayService.ProcessPaymentSuccessByOrderNo(c.Request.Context(), orderNo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
response.Success(c, gin.H{
|
|
|
|
|
"message": "支付成功处理完成",
|
|
|
|
|
"order_no": orderNo,
|
|
|
|
|
})
|
|
|
|
|
}
|