trade_order.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  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. ProductName: productOrder.ProductName,
  65. TransactionID: tradeOrderNo,
  66. Amount: productOrder.TotalAmount,
  67. Mobile: productOrder.Mobile,
  68. AreaCode: productOrder.AreaCode,
  69. RealName: productOrder.RealName,
  70. PaymentWay: order.WechatPayWay,
  71. Currency: RMB,
  72. MerchantID: merchantNo,
  73. UserID: userId,
  74. TemplateUserID: templateUserId,
  75. PaymentType: order.PaymentTypePay,
  76. }
  77. err = tx.Create(&tradeOrder).Error
  78. if err != nil {
  79. logger.Error("创建支付订单失败%v", err)
  80. return
  81. }
  82. err = tx.Model(&order.ProductOrder{}).Where("id = ?", productOrder.ID).Updates(map[string]interface{}{
  83. "trade_id": tradeOrder.ID,
  84. "trade_no": tradeOrder.TransactionID,
  85. "payment_time": time.Now(),
  86. "payment_amount": tradeOrder.Amount,
  87. "payment_way": tradeOrder.PaymentWay,
  88. }).Error
  89. return
  90. }
  91. func convertToDTO(tradeOrder order.TradeOrder) TradeOrderDTO {
  92. return TradeOrderDTO{
  93. ID: tradeOrder.ID,
  94. TransactionID: tradeOrder.TransactionID,
  95. ProductOrderID: tradeOrder.ProductOrderID,
  96. PaymentAccount: tradeOrder.PaymentAccount,
  97. PaymentWay: string(tradeOrder.PaymentWay),
  98. Amount: tradeOrder.Amount,
  99. Currency: tradeOrder.Currency,
  100. MerchantID: tradeOrder.MerchantID,
  101. UserID: tradeOrder.UserID,
  102. TemplateUserID: tradeOrder.UserID,
  103. PaymentType: string(tradeOrder.PaymentType),
  104. PaymentStatus: string(tradeOrder.PaymentStatus),
  105. DealTime: tradeOrder.DealTime,
  106. }
  107. }
  108. func GetUnFailedTradeFlowByProductOrder(productOrderNo string) (dtoList []TradeOrderDTO, err error) {
  109. var tradeOrderList []order.TradeOrder
  110. tradeOrderList, err = order.GetUnFailedTradeFlowByProductOrder(productOrderNo)
  111. for _, tradeOrder := range tradeOrderList {
  112. dtoList = append(dtoList, convertToDTO(tradeOrder))
  113. }
  114. return
  115. }
  116. func GetTradeOrderByNo(tradeOrderNo string) (dto TradeOrderDTO, err error) {
  117. var tradeOrder order.TradeOrder
  118. tradeOrder, err = order.GetTradeOrderByNo(tradeOrderNo, order.PaymentTypePay)
  119. dto = convertToDTO(tradeOrder)
  120. return
  121. }
  122. type RefundDealFlowDTO struct {
  123. OperatorUserID int `gorm:"column:operator_user_id"`
  124. ProductOrderNo string `gorm:"column:product_order_no"`
  125. RefundOrderNo string `gorm:"column:refund_order_no"`
  126. }
  127. func convertRefundDTO(flow order.RefundDealFlow) RefundDealFlowDTO {
  128. return RefundDealFlowDTO{
  129. OperatorUserID: flow.OperatorUserID,
  130. ProductOrderNo: flow.ProductOrderNo,
  131. RefundOrderNo: flow.RefundOrderNo,
  132. }
  133. }
  134. func createRefundMetaInfo(sysUserId int, productOrderNo string, flag string) (err error) {
  135. productOrder, err := order.GetOrderByOrderNo(productOrderNo)
  136. if err != nil {
  137. logger.Error("生成退款消息通知失败,获取订单信息失败:v,订单编号:%s", err, productOrderNo)
  138. return
  139. }
  140. var result string
  141. switch flag {
  142. case RefundSuccess:
  143. result = "成功"
  144. case RefundFail:
  145. result = "失败"
  146. default:
  147. logger.Error("生成退款消息通知失败,未知的退款状态%s,订单编号:%s", flag, productOrderNo)
  148. return
  149. }
  150. refundInfo := message.RefundMetaData{
  151. RealName: productOrder.RealName,
  152. ProductOrderNo: productOrderNo,
  153. Result: result,
  154. }
  155. bytes, err := json.Marshal(refundInfo)
  156. if err != nil {
  157. logger.Error("生成退款消息通知失败,序列化退款信息失败:%v,订单编号:%s", err, productOrderNo)
  158. return
  159. }
  160. metaInfo := message.MetaInfo{
  161. Meta: string(bytes),
  162. MetaType: message.SysUserNoticeType,
  163. SourceType: message.RefundSourceType,
  164. Status: message.InitStatusType,
  165. From: "HTTradePlate",
  166. To: strconv.Itoa(sysUserId),
  167. }
  168. return message.CreateMetaInfo(metaInfo)
  169. }
  170. func DealRefund(refundOrderNo string, flag string) (dto RefundDealFlowDTO, err error) {
  171. flow, err := order.GetRefundFlow(refundOrderNo)
  172. if err != nil {
  173. logger.Error("获取退款流水失败%v,退款订单:%s", err, refundOrderNo)
  174. return
  175. }
  176. dto = convertRefundDTO(flow)
  177. //处理退款订单
  178. TradeOrder, err := order.GetTradeOrderByNo(flow.RefundOrderNo, order.PaymentTypeRefund)
  179. if err != nil {
  180. logger.Error("获取退款订单失败%v,退款订单:%s", err, refundOrderNo)
  181. return
  182. }
  183. isSuccess := false
  184. if flag == RefundSuccess {
  185. isSuccess = true
  186. }
  187. err = order.DealRefundOrder(TradeOrder, isSuccess)
  188. if err != nil {
  189. logger.Error("处理退款结果失败%v,退款订单:%s", err, refundOrderNo)
  190. return
  191. }
  192. _ = createRefundMetaInfo(flow.OperatorUserID, flow.ProductOrderNo, flag)
  193. return
  194. }
  195. func DealPayment(tradeOrderNo string, flag string) (productOrderDTO ProductOrderDTO, err error) {
  196. //处理退款订单
  197. tradeOrder, err := order.GetTradeOrderByNo(tradeOrderNo, order.PaymentTypePay)
  198. if err != nil {
  199. logger.Error("获取支付订单失败%v,支付订单:%s", err, tradeOrderNo)
  200. return
  201. }
  202. isSuccess := false
  203. if flag == PaySuccess {
  204. isSuccess = true
  205. }
  206. err = order.DealPaymentOrder(tradeOrder, isSuccess)
  207. if err != nil {
  208. logger.Error("处理支付结果失败%v,支付订单:%s", err, tradeOrderNo)
  209. return
  210. }
  211. var productOrder order.ProductOrder
  212. productOrder, err = order.GetOrderByOrderNo(tradeOrder.ProductOrderID)
  213. if err != nil {
  214. logger.Error("获取产品订单失败%v,支付订单:%s", err, tradeOrderNo)
  215. return
  216. }
  217. productOrderDTO = ConvertProductOrderDTO(productOrder)
  218. return
  219. }