feat: link transaction with balance and payment (#3052)

* feat: add and update transaction when recharging

* feat: add pay with balance

* feat: improve code format

* feat: update icon url for balance
This commit is contained in:
DacongDA
2024-07-12 15:48:37 +08:00
committed by GitHub
parent cef2ab213b
commit 7f2869cecb
9 changed files with 130 additions and 6 deletions

View File

@ -201,7 +201,7 @@ func notifyPayment(body []byte, owner string, paymentName string) (*Payment, *pp
}
if payment.IsRecharge {
err = updateUserBalance(payment.Owner, payment.User, payment.Price)
err = UpdateUserBalance(payment.Owner, payment.User, payment.Price)
return payment, notifyResult, err
}
@ -222,6 +222,19 @@ func NotifyPayment(body []byte, owner string, paymentName string) (*Payment, err
if err != nil {
return nil, err
}
transaction, err := GetTransaction(payment.GetId())
if err != nil {
return nil, err
}
if transaction != nil {
transaction.State = payment.State
_, err = UpdateTransaction(transaction.GetId(), transaction)
if err != nil {
return nil, err
}
}
}
return payment, nil

View File

@ -227,13 +227,17 @@ func BuyProduct(id string, user *User, providerName, pricingName, planName, host
NotifyUrl: notifyUrl,
PaymentEnv: paymentEnv,
}
// custom process for WeChat & WeChat Pay
if provider.Type == "WeChat Pay" {
payReq.PayerId, err = getUserExtraProperty(user, "WeChat", idp.BuildWechatOpenIdKey(provider.ClientId2))
if err != nil {
return nil, nil, err
}
} else if provider.Type == "Balance" {
payReq.PayerId = user.GetId()
}
payResp, err := pProvider.Pay(payReq)
if err != nil {
return nil, nil, err
@ -264,12 +268,46 @@ func BuyProduct(id string, user *User, providerName, pricingName, planName, host
OutOrderId: payResp.OrderId,
}
transaction := &Transaction{
Owner: payment.Owner,
Name: payment.Name,
DisplayName: payment.DisplayName,
Provider: provider.Name,
Category: provider.Category,
Type: provider.Type,
ProductName: product.Name,
ProductDisplayName: product.DisplayName,
Detail: product.Detail,
Tag: product.Tag,
Currency: product.Currency,
Amount: payment.Price,
ReturnUrl: payment.ReturnUrl,
User: payment.User,
Application: owner,
Payment: payment.GetId(),
State: pp.PaymentStateCreated,
}
if provider.Type == "Dummy" {
payment.State = pp.PaymentStatePaid
err = updateUserBalance(user.Owner, user.Name, payment.Price)
err = UpdateUserBalance(user.Owner, user.Name, payment.Price)
if err != nil {
return nil, nil, err
}
} else if provider.Type == "Balance" {
if product.Price > user.Balance {
return nil, nil, fmt.Errorf("insufficient user balance")
}
transaction.Amount = -transaction.Amount
err = UpdateUserBalance(user.Owner, user.Name, -product.Price)
if err != nil {
return nil, nil, err
}
payment.State = pp.PaymentStatePaid
transaction.State = pp.PaymentStatePaid
}
affected, err := AddPayment(payment)
@ -280,6 +318,17 @@ func BuyProduct(id string, user *User, providerName, pricingName, planName, host
if !affected {
return nil, nil, fmt.Errorf("failed to add payment: %s", util.StructToJson(payment))
}
if product.IsRecharge || provider.Type == "Balance" {
affected, err = AddTransaction(transaction)
if err != nil {
return nil, nil, err
}
if !affected {
return nil, nil, fmt.Errorf("failed to add transaction: %s", util.StructToJson(payment))
}
}
return payment, payResp.AttachInfo, nil
}

View File

@ -309,6 +309,12 @@ func GetPaymentProvider(p *Provider) (pp.PaymentProvider, error) {
return nil, err
}
return pp, nil
} else if typ == "Balance" {
pp, err := pp.NewBalancePaymentProvider()
if err != nil {
return nil, err
}
return pp, nil
} else {
return nil, fmt.Errorf("the payment provider type: %s is not supported", p.Type)
}

View File

@ -17,6 +17,7 @@ package object
import (
"fmt"
"github.com/casdoor/casdoor/pp"
"github.com/casdoor/casdoor/util"
"github.com/xorm-io/core"
)
@ -43,7 +44,7 @@ type Transaction struct {
Application string `xorm:"varchar(100)" json:"application"`
Payment string `xorm:"varchar(100)" json:"payment"`
State string `xorm:"varchar(100)" json:"state"`
State pp.PaymentState `xorm:"varchar(100)" json:"state"`
}
func GetTransactionCount(owner, field, value string) (int64, error) {

View File

@ -1158,7 +1158,7 @@ func GenerateIdForNewUser(application *Application) (string, error) {
return res, nil
}
func updateUserBalance(owner string, name string, balance float64) error {
func UpdateUserBalance(owner string, name string, balance float64) error {
user, err := getUser(owner, name)
if err != nil {
return err