diff --git a/api/proto/vas/proto/pay.go b/api/proto/vas/proto/pay.go index 19519f26..0684d5e5 100644 --- a/api/proto/vas/proto/pay.go +++ b/api/proto/vas/proto/pay.go @@ -34,12 +34,14 @@ const ( PayTypeWxpayH5 = "wxpay_h5" // 微信支付 h5 PayTypeYeepayAlipayH5 = "yeepay_alipay_h5" // 易宝 微信h5支付 PayTypeYeepayWxpayH5 = "yeepay_wxpay_h5" // 易宝 微信h5支付 + PayTypeCoin = "coin" // 金币支付 ) const ( CallBackPayTypeAlipay = "alipay" CallBackPayTypeWxpay = "wxpay" CallBackPayTypeYeepay = "yeepay" + CallBackPayTypeCoin = "coin" ) const ( diff --git a/app/mix/service/logic/vas.go b/app/mix/service/logic/vas.go index ada0059c..6feb102f 100644 --- a/app/mix/service/logic/vas.go +++ b/app/mix/service/logic/vas.go @@ -345,6 +345,8 @@ func (v *Vas) CreateOrder(ctx *gin.Context, req *vasproto.CreateOrderReq) (data } yeepayWxpayH5ParamStr = aggPayResp.PrePayTn req.Oid3 = yeepayCli.MerchantNo + case vasproto.PayTypeCoin: + return v.CreateOrderByCoin(ctx, req, product) } // 添加订单 @@ -395,6 +397,110 @@ func (v *Vas) CreateOrder(ctx *gin.Context, req *vasproto.CreateOrderReq) (data return } +func (v *Vas) CreateOrderByCoin(ctx *gin.Context, req *vasproto.CreateOrderReq, product *dbstruct.Product) (data *vasproto.CreateOrderData, err error) { + var ( + order *dbstruct.Order + orderId = idgenerator.GenOrderId() // 订单id + priceCoin = product.GetRealPriceCoin() + ) + + // 开启事务 + tx, err := v.store.VasBegin(ctx) + if err != nil { + logger.Error("vas begin fail, err: %v", err) + return nil, err + } + defer func() { + if err != nil { + logger.Error("global err, req: %v, order: %v, err: %v", util.ToJson(req), util.ToJson(order), err) + } + errTx := v.store.DealTxCR(tx, err) + if errTx != nil { + logger.Error("DealTxCR fail, err: %v", errTx) + return + } + }() + + // 检查钱包 + wallet, exists := v.CheckWalletExist(ctx, tx, req.Mid) + if !exists { + err = errs.ErrVasWalletNotExist + logger.Error("CheckWalletExist fail, mid: %v, err: %v", req.Mid, err) + return + } + if wallet.GetCoins() <= priceCoin { + err = errs.ErrVasNoEnoughCoin + logger.Error("not enough coin, mid: %v, coins: %v, err: %v", req.Mid, wallet.Coins, err) + return + } + + // 扣金币 + err = v.store.DecCoins(ctx, tx, req.Mid, priceCoin) + if err != nil { + logger.Error("DecCoins fail, mid: %v, priceCoin: %v, err: %v", req.Mid, priceCoin, err) + return + } + + // 添加订单 + var ( + timeNow = time.Now().Unix() + ) + order = &dbstruct.Order{ + ID: goproto.String(orderId), + Mid: goproto.Int64(req.Mid), + Uid: goproto.Int64(req.Uid), + Oid1: goproto.String(req.Oid1), + Oid2: goproto.String(req.Oid2), + Oid3: goproto.String(req.Oid3), + ProductId: goproto.String(req.ProductId), + PayType: goproto.String(req.PayType), + PayAmount: goproto.Int64(product.RealPrice), + Coins: goproto.Int64(product.ValueCoins), + OrderStatus: goproto.Int32(dbstruct.VasOrderStatusInit), + OrderFrom: goproto.String(req.From), + Ct: goproto.Int64(timeNow), + Ut: goproto.Int64(timeNow), + Operator: goproto.String(req.Operator), + Did: goproto.String(req.Did), + Version: goproto.String(req.Version), + OsVersion: goproto.String(req.Version), + DevType: goproto.Int32(req.DevType), + Channel: goproto.String(req.Channel), + Model: goproto.String(req.Model), + NetType: goproto.String(req.NetType), + Ip: goproto.String(req.Ip), + } + err = v.store.CreateOrder(ctx, tx, order) + if err != nil { + logger.Error("CreateOrder fail, order: %v, err: %v", util.ToJson(order), err) + return + } + + // 提交事务 + errTx := v.store.DealTxCR(tx, err) + if errTx != nil { + logger.Error("DealTxCR fail, err: %v", errTx) + err = errTx + return + } + + // 手动回调 + err = v.PayCallback(ctx, &vasproto.PayCallbackParamIn{ + OrderId: orderId, + OutOrderId: fmt.Sprintf("%s_bycoin", orderId), + CallbackPayType: vasproto.CallBackPayTypeCoin, + }) + if err != nil { + logger.Error("PayCallback fail, err: %v", err) + return + } + + data = &vasproto.CreateOrderData{ + OrderId: orderId, + } + return +} + func (v *Vas) CheckWalletExist(ctx *gin.Context, tx *sqlx.Tx, mid int64) (wallet *dbstruct.Wallet, exist bool) { wallet, err := v.store.GetWalletByMid(ctx, tx, mid) switch err { diff --git a/dbstruct/product.go b/dbstruct/product.go index ac87fb1c..936eb208 100644 --- a/dbstruct/product.go +++ b/dbstruct/product.go @@ -96,3 +96,7 @@ type Product struct { Images []*ToCImage `json:"images"` Videos []*ToCVideo `json:"videos"` } + +func (p Product) GetRealPriceCoin() int64 { + return p.RealPrice / 10 +}