package service import ( "context" "encoding/json" "errors" "fmt" "gorm.io/gorm" "pure-admin/dto" "pure-admin/global" "pure-admin/initialize/api" "pure-admin/model" "pure-admin/model/request" "pure-admin/model/response" "pure-admin/utils" "time" ) func getWallet(platform, uuid string) (error, model.Wallet) { var ( err error result model.Wallet ) err = global.MG_DB.Model(&model.Wallet{}).Where("platform = ? AND user_id = ?", platform, uuid).First(&result).Error return err, result } func FundRecharge(info *request.FundRecharge) (error, response.PayResult) { var ( err error wallet model.Wallet billFund model.BillFund result response.PayResult ) err = global.MG_DB.Model(&model.Wallet{}).Where("platform = 'bkb' AND user_id = 'bkb'").First(&wallet).Error if err != nil { return err, result } billFund.UserID = "bkb" billFund.TransactionType = 2 billFund.TransactionId = "RC" + generate() billFund.Title = "recharge" billFund.Price = info.Amount billFund.Balance = wallet.Fund + info.Amount billFund.Platform = "bkb" billFund.Status = 1 tx := global.MG_DB.Begin() err = tx.Model(&model.BillFund{}).Create(&billFund).Error if err != nil { tx.Rollback() return err, result } var payChannel string if info.PayMode == 1 { payChannel = "paypal" } attach, _ := json.Marshal(map[string]string{"transactionId": billFund.TransactionId}) params := api.PayTransRequest{ Appid: "bkb5918273465092837", Mchid: "11000001", OutTradeNo: billFund.TransactionId, Attach: string(attach), NotifyUrl: global.MG_CONFIG.Paypal.NotifyUrl + "/base/payment/payback", Amount: info.Amount, Currency: "USD", PayChannel: payChannel, ReturnUrl: global.MG_CONFIG.Paypal.ReturnUrl, CancelUrl: global.MG_CONFIG.Paypal.CancelUrl, } payOrder, err := global.PAY_CLIENT.PayTransactionAppUrl(context.Background(), ¶ms) if err != nil { fmt.Println(err.Error()) tx.Rollback() return errors.New("open " + payChannel + " failed"), result } err = tx.Model(&model.BillFund{}).Where("id = ?", billFund.ID).UpdateColumn("pay_id", payOrder.PayId).Error if err != nil { tx.Rollback() return err, result } tx.Commit() result.PayChannel = payOrder.PayChannel result.PayId = payOrder.PayId result.PayReturn = payOrder.PayReturn result.PayStatus = payOrder.PayStatus return err, result } func PaypalCallback(info *dto.PaybackBody) error { // 开始交易 for { ok, err := global.MG_REDIS.SetNX("payback-"+info.TransactionId, "used", 10*time.Second).Result() if ok && err == nil { // 获取成功 break } } defer func() { // 释放锁 _, _ = utils.RedisDel("payback-" + info.TransactionId) }() switch info.ResourceType { case "pay": // 支付结果 if info.Status != "SUCCESS" { return nil } else { var ( err error billFund model.BillFund ) err = global.MG_DB.Model(&model.BillFund{}).Where("transaction_id = ?", info.OutTradeNo).First(&billFund).Error if err != nil { return err } tx := global.MG_DB.Begin() err = tx.Model(&model.BillFund{}).Where("id = ?", billFund.ID).UpdateColumn("status", 2).Error if err != nil { tx.Rollback() return err } err = tx.Model(&model.Wallet{}).Where("platform = 'seller' AND user_id = ?", billFund.UserID).UpdateColumn("fund", gorm.Expr("fund + ?", billFund.Price)).Error if err != nil { tx.Rollback() return err } tx.Commit() } case "payout": // 提现结果 var ( err error status string withdrawal model.Withdrawal ) err = global.MG_DB.Model(&model.Withdrawal{}).Where("flow_no = ?", info.OutTradeNo).First(&withdrawal).Error if err != nil { return err } tx := global.MG_DB.Begin() if info.Status != "Success" { status = "2" } else { status = "1" // 将对应钱包提现状态恢复 err = tx.Model(&model.Wallet{}).Where("id = ?", withdrawal.CreateBy).UpdateColumn("state", 0).Error if err != nil { tx.Rollback() return err } } err = tx.Model(&model.Withdrawal{}).Where("id = ?", withdrawal.ID).UpdateColumn("status", status).Error if err != nil { tx.Rollback() return err } tx.Commit() } return nil }