Bläddra i källkod

fix: make virtual recharge idempotent

Codex 1 månad sedan
förälder
incheckning
57a0713d50

+ 11 - 5
go/gopath/src/fohow.com/apps/controllers/pay_controller/virtual_pay_controller.go

@@ -324,16 +324,22 @@ func virtualPayHMAC(key, data string) string {
 
 func markVirtualRechargePaid(order *balance_model.RechargeCashOrder, tradeNo string) bool {
 	if order.State == 1 {
-		rechargeCash(order.WxUserId, order.UserId, order.TotalPrice, order.OrderId)
 		return true
 	}
+	paiedAt := time.Now().Unix()
+	marked, err := balance_model.MarkRechargeCashOrderPaid(order.OrderId, tradeNo, balance_model.PAY_WAY_TYPE_RECHARGE_VIRTUAL, paiedAt)
+	if err != nil {
+		beego.BeeLogger.Error("markVirtualRechargePaid mark order failed, order_id=%s, err=%s", order.OrderId, err)
+		return false
+	}
 	order.State = 1
 	order.TradeNo = tradeNo
 	order.PayWay = balance_model.PAY_WAY_TYPE_RECHARGE_VIRTUAL
-	order.PaiedAt = time.Now().Unix()
-	if err := order.Save(); err != nil {
-		beego.BeeLogger.Error("markVirtualRechargePaid save order failed, order_id=%s, err=%s", order.OrderId, err)
-		return false
+	if order.PaiedAt == 0 {
+		order.PaiedAt = paiedAt
+	}
+	if !marked {
+		return true
 	}
 	rechargeCash(order.WxUserId, order.UserId, order.TotalPrice, order.OrderId)
 	return true

+ 16 - 0
go/gopath/src/fohow.com/apps/models/balance_model/cash_balance.go

@@ -375,6 +375,22 @@ func (self *RechargeCashOrder) Save() error {
 	return err
 }
 
+func MarkRechargeCashOrderPaid(orderId, tradeNo, payWay string, paiedAt int64) (bool, error) {
+	tbn := new(RechargeCashOrder).TableName()
+	sql := fmt.Sprintf("UPDATE `%s` SET `state`=1, `trade_no`=?, `pay_way`=?, `paied_at`=?, `updated_at`=NOW() WHERE `order_id`=? AND (`state` IS NULL OR `state`<>1) LIMIT 1", tbn)
+	res, err := orm.NewOrm().Raw(sql, tradeNo, payWay, paiedAt, orderId).Exec()
+	if err != nil {
+		beego.BeeLogger.Error("MarkRechargeCashOrderPaid order_id=[%s] err=[%s]", orderId, err)
+		return false, err
+	}
+	rows, err := res.RowsAffected()
+	if err != nil {
+		beego.BeeLogger.Error("MarkRechargeCashOrderPaid rows affected order_id=[%s] err=[%s]", orderId, err)
+		return false, err
+	}
+	return rows > 0, nil
+}
+
 func GetRechargeCashOrderByOId(oId string, useCache bool) *RechargeCashOrder {
 	k := fmt.Sprintf("balance_model.GetRechargeCashOrderByOId[%s]", oId)
 	if useCache {