create order. add paytype: coin
This commit is contained in:
parent
b35e2ac7a3
commit
8bf8e9357f
|
@ -32,11 +32,13 @@ const (
|
|||
PayTypeWxpayNative = "wxpay_native" // 微信 native
|
||||
PayTypeWxpayJsapi = "wxpay_jsapi" // 微信 jsapi
|
||||
PayTypeWxpayH5 = "wxpay_h5" // 微信支付 h5
|
||||
PayTypeCoin = "coin" // 金币支付
|
||||
)
|
||||
|
||||
const (
|
||||
CallBackPayTypeAlipay = "alipay"
|
||||
CallBackPayTypeWxpay = "wxpay"
|
||||
CallBackPayTypeCoin = "coin"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -296,6 +296,8 @@ func (v *Vas) CreateOrder(ctx *gin.Context, req *vasproto.CreateOrderReq) (data
|
|||
return
|
||||
}
|
||||
req.Oid3 = wxpayCli.AppId
|
||||
case vasproto.PayTypeCoin:
|
||||
return v.CreateOrderByCoin(ctx, req, product)
|
||||
}
|
||||
|
||||
// 添加订单
|
||||
|
@ -344,6 +346,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 {
|
||||
|
@ -1249,7 +1355,7 @@ func (v *Vas) GetUserWechatUnlock(ctx *gin.Context, mid, uid int64) (uu *dbstruc
|
|||
}
|
||||
|
||||
// 【支付】回调
|
||||
func (v *Vas) PayCallback(ctx *gin.Context, p *vasproto.PayCallbackParamIn) {
|
||||
func (v *Vas) PayCallback(ctx *gin.Context, p *vasproto.PayCallbackParamIn) (err error) {
|
||||
var (
|
||||
orderId = p.OrderId
|
||||
outOrderId = p.OutOrderId
|
||||
|
@ -1261,16 +1367,16 @@ func (v *Vas) PayCallback(ctx *gin.Context, p *vasproto.PayCallbackParamIn) {
|
|||
checkOrder, err := v.store.GetOrderById(ctx, nil, orderId)
|
||||
if err != nil {
|
||||
logger.Error("GetOrderById fail, p: %v, err: %v", util.ToJson(p), err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
if checkOrder == nil {
|
||||
logger.Warn("GetOrderById nil, p: %v", util.ToJson(p))
|
||||
return
|
||||
return err
|
||||
}
|
||||
// 是否已处理过的订单
|
||||
if checkOrder.GetOrderStatus() != dbstruct.VasOrderStatusInit {
|
||||
logger.Error("repeat deal, p: %v", util.ToJson(p))
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
// out_order_id检查
|
||||
|
@ -1281,29 +1387,29 @@ func (v *Vas) PayCallback(ctx *gin.Context, p *vasproto.PayCallbackParamIn) {
|
|||
}
|
||||
if err != nil {
|
||||
logger.Error("GetOrderByOutOrderId fail, p: %v, err: %v", util.ToJson(p), err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
if outOrder != nil {
|
||||
logger.Error("out order exists, p: %v", util.ToJson(p))
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
// 获取商品
|
||||
product, err := v.store.GetProductById(ctx, checkOrder.GetProductId())
|
||||
if err != nil {
|
||||
logger.Error("GetProductById fail, id: %v, err: %v", checkOrder.GetProductId(), err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
if product == nil {
|
||||
logger.Error("GetProductById nil, id: %v", checkOrder.GetProductId())
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
// 钱包
|
||||
_, hasWallet := v.CheckWalletExist(ctx, nil, checkOrder.GetMid())
|
||||
if !hasWallet {
|
||||
logger.Error("CheckWalletExist fail, mid: %v", checkOrder.GetMid())
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
// 解锁信息
|
||||
|
@ -1313,7 +1419,7 @@ func (v *Vas) PayCallback(ctx *gin.Context, p *vasproto.PayCallbackParamIn) {
|
|||
_, hasZoneUnlock := v.CheckZoneUnlockExist(ctx, nil, mid, zid)
|
||||
if !hasZoneUnlock {
|
||||
logger.Error("CheckZoneUnlockExist fail, mid: %v, zid: %v", mid, zid)
|
||||
return
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1321,7 +1427,7 @@ func (v *Vas) PayCallback(ctx *gin.Context, p *vasproto.PayCallbackParamIn) {
|
|||
tx, err := v.store.VasBegin(ctx)
|
||||
if err != nil {
|
||||
logger.Error("vas begin fail, err: %v", err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
_ = v.AddOplogOrder(
|
||||
|
@ -1368,7 +1474,7 @@ func (v *Vas) PayCallback(ctx *gin.Context, p *vasproto.PayCallbackParamIn) {
|
|||
order, err := v.store.GetOrderByIdForUpdate(ctx, tx, orderId)
|
||||
if err != nil {
|
||||
logger.Error("GetOrderByIdForUpdate fail, p: %v", util.ToJson(p))
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
// 锁住钱包
|
||||
|
@ -1403,14 +1509,14 @@ func (v *Vas) PayCallback(ctx *gin.Context, p *vasproto.PayCallbackParamIn) {
|
|||
err = v.store.CreateConsumeHistory(ctx, tx, ch)
|
||||
if err != nil {
|
||||
logger.Error("CreateConsumeHistory fail, ch: %v, err: %v", util.ToJson(ch), err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
// 更新状态
|
||||
err = v.store.UpdateOrderStatus(ctx, tx, orderId, dbstruct.VasOrderStatusInit, dbstruct.VasOrderStatusPaySuccess)
|
||||
if err != nil {
|
||||
logger.Error("UpdateOrderStatus fail, p: %v", util.ToJson(p))
|
||||
return
|
||||
return err
|
||||
}
|
||||
afterStatus = dbstruct.VasOrderStatusPaySuccess
|
||||
|
||||
|
@ -1418,7 +1524,7 @@ func (v *Vas) PayCallback(ctx *gin.Context, p *vasproto.PayCallbackParamIn) {
|
|||
err = v.store.UpdateOutOrderId(ctx, tx, orderId, outOrderId)
|
||||
if err != nil {
|
||||
logger.Error("UpdateOutOrderId fail, p: %v", util.ToJson(p))
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
// 商品判断
|
||||
|
@ -1428,12 +1534,12 @@ func (v *Vas) PayCallback(ctx *gin.Context, p *vasproto.PayCallbackParamIn) {
|
|||
err = v.store.IncCoins(ctx, tx, order.GetMid(), order.GetCoins())
|
||||
if err != nil {
|
||||
logger.Error("IncCoins fail, order: %v, err: %v", util.ToJson(order), err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
err = v.store.UpdateOrderStatus(ctx, tx, orderId, dbstruct.VasOrderStatusPaySuccess, dbstruct.VasOrderStatusFinish)
|
||||
if err != nil {
|
||||
logger.Error("UpdateOrderStatus fail, order: %v, err: %v", util.ToJson(order), err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
afterStatus = dbstruct.VasOrderStatusFinish
|
||||
case product.Id == dbstruct.ProductIdH5ContactWechat:
|
||||
|
@ -1441,32 +1547,32 @@ func (v *Vas) PayCallback(ctx *gin.Context, p *vasproto.PayCallbackParamIn) {
|
|||
err = v.store.IncCoins(ctx, tx, order.GetMid(), order.GetCoins())
|
||||
if err != nil {
|
||||
logger.Error("IncCoins fail, order: %v, err: %v", util.ToJson(order), err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
case product.Id == dbstruct.ProductIdMembership:
|
||||
// 解锁会员资格
|
||||
_, err = v.UnlockMembership(ctx, tx, util.DerefInt64(order.Mid), product, order, wallet)
|
||||
if err != nil {
|
||||
logger.Error("UnlockMembership fail, order: %v, err: %v", util.ToJson(order), err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
case product.Id == dbstruct.ProductIdH5ZoneMoment:
|
||||
err = v.UnlockZoneMoment(ctx, tx, order)
|
||||
if err != nil {
|
||||
logger.Error("UnlockZoneMoment fail, order: %v, err: %v", util.ToJson(order), err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
case product.Id == dbstruct.ProductIdH5ZoneAdmission:
|
||||
err = v.UnlockZoneAdmission(ctx, tx, order, dbstruct.ZoneUnlockTypePay)
|
||||
if err != nil {
|
||||
logger.Error("UnlockZoneAdmission fail, order: %v, err: %v", util.ToJson(order), err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
case product.Id == dbstruct.ProductIdH5ZoneSuperfanship:
|
||||
err = v.UnlockZoneSuperfanship(ctx, tx, order, dbstruct.ZoneUnlockTypePay)
|
||||
if err != nil {
|
||||
logger.Error("UnlockZoneSuperfanship fail, order: %v, err: %v", util.ToJson(order), err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1474,8 +1580,9 @@ func (v *Vas) PayCallback(ctx *gin.Context, p *vasproto.PayCallbackParamIn) {
|
|||
_err := v.UnlockZoneIronfanshipReachConsume(ctx, tx, order.GetMid(), order.GetZid(), order.GetUid())
|
||||
if _err != nil {
|
||||
logger.Error("UnlockZoneIronfanshipReachConsume fail, order: %v, err: %v", util.ToJson(order), _err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (v *Vas) GetCoinOrderById(ctx *gin.Context, id string) (*dbstruct.CoinOrder, error) {
|
||||
|
|
|
@ -499,7 +499,7 @@ func (s *Service) H5DirectUnlockWechat(ctx *gin.Context, req *vasproto.H5DirectU
|
|||
|
||||
// 支付回调
|
||||
func (s *Service) PayCallback(ctx *gin.Context, req *vasproto.PayCallbackParamIn) (data *vasproto.H5DirectUnlockWechatData, ec errcode.ErrCode) {
|
||||
_DefaultVas.PayCallback(ctx, req)
|
||||
_ = _DefaultVas.PayCallback(ctx, req)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -96,3 +96,7 @@ type Product struct {
|
|||
Images []*ToCImage `json:"images"`
|
||||
Videos []*ToCVideo `json:"videos"`
|
||||
}
|
||||
|
||||
func (p Product) GetRealPriceCoin() int64 {
|
||||
return p.RealPrice / 10
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue