mirror of
https://github.com/labring/sealos.git
synced 2026-09-24 15:46:19 +08:00
Corporate (#5726)
* support_pay_refund * corporate --------- Co-authored-by: wj <3638877@qq.com>
This commit is contained in:
@@ -913,6 +913,15 @@ func (c *Cockroach) updateWithAccount(userUID uuid.UUID, isDeduction, add, isAct
|
||||
return HandleUpdateResult(result, types.Account{}.TableName())
|
||||
}
|
||||
|
||||
func (c *Cockroach) UpdateWithAccount(
|
||||
userUID uuid.UUID,
|
||||
isDeduction, add, isActive bool,
|
||||
amount int64,
|
||||
db *gorm.DB,
|
||||
) error {
|
||||
return c.updateWithAccount(userUID, isDeduction, add, isActive, amount, db)
|
||||
}
|
||||
|
||||
func HandleUpdateResult(result *gorm.DB, entityName string) error {
|
||||
if result.Error != nil {
|
||||
return fmt.Errorf("failed to update %s: %w", entityName, result.Error)
|
||||
@@ -1735,7 +1744,7 @@ func (c *Cockroach) transferAccount(from, to *types.UserQueryOpts, amount int64,
|
||||
func (c *Cockroach) InitTables() error {
|
||||
err := CreateTableIfNotExist(c.DB, types.Account{}, types.AccountTransaction{}, types.Payment{}, types.Transfer{}, types.Region{}, types.Invoice{},
|
||||
types.InvoicePayment{}, types.Configs{}, types.Credits{}, types.CreditsTransaction{},
|
||||
types.CardInfo{}, types.PaymentOrder{},
|
||||
types.CardInfo{}, types.PaymentOrder{}, types.PaymentRefund{}, types.Corporate{},
|
||||
types.SubscriptionPlan{}, types.Subscription{}, types.SubscriptionTransaction{},
|
||||
types.AccountRegionUserTask{}, types.UserKYC{}, types.RegionConfig{}, types.Debt{}, types.DebtStatusRecord{}, types.DebtResumeDeductionBalanceTransaction{},
|
||||
types.UserTimeRangeTraffic{})
|
||||
@@ -1808,6 +1817,17 @@ func (c *Cockroach) InitTables() error {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 增加状态列
|
||||
if !c.DB.Migrator().HasColumn(&types.Payment{}, "status") {
|
||||
fmt.Println("add column status to payment")
|
||||
// 注意:IF NOT EXISTS 避免重复报错
|
||||
sql := `ALTER TABLE "Payment" ADD COLUMN IF NOT EXISTS "status" TEXT NOT NULL DEFAULT 'PAID';`
|
||||
if err := c.DB.Exec(sql).Error; err != nil {
|
||||
return fmt.Errorf("failed to add payment.status column: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2032,3 +2052,49 @@ func (c *Cockroach) GetEnterpriseRealNameInfoByUserID(userID string) (*types.Ent
|
||||
}
|
||||
return &enterpriseRealNameInfo, nil
|
||||
}
|
||||
|
||||
func (c *Cockroach) CreateCorporate(account *types.Corporate) error {
|
||||
return c.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if account.UserUID == "" {
|
||||
return fmt.Errorf("corporate uid is empty")
|
||||
}
|
||||
if account.ReceiptSerialNumber == "" {
|
||||
return fmt.Errorf("corporate receiptSerialNumber is empty")
|
||||
}
|
||||
if account.PayerName == "" {
|
||||
return fmt.Errorf("corporate payerName is empty")
|
||||
}
|
||||
if account.PaymentAmount < 0 {
|
||||
return fmt.Errorf("corporate paymentAmount is zero")
|
||||
}
|
||||
id, err := gonanoid.New(12)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to generate payment id: %v", err)
|
||||
}
|
||||
account.ID = id
|
||||
pay := &types.Payment{}
|
||||
pay.ID = account.ID
|
||||
pay.UserUID, err = c.getUserUIDByID(account.UserUID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get user uid: %v", err)
|
||||
}
|
||||
pay.Method = "corporate"
|
||||
pay.TradeNO = account.ReceiptSerialNumber
|
||||
pay.Amount = account.PaymentAmount
|
||||
pay.Gift = account.GiftAmount
|
||||
pay.Status = types.PaymentStatusPAID
|
||||
if err := c.DB.Create(pay).Error; err != nil {
|
||||
return fmt.Errorf("failed to create payment: %w", err)
|
||||
}
|
||||
if err := c.DB.Create(account).Error; err != nil {
|
||||
return fmt.Errorf("failed to create corporate: %w", err)
|
||||
}
|
||||
amount := account.PaymentAmount + account.GiftAmount
|
||||
if account.PaymentAmount > 0 {
|
||||
if err := c.UpdateWithAccount(pay.UserUID, false, true, false, amount, tx); err != nil {
|
||||
return fmt.Errorf("failed to update corporate payment amount: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/labring/sealos/controllers/pkg/types"
|
||||
)
|
||||
|
||||
@@ -115,3 +116,26 @@ func TestCockroach_InitTables(t *testing.T) {
|
||||
// t.Fatalf("AddDeductionBalanceWithCredits() error = %v", err)
|
||||
//}
|
||||
}
|
||||
|
||||
func TestCockroach_CreateCorporate(t *testing.T) {
|
||||
os.Setenv("LOCAL_REGION", "")
|
||||
ck, err := NewCockRoach("/", "")
|
||||
if err != nil {
|
||||
t.Errorf("NewCockRoach() error = %v", err)
|
||||
return
|
||||
}
|
||||
defer ck.Close()
|
||||
|
||||
cor := &types.Corporate{
|
||||
UserUID: "66EqYNUnLr",
|
||||
ReceiptSerialNumber: uuid.New().String(),
|
||||
PayerName: "payerName",
|
||||
PaymentAmount: 1_000_000,
|
||||
GiftAmount: 1_000_000,
|
||||
}
|
||||
err = ck.CreateCorporate(cor)
|
||||
if err != nil {
|
||||
t.Errorf("CreateCorporate() error = %v", err)
|
||||
}
|
||||
t.Logf("cor: %+v", cor)
|
||||
}
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
package pay
|
||||
|
||||
type RefundOption struct {
|
||||
OrderID string `json:"order_id"`
|
||||
TradeNo string `json:"trade_no"`
|
||||
Amount int64 `json:"amount"`
|
||||
OrderID string `json:"order_id"`
|
||||
RefundID string `json:"refund_id"`
|
||||
TradeNo string `json:"trade_no"`
|
||||
Amount int64 `json:"amount"`
|
||||
}
|
||||
|
||||
type Interface interface {
|
||||
|
||||
@@ -19,6 +19,8 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/core"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/services/refunddomestic"
|
||||
)
|
||||
@@ -74,10 +76,15 @@ func (w WechatPayment) RefundPayment(option RefundOption) (string, string, error
|
||||
return "", "", fmt.Errorf("order %s has not been paid or the payment time is unknown and cannot be refunded", option.TradeNo)
|
||||
}
|
||||
|
||||
_, paidAmount, err := w.GetPaymentDetails(option.TradeNo)
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("failed to query the payment order: %v", err)
|
||||
}
|
||||
|
||||
// generate a merchant refund number
|
||||
refundNo := GetRandomString(32)
|
||||
if refundNo == "" {
|
||||
return "", "", fmt.Errorf("generate refundNo failed")
|
||||
refundNo := uuid.NewString()
|
||||
if option.RefundID != "" {
|
||||
refundNo = option.RefundID
|
||||
}
|
||||
|
||||
// Amount Unit Conversion: option. Amount is the "cent", which is the same as CreatePayment (amount/10000)
|
||||
@@ -94,7 +101,7 @@ func (w WechatPayment) RefundPayment(option RefundOption) (string, string, error
|
||||
OutRefundNo: core.String(refundNo),
|
||||
Reason: core.String(fmt.Sprintf("refund for order %s", option.OrderID)),
|
||||
Amount: &refunddomestic.AmountReq{
|
||||
Total: core.Int64(refundAmt),
|
||||
Total: core.Int64(paidAmount / 10000),
|
||||
Refund: core.Int64(refundAmt),
|
||||
Currency: core.String("CNY"),
|
||||
},
|
||||
|
||||
@@ -24,9 +24,10 @@ type PaymentRaw struct {
|
||||
ActivityType ActivityType `gorm:"type:text;column:activityType"`
|
||||
Message string `gorm:"type:text;not null"`
|
||||
//TODO 初始化判断 新加字段
|
||||
CardUID *uuid.UUID `gorm:"type:uuid"`
|
||||
Type PaymentType `gorm:"type:text"` // 交易类型: AccountRecharge, Subscription,UpgradeSubscription...
|
||||
ChargeSource ChargeSource `gorm:"type:text"`
|
||||
CardUID *uuid.UUID `gorm:"type:uuid"`
|
||||
Type PaymentType `gorm:"type:text"` // 交易类型: AccountRecharge, Subscription,UpgradeSubscription...
|
||||
ChargeSource ChargeSource `gorm:"type:text"`
|
||||
Status PaymentStatus `gorm:"type:text;column:status;not null"`
|
||||
}
|
||||
|
||||
type ChargeSource string
|
||||
@@ -45,12 +46,19 @@ type PaymentOrder struct {
|
||||
}
|
||||
|
||||
type (
|
||||
PaymentStatus string
|
||||
PaymentOrderStatus string
|
||||
CardPaymentStatus string
|
||||
PaymentType string
|
||||
)
|
||||
|
||||
const (
|
||||
PaymentStatusPAID PaymentStatus = "PAID"
|
||||
PaymentStatusRefunded PaymentStatus = "REFUNDED"
|
||||
)
|
||||
|
||||
const (
|
||||
// PaymentOrderStatusPending TODO will delete
|
||||
PaymentOrderStatusPending PaymentOrderStatus = "PENDING"
|
||||
PaymentOrderStatusSuccess PaymentOrderStatus = "SUCCESS"
|
||||
PaymentOrderStatusFailed PaymentOrderStatus = "FAILED"
|
||||
@@ -218,3 +226,34 @@ func (c *CaptureResponse) Raw() []byte {
|
||||
data, _ := json.Marshal(c)
|
||||
return data
|
||||
}
|
||||
|
||||
type PaymentRefund struct {
|
||||
TradeNo string `json:"tradeNo" gorm:"type:uuid;not null"`
|
||||
ID string `json:"Id" gorm:"type:string;not null"` //外键 跟payment关联
|
||||
Method string `json:"method" gorm:"type:varchar(255);not null"` // 退款方式
|
||||
//OutTradeNo string `json:"outTradeNo" gorm:"type:uuid"`
|
||||
RefundNo string `json:"refundNo" gorm:"type:string;not null"`
|
||||
RefundAmount int64 `json:"refundAmount" gorm:"type:float;not null"`
|
||||
DeductAmount int64 `json:"deductAmount" gorm:"type:float;not null"` // 从 account的 balance里面扣款
|
||||
CreatedAt time.Time `json:"createdAt" gorm:"type:timestamp(3) with time zone;default:current_timestamp"`
|
||||
RefundReason string `json:"refundReason" gorm:"type:text"`
|
||||
}
|
||||
|
||||
func (PaymentRefund) TableName() string {
|
||||
return "PaymentRefund"
|
||||
}
|
||||
|
||||
type Corporate struct {
|
||||
UserUID string `json:"userUid" gorm:"type:string;not null"`
|
||||
ID string `json:"Id" gorm:"type:string;not null"`
|
||||
ReceiptSerialNumber string `json:"receiptSerialNumber" gorm:"type:uuid;not null"`
|
||||
PayerName string `json:"payerName" gorm:"type:varchar(255);not null"`
|
||||
PaymentAmount int64 `json:"paymentAmount" gorm:"type:float;not null"`
|
||||
GiftAmount int64 `json:"giftAmount" gorm:"type:float;not null"`
|
||||
PayDate time.Time `json:"payDate" gorm:"type:timestamp(3) with time zone;default:current_timestamp"`
|
||||
CreationDate time.Time `json:"creationDate" gorm:"type:timestamp(3) with time zone;default:current_timestamp"`
|
||||
}
|
||||
|
||||
func (Corporate) TableName() string {
|
||||
return "Corporate"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user