trade_order.go 7.3 KB

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