kra-new/internal/data/payment/payment_event.go

123 lines
4.1 KiB
Go

package payment
import (
"context"
"errors"
bizpayment "kra/internal/biz/payment"
"time"
"gorm.io/gorm"
)
type paymentEventPO struct {
ID uint64 `gorm:"primaryKey"`
Provider string `gorm:"size:64;not null;index:idx_pay_events_order,priority:1"`
TradeNo string `gorm:"size:128;not null;index:idx_pay_events_order,priority:2"`
Type string `gorm:"size:64;not null;index"`
Source string `gorm:"size:64;not null;index"`
Status string `gorm:"size:64"`
ProviderStatus string `gorm:"size:64"`
Message string `gorm:"size:512"`
EventID string `gorm:"size:128;index"`
PayloadHash string `gorm:"size:64"`
Amount int64 `gorm:"not null;default:0"`
Currency string `gorm:"size:16"`
OperatorID uint `gorm:"index"`
OperatorName string `gorm:"size:128"`
ClientIP string `gorm:"size:64"`
UserAgent string `gorm:"size:512"`
DeviceID string `gorm:"size:128"`
CreatedAt time.Time `gorm:"index"`
}
func (paymentEventPO) TableName() string { return "pay_events" }
func toBizPaymentEvent(po *paymentEventPO) *bizpayment.PaymentEvent {
if po == nil {
return nil
}
return &bizpayment.PaymentEvent{
ID: po.ID, Provider: po.Provider, TradeNo: po.TradeNo, Type: po.Type, Source: po.Source,
Status: po.Status, ProviderStatus: po.ProviderStatus, Message: po.Message, EventID: po.EventID,
PayloadHash: po.PayloadHash, Amount: po.Amount, Currency: po.Currency, OperatorID: po.OperatorID,
OperatorName: po.OperatorName, ClientIP: po.ClientIP, UserAgent: po.UserAgent, DeviceID: po.DeviceID,
CreatedAt: po.CreatedAt,
}
}
func appendPaymentEvent(ctx context.Context, tx *gorm.DB, order *paymentOrderPO, event *bizpayment.PaymentEvent) error {
if tx == nil || order == nil || event == nil {
return nil
}
eventType := trimTo(event.Type, 64)
if eventType == "" {
return errors.New("支付事件类型为空")
}
operation := bizpayment.PaymentOperationFromContext(ctx)
source := trimTo(event.Source, 64)
if source == "" {
source = trimTo(operation.Source, 64)
}
if source == "" {
source = "system"
}
message := trimTo(event.Message, 512)
if message == "" {
message = trimTo(operation.Reason, 512)
}
operatorID := event.OperatorID
if operatorID == 0 {
operatorID = operation.OperatorID
}
operatorName := trimTo(event.OperatorName, 128)
if operatorName == "" {
operatorName = trimTo(operation.OperatorName, 128)
}
clientIP := trimTo(event.ClientIP, 64)
if clientIP == "" {
clientIP = trimTo(operation.ClientIP, 64)
}
userAgent := trimTo(event.UserAgent, 512)
if userAgent == "" {
userAgent = trimTo(operation.UserAgent, 512)
}
deviceID := trimTo(event.DeviceID, 128)
if deviceID == "" {
deviceID = trimTo(operation.DeviceID, 128)
}
return tx.Create(&paymentEventPO{
Provider: order.Provider, TradeNo: order.TradeNo, Type: eventType, Source: source,
Status: trimTo(event.Status, 64), ProviderStatus: trimTo(event.ProviderStatus, 64), Message: message,
EventID: trimTo(event.EventID, 128), PayloadHash: trimTo(event.PayloadHash, 64), Amount: event.Amount,
Currency: trimTo(event.Currency, 16), OperatorID: operatorID, OperatorName: operatorName,
ClientIP: clientIP, UserAgent: userAgent, DeviceID: deviceID,
}).Error
}
func savePaymentOrderWithEvent(ctx context.Context, tx *gorm.DB, order *paymentOrderPO, event *bizpayment.PaymentEvent) error {
if err := tx.Save(order).Error; err != nil {
return err
}
return appendPaymentEvent(ctx, tx, order, event)
}
func (r *paymentOrderRepo) ListPaymentEvents(ctx context.Context, provider, tradeNo string, limit int) ([]*bizpayment.PaymentEvent, error) {
if limit <= 0 {
limit = 100
}
if limit > 500 {
limit = 500
}
var rows []paymentEventPO
if err := r.data.DB().WithContext(ctx).
Where("provider = ? AND trade_no = ?", provider, tradeNo).
Order("id DESC").Limit(limit).Find(&rows).Error; err != nil {
return nil, err
}
items := make([]*bizpayment.PaymentEvent, 0, len(rows))
for i := range rows {
items = append(items, toBizPaymentEvent(&rows[i]))
}
return items, nil
}