package order import ( "encoding/json" logger "eta/eta_mini_ht_api/common/component/log" "eta/eta_mini_ht_api/models" merchantDao "eta/eta_mini_ht_api/models/merchant" "eta/eta_mini_ht_api/models/message" "eta/eta_mini_ht_api/models/order" "fmt" "math/rand" "strconv" "time" ) const ( RMB = "CNY" AliPayWay PaymentWay = "alipay" WechatPay PaymentWay = "wechat" RefundSuccess = "success" RefundFail = "fail" PaySuccess = "success" PayFail = "fail" ) type PaymentWay string type TradeOrderDTO struct { ID int `gorm:"column:id;primaryKey"` TransactionID string `gorm:"column:transaction_id;type:varchar(255);comment:第三方平台ID"` ProductOrderID string `gorm:"column:product_order_id;type:varchar(255);comment:商品订单号"` PaymentAccount string `gorm:"column:payment_account;type:varchar(255);comment:支付账号"` PaymentWay string `gorm:"column:payment_way;type:enum('wechat');comment:支付渠道"` Amount string `gorm:"column:amount;type:varchar(20);comment:支付金额"` Currency string `gorm:"column:currency;type:varchar(255);comment:货币"` MerchantID string `gorm:"column:merchant_id;type:int(11);comment:商户id"` UserID int `gorm:"column:user_id;type:int(11);comment:用户id"` TemplateUserID int `gorm:"column:template_user_id;type:int(11);comment:临时用户id"` PaymentType string `gorm:"column:payment_type;type:enum('pay','refund');comment:订单类型"` PaymentStatus string `gorm:"column:payment_status;type:enum('pending','processing','done','failed');comment:支付状态"` DealTime time.Time `gorm:"column:deal_time;type:datetime;comment:完成时间"` } func GenerateTradeOrderNo() string { timestamp := time.Now().UnixNano() / 1000000 // 毫秒级时间戳 // 生成随机数 rand.New(rand.NewSource(time.Now().UnixNano())) randomPart := rand.Intn(999999) // 格式化订单号 orderNumber := fmt.Sprintf("T%d%06d", timestamp, randomPart) return orderNumber } func CreateTradeOrder(userId, templateUserId int, productOrderNo, tradeOrderNo, merchantNo string) (err error) { db := models.Main() productOrder, err := order.GetOrderByUser(templateUserId, productOrderNo) if err != nil { logger.Error("获取商品订单信息失败%v", err) return } tx := db.Begin() defer func() { if err != nil { tx.Rollback() return } tx.Commit() }() tradeOrder := order.TradeOrder{ ProductOrderID: productOrderNo, ProductName: productOrder.ProductName, TransactionID: tradeOrderNo, Amount: productOrder.TotalAmount, Mobile: productOrder.Mobile, AreaCode: productOrder.AreaCode, RealName: productOrder.RealName, PaymentWay: order.WechatPayWay, Currency: RMB, MerchantID: merchantNo, UserID: userId, TemplateUserID: templateUserId, PaymentType: order.PaymentTypePay, } err = tx.Create(&tradeOrder).Error if err != nil { logger.Error("创建支付订单失败%v", err) return } err = tx.Model(&order.ProductOrder{}).Where("id = ?", productOrder.ID).Updates(map[string]interface{}{ "trade_id": tradeOrder.ID, "trade_no": tradeOrder.TransactionID, "payment_time": time.Now(), "payment_amount": tradeOrder.Amount, "payment_way": tradeOrder.PaymentWay, }).Error return } func convertToDTO(tradeOrder order.TradeOrder) TradeOrderDTO { return TradeOrderDTO{ ID: tradeOrder.ID, TransactionID: tradeOrder.TransactionID, ProductOrderID: tradeOrder.ProductOrderID, PaymentAccount: tradeOrder.PaymentAccount, PaymentWay: string(tradeOrder.PaymentWay), Amount: tradeOrder.Amount, Currency: tradeOrder.Currency, MerchantID: tradeOrder.MerchantID, UserID: tradeOrder.UserID, TemplateUserID: tradeOrder.UserID, PaymentType: string(tradeOrder.PaymentType), PaymentStatus: string(tradeOrder.PaymentStatus), DealTime: tradeOrder.DealTime, } } func GetUnFailedTradeFlowByProductOrder(productOrderNo string) (dtoList []TradeOrderDTO, err error) { var tradeOrderList []order.TradeOrder tradeOrderList, err = order.GetUnFailedTradeFlowByProductOrder(productOrderNo) for _, tradeOrder := range tradeOrderList { dtoList = append(dtoList, convertToDTO(tradeOrder)) } return } func GetTradeOrderByNo(tradeOrderNo string) (dto TradeOrderDTO, err error) { var tradeOrder order.TradeOrder tradeOrder, err = order.GetTradeOrderByNo(tradeOrderNo, order.PaymentTypePay) dto = convertToDTO(tradeOrder) return } type RefundDealFlowDTO struct { OperatorUserID int `gorm:"column:operator_user_id"` ProductOrderNo string `gorm:"column:product_order_no"` RefundOrderNo string `gorm:"column:refund_order_no"` } func convertRefundDTO(flow order.RefundDealFlow) RefundDealFlowDTO { return RefundDealFlowDTO{ OperatorUserID: flow.OperatorUserID, ProductOrderNo: flow.ProductOrderNo, RefundOrderNo: flow.RefundOrderNo, } } func createRefundMetaInfo(sysUserId int, productOrderNo string, flag string) (err error) { productOrder, err := order.GetOrderByOrderNo(productOrderNo) if err != nil { logger.Error("生成退款消息通知失败,获取订单信息失败:v,订单编号:%s", err, productOrderNo) return } var result string switch flag { case RefundSuccess: result = "成功" case RefundFail: result = "失败" default: logger.Error("生成退款消息通知失败,未知的退款状态%s,订单编号:%s", flag, productOrderNo) return } refundInfo := message.RefundMetaData{ RealName: productOrder.RealName, ProductOrderNo: productOrderNo, Result: result, } bytes, err := json.Marshal(refundInfo) if err != nil { logger.Error("生成退款消息通知失败,序列化退款信息失败:%v,订单编号:%s", err, productOrderNo) return } metaInfo := message.MetaInfo{ Meta: string(bytes), MetaType: message.SysUserNoticeType, SourceType: message.RefundSourceType, Status: message.InitStatusType, From: "HTTradePlate", To: strconv.Itoa(sysUserId), } return message.CreateMetaInfo(metaInfo) } func DealRefund(refundOrderNo string, flag string) (productOrderDTO ProductOrderDTO, err error) { flow, err := order.GetRefundFlow(refundOrderNo) if err != nil { logger.Error("获取退款流水失败%v,退款订单:%s", err, refundOrderNo) return } //处理退款订单 tradeOrder, err := order.GetTradeOrderByNo(flow.RefundOrderNo, order.PaymentTypeRefund) if err != nil { logger.Error("获取退款订单失败%v,退款订单:%s", err, refundOrderNo) return } isSuccess := false if flag == RefundSuccess { isSuccess = true } err = order.DealRefundOrder(tradeOrder, isSuccess) if err != nil { logger.Error("处理退款结果失败%v,退款订单:%s", err, refundOrderNo) return } var productOrder order.ProductOrder productOrder, err = order.GetOrderByOrderNo(tradeOrder.ProductOrderID) if err != nil { logger.Error("获取产品订单失败%v,退款订单:%s", err, refundOrderNo) return } productOrderDTO = ConvertProductOrderDTO(productOrder) _ = createRefundMetaInfo(flow.OperatorUserID, flow.ProductOrderNo, flag) return } func DealPayment(tradeOrderNo string, flag string) (productOrderDTO ProductOrderDTO, err error) { //处理退款订单 tradeOrder, err := order.GetTradeOrderByNo(tradeOrderNo, order.PaymentTypePay) if err != nil { logger.Error("获取支付订单失败%v,支付订单:%s", err, tradeOrderNo) return } isSuccess := false if flag == PaySuccess { isSuccess = true } var productOrder order.ProductOrder productOrder, err = order.GetOrderByOrderNo(tradeOrder.ProductOrderID) if err != nil { logger.Error("获取产品订单失败%v,支付订单:%s", err, tradeOrderNo) return } product, err := merchantDao.GetMerchantProductById(productOrder.ProductID) if err != nil { logger.Error("获取产品信息失败:%v,productId:%d", err, productOrder.ProductID) } var validDuration string if product.Type == merchantDao.Package { beginDate := time.Now().Format(time.DateOnly) endDate := time.Now().Add(time.Duration(product.ValidDays * 24)).Format(time.DateOnly) validDuration = fmt.Sprintf("%s~%s", beginDate, endDate) } else { validDuration = "永久有效" } err = order.DealPaymentOrder(tradeOrder, isSuccess, validDuration) if err != nil { logger.Error("处理支付结果失败%v,支付订单:%s", err, tradeOrderNo) return } productOrderDTO = ConvertProductOrderDTO(productOrder) return }