123 lines
4.1 KiB
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
|
|
}
|