trade_order.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. package order
  2. import (
  3. "encoding/json"
  4. logger "eta/eta_mini_ht_api/common/component/log"
  5. "eta/eta_mini_ht_api/models"
  6. "eta/eta_mini_ht_api/models/message"
  7. "eta/eta_mini_ht_api/models/order"
  8. "fmt"
  9. "math/rand"
  10. "strconv"
  11. "time"
  12. )
  13. const (
  14. RMB = "CNY"
  15. AliPayWay PaymentWay = "alipay"
  16. WechatPay PaymentWay = "wechat"
  17. RefundSuccess = "success"
  18. RefundFail = "fail"
  19. )
  20. type PaymentWay string
  21. type TradeOrderDTO struct {
  22. ID int `gorm:"column:id;primaryKey"`
  23. TransactionID string `gorm:"column:transaction_id;type:varchar(255);comment:第三方平台ID"`
  24. ProductOrderID string `gorm:"column:product_order_id;type:varchar(255);comment:商品订单号"`
  25. PaymentAccount string `gorm:"column:payment_account;type:varchar(255);comment:支付账号"`
  26. PaymentWay string `gorm:"column:payment_way;type:enum('wechat');comment:支付渠道"`
  27. Amount string `gorm:"column:amount;type:varchar(20);comment:支付金额"`
  28. Currency string `gorm:"column:currency;type:varchar(255);comment:货币"`
  29. MerchantID string `gorm:"column:merchant_id;type:int(11);comment:商户id"`
  30. UserID int `gorm:"column:user_id;type:int(11);comment:用户id"`
  31. TemplateUserID int `gorm:"column:template_user_id;type:int(11);comment:临时用户id"`
  32. PaymentType string `gorm:"column:payment_type;type:enum('pay','refund');comment:订单类型"`
  33. PaymentStatus string `gorm:"column:payment_status;type:enum('pending','processing','done','failed');comment:支付状态"`
  34. DealTime time.Time `gorm:"column:deal_time;type:datetime;comment:完成时间"`
  35. }
  36. func GenerateTradeOrderNo() string {
  37. timestamp := time.Now().UnixNano() / 1000000 // 毫秒级时间戳
  38. // 生成随机数
  39. rand.New(rand.NewSource(time.Now().UnixNano()))
  40. randomPart := rand.Intn(999999)
  41. // 格式化订单号
  42. orderNumber := fmt.Sprintf("T%d%06d", timestamp, randomPart)
  43. return orderNumber
  44. }
  45. func CreateTradeOrder(userId, templateUserId int, productOrderNo, tradeOrderNo, merchantNo string) (err error) {
  46. db := models.Main()
  47. productOrder, err := order.GetOrderByUser(templateUserId, productOrderNo)
  48. if err != nil {
  49. logger.Error("获取商品订单信息失败%v", err)
  50. return
  51. }
  52. tx := db.Begin()
  53. defer func() {
  54. if err != nil {
  55. tx.Rollback()
  56. return
  57. }
  58. tx.Commit()
  59. }()
  60. tradeOrder := order.TradeOrder{
  61. ProductOrderID: productOrderNo,
  62. TransactionID: tradeOrderNo,
  63. Amount: productOrder.TotalAmount,
  64. PaymentWay: order.WechatPayWay,
  65. Currency: RMB,
  66. MerchantID: merchantNo,
  67. UserID: userId,
  68. TemplateUserID: templateUserId,
  69. PaymentType: order.PaymentTypePay,
  70. }
  71. err = tx.Create(&tradeOrder).Error
  72. if err != nil {
  73. logger.Error("创建支付订单失败%v", err)
  74. return
  75. }
  76. err = tx.Model(&order.ProductOrder{}).Where("id = ?", productOrder.ID).Updates(map[string]interface{}{
  77. "trade_id": tradeOrder.ID,
  78. "trade_no": tradeOrder.TransactionID,
  79. "payment_time": time.Now(),
  80. "payment_amount": tradeOrder.Amount,
  81. "payment_way": tradeOrder.PaymentWay,
  82. }).Error
  83. return
  84. }
  85. func convertToDTO(tradeOrder order.TradeOrder) TradeOrderDTO {
  86. return TradeOrderDTO{
  87. ID: tradeOrder.ID,
  88. TransactionID: tradeOrder.TransactionID,
  89. ProductOrderID: tradeOrder.ProductOrderID,
  90. PaymentAccount: tradeOrder.PaymentAccount,
  91. PaymentWay: string(tradeOrder.PaymentWay),
  92. Amount: tradeOrder.Amount,
  93. Currency: tradeOrder.Currency,
  94. MerchantID: tradeOrder.MerchantID,
  95. UserID: tradeOrder.UserID,
  96. TemplateUserID: tradeOrder.UserID,
  97. PaymentType: string(tradeOrder.PaymentType),
  98. PaymentStatus: string(tradeOrder.PaymentStatus),
  99. DealTime: tradeOrder.DealTime,
  100. }
  101. }
  102. func GetUnFailedTradeFlowByProductOrder(productOrderNo string) (dtoList []TradeOrderDTO, err error) {
  103. var tradeOrderList []order.TradeOrder
  104. tradeOrderList, err = order.GetUnFailedTradeFlowByProductOrder(productOrderNo)
  105. for _, tradeOrder := range tradeOrderList {
  106. dtoList = append(dtoList, convertToDTO(tradeOrder))
  107. }
  108. return
  109. }
  110. func GetTradeOrderByNo(tradeOrderNo string) (dto TradeOrderDTO, err error) {
  111. var tradeOrder order.TradeOrder
  112. tradeOrder, err = order.GetTradeOrderByNo(tradeOrderNo, order.PaymentTypePay)
  113. dto = convertToDTO(tradeOrder)
  114. return
  115. }
  116. type RefundDealFlowDTO struct {
  117. OperatorUserID int `gorm:"column:operator_user_id"`
  118. ProductOrderNo string `gorm:"column:product_order_no"`
  119. RefundOrderNo string `gorm:"column:refund_order_no"`
  120. }
  121. func DealRefund(refundOrderNo string, flag string) (dto RefundDealFlowDTO, err error) {
  122. flow, err := order.GetRefundFlow(refundOrderNo)
  123. if err != nil {
  124. logger.Error("获取退款流水失败%v,退款订单:%s", err, refundOrderNo)
  125. return
  126. }
  127. dto = convertRefundDTO(flow)
  128. //处理退款订单
  129. TradeOrder, err := order.GetTradeOrderByNo(flow.RefundOrderNo, order.PaymentTypeRefund)
  130. if err != nil {
  131. logger.Error("获取退款订单失败%v,退款订单:%s", err, refundOrderNo)
  132. return
  133. }
  134. err = order.DealRefundOrder(TradeOrder, true)
  135. if err != nil {
  136. logger.Error("处理退款结果失败%v,退款订单:%s", err, refundOrderNo)
  137. return
  138. }
  139. _ = createRefundMetaInfo(flow.OperatorUserID, flow.ProductOrderNo, flag)
  140. return
  141. }
  142. func convertRefundDTO(flow order.RefundDealFlow) RefundDealFlowDTO {
  143. return RefundDealFlowDTO{
  144. OperatorUserID: flow.OperatorUserID,
  145. ProductOrderNo: flow.ProductOrderNo,
  146. RefundOrderNo: flow.RefundOrderNo,
  147. }
  148. }
  149. func createRefundMetaInfo(sysUserId int, productOrderNo string, flag string) (err error) {
  150. productOrder, err := order.GetOrderByOrderNo(productOrderNo)
  151. if err != nil {
  152. logger.Error("生成退款消息通知失败,获取订单信息失败:v,订单编号:%s", err, productOrderNo)
  153. return
  154. }
  155. var result string
  156. switch flag {
  157. case RefundSuccess:
  158. result = "成功"
  159. case RefundFail:
  160. result = "失败"
  161. default:
  162. logger.Error("生成退款消息通知失败,未知的退款状态%s,订单编号:%s", flag, productOrderNo)
  163. return
  164. }
  165. refundInfo := message.RefundMetaData{
  166. RealName: productOrder.RealName,
  167. ProductOrderNo: productOrderNo,
  168. Result: result,
  169. }
  170. bytes, err := json.Marshal(refundInfo)
  171. if err != nil {
  172. logger.Error("生成退款消息通知失败,序列化退款信息失败:%v,订单编号:%s", err, productOrderNo)
  173. return
  174. }
  175. metaInfo := message.MetaInfo{
  176. Meta: string(bytes),
  177. MetaType: message.SysUserNoticeType,
  178. SourceType: message.RefundSourceType,
  179. Status: message.InitStatusType,
  180. From: "HTTradePlate",
  181. To: strconv.Itoa(sysUserId),
  182. }
  183. return message.CreateMetaInfo(metaInfo)
  184. }